Skip to content
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 Swift Package Manager component detection support #1316

Open
wants to merge 11 commits into
base: main
Choose a base branch
from

Conversation

raporpe
Copy link
Contributor

@raporpe raporpe commented Nov 28, 2024

Component detection does not currently support detection of Swift Package Manager. This package manager is the new default for swift-related projects now that CocoaPods (supported by Component detection) is on maintenance mode.

This new detector adds basic support to SwiftPM by parsing the JSON file Package.resolved that is generated when dependencies are resolved. This file is usually present in repositories and after building a Swift Package and its contents are enough to detect both direct and transitive dependencies.

This detector does not parse the Package.swift file (hard to parse and does not include transitive dependencies) and does not differentiate between build dependencies, transitive dependencies, and direct dependencies (it is not possible by just parsing Package.resolved).

This detector will register two kind of components: a SwiftPMComponent and a GitComponent. I have decided to also register a Git component because SwiftPM does not rely in a repository infrastructure such as NPM, it directly downloads other Swift Packages from the git repositories. I need feedback in this regard, since I do not know what is the best practice (maybe having two registered components for the same dependency is not a good idea?)

I had to invest time in troubleshooting the verification tests because I was not passing them. The issue is that the reference snapshot has less packages because the environments differ for PipReport since PR #1259. I have added the same environment vars to the snapshot-publish pipeline although maybe @pauld-msft could take a look at this PR to verify that my modification is correct.

@raporpe raporpe requested a review from a team as a code owner November 28, 2024 13:08
@raporpe raporpe requested a review from JamieMagee November 28, 2024 13:08
@raporpe
Copy link
Contributor Author

raporpe commented Nov 28, 2024

@raporpe please read the following Contributor License Agreement(CLA). If you agree with the CLA, please reply with the following information.

@microsoft-github-policy-service agree [company="{your company}"]

Options:

  • (default - no company specified) I have sole ownership of intellectual property rights to my Submissions and I am not making Submissions in the course of work for my employer.
@microsoft-github-policy-service agree
  • (when company given) I am making Submissions in the course of work for my employer (or my employer has intellectual property rights in my Submissions by contract or applicable law). I have permission from my employer to make Submissions and enter into this Agreement on behalf of my employer. By signing below, the defined term “You” includes me and my employer.
@microsoft-github-policy-service agree company="Microsoft"

Contributor License Agreement

@microsoft-github-policy-service agree company="Microsoft"

Copy link

codecov bot commented Nov 28, 2024

Codecov Report

All modified and coverable lines are covered by tests ✅

Project coverage is 89.5%. Comparing base (14b3ed3) to head (ffb3aa5).

Additional details and impacted files
@@           Coverage Diff           @@
##            main   #1316     +/-   ##
=======================================
+ Coverage   89.3%   89.5%   +0.1%     
=======================================
  Files        384     389      +5     
  Lines      30106   30609    +503     
  Branches    1840    1851     +11     
=======================================
+ Hits       26901   27405    +504     
+ Misses      2812    2811      -1     
  Partials     393     393             

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

// We also register a Git component for the same package so that the git URL is registered.
// Swift Package Manager directly downloads the package from the git URL.
var detectedGitComponent = new GitComponent(
repositoryUrl: new Uri(package.Location),
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

is this location guaranteed to be a valid Git Url? I ask because if this is missing or an unexpected location it will effectively break the parsing of all Swift components in that scan.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

When developing the detectector I tried to look into the SwiftPM documentation and found not format guarantee that this is a git url. Swift expects a repository when the kind is "remoteSourceControl". Anyway, I'm going to take a look into the SwiftPM source code to see what it's actually doing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ok I found the documentation that I needed:
Screenshot 2025-01-27 at 18 23 12

and

Screenshot 2025-01-27 at 18 19 45

and in the source code they are verifying that the URL is a valid git repository because SwiftPM depends on git tags to be able to download the specified version.

This is the source code where they are doing it:

Screenshot 2025-01-27 at 18 18 26 Screenshot 2025-01-27 at 18 18 43

So yes, I would say it's very very probable that this is almost always going to be a valid git url for most cases.

These are all the available "Kinds" of packages and I'm covering one of the most common, which is the git url. I think that SwiftPM registries are not that common.

Screenshot 2025-01-27 at 17 53 26

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As you told me in teams, I will make sure to enclose each for loop iteration with a try so that if a single dependency fails the rest of dependencies will be registered 👍🏼

type: "swift",
@namespace: new Uri(this.packageUrl).Host,
name: this.Name,
version: this.hash, // Hash has priority over version when creating a PackageURL
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

have you confirmed in PURL spec hash is what is used as opposed to version? These are not meant to be arbitrary. We should be aligned with the spec has defined for Swift, I don't recall seeing hashes for purls in the past. See sample Swift PURL and purl-spec

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants