From 9515d88a730a139c52245832122774b56ed29f68 Mon Sep 17 00:00:00 2001 From: Justin Hutchings Date: Mon, 18 Apr 2022 04:20:25 +0000 Subject: [PATCH 1/4] Add Paket support --- README.md | 2 +- .../nuget/NuGetComponentDetector.cs | 27 +++++++++++- .../NuGetComponentDetectorTests.cs | 44 +++++++++++++++++++ 3 files changed, 71 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index a72890916..5b129da11 100644 --- a/README.md +++ b/README.md @@ -29,7 +29,7 @@ ComponentDetection is a package scanning tool intended to be used at build time. | Go | ✔ | ❌ | | Maven | ✔ | ✔ | | NPM (including Yarn, Pnpm) | ✔ | ✔ | -| NuGet | ✔ | ✔ | +| NuGet (including Paket) | ✔ | ✔ | | Pip (Python) | ✔ | ✔ | | Poetry (Python, lockfiles only) | ✔ | ❌ | | Ruby | ✔ | ✔ | diff --git a/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs b/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs index d93dc9911..d67a99d3a 100644 --- a/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs +++ b/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Reactive.Linq; +using System.Text.RegularExpressions; using System.Threading.Tasks; using System.Xml; using System.Xml.Linq; @@ -21,7 +22,7 @@ public class NuGetComponentDetector : FileComponentDetector public override IEnumerable Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.NuGet) }; - public override IList SearchPatterns { get; } = new List { "*.nupkg", "*.nuspec", NugetConfigFileName }; + public override IList SearchPatterns { get; } = new List { "*.nupkg", "*.nuspec", NugetConfigFileName, "paket.lock" }; public override IEnumerable SupportedComponentTypes { get; } = new[] { ComponentType.NuGet }; @@ -90,6 +91,10 @@ private async Task ProcessFile(ProcessRequest processRequest) { nuspecBytes = await NuGetNuspecUtilities.GetNuspecBytesFromNuspecStream(stream.Stream, stream.Stream.Length); } + else if ("paket.lock".Equals(stream.Pattern, StringComparison.OrdinalIgnoreCase)) + { + ParsePaketLock(processRequest); + } else { return; @@ -125,6 +130,26 @@ private async Task ProcessFile(ProcessRequest processRequest) } } + private void ParsePaketLock(ProcessRequest processRequest) { + var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder; + var stream = processRequest.ComponentStream; + + using StreamReader reader = new StreamReader(stream.Stream); + + string line; + while ((line = reader.ReadLine()) != null) + { + var matches = Regex.Matches(line, @"\s*([a-zA-Z0-9-.]*) \([<>=]*[ ]*([0-9a-zA-Z-.]*)\)", RegexOptions.Singleline); + foreach (Match match in matches) + { + string name = match.Groups[1].Value; + string version = match.Groups[2].Value; + NuGetComponent component = new NuGetComponent(name, version); + singleFileComponentRecorder.RegisterUsage(new DetectedComponent(component)); + } + } + } + private IList GetRepositoryPathsFromNugetConfig(IComponentStream componentStream) { List potentialPaths = new List(); diff --git a/test/Microsoft.ComponentDetection.Detectors.Tests/NuGetComponentDetectorTests.cs b/test/Microsoft.ComponentDetection.Detectors.Tests/NuGetComponentDetectorTests.cs index a88b0238f..04c8e98ca 100644 --- a/test/Microsoft.ComponentDetection.Detectors.Tests/NuGetComponentDetectorTests.cs +++ b/test/Microsoft.ComponentDetection.Detectors.Tests/NuGetComponentDetectorTests.cs @@ -111,6 +111,50 @@ public async Task TestNugetDetector_ReturnsValidMixedComponent() Assert.AreEqual(2, componentRecorder.GetDetectedComponents().Count()); } + [TestMethod] + public async Task TestNugetDetector_ReturnsValidPaketComponent() + { + var paketLock = @" +NUGET + remote: https://nuget.org/api/v2 + Castle.Core (3.3.0) + Castle.Core-log4net (3.3.0) + Castle.Core (>= 3.3.0) + log4net (1.2.10) + Castle.LoggingFacility (3.3.0) + Castle.Core (>= 3.3.0) + Castle.Windsor (>= 3.3.0) + Castle.Windsor (3.3.0) + Castle.Core (>= 3.3.0) + Castle.Windsor-log4net (3.3.0) + Castle.Core-log4net (>= 3.3.0) + Castle.LoggingFacility (>= 3.3.0) + Rx-Core (2.2.5) + Rx-Interfaces (>= 2.2.5) + Rx-Interfaces (2.2.5) + Rx-Linq (2.2.5) + Rx-Interfaces (>= 2.2.5) + Rx-Core (>= 2.2.5) + Rx-Main (2.2.5) + Rx-Interfaces (>= 2.2.5) + Rx-Core (>= 2.2.5) + Rx-Linq (>= 2.2.5) + Rx-PlatformServices (>= 2.2.5) + Rx-PlatformServices (2.2.5) + Rx-Interfaces (>= 2.2.5) + Rx-Core (>= 2.2.5) + log4net (1.2.10) + "; + + var (scanResult, componentRecorder) = await detectorTestUtility + .WithFile("paket.lock", paketLock) + .ExecuteDetector(); + + Assert.AreEqual(ProcessingResultCode.Success, scanResult.ResultCode); + // While there are 26 lines in the sample, several dependencies are identical, so there are only 11 matches. + Assert.AreEqual(11, componentRecorder.GetDetectedComponents().Count()); + } + [TestMethod] public async Task TestNugetDetector_HandlesMalformedComponentsInComponentList() { From de4cb16b2e2f58c274c2ab1a6d5ed63ada951bae Mon Sep 17 00:00:00 2001 From: amitla1 <46578839+amitla1@users.noreply.github.com> Date: Mon, 29 Aug 2022 17:41:54 -0700 Subject: [PATCH 2/4] Update NuGetComponentDetector.cs --- .../nuget/NuGetComponentDetector.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs b/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs index c37895e90..c7da06da5 100644 --- a/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs +++ b/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs @@ -135,7 +135,8 @@ private async Task ProcessFile(ProcessRequest processRequest) } } - private void ParsePaketLock(ProcessRequest processRequest) { + private void ParsePaketLock(ProcessRequest processRequest) + { var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder; var stream = processRequest.ComponentStream; From 443eebd2fcc44fc61584fb5d595a614085fad0e0 Mon Sep 17 00:00:00 2001 From: amitla1 <46578839+amitla1@users.noreply.github.com> Date: Mon, 29 Aug 2022 17:42:31 -0700 Subject: [PATCH 3/4] Remove whitespace --- .../nuget/NuGetComponentDetector.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs b/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs index c7da06da5..2e520134b 100644 --- a/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs +++ b/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs @@ -143,7 +143,7 @@ private void ParsePaketLock(ProcessRequest processRequest) using StreamReader reader = new StreamReader(stream.Stream); string line; - while ((line = reader.ReadLine()) != null) + while ((line = reader.ReadLine()) != null) { var matches = Regex.Matches(line, @"\s*([a-zA-Z0-9-.]*) \([<>=]*[ ]*([0-9a-zA-Z-.]*)\)", RegexOptions.Singleline); foreach (Match match in matches) From f0fa38387cac7690970aaa8bce53aef3a12aa908 Mon Sep 17 00:00:00 2001 From: amitla1 <46578839+amitla1@users.noreply.github.com> Date: Mon, 29 Aug 2022 19:06:05 -0700 Subject: [PATCH 4/4] Remove white spaces --- .../nuget/NuGetComponentDetector.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs b/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs index 2e520134b..10cd87105 100644 --- a/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs +++ b/src/Microsoft.ComponentDetection.Detectors/nuget/NuGetComponentDetector.cs @@ -135,7 +135,7 @@ private async Task ProcessFile(ProcessRequest processRequest) } } - private void ParsePaketLock(ProcessRequest processRequest) + private void ParsePaketLock(ProcessRequest processRequest) { var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder; var stream = processRequest.ComponentStream; @@ -146,7 +146,7 @@ private void ParsePaketLock(ProcessRequest processRequest) while ((line = reader.ReadLine()) != null) { var matches = Regex.Matches(line, @"\s*([a-zA-Z0-9-.]*) \([<>=]*[ ]*([0-9a-zA-Z-.]*)\)", RegexOptions.Singleline); - foreach (Match match in matches) + foreach (Match match in matches) { string name = match.Groups[1].Value; string version = match.Groups[2].Value;