-
Notifications
You must be signed in to change notification settings - Fork 91
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Initial implementation of VcpkgDetector and VcpkgComponent (#52)
* Initial implementation of VcpkgDetector and VcpkgComponent * Fix warnings * Initial implementation of VcpkgDetector and VcpkgComponent * Fix warnings * Update src/Microsoft.ComponentDetection.Detectors/vcpkg/VcpkgComponentDetector.cs * Address PR comments. Add parsing for Annotations. * Use DateTime property for annotation object * Add tests for VcpkgComponentDetector * Satisfy format detector * Update src/Microsoft.ComponentDetection.Detectors/vcpkg/VcpkgComponentDetector.cs Co-authored-by: Greg Villicana <[email protected]>
- Loading branch information
1 parent
9c00871
commit a990db1
Showing
10 changed files
with
659 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -44,8 +44,11 @@ public enum ComponentType : byte | |
|
||
[EnumMember] | ||
Conda = 13, | ||
|
||
[EnumMember] | ||
Spdx = 14, | ||
|
||
[EnumMember] | ||
Vcpkg = 15, | ||
} | ||
} |
73 changes: 73 additions & 0 deletions
73
src/Microsoft.ComponentDetection.Contracts/TypedComponent/VcpkgComponent.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,73 @@ | ||
using PackageUrl; | ||
|
||
namespace Microsoft.ComponentDetection.Contracts.TypedComponent | ||
{ | ||
public class VcpkgComponent : TypedComponent | ||
{ | ||
private VcpkgComponent() | ||
{ | ||
/* Reserved for deserialization */ | ||
} | ||
|
||
public VcpkgComponent(string spdxid, string name, string version, string triplet = null, string portVersion = null, string description = null, string downloadLocation = null) | ||
{ | ||
SPDXID = ValidateRequiredInput(spdxid, nameof(SPDXID), nameof(ComponentType.Vcpkg)); | ||
Name = ValidateRequiredInput(name, nameof(Name), nameof(ComponentType.Vcpkg)); | ||
Version = version; | ||
PortVersion = portVersion; | ||
Triplet = triplet; | ||
Description = description; | ||
DownloadLocation = downloadLocation; | ||
} | ||
|
||
public string SPDXID { get; set; } | ||
|
||
public string Name { get; set; } | ||
|
||
public string DownloadLocation { get; set; } | ||
|
||
public string Triplet { get; set; } | ||
|
||
public string Version { get; set; } | ||
|
||
public string Description { get; set; } | ||
|
||
public string PortVersion { get; set; } | ||
|
||
public override ComponentType Type => ComponentType.Vcpkg; | ||
|
||
public override string Id | ||
{ | ||
get | ||
{ | ||
if (PortVersion != null) | ||
{ | ||
return $"{Name} {Version}#{PortVersion} - {Type}"; | ||
} | ||
else | ||
{ | ||
return $"{Name} {Version} - {Type}"; | ||
} | ||
} | ||
} | ||
|
||
public override PackageURL PackageUrl | ||
{ | ||
get | ||
{ | ||
if (PortVersion != null) | ||
{ | ||
return new PackageURL($"pkg:vcpkg/{Name}@{Version}?port_version={PortVersion}"); | ||
} | ||
else if (Version != null) | ||
{ | ||
return new PackageURL($"pkg:vcpkg/{Name}@{Version}"); | ||
} | ||
else | ||
{ | ||
return new PackageURL($"pkg:vcpkg/{Name}"); | ||
} | ||
} | ||
} | ||
} | ||
} |
15 changes: 15 additions & 0 deletions
15
src/Microsoft.ComponentDetection.Detectors/vcpkg/Contracts/Annotation.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
using System; | ||
|
||
namespace Microsoft.ComponentDetection.Detectors.Vcpkg.Contracts | ||
{ | ||
public class Annotation | ||
{ | ||
public DateTime Date { get; set; } | ||
|
||
public string Comment { get; set; } | ||
|
||
public string Type { get; set; } | ||
|
||
public string Annotator { get; set; } | ||
} | ||
} |
21 changes: 21 additions & 0 deletions
21
src/Microsoft.ComponentDetection.Detectors/vcpkg/Contracts/Package.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
namespace Microsoft.ComponentDetection.Detectors.Vcpkg.Contracts | ||
{ | ||
public class Package | ||
{ | ||
public string SPDXID { get; set; } | ||
|
||
public string VersionInfo { get; set; } | ||
|
||
public string DownloadLocation { get; set; } | ||
|
||
public string Filename { get; set; } | ||
|
||
public string Homepage { get; set; } | ||
|
||
public string Description { get; set; } | ||
|
||
public string Name { get; set; } | ||
|
||
public Annotation[] Annotations { get; set; } | ||
} | ||
} |
12 changes: 12 additions & 0 deletions
12
src/Microsoft.ComponentDetection.Detectors/vcpkg/Contracts/VcpkgSBOM.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
namespace Microsoft.ComponentDetection.Detectors.Vcpkg.Contracts | ||
{ | ||
/// <summary> | ||
/// Matches a subset of https://raw.githubusercontent.com/spdx/spdx-spec/v2.2.1/schemas/spdx-schema.json. | ||
/// </summary> | ||
public class VcpkgSBOM | ||
{ | ||
public Package[] Packages { get; set; } | ||
|
||
public string Name { get; set; } | ||
} | ||
} |
118 changes: 118 additions & 0 deletions
118
src/Microsoft.ComponentDetection.Detectors/vcpkg/VcpkgComponentDetector.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,118 @@ | ||
using System; | ||
using System.Collections.Generic; | ||
using System.Composition; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Text.RegularExpressions; | ||
using System.Threading.Tasks; | ||
using Microsoft.ComponentDetection.Common; | ||
using Microsoft.ComponentDetection.Common.Telemetry.Records; | ||
using Microsoft.ComponentDetection.Contracts; | ||
using Microsoft.ComponentDetection.Contracts.Internal; | ||
using Microsoft.ComponentDetection.Contracts.TypedComponent; | ||
using Microsoft.ComponentDetection.Detectors.Vcpkg.Contracts; | ||
using Newtonsoft.Json; | ||
|
||
namespace Microsoft.ComponentDetection.Detectors.Vcpkg | ||
{ | ||
[Export(typeof(IComponentDetector))] | ||
public class VcpkgComponentDetector : FileComponentDetector, IDefaultOffComponentDetector | ||
{ | ||
[Import] | ||
public ICommandLineInvocationService CommandLineInvocationService { get; set; } | ||
|
||
[Import] | ||
public IEnvironmentVariableService EnvVarService { get; set; } | ||
|
||
public override string Id { get; } = "Vcpkg"; | ||
|
||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.Vcpkg) }; | ||
|
||
public override IList<string> SearchPatterns { get; } = new List<string> { "vcpkg.spdx.json" }; | ||
|
||
public override IEnumerable<ComponentType> SupportedComponentTypes { get; } = new[] { ComponentType.Vcpkg }; | ||
|
||
public override int Version => 1; | ||
|
||
private HashSet<string> projectRoots = new HashSet<string>(); | ||
|
||
protected override async Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs) | ||
{ | ||
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder; | ||
var file = processRequest.ComponentStream; | ||
|
||
Logger.LogWarning($"vcpkg detector found {file}"); | ||
|
||
var projectRootDirectory = Directory.GetParent(file.Location); | ||
if (projectRoots.Any(path => projectRootDirectory.FullName.StartsWith(path))) | ||
{ | ||
return; | ||
} | ||
|
||
await ParseSpdxFile(singleFileComponentRecorder, file); | ||
} | ||
|
||
private async Task ParseSpdxFile( | ||
ISingleFileComponentRecorder singleFileComponentRecorder, | ||
IComponentStream file) | ||
{ | ||
using var reader = new StreamReader(file.Stream); | ||
VcpkgSBOM sbom; | ||
try | ||
{ | ||
sbom = JsonConvert.DeserializeObject<VcpkgSBOM>(await reader.ReadToEndAsync()); | ||
} | ||
catch (Exception) | ||
{ | ||
return; | ||
} | ||
|
||
if (sbom?.Packages == null) | ||
{ | ||
return; | ||
} | ||
|
||
foreach (var item in sbom.Packages) | ||
{ | ||
try | ||
{ | ||
if (string.IsNullOrEmpty(item.Name)) | ||
{ | ||
continue; | ||
} | ||
|
||
Logger.LogWarning($"parsed package {item.Name}"); | ||
if (item.SPDXID == "SPDXRef-port") | ||
{ | ||
var split = item.VersionInfo.Split('#'); | ||
var component = new VcpkgComponent(item.SPDXID, item.Name, split[0], portVersion: split.Length >= 2 ? split[1] : "0", downloadLocation: item.DownloadLocation); | ||
singleFileComponentRecorder.RegisterUsage(new DetectedComponent(component)); | ||
} | ||
else if (item.SPDXID == "SPDXRef-binary") | ||
{ | ||
var split = item.Name.Split(':'); | ||
var component = new VcpkgComponent(item.SPDXID, item.Name, item.VersionInfo, triplet: split[1], downloadLocation: item.DownloadLocation); | ||
singleFileComponentRecorder.RegisterUsage(new DetectedComponent(component)); | ||
} | ||
else if (item.SPDXID.StartsWith("SPDXRef-resource-")) | ||
{ | ||
var dl = item.DownloadLocation; | ||
var split = dl.Split("#"); | ||
var subpath = split.Length > 1 ? split[1] : null; | ||
dl = split.Length > 1 ? split[0] : dl; | ||
split = dl.Split("@"); | ||
var version = split.Length > 1 ? split[1] : null; | ||
dl = split.Length > 1 ? split[0] : dl; | ||
|
||
var component = new VcpkgComponent(item.SPDXID, item.Name, version, downloadLocation: dl); | ||
singleFileComponentRecorder.RegisterUsage(new DetectedComponent(component)); | ||
} | ||
} | ||
catch (Exception) | ||
{ | ||
Logger.LogWarning($"failed while handling {item.Name}"); | ||
} | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.