-
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.
adding support for pub package manager
- Loading branch information
Aviad
authored and
Aviad
committed
Nov 3, 2023
1 parent
62c482b
commit 93b7e1c
Showing
11 changed files
with
332 additions
and
0 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
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 |
---|---|---|
|
@@ -56,4 +56,7 @@ public enum ComponentType : byte | |
|
||
[EnumMember] | ||
Conan = 17, | ||
|
||
[EnumMember] | ||
Pub = 18, | ||
} |
72 changes: 72 additions & 0 deletions
72
src/Microsoft.ComponentDetection.Contracts/TypedComponent/PubComponent.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,72 @@ | ||
namespace Microsoft.ComponentDetection.Contracts.TypedComponent; | ||
|
||
public class PubComponent : TypedComponent | ||
{ | ||
public PubComponent() | ||
{ | ||
/* Reserved for deserialization */ | ||
} | ||
|
||
public PubComponent(string name, string version, string dependency, string hash = null, string url = null) | ||
{ | ||
this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.Pub)); | ||
this.Version = this.ValidateRequiredInput(version, nameof(this.Version), nameof(ComponentType.Pub)); | ||
this.Dependency = dependency; | ||
this.Hash = hash; // Not required; | ||
this.Url = url; | ||
} | ||
|
||
public string Name { get; } | ||
|
||
public string Version { get; set; } | ||
|
||
public string Hash { get; set; } | ||
|
||
public string Url { get; set; } | ||
|
||
public string Dependency { get; set; } | ||
|
||
public override ComponentType Type => ComponentType.Pub; | ||
|
||
public override string Id => $"{this.Name} {this.Version} - {this.Type}"; | ||
|
||
public override string ToString() | ||
{ | ||
return $"Name={this.Name}\tVersion={this.Version}\tUrl={this.Url}"; | ||
} | ||
|
||
protected bool Equals(PubComponent other) => this.Name == other.Name && this.Version == other.Version && this.Hash == other.Hash && this.Url == other.Url && this.Dependency == other.Dependency; | ||
|
||
public override bool Equals(object obj) | ||
{ | ||
if (obj is null) | ||
{ | ||
return false; | ||
} | ||
|
||
if (ReferenceEquals(this, obj)) | ||
{ | ||
return true; | ||
} | ||
|
||
if (obj.GetType() != this.GetType()) | ||
{ | ||
return false; | ||
} | ||
|
||
return this.Equals((PubComponent)obj); | ||
} | ||
|
||
public override int GetHashCode() | ||
{ | ||
unchecked | ||
{ | ||
var hashCode = this.Name != null ? this.Name.GetHashCode() : 0; | ||
hashCode = (hashCode * 397) ^ (this.Version != null ? this.Version.GetHashCode() : 0); | ||
hashCode = (hashCode * 397) ^ (this.Hash != null ? this.Hash.GetHashCode() : 0); | ||
hashCode = (hashCode * 397) ^ (this.Url != null ? this.Url.GetHashCode() : 0); | ||
hashCode = (hashCode * 397) ^ (this.Dependency != null ? this.Dependency.GetHashCode() : 0); | ||
return hashCode; | ||
} | ||
} | ||
} |
67 changes: 67 additions & 0 deletions
67
src/Microsoft.ComponentDetection.Detectors/pub/PubComponentDetector.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,67 @@ | ||
namespace Microsoft.ComponentDetection.Detectors.Pub; | ||
|
||
using System; | ||
using System.Collections.Generic; | ||
using System.IO; | ||
using System.Threading.Tasks; | ||
using Microsoft.ComponentDetection.Contracts; | ||
using Microsoft.ComponentDetection.Contracts.Internal; | ||
using Microsoft.ComponentDetection.Contracts.TypedComponent; | ||
using Microsoft.Extensions.Logging; | ||
using YamlDotNet.Serialization; | ||
|
||
public class PubComponentDetector : FileComponentDetector | ||
{ | ||
public PubComponentDetector( | ||
IComponentStreamEnumerableFactory componentStreamEnumerableFactory, | ||
IObservableDirectoryWalkerFactory walkerFactory, | ||
ILogger<PubComponentDetector> logger) | ||
{ | ||
this.ComponentStreamEnumerableFactory = componentStreamEnumerableFactory; | ||
this.Scanner = walkerFactory; | ||
this.Logger = logger; | ||
} | ||
|
||
public override string Id => "pub"; | ||
|
||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.Pub) }; | ||
|
||
public override IEnumerable<ComponentType> SupportedComponentTypes { get; } = new[] { ComponentType.Pub }; | ||
|
||
public override int Version => 1; | ||
|
||
public override IList<string> SearchPatterns => new List<string> { "pubspec.lock" }; | ||
|
||
protected override async Task OnFileFoundAsync(ProcessRequest processRequest, IDictionary<string, string> detectorArgs) | ||
{ | ||
using var reader = new StreamReader(processRequest.ComponentStream.Stream); | ||
var text = await reader.ReadToEndAsync(); | ||
|
||
var deserializer = new DeserializerBuilder().IgnoreUnmatchedProperties().Build(); | ||
try | ||
{ | ||
var parsedFile = deserializer.Deserialize<PubSpecLock>(text); | ||
this.Logger.LogDebug("SDK {Dart}", parsedFile.Sdks.Dart); | ||
|
||
foreach (var package in parsedFile.Packages) | ||
{ | ||
if (package.Value.Source == "hosted") | ||
{ | ||
var component = new PubComponent( | ||
package.Value.GetName(), | ||
package.Value.Version, | ||
package.Value.Dependency, | ||
package.Value.GetSha256(), | ||
package.Value.GePackageDownloadedSource()); | ||
this.Logger.LogInformation("Registering component {Package}", component); | ||
|
||
processRequest.SingleFileComponentRecorder.RegisterUsage(new DetectedComponent(component)); | ||
} | ||
} | ||
} | ||
catch (Exception ex) | ||
{ | ||
this.Logger.LogError(ex, "Error while parsing lock file"); | ||
} | ||
} | ||
} |
18 changes: 18 additions & 0 deletions
18
src/Microsoft.ComponentDetection.Detectors/pub/PubSpecLock.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,18 @@ | ||
namespace Microsoft.ComponentDetection.Detectors.Pub; | ||
|
||
using System.Collections.Generic; | ||
using System.Runtime.Serialization; | ||
using YamlDotNet.Serialization; | ||
|
||
/// <summary> | ||
/// Model of the pub-spec lock file. | ||
/// </summary> | ||
[DataContract] | ||
public class PubSpecLock | ||
{ | ||
[YamlMember(Alias = "packages")] | ||
public Dictionary<string, PubSpecLockPackage> Packages { get; set; } | ||
|
||
[YamlMember(Alias = "sdks")] | ||
public SDK Sdks { get; set; } | ||
} |
44 changes: 44 additions & 0 deletions
44
src/Microsoft.ComponentDetection.Detectors/pub/PubSpecLockPackage.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,44 @@ | ||
namespace Microsoft.ComponentDetection.Detectors.Pub; | ||
|
||
using System.Runtime.Serialization; | ||
using YamlDotNet.Serialization; | ||
|
||
/// <summary> | ||
/// Model of the pub-spec lock file. | ||
/// </summary> | ||
[DataContract] | ||
public class PubSpecLockPackage | ||
{ | ||
[YamlMember(Alias = "source")] | ||
public string Source { get; set; } | ||
|
||
[YamlMember(Alias = "version")] | ||
public string Version { get; set; } | ||
|
||
[YamlMember(Alias = "dependency")] | ||
public string Dependency { get; set; } | ||
|
||
[YamlMember(Alias = "description")] | ||
public dynamic Description { get; set; } | ||
|
||
/// <summary> | ||
/// /// Returns the description\sha256 path | ||
/// The value can be null. | ||
/// </summary> | ||
/// <returns> Returns the package SHA-256 as in the pubspec.lock file.</returns> | ||
public string GetSha256() => this.Description["sha256"]; | ||
|
||
/// <summary> | ||
/// Returns the description\url path | ||
/// The value can be null. | ||
/// </summary> | ||
/// <returns>Returns the package url as in the pubspec.lock file.</returns> | ||
public string GePackageDownloadedSource() => this.Description["url"]; | ||
|
||
/// <summary> | ||
/// Returns the description\name path | ||
/// The value can be null. | ||
/// </summary> | ||
/// <returns>Returns the package name as in the pubspec.lock file.</returns> | ||
public string GetName() => this.Description["name"]; | ||
} |
20 changes: 20 additions & 0 deletions
20
src/Microsoft.ComponentDetection.Detectors/pub/PubSpecLockPackageDescription.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,20 @@ | ||
namespace Microsoft.ComponentDetection.Detectors.Pub; | ||
|
||
using System.Runtime.Serialization; | ||
using YamlDotNet.Serialization; | ||
|
||
/// <summary> | ||
/// Model of the pub-spec lock file. | ||
/// </summary> | ||
[DataContract] | ||
public class PubSpecLockPackageDescription | ||
{ | ||
[YamlMember(Alias = "name")] | ||
public string Name { get; set; } | ||
|
||
[YamlMember(Alias = "sha256")] | ||
public string Sha256 { get; set; } | ||
|
||
[YamlMember(Alias = "url")] | ||
public string Url { get; set; } | ||
} |
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,14 @@ | ||
namespace Microsoft.ComponentDetection.Detectors.Pub; | ||
|
||
using System.Runtime.Serialization; | ||
using YamlDotNet.Serialization; | ||
|
||
[DataContract] | ||
public class SDK | ||
{ | ||
[YamlMember(Alias = "dart")] | ||
public string Dart { get; set; } | ||
|
||
[YamlMember(Alias = "flutter")] | ||
public string Flutter { get; set; } | ||
} |
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
87 changes: 87 additions & 0 deletions
87
test/Microsoft.ComponentDetection.Detectors.Tests/PubComponentDetectorTests.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,87 @@ | ||
namespace Microsoft.ComponentDetection.Detectors.Tests; | ||
|
||
using System.Linq; | ||
using System.Threading.Tasks; | ||
using FluentAssertions; | ||
using Microsoft.ComponentDetection.Contracts; | ||
using Microsoft.ComponentDetection.Contracts.TypedComponent; | ||
using Microsoft.ComponentDetection.Detectors.Pub; | ||
using Microsoft.ComponentDetection.TestsUtilities; | ||
using Microsoft.VisualStudio.TestTools.UnitTesting; | ||
|
||
[TestClass] | ||
[TestCategory("Governance/All")] | ||
[TestCategory("Governance/ComponentDetection")] | ||
public class PubComponentDetectorTests : BaseDetectorTest<PubComponentDetector> | ||
{ | ||
private readonly string testPubSpecLockFile = @"# Generated by pub | ||
# See https://dart.dev/tools/pub/glossary#lockfile | ||
packages: | ||
analyzer: | ||
dependency: ""direct dev"" | ||
description: | ||
name: analyzer | ||
sha256: ""sh1"" | ||
url: ""https://pub.dev"" | ||
source: hosted | ||
version: ""5.13.0"" | ||
archive: | ||
dependency: transitive | ||
description: | ||
name: archive | ||
sha256: ""sh2"" | ||
url: ""https://pub.dev"" | ||
source: hosted | ||
version: ""3.4.4"" | ||
async: | ||
dependency: direct main | ||
description: | ||
name: async | ||
sha256: ""sh3"" | ||
url: ""https://pub.dev"" | ||
source: hosted | ||
version: ""2.11.0"" | ||
flutter: | ||
dependency: ""direct main"" | ||
description: flutter | ||
source: sdk | ||
version: ""0.0.0"" | ||
sdks: | ||
dart: "">=3.0.0 <4.0.0"" | ||
flutter: "">=3.10.0"" | ||
"; | ||
|
||
[TestMethod] | ||
public async Task TestDetectorAsync() | ||
{ | ||
var (result, componentRecorder) = await this.DetectorTestUtility | ||
.WithFile("pubspec.lock", this.testPubSpecLockFile) | ||
.ExecuteDetectorAsync(); | ||
|
||
result.ResultCode.Should().Be(ProcessingResultCode.Success); | ||
componentRecorder.GetDetectedComponents().Count().Should().Be(3); | ||
|
||
var components = componentRecorder.GetDetectedComponents().Select(x => x.Component).ToArray(); | ||
|
||
components.Should().Contain(new PubComponent( | ||
"analyzer", | ||
"5.13.0", | ||
"direct dev", | ||
"sh1", | ||
"https://pub.dev")); | ||
|
||
components.Should().Contain(new PubComponent( | ||
"archive", | ||
"3.4.4", | ||
"transitive", | ||
"sh2", | ||
"https://pub.dev")); | ||
|
||
components.Should().Contain(new PubComponent( | ||
"async", | ||
"2.11.0", | ||
"direct main", | ||
"sh3", | ||
"https://pub.dev")); | ||
} | ||
} |