Skip to content

Commit 15eb5fa

Browse files
author
Tom Fay
authored
Fix Rust component detector to support "x.y.z" version specifiers in Cargo.toml (#43)
* Handle "x.y.z" version specifiers like "^x.y.z" To match cargo's behaviour * Don't allow caret/tilde requirements with wildcard * enforce whole regex match for tilde/caret reqs so that 1.2.* isn't interpreted as ^1.2.* * bump detector versions
1 parent 8b392ce commit 15eb5fa

6 files changed

Lines changed: 75 additions & 17 deletions

File tree

.devcontainer/Dockerfile

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
11
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.202.1/containers/dotnet/.devcontainer/base.Dockerfile
22

33
# [Choice] .NET version: 6.0, 5.0, 3.1, 2.1
4-
ARG VARIANT="6.0"
5-
#FROM mcr.microsoft.com/vscode/devcontainers/dotnet:0-${VARIANT}
6-
FROM mcr.microsoft.com/vscode/devcontainers/dotnet:dev-6.0
4+
ARG VARIANT="3.1"
5+
FROM mcr.microsoft.com/vscode/devcontainers/dotnet:dev-${VARIANT}
76

87
# [Choice] Node.js version: none, lts/*, 16, 14, 12, 10
98
ARG NODE_VERSION="none"

.devcontainer/devcontainer.json

Lines changed: 5 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,28 @@
22
// https://github.com/microsoft/vscode-dev-containers/tree/v0.202.1/containers/dotnet
33
{
44
"name": "C# (.NET)",
5-
"runArgs": ["--init"],
5+
"runArgs": [
6+
"--init"
7+
],
68
"build": {
79
"dockerfile": "Dockerfile",
8-
"args": {
10+
"args": {
911
// Update 'VARIANT' to pick a .NET Core version: 2.1, 3.1, 5.0, 6.0
10-
"VARIANT": "6.0",
12+
"VARIANT": "3.1",
1113
// Options
1214
"NODE_VERSION": "lts/*",
1315
"INSTALL_AZURE_CLI": "false"
1416
}
1517
},
16-
1718
// Set *default* container specific settings.json values on container create.
1819
"settings": {},
19-
2020
// Add the IDs of extensions you want installed when the container is created.
2121
"extensions": [
2222
"ms-dotnettools.csharp",
2323
"vsls-contrib.codetour"
2424
],
25-
2625
// Use 'forwardPorts' to make a list of ports inside the container available locally.
2726
// "forwardPorts": [5000, 5001],
28-
2927
// [Optional] To reuse of your local HTTPS dev cert:
3028
//
3129
// 1. Export it locally using this command:
@@ -48,10 +46,8 @@
4846
//
4947
// * If only using Remote - Containers with a local container, uncomment this line instead:
5048
// "mounts": [ "source=${env:HOME}${env:USERPROFILE}/.aspnet/https,target=/home/vscode/.aspnet/https,type=bind" ],
51-
5249
// Use 'postCreateCommand' to run commands after the container is created.
5350
"postCreateCommand": "dotnet restore",
54-
5551
// Comment out connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root.
5652
// "remoteUser": "vscode",
5753
"features": {

src/Microsoft.ComponentDetection.Detectors/rust/RustCrateDetector.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class RustCrateDetector : FileComponentDetector
2121

2222
public override IEnumerable<ComponentType> SupportedComponentTypes => new[] { ComponentType.Cargo };
2323

24-
public override int Version { get; } = 4;
24+
public override int Version { get; } = 5;
2525

2626
public override IEnumerable<string> Categories => new List<string> { "Rust" };
2727

src/Microsoft.ComponentDetection.Detectors/rust/RustCrateV2Detector.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ public class RustCrateV2Detector : FileComponentDetector
2121

2222
public override IEnumerable<ComponentType> SupportedComponentTypes => new[] { ComponentType.Cargo };
2323

24-
public override int Version { get; } = 3;
24+
public override int Version { get; } = 4;
2525

2626
public override IEnumerable<string> Categories => new List<string> { "Rust" };
2727

src/Microsoft.ComponentDetection.Detectors/rust/SemVer/Desugarer.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,12 +17,17 @@ internal static class Desugarer
1717
{
1818
private const string VersionChars = @"[0-9a-zA-Z\-\+\.\*]";
1919

20+
// tilde and caret requirements can't also have wildcards in them
21+
private const string VersionCharsNoWildcard = @"[0-9a-zA-Z\-\+\.]";
22+
2023
private static readonly Regex TildePatternRegex = new Regex(
21-
$@"^\s*~\s*({VersionChars}+)\s*",
24+
$@"^\s*~\s*({VersionCharsNoWildcard}+)\s*$",
2225
RegexOptions.Compiled);
2326

27+
// The caret is optional, as Cargo treats "x.y.z" like "^x.y.z":
28+
// https://doc.rust-lang.org/cargo/reference/specifying-dependencies.html#specifying-dependencies-from-cratesio
2429
private static readonly Regex CaretPatternRegex = new Regex(
25-
$@"^\s*\^\s*({VersionChars}+)\s*",
30+
$@"^\s*\^?\s*({VersionCharsNoWildcard}+)\s*$",
2631
RegexOptions.Compiled);
2732

2833
private static readonly Regex HyphenPatternRegex = new Regex(
@@ -241,4 +246,4 @@ private static Comparator[] MinMaxComparators(SemVersion minVersion, SemVersion
241246
}
242247
}
243248
}
244-
}
249+
}

test/Microsoft.ComponentDetection.Detectors.Tests/RustCrateDetectorTests.cs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -729,6 +729,64 @@ public async Task TestRustV2Detector_WorkspacesWithSubDirectories()
729729
componentRecorder.ForAllComponents(x => x.AllFileLocations.Count().Should().Be(4));
730730
}
731731

732+
[TestMethod]
733+
public async Task TestRustDetector_UnequalButSemverCompatibleRoot()
734+
{
735+
var testTomlString = @"
736+
[package]
737+
name = ""test""
738+
version = ""0.1.0""
739+
edition = ""2021""
740+
741+
[dependencies]
742+
c-ares = ""7.1.0""
743+
";
744+
var testLockString = @"
745+
[[package]]
746+
name = ""c-ares""
747+
version = ""7.5.2""
748+
source = ""registry+https://github.com/rust-lang/crates.io-index""
749+
checksum = ""a8554820e0b20a1b58b4626a3477fa4bccb1f8ee75c61ef547d50523a517126f""
750+
dependencies = [
751+
""c-ares-sys"",
752+
]
753+
754+
[[package]]
755+
name = ""c-ares-sys""
756+
version = ""5.3.3""
757+
source = ""registry+https://github.com/rust-lang/crates.io-index""
758+
checksum = ""067403b940b1320de22c347323f2cfd20b7c64b5709ab47928f5eb000e585fe0""
759+
760+
[[package]]
761+
name = ""test""
762+
version = ""0.1.0""
763+
dependencies = [
764+
""c-ares"",
765+
]
766+
";
767+
var (result, componentRecorder) = await detectorV2TestUtility
768+
.WithFile("Cargo.lock", testLockString)
769+
.WithFile("Cargo.toml", testTomlString, new List<string> { "Cargo.toml" })
770+
.ExecuteDetector();
771+
772+
Assert.AreEqual(ProcessingResultCode.Success, result.ResultCode);
773+
Assert.AreEqual(2, componentRecorder.GetDetectedComponents().Count());
774+
775+
var graph = componentRecorder.GetDependencyGraphsByLocation().Values.First(); // There should only be 1
776+
777+
// Verify explicitly referenced roots
778+
var rootComponents = new List<string>
779+
{
780+
"c-ares 7.5.2 - Cargo",
781+
};
782+
783+
rootComponents.ForEach(rootComponentId => graph.IsComponentExplicitlyReferenced(rootComponentId).Should().BeTrue());
784+
785+
// Verify dependencies for other_dependency
786+
var cAresDependencies = new List<string> { "c-ares-sys 5.3.3 - Cargo" };
787+
graph.GetDependenciesForComponent("c-ares 7.5.2 - Cargo").Should().BeEquivalentTo(cAresDependencies);
788+
}
789+
732790
/// <summary>
733791
/// (my_dependency, 1.0, root)
734792
/// (my_other_dependency, 0.1.0, root)

0 commit comments

Comments
 (0)