-
Notifications
You must be signed in to change notification settings - Fork 593
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add cataloger for Swift Package Manager. #1919
Add cataloger for Swift Package Manager. #1919
Conversation
74ba142
to
cc5bc75
Compare
Thanks for the contribution @trilleplay! I ran this against: https://github.com/mozilla-mobile/firefox-ios to get a better idea of what we are now picking up with this addition. The answer is a ton: VS I'm going to go through the PR a bit more in detail to add any comments or questions, but from first glance this is excellent |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Small comments just getting a discussion going about parts I don't understand - thanks again so much for the PR and the time/effort on this one - looking forward to getting it merged!
@@ -54,6 +54,8 @@ func SourceInfo(p pkg.Package) string { | |||
answer = "acquired package info from nix store path" | |||
case pkg.Rpkg: | |||
answer = "acquired package info from R-package DESCRIPTION file" | |||
case pkg.SwiftPkg: | |||
answer = "acquired package info from resolved Swift package manifest" |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this description correct?
I'm pretty inexperienced with the Swift ecosystem, but the docs I've read describe the package manifest file as the Package.swift
file. When I run the branch against a swift project I see packages sourced from Package.resolved
<-- is there a different name for this file or is this also a manifest?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The Package.swift
file describes a package (i.e something that would be distributed with Swift Package Manager), meanwhile the Package.resolved
file describes dependencies that the project depends on. The Package.resolved
file is the result of looking up the dependencies of the given project, so it's a standalone manifest.
*/ | ||
package swift | ||
|
||
import ( | ||
"github.com/anchore/syft/syft/pkg/cataloger/generic" | ||
) | ||
|
||
func NewSwiftPackageManagerCataloger() *generic.Cataloger { | ||
return generic.NewCataloger("spm-cataloger"). | ||
WithParserByGlobs(parsePackageResolved, "**/Package.resolved", "**/.package.resolved") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any other globs that we should consider for a swift project that would contain dependencies managed by the package manager?
I noticed the command swift package show-dependencies
and didn't know if it sourced this graph from other local files.
Example - I ran swift packages show-dependencies
for https://github.com/mozilla-mobile/firefox-ios
.
├── swift<https://github.com/danger/[email protected]>
│ ├── logger<https://github.com/shibapm/[email protected]>
│ ├── version<https://github.com/mxcl/[email protected]>
│ └── octokit.swift<https://github.com/nerdishbynature/[email protected]>
│ └── requestkit<https://github.com/nerdishbynature/[email protected]>
└── danger-swift-coverage<https://github.com/f-meloni/[email protected]>
└── swift<https://github.com/danger/[email protected]>
├── logger<https://github.com/shibapm/[email protected]>
├── version<https://github.com/mxcl/[email protected]>
└── octokit.swift<https://github.com/nerdishbynature/[email protected]>
└── requestkit<https://github.com/nerdishbynature/[email protected]>
But that seems like it contains a lot less than what we resolved in the SBOM:
➜ firefox-ios git:(main) ✗ syft dir:. --name firefox-ios | grep swift
Flag --name has been deprecated, use: source-name
✔ Indexed file system .
✔ Cataloged packages [678 packages]
Commandant 0.17.0 swift
CwlCatchException 1.2.0 swift
CwlPreconditionTesting 1.2.0 swift
DangerXCodeSummary 1.1.0 swift
Komondor 1.0.4 swift
Komondor 1.1.4 swift
Logger 0.2.3 swift
Nimble 7.3.1 swift
Nimble 8.0.5 swift
OctoKit 0.10.0 swift
OctoKit 0.12.0 swift
PackageConfig 0.13.0 swift
PackageConfig 1.1.3 swift
Quick 1.3.2 swift
Quick 2.2.0 swift
RequestKit 2.4.0 swift
RequestKit 3.1.0 swift
RequestKit 3.2.0 swift
RequestKit 3.2.1 swift
Rocket 1.0.0 swift
Rocket 1.2.1 swift
SWXMLHash 5.0.1 swift
SWXMLHash 6.0.0 swift
ShellOut 2.3.0 swift
SourceKitten 0.28.0 swift
SourceKitten 0.32.0 swift
SwiftFormat 0.43.5 swift
SwiftFormat 0.50.5 swift
SwiftLint 0.38.2 swift
SwiftLint 0.48.0 swift
SwiftShell 5.0.1 swift
SwiftShell 5.1.0-beta.1 swift
SwiftSyntax 0.50600.1 swift
SwiftyTextTable 0.9.0 swift
TestSpy 0.3.1 swift
Version 1.2.0 swift
Version 2.0.1 swift
Yams 2.0.0 swift
Yams 4.0.6 swift
a-star 3.0.0-beta-1 swift
danger-swift 3.0.0 swift
danger-swift-coverage 1.2.1 swift
dip 7.1.1 swift
fuzi swift
gcdwebserver swift
glean-swift 53.0.0 swift
ios_sdk 4.33.4 swift
kif 3.8.7 swift
kingfisher 7.6.2 swift
logger 0.2.3 swift
mappamundi swift
octokit.swift 0.12.0 swift
requestkit 3.2.1 swift
rust-components-swift 117.0.20230711050401 swift
sentry-cocoa 8.8.0 swift
snapkit 5.6.0 swift
swift 3.16.0 swift
swift-argument-parser 1.0.3 swift
swift-snapshot-testing 1.10.0 swift
swiftybeaver 2.0.0 swift
swiftyjson 5.0.1 swift
telemetry-ios 2.0.0 swift
version 2.0.1 swift
Also I noticed that this list is much longer a second time around after running a few swift package
commands.
Is the user expected to have resolved/downloaded certain dependency information before generating the SBOM for this cataloger to produce the optimal package output?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The user is expected to have resolved packages (this can be done by building an App which depends on SPM packages) otherwise a Package.resolved
file is not generated.
Without knowing what you did in those swift package commands, it could be that you resolved more package information, but at a different level. My guess is that a target specific dependency got resolved at the root-project level, this part touches a bit on the question you had about the globs, as far as they go, it's my understanding that .package.resolved
file contains the root level dependencies, whilst the Package.resolved
files contain the packages that are specific to targets. So could be that one of the commands you added changed the scope of where the dependencies were resolved, is my best guess. I'm by no means an expert of swift package manager.
Version string `json:"version"` | ||
} | ||
|
||
// parsePackageResolved is a parser for the contents of a Package.resolved file, which is generated by Xcode after it's resolved Swift Package Manger packages. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Are there any relationships we should consider between Packages
that are resolved from the ./Package.resolved
vs ./.builds/checkout
or other locations that a .resolved
file might be found?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The relationship to be considered could be the target specific ones, if a resolved file is in only a certain target directory, it might indicate it's only required for that specific target.
I'm actually a bit uncertain as far as ./.builds/
go (once again no Swift Package Manager expert), I don't remember seeing that in my testing, but I do know that the location of the resolved file does depend on how you resolved, so it differs from CLI and Xcode, when it comes to resolving packages. So could be why I did not see that file in my testing?
Signed-off-by: Tristan Farkas <[email protected]>
cc5bc75
to
13dd2d1
Compare
Rebased on main. |
Thanks for the rebase and comments back on this @trilleplay! I'll bring this up at one of our team sync's today and look to try and get this merged for the next release - thanks again for all the work you put in here! |
Thanks for the merge @spiffcs ! 😁 |
Signed-off-by: Tristan Farkas <[email protected]>
This PR adds support for parsing
Package.resolved
files, which are generated by Swift Package Manager.