Local Swift packages in workspace are not scanned
I have a workspace that contains an xcodeproj with my app target, and a handful of local Swift packages that the app depends on. The local swift packages are top-level in the workspace, alongside the project for my app. The packages are all iOS specific, so I'm building separately and passing the index-store-path:
xcodebuild -quiet -scheme $my_app_target -destination 'generic/platform=iOS' -derivedDataPath $my_index_store_path build
periphery scan --skip-build --index-store-path "${my_index_store_path}/Index.noindex/DataStore" --verbose
.periphery.yml:
retain_objc_accessible: true
schemes:
# list of all my local swift package schemes
targets:
- MyAppTarget
workspace: MyWorkspace.xcworkspace
The command runs without any errors and detects unused code, but only in my app target. [index:swift:phase:one] and [index:swift:phase:two] only list Swift files that are part of my app target, and do not list any files in my local packages.
It looks like https://github.com/peripheryapp/periphery/pull/455 added support for this, but maybe it only works for local packages that are part of a project, not a workspace.
https://github.com/peripheryapp/periphery#how-to-use
To get coherent results from Periphery, it's crucial to understand the implications of the build targets you choose to analyze. For example, imagine a project consisting of three targets: App, Lib and Tests. The App target imports Lib, and the Tests targets imports both App and Lib. If you were to provide all three to the --targets option then Periphery will be able to analyze your project as a whole. However, if you only choose to analyze App and Lib, but not Tests, Periphery may report some instances of unused code that are only referenced by Tests. Therefore when you suspect Periphery has provided an incorrect result, it's important to consider the targets that you have chosen to analyze.
You need to also specify the local package targets, try using scan --setup to begin with.
I used scan --setup but it does not find the local package targets in the workspace. If I manually specify the local package targets and run scan, I get error: Target 'MyLocalPackageTarget' does not exist in 'MyWorkspace.xcworkspace'.
I did get it to work by moving all my local packages inside my apps project, which is inside the workspace, but that's a change I have to undo after running the tool since I need my local packages to be top-level in the workspace.
@harrisonfriia Can you please provide a sample project that demonstrates the issue? It's very hard for me to implement a fix for this without being able to inspect the pbxproj.
i have a similar setup with a workspace containing a project and a set of local dependencies that live in a directory in the root folder along with the workspace and project.
i'm also seeing similar behavior where Periphery only returns results for the application target when what i'm really interested in is seeing unused code in the local frameworks that isn't referenced anywhere in the the application target's dependency graph.
here's a workspace configured similar to the one i'm working on: https://github.com/im-jersh/PeripheryLocalPackages
as @harrisonfriia mentioned, i was able to add the local package as a dependency to the project and then Periphery would see it as an option to analyze. however, this configuration didn't seem to produce the correct results.
I got similar troubles with local dependencies. I'm working on the task of adding local packages (as in the example of @im-jersh) to the scanning area of the Periphery, but it looks like it didn't produce needed results. This packages aren't got their own targets but added as libraries in FrameWorks, Libraries and Embedded Content in General properties of my main target. Is there any possibilities to add list of "interesting" local packages to Periphery scan properties?
@ileitch would love to offer any help i can to move this forward! would you be able to point out the specific pbxproj configurations that you were hoping to see in my example project? with a little direction i could dig into this myself and see if i can work out this issue
I'm also interested in this 👀 subscribing to this thread
@im-jersh Sorry, I missed your previous comment with the example project, thanks for providing this! The crux of the issue here is that in Xcode <= 14.3.1 local package are poorly represented in the pbxproj. Periphery's support is a hack that scans through PBXFileReference to find the paths to the local packages. Your example project does not contain these references.
It's simple enough to fix though. Using Xcode <= 14.3.1 (explained below), add the local packages on the Package Dependencies section of the project.
After the adding the package, it may not show up in the package list (good job, Apple), but it will have modified the pbxproj with the PBXFileReference.
Now when you run periphery scan --setup, you'll see the local package targets:
In Xcode 15, Apple have improved the internal presentation of local packages, however tuist/XcodeProj doesn't yet support parsing this new format, so for now you'll need to use 14.3 when adding local packages.
that was it! appreciate the thoughtful response. could've sworn i had tested that configuration but i guess not 🤷.
not surprised this is what was causing my issues in the actual workspace i'm attempting to analyze. that one has quite a few more local packages within it and i likely elected to forego adding that local package reference to the pbxproj since it's not necessary for compilation/linking.
and thank you for pointing out the lack of Xcode 15 support. i'm actually in the the tail end of validating local builds and updating our CI to Xcode 15 so this info will likely save me a few hours of headaches.
are there any documentation updates that i could offer to open in a PR to help anyone else with this workspace configuration and looking to integrate Periphery? maybe just in the README?
looks like you also need to include the frameworks under the target's Framework, Libraries, and Embedded Content in order for Periphery to see them as build targets that can be analyzed
i also just confirmed this worked for the actual workspace i want to analyze!!
This still is an issue on XCode 15. The local package target is not visible to periphery even though the scheme is visible. Tested on 2.18.0