-
Notifications
You must be signed in to change notification settings - Fork 113
Change Rust/Cargo detector to be lock file based #117
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
Conversation
arlosi
left a comment
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.
I'm not an expert in CG, but I think this makes sense to get Cargo support to stop missing dependencies as mentioned in #116 - even if it means we give up dev-dependency detection for now.
src/Microsoft.ComponentDetection.Contracts/TypedComponent/CargoComponent.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Contracts/TypedComponent/CargoComponent.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/rust/Contracts/CargoPackage.cs
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/rust/RustCrateDetector.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/rust/RustCrateDetector.cs
Outdated
Show resolved
Hide resolved
src/Microsoft.ComponentDetection.Detectors/rust/RustCrateDetector.cs
Outdated
Show resolved
Hide resolved
ad8b3f2 to
42ba5f2
Compare
|
Hey @arlosi and @danielframpton, is there anything else blocking this pr? It would be nice to have component detection in good shape for rust. Thanks! |
|
It needs review from the maintainers. Neither @danielframpton nor I can approve it. |
|
Thanks @arlosi, @jcfiorenzano @cobya do you think this can be merged? Do you miss something before it can be approved? |
42ba5f2 to
d8a3cbc
Compare
|
I have simplified this PR to focus on the source of dependencies (lock vs toml) deferring the question of multiple registries to see if we can land the highest priority part this change. |
| if (packagesByName.TryGetValue(cargoPackage.name, out var packageList)) | ||
| { | ||
| if (packageList.Any(p => p.package.Equals(cargoPackage))) | ||
| { | ||
| // Ignore duplicate packages | ||
| continue; | ||
| } | ||
| } |
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.
Should there be an else here? Or can these two conditionals be combined?
| { | ||
| try | ||
| { | ||
| // Extract the informationfrom the dependency (name with optional version and source) |
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.
| // Extract the informationfrom the dependency (name with optional version and source) | |
| // Extract the information from the dependency (name with optional version and source) |
| @"^([^ ]+)(?: ([^ ]+))?(?: \(([^()]*)\))?$", | ||
| RegexOptions.Compiled); | ||
|
|
||
| private const int PackageNameGroup = 1; | ||
| private const int VersionGroup = 2; | ||
| private const int SourceGroup = 3; | ||
|
|
||
| private static bool ParseDependency(string dependency, out string packageName, out string version, out string source) | ||
| { | ||
| var match = DependencyFormatRegex.Match(dependency); | ||
| packageName = match.Groups[PackageNameGroup].Success ? match.Groups[PackageNameGroup].Value : null; | ||
| version = match.Groups[VersionGroup].Success ? match.Groups[VersionGroup].Value : null; | ||
| source = match.Groups[SourceGroup].Success ? match.Groups[SourceGroup].Value : null; |
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.
nit: named groups1
| @"^([^ ]+)(?: ([^ ]+))?(?: \(([^()]*)\))?$", | |
| RegexOptions.Compiled); | |
| private const int PackageNameGroup = 1; | |
| private const int VersionGroup = 2; | |
| private const int SourceGroup = 3; | |
| private static bool ParseDependency(string dependency, out string packageName, out string version, out string source) | |
| { | |
| var match = DependencyFormatRegex.Match(dependency); | |
| packageName = match.Groups[PackageNameGroup].Success ? match.Groups[PackageNameGroup].Value : null; | |
| version = match.Groups[VersionGroup].Success ? match.Groups[VersionGroup].Value : null; | |
| source = match.Groups[SourceGroup].Success ? match.Groups[SourceGroup].Value : null; | |
| @"^(?<packageName>[^ ]+)(?: (?<version>[^ ]+))?(?: \((?<source>[^()]*)\))?$", | |
| RegexOptions.Compiled); | |
| private static bool ParseDependency(string dependency, out string packageName, out string version, out string source) | |
| { | |
| var match = DependencyFormatRegex.Match(dependency); | |
| packageName = match.Groups["packageName"].Success ? match.Groups["packageName"].Value : null; | |
| version = match.Groups["version"].Success ? match.Groups["version"].Value : null; | |
| source = match.Groups["source"].Success ? match.Groups["source"].Value : null; |
Footnotes
|
@danielframpton are the verification tests for rust still sufficient, or do they need updating as well? |
JamieMagee
left a comment
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.
Approved pending comments
|
Snapshot tests are expected to fail due to changes in the detector. |
|
@danielframpton Do you have time to address the comments and resolve conflicts? |
| if (!IsLocalPackage(package) && !seenAsDependency.Contains(package)) | ||
| { | ||
| var detectedComponent = new DetectedComponent(component); | ||
| singleFileComponentRecorder.RegisterUsage(detectedComponent, isExplicitReferencedDependency: true); |
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.
What happened to dev dependency detection? Is that being considered in these updates, if so, how will those be treated now? Users won't like to start picking up dependencies as regular build time dependencies when they used to be dev dependencies.
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.
This does not report dev dependencies separately (e.g., they are included alongside other dependencies as well) as that information is not currently included in the lock file. Unfortunately, there isn't an obvious middle ground here between having something that is simple and robust (lock file processing) or replicating the full functionality of cargo.
This change puts us in the position of not missing dependencies, with the option to (in the future) introduce a tool that uses cargo to get a more accurate picture (either directly or by consuming SBOMs generated from cargo).
|
@danielframpton Do we believe this PR is on track for September? |
d8a3cbc to
45fc653
Compare
Review feedback Revert inclusion of registry in package identity for the initial change PR feedback and adding a multiple registry test (to validate that it doesn't cause problems)
45fc653 to
ae9ca2f
Compare
|
@danielframpton thanks for deconflicting this PR ❤️ I just wanted to double check with you that you're good with this being merged? |
|
Thanks @JamieMagee! I am, I have responded to all the feedback and updated across the code analysis fixes. Let me know if there is anything I have missed. |
|
👋 Hi! It looks like you modified some files in the
If none of the above scenarios apply, feel free to ignore this comment 🙂 |
This is a significant change to Rust component detection to solely use the
Cargo.lockfile to detect component usage (e.g., no longer processingCargo.toml).As discussed in #116 there are several issues with the existing
Cargo.tomlprocessing that this change sidesteps by reporting all crates fromCargo.lock.This change also explicitly includes the package registry in the identifier for components. I have not investigated what implications there may be for this to downstream tools, but because Cargo has support for multiple registries the package name and version number is insufficient to identify the package (because of multiple registries or a local package with the same name as one published in the registry).
In general, the sole use of the
Cargo.lockfile should strictly increase the number of crates reported, although I did observe some reductions that were due to this change no longer reporting some local/path crates as components (because they had a version and path specified) but I believe this was unintentional/unexpected.There was also significant duplication in the code between v1 and v2 detectors, but in rewriting the logic to process the lock file I was able to use the same logic for both formats.
I expect this to need a careful review and some changes before landing, but I wanted to send out the PR to make some progress on getting these issues resolved.
Fixes #116