Fix analyzer warnings: SA1142, SA1201 (#308)
This commit is contained in:
Родитель
abd15de7f1
Коммит
b1532df7a8
|
@ -459,18 +459,10 @@ dotnet_naming_rule.parameters_rule.severity = warning
|
|||
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers
|
||||
##########################################
|
||||
|
||||
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1142.md
|
||||
# Refer to tuple fields by name
|
||||
dotnet_diagnostic.SA1142.severity = suggestion
|
||||
|
||||
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1200.md
|
||||
# Using directive should appear within a namespace declaration
|
||||
dotnet_diagnostic.SA1200.severity = suggestion
|
||||
|
||||
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1201.md
|
||||
# A field should not follow a property
|
||||
dotnet_diagnostic.SA1201.severity = suggestion
|
||||
|
||||
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1203.md
|
||||
# 'public' members should come before 'private' members
|
||||
dotnet_diagnostic.SA1203.severity = suggestion
|
||||
|
@ -570,9 +562,6 @@ dotnet_diagnostic.CA2007.severity = suggestion
|
|||
# CA1062: Validate arguments of public methods
|
||||
dotnet_diagnostic.CA1062.severity = suggestion
|
||||
|
||||
# SA1201: Elements should appear in the correct order
|
||||
dotnet_diagnostic.SA1201.severity = suggestion
|
||||
|
||||
# CA1819: Properties should not return arrays
|
||||
dotnet_diagnostic.CA1819.severity = suggestion
|
||||
|
||||
|
|
|
@ -8,16 +8,16 @@ namespace Microsoft.ComponentDetection.Common
|
|||
{
|
||||
public class ComponentStreamEnumerable : IEnumerable<IComponentStream>
|
||||
{
|
||||
private IEnumerable<MatchedFile> ToEnumerate { get; }
|
||||
|
||||
private ILogger Logger { get; }
|
||||
|
||||
public ComponentStreamEnumerable(IEnumerable<MatchedFile> fileEnumerable, ILogger logger)
|
||||
{
|
||||
this.ToEnumerate = fileEnumerable;
|
||||
this.Logger = logger;
|
||||
}
|
||||
|
||||
private IEnumerable<MatchedFile> ToEnumerate { get; }
|
||||
|
||||
private ILogger Logger { get; }
|
||||
|
||||
public IEnumerator<IComponentStream> GetEnumerator()
|
||||
{
|
||||
foreach (var filePairing in this.ToEnumerate)
|
||||
|
|
|
@ -94,12 +94,6 @@ namespace Microsoft.ComponentDetection.Common.DependencyGraph
|
|||
{
|
||||
private readonly ILogger log;
|
||||
|
||||
public string ManifestFileLocation { get; }
|
||||
|
||||
IDependencyGraph ISingleFileComponentRecorder.DependencyGraph => this.DependencyGraph;
|
||||
|
||||
internal DependencyGraph DependencyGraph { get; }
|
||||
|
||||
private readonly ConcurrentDictionary<string, DetectedComponent> detectedComponentsInternal = new ConcurrentDictionary<string, DetectedComponent>();
|
||||
|
||||
private readonly ComponentRecorder recorder;
|
||||
|
@ -114,6 +108,12 @@ namespace Microsoft.ComponentDetection.Common.DependencyGraph
|
|||
this.DependencyGraph = new DependencyGraph(enableManualTrackingOfExplicitReferences);
|
||||
}
|
||||
|
||||
public string ManifestFileLocation { get; }
|
||||
|
||||
IDependencyGraph ISingleFileComponentRecorder.DependencyGraph => this.DependencyGraph;
|
||||
|
||||
internal DependencyGraph DependencyGraph { get; }
|
||||
|
||||
public DetectedComponent GetComponent(string componentId)
|
||||
{
|
||||
if (this.detectedComponentsInternal.TryGetValue(componentId, out var detectedComponent))
|
||||
|
|
|
@ -15,8 +15,6 @@ namespace Microsoft.ComponentDetection.Common.DependencyGraph
|
|||
{
|
||||
private ConcurrentDictionary<string, ComponentRefNode> componentNodes;
|
||||
|
||||
internal ConcurrentDictionary<string, byte> AdditionalRelatedFiles { get; } = new ConcurrentDictionary<string, byte>();
|
||||
|
||||
private bool enableManualTrackingOfExplicitReferences;
|
||||
|
||||
public DependencyGraph(bool enableManualTrackingOfExplicitReferences)
|
||||
|
@ -25,6 +23,8 @@ namespace Microsoft.ComponentDetection.Common.DependencyGraph
|
|||
this.enableManualTrackingOfExplicitReferences = enableManualTrackingOfExplicitReferences;
|
||||
}
|
||||
|
||||
internal ConcurrentDictionary<string, byte> AdditionalRelatedFiles { get; } = new ConcurrentDictionary<string, byte>();
|
||||
|
||||
public void AddComponent(ComponentRefNode componentNode, string parentComponentId = null)
|
||||
{
|
||||
if (componentNode == null)
|
||||
|
@ -134,27 +134,6 @@ namespace Microsoft.ComponentDetection.Common.DependencyGraph
|
|||
return this.IsExplicitReferencedDependency(this.componentNodes[componentId]);
|
||||
}
|
||||
|
||||
internal class ComponentRefNode
|
||||
{
|
||||
internal bool IsExplicitReferencedDependency { get; set; }
|
||||
|
||||
internal string Id { get; set; }
|
||||
|
||||
internal ISet<string> DependencyIds { get; private set; }
|
||||
|
||||
internal ISet<string> DependedOnByIds { get; private set; }
|
||||
|
||||
internal bool? IsDevelopmentDependency { get; set; }
|
||||
|
||||
internal DependencyScope? DependencyScope { get; set; }
|
||||
|
||||
internal ComponentRefNode()
|
||||
{
|
||||
this.DependencyIds = new HashSet<string>();
|
||||
this.DependedOnByIds = new HashSet<string>();
|
||||
}
|
||||
}
|
||||
|
||||
private void GetExplicitReferencedDependencies(ComponentRefNode component, IList<string> explicitReferencedDependencyIds, ISet<string> visited)
|
||||
{
|
||||
if (this.IsExplicitReferencedDependency(component))
|
||||
|
@ -194,5 +173,26 @@ namespace Microsoft.ComponentDetection.Common.DependencyGraph
|
|||
parentComponentRefNode.DependencyIds.Add(componentId);
|
||||
this.componentNodes[componentId].DependedOnByIds.Add(parentComponentId);
|
||||
}
|
||||
|
||||
internal class ComponentRefNode
|
||||
{
|
||||
internal ComponentRefNode()
|
||||
{
|
||||
this.DependencyIds = new HashSet<string>();
|
||||
this.DependedOnByIds = new HashSet<string>();
|
||||
}
|
||||
|
||||
internal bool IsExplicitReferencedDependency { get; set; }
|
||||
|
||||
internal string Id { get; set; }
|
||||
|
||||
internal ISet<string> DependencyIds { get; private set; }
|
||||
|
||||
internal ISet<string> DependedOnByIds { get; private set; }
|
||||
|
||||
internal bool? IsDevelopmentDependency { get; set; }
|
||||
|
||||
internal DependencyScope? DependencyScope { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,58 @@ namespace Microsoft.ComponentDetection.Common
|
|||
{
|
||||
public class DockerRegex
|
||||
{
|
||||
public static Regex AlphaNumericRegexp = new Regex("[a-z0-9]+");
|
||||
public static Regex SeparatorRegexp = new Regex("(?:[._]|__|[-]*)");
|
||||
|
||||
public static Regex DomainComponentRegexp = new Regex("(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])");
|
||||
public static Regex TagRegexp = new Regex(@"[\w][\w.-]{0,127}");
|
||||
public static Regex DigestRegexp = new Regex("[a-zA-Z][a-zA-Z0-9]*(?:[-_+.][a-zA-Z][a-zA-Z0-9]*)*[:][a-fA-F0-9]{32,}");
|
||||
public static Regex IdentifierRegexp = new Regex("[a-f0-9]{64}");
|
||||
|
||||
public static Regex NameComponentRegexp = Expression(
|
||||
AlphaNumericRegexp,
|
||||
Optional(Repeated(SeparatorRegexp, AlphaNumericRegexp)));
|
||||
|
||||
public static Regex DomainRegexp = Expression(
|
||||
DomainComponentRegexp,
|
||||
Optional(
|
||||
Repeated(
|
||||
new Regex(@"\."),
|
||||
DomainComponentRegexp)),
|
||||
Optional(
|
||||
new Regex(":"),
|
||||
new Regex("[0-9]+")));
|
||||
|
||||
public static Regex AnchoredDigestRegexp = Anchored(DigestRegexp);
|
||||
|
||||
public static Regex NameRegexp = Expression(
|
||||
Optional(
|
||||
DomainRegexp,
|
||||
new Regex(@"\/")),
|
||||
NameComponentRegexp,
|
||||
Optional(
|
||||
Repeated(
|
||||
new Regex(@"\/"),
|
||||
NameComponentRegexp)));
|
||||
|
||||
public static Regex AnchoredNameRegexp = Anchored(
|
||||
Optional(
|
||||
Capture(DomainRegexp),
|
||||
new Regex(@"\/")),
|
||||
Capture(
|
||||
NameComponentRegexp,
|
||||
Optional(
|
||||
Repeated(
|
||||
new Regex(@"\/"),
|
||||
NameComponentRegexp))));
|
||||
|
||||
public static Regex ReferenceRegexp = Anchored(
|
||||
Capture(NameRegexp),
|
||||
Optional(new Regex(":"), Capture(TagRegexp)),
|
||||
Optional(new Regex("@"), Capture(DigestRegexp)));
|
||||
|
||||
public static Regex AnchoredIdentifierRegexp = Anchored(IdentifierRegexp);
|
||||
|
||||
/// <summary>
|
||||
/// expression defines a full expression, where each regular expression must follow the previous.
|
||||
/// </summary>
|
||||
|
@ -64,57 +116,5 @@ namespace Microsoft.ComponentDetection.Common
|
|||
{
|
||||
return new Regex($"({Expression(regexps).ToString()})");
|
||||
}
|
||||
|
||||
public static Regex AlphaNumericRegexp = new Regex("[a-z0-9]+");
|
||||
public static Regex SeparatorRegexp = new Regex("(?:[._]|__|[-]*)");
|
||||
|
||||
public static Regex DomainComponentRegexp = new Regex("(?:[a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9])");
|
||||
public static Regex TagRegexp = new Regex(@"[\w][\w.-]{0,127}");
|
||||
public static Regex DigestRegexp = new Regex("[a-zA-Z][a-zA-Z0-9]*(?:[-_+.][a-zA-Z][a-zA-Z0-9]*)*[:][a-fA-F0-9]{32,}");
|
||||
public static Regex IdentifierRegexp = new Regex("[a-f0-9]{64}");
|
||||
|
||||
public static Regex NameComponentRegexp = Expression(
|
||||
AlphaNumericRegexp,
|
||||
Optional(Repeated(SeparatorRegexp, AlphaNumericRegexp)));
|
||||
|
||||
public static Regex DomainRegexp = Expression(
|
||||
DomainComponentRegexp,
|
||||
Optional(
|
||||
Repeated(
|
||||
new Regex(@"\."),
|
||||
DomainComponentRegexp)),
|
||||
Optional(
|
||||
new Regex(":"),
|
||||
new Regex("[0-9]+")));
|
||||
|
||||
public static Regex AnchoredDigestRegexp = Anchored(DigestRegexp);
|
||||
|
||||
public static Regex NameRegexp = Expression(
|
||||
Optional(
|
||||
DomainRegexp,
|
||||
new Regex(@"\/")),
|
||||
NameComponentRegexp,
|
||||
Optional(
|
||||
Repeated(
|
||||
new Regex(@"\/"),
|
||||
NameComponentRegexp)));
|
||||
|
||||
public static Regex AnchoredNameRegexp = Anchored(
|
||||
Optional(
|
||||
Capture(DomainRegexp),
|
||||
new Regex(@"\/")),
|
||||
Capture(
|
||||
NameComponentRegexp,
|
||||
Optional(
|
||||
Repeated(
|
||||
new Regex(@"\/"),
|
||||
NameComponentRegexp))));
|
||||
|
||||
public static Regex ReferenceRegexp = Anchored(
|
||||
Capture(NameRegexp),
|
||||
Optional(new Regex(":"), Capture(TagRegexp)),
|
||||
Optional(new Regex("@"), Capture(DigestRegexp)));
|
||||
|
||||
public static Regex AnchoredIdentifierRegexp = Anchored(IdentifierRegexp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,13 +21,13 @@ namespace Microsoft.ComponentDetection.Common
|
|||
|
||||
private static int incrementingContainerId;
|
||||
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
// Base image annotations from ADO dockerTask
|
||||
private const string BaseImageRefAnnotation = "image.base.ref.name";
|
||||
private const string BaseImageDigestAnnotation = "image.base.digest";
|
||||
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public async Task<bool> CanPingDockerAsync(CancellationToken cancellationToken = default)
|
||||
{
|
||||
try
|
||||
|
|
|
@ -10,6 +10,21 @@ namespace Microsoft.ComponentDetection.Common
|
|||
private readonly Lazy<byte[]> fileBuffer;
|
||||
private readonly ILogger logger;
|
||||
|
||||
public LazyComponentStream(FileInfo fileInfo, string pattern, ILogger logger)
|
||||
{
|
||||
this.Pattern = pattern;
|
||||
this.Location = fileInfo.FullName;
|
||||
this.fileInfo = fileInfo;
|
||||
this.logger = logger;
|
||||
this.fileBuffer = new Lazy<byte[]>(this.SafeOpenFile);
|
||||
}
|
||||
|
||||
public Stream Stream => new MemoryStream(this.fileBuffer.Value);
|
||||
|
||||
public string Pattern { get; set; }
|
||||
|
||||
public string Location { get; set; }
|
||||
|
||||
private byte[] SafeOpenFile()
|
||||
{
|
||||
try
|
||||
|
@ -33,20 +48,5 @@ namespace Microsoft.ComponentDetection.Common
|
|||
|
||||
return new byte[0];
|
||||
}
|
||||
|
||||
public LazyComponentStream(FileInfo fileInfo, string pattern, ILogger logger)
|
||||
{
|
||||
this.Pattern = pattern;
|
||||
this.Location = fileInfo.FullName;
|
||||
this.fileInfo = fileInfo;
|
||||
this.logger = logger;
|
||||
this.fileBuffer = new Lazy<byte[]>(this.SafeOpenFile);
|
||||
}
|
||||
|
||||
public Stream Stream => new MemoryStream(this.fileBuffer.Value);
|
||||
|
||||
public string Pattern { get; set; }
|
||||
|
||||
public string Location { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace Microsoft.ComponentDetection.Common
|
|||
[Shared]
|
||||
public class Logger : ILogger
|
||||
{
|
||||
public const string LogRelativePath = "GovCompDisc_Log_{timestamp}.log";
|
||||
|
||||
[Import]
|
||||
public IFileWritingService FileWritingService { get; set; }
|
||||
|
||||
|
@ -23,8 +25,6 @@ namespace Microsoft.ComponentDetection.Common
|
|||
|
||||
private bool WriteToFile { get; set; }
|
||||
|
||||
public const string LogRelativePath = "GovCompDisc_Log_{timestamp}.log";
|
||||
|
||||
public void Init(VerbosityMode verbosity)
|
||||
{
|
||||
this.WriteToFile = true;
|
||||
|
|
|
@ -17,29 +17,6 @@ namespace Microsoft.ComponentDetection.Common
|
|||
[Shared]
|
||||
public class PathUtilityService : IPathUtilityService
|
||||
{
|
||||
/// <summary>
|
||||
/// This call can be made on a linux system to get the absolute path of a file. It will resolve nested layers.
|
||||
/// Note: You may pass IntPtr.Zero to the output parameter. You MUST then free the IntPtr that RealPathLinux returns
|
||||
/// using FreeMemoryLinux otherwise things will get very leaky.
|
||||
/// </summary>
|
||||
/// <param name="path"> The path to resolve. </param>
|
||||
/// <param name="output"> The pointer output. </param>
|
||||
/// <returns> A pointer <see cref= "IntPtr"/> to the absolute path of a file. </returns>
|
||||
[DllImport("libc", EntryPoint = "realpath")]
|
||||
public static extern IntPtr RealPathLinux([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr output);
|
||||
|
||||
/// <summary>
|
||||
/// Use this function to free memory and prevent memory leaks.
|
||||
/// However, beware.... Improper usage of this function will cause segfaults and other nasty double-free errors.
|
||||
/// THIS WILL CRASH THE CLR IF YOU USE IT WRONG.
|
||||
/// </summary>
|
||||
/// <param name="toFree">Pointer to the memory space to free. </param>
|
||||
[DllImport("libc", EntryPoint = "free")]
|
||||
public static extern void FreeMemoryLinux([In] IntPtr toFree);
|
||||
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public const uint CreationDispositionRead = 0x3;
|
||||
|
||||
public const uint FileFlagBackupSemantics = 0x02000000;
|
||||
|
@ -48,8 +25,15 @@ namespace Microsoft.ComponentDetection.Common
|
|||
|
||||
public const string LongPathPrefix = "\\\\?\\";
|
||||
|
||||
private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
private static readonly bool IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
private static readonly bool IsMacOS = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
||||
|
||||
private readonly ConcurrentDictionary<string, string> resolvedPaths = new ConcurrentDictionary<string, string>();
|
||||
|
||||
private object isRunningOnWindowsContainerLock = new object();
|
||||
private bool? isRunningOnWindowsContainer = null;
|
||||
|
||||
public bool IsRunningOnWindowsContainer
|
||||
{
|
||||
get
|
||||
|
@ -69,12 +53,28 @@ namespace Microsoft.ComponentDetection.Common
|
|||
}
|
||||
}
|
||||
|
||||
private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
|
||||
private static readonly bool IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
private static readonly bool IsMacOS = RuntimeInformation.IsOSPlatform(OSPlatform.OSX);
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
private object isRunningOnWindowsContainerLock = new object();
|
||||
private bool? isRunningOnWindowsContainer = null;
|
||||
/// <summary>
|
||||
/// This call can be made on a linux system to get the absolute path of a file. It will resolve nested layers.
|
||||
/// Note: You may pass IntPtr.Zero to the output parameter. You MUST then free the IntPtr that RealPathLinux returns
|
||||
/// using FreeMemoryLinux otherwise things will get very leaky.
|
||||
/// </summary>
|
||||
/// <param name="path"> The path to resolve. </param>
|
||||
/// <param name="output"> The pointer output. </param>
|
||||
/// <returns> A pointer <see cref= "IntPtr"/> to the absolute path of a file. </returns>
|
||||
[DllImport("libc", EntryPoint = "realpath")]
|
||||
public static extern IntPtr RealPathLinux([MarshalAs(UnmanagedType.LPStr)] string path, IntPtr output);
|
||||
|
||||
/// <summary>
|
||||
/// Use this function to free memory and prevent memory leaks.
|
||||
/// However, beware.... Improper usage of this function will cause segfaults and other nasty double-free errors.
|
||||
/// THIS WILL CRASH THE CLR IF YOU USE IT WRONG.
|
||||
/// </summary>
|
||||
/// <param name="toFree">Pointer to the memory space to free. </param>
|
||||
[DllImport("libc", EntryPoint = "free")]
|
||||
public static extern void FreeMemoryLinux([In] IntPtr toFree);
|
||||
|
||||
public static bool MatchesPattern(string searchPattern, ref FileSystemEntry fse)
|
||||
{
|
||||
|
|
|
@ -4,11 +4,11 @@ namespace Microsoft.ComponentDetection.Common.Telemetry.Attributes
|
|||
{
|
||||
public class TelemetryServiceAttribute : Attribute
|
||||
{
|
||||
public string ServiceType { get; }
|
||||
|
||||
public TelemetryServiceAttribute(string serviceType)
|
||||
{
|
||||
this.ServiceType = serviceType;
|
||||
}
|
||||
|
||||
public string ServiceType { get; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,16 +15,16 @@ namespace Microsoft.ComponentDetection.Common.Telemetry
|
|||
{
|
||||
private static ConcurrentQueue<JObject> records = new ConcurrentQueue<JObject>();
|
||||
|
||||
public const string TelemetryRelativePath = "ScanTelemetry_{timestamp}.json";
|
||||
|
||||
private TelemetryMode telemetryMode = TelemetryMode.Production;
|
||||
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
[Import]
|
||||
public IFileWritingService FileWritingService { get; set; }
|
||||
|
||||
public const string TelemetryRelativePath = "ScanTelemetry_{timestamp}.json";
|
||||
|
||||
private TelemetryMode telemetryMode = TelemetryMode.Production;
|
||||
|
||||
public void Flush()
|
||||
{
|
||||
this.FileWritingService.WriteFile(TelemetryRelativePath, JsonConvert.SerializeObject(records));
|
||||
|
|
|
@ -6,18 +6,20 @@ namespace Microsoft.ComponentDetection.Common.Telemetry.Records
|
|||
{
|
||||
public abstract class BaseDetectionTelemetryRecord : IDetectionTelemetryRecord
|
||||
{
|
||||
public abstract string RecordName { get; }
|
||||
|
||||
[Metric]
|
||||
public TimeSpan? ExecutionTime { get; protected set; }
|
||||
|
||||
private Stopwatch stopwatch = new Stopwatch();
|
||||
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected BaseDetectionTelemetryRecord()
|
||||
{
|
||||
this.stopwatch.Start();
|
||||
}
|
||||
|
||||
public abstract string RecordName { get; }
|
||||
|
||||
[Metric]
|
||||
public TimeSpan? ExecutionTime { get; protected set; }
|
||||
|
||||
public void StopExecutionTimer()
|
||||
{
|
||||
if (this.stopwatch.IsRunning)
|
||||
|
@ -32,8 +34,6 @@ namespace Microsoft.ComponentDetection.Common.Telemetry.Records
|
|||
this.Dispose(true);
|
||||
}
|
||||
|
||||
private bool disposedValue = false;
|
||||
|
||||
protected virtual void Dispose(bool disposing)
|
||||
{
|
||||
if (!this.disposedValue)
|
||||
|
|
|
@ -4,6 +4,8 @@ namespace Microsoft.ComponentDetection.Common.Telemetry.Records
|
|||
{
|
||||
public class NuGetProjectAssetsTelemetryRecord : IDetectionTelemetryRecord, IDisposable
|
||||
{
|
||||
private bool disposedValue = false;
|
||||
|
||||
public string RecordName => "NuGetProjectAssets";
|
||||
|
||||
public string FoundTargets { get; set; }
|
||||
|
@ -12,8 +14,6 @@ namespace Microsoft.ComponentDetection.Common.Telemetry.Records
|
|||
|
||||
public string Frameworks { get; set; }
|
||||
|
||||
private bool disposedValue = false;
|
||||
|
||||
public void Dispose()
|
||||
{
|
||||
this.Dispose(true);
|
||||
|
|
|
@ -12,22 +12,22 @@ namespace Microsoft.ComponentDetection.Common.Telemetry
|
|||
/// </summary>
|
||||
public sealed class TelemetryRelay
|
||||
{
|
||||
[ImportMany]
|
||||
public static IEnumerable<ITelemetryService> TelemetryServices { get; set; }
|
||||
|
||||
private static readonly TelemetryRelay InternalInstance = new TelemetryRelay();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the telemetry relay has been shutdown.
|
||||
/// </summary>
|
||||
public static bool Active { get; private set; } = true;
|
||||
|
||||
private TelemetryRelay()
|
||||
{
|
||||
// For things not populating the telemetry services collection, let's not throw.
|
||||
TelemetryServices = Enumerable.Empty<ITelemetryService>();
|
||||
}
|
||||
|
||||
[ImportMany]
|
||||
public static IEnumerable<ITelemetryService> TelemetryServices { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether or not the telemetry relay has been shutdown.
|
||||
/// </summary>
|
||||
public static bool Active { get; private set; } = true;
|
||||
|
||||
/// <summary>
|
||||
/// Gets the singleton.
|
||||
/// </summary>
|
||||
|
|
|
@ -27,6 +27,11 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels
|
|||
{ ComponentType.Vcpkg, typeof(VcpkgComponent) },
|
||||
};
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override bool CanConvert(Type objectType)
|
||||
{
|
||||
return objectType == typeof(TypedComponent.TypedComponent);
|
||||
|
@ -45,11 +50,6 @@ namespace Microsoft.ComponentDetection.Contracts.BcdeModels
|
|||
return instanceOfTypedComponent;
|
||||
}
|
||||
|
||||
public override bool CanWrite
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public override void WriteJson(
|
||||
JsonWriter writer,
|
||||
object value,
|
||||
|
|
|
@ -8,6 +8,8 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public class DetectedComponent
|
||||
{
|
||||
private readonly object hashLock = new object();
|
||||
|
||||
/// <summary>Creates a new DetectedComponent.</summary>
|
||||
/// <param name="component">The typed component instance to base this detection on.</param>
|
||||
/// <param name="detector">The detector that detected this component.</param>
|
||||
|
@ -57,6 +59,8 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
/// <summary> Gets or sets Dependency Scope of the component.</summary>
|
||||
public DependencyScope? DependencyScope { get; set; }
|
||||
|
||||
private string DebuggerDisplay => $"{this.Component.DebuggerDisplay}";
|
||||
|
||||
/// <summary>Adds a filepath to the FilePaths hashset for this detected component.</summary>
|
||||
/// <param name="filePath">The file path to add to the hashset.</param>
|
||||
public void AddComponentFilePath(string filePath)
|
||||
|
@ -66,9 +70,5 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
this.FilePaths.Add(filePath);
|
||||
}
|
||||
}
|
||||
|
||||
private string DebuggerDisplay => $"{this.Component.DebuggerDisplay}";
|
||||
|
||||
private readonly object hashLock = new object();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,8 +1,19 @@
|
|||
namespace Microsoft.ComponentDetection.Contracts
|
||||
{
|
||||
public enum DockerReferenceKind
|
||||
{
|
||||
Canonical = 0,
|
||||
Repository = 1,
|
||||
Tagged = 2,
|
||||
Dual = 3,
|
||||
Digest = 4,
|
||||
}
|
||||
|
||||
#pragma warning disable SA1402
|
||||
public class DockerReference
|
||||
{
|
||||
public virtual DockerReferenceKind Kind { get; }
|
||||
|
||||
public static DockerReference CreateDockerReference(string repository, string domain, string digest, string tag)
|
||||
{
|
||||
if (!string.IsNullOrEmpty(repository) && string.IsNullOrEmpty(domain))
|
||||
|
@ -60,23 +71,12 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
}
|
||||
}
|
||||
|
||||
public virtual DockerReferenceKind Kind { get; }
|
||||
|
||||
public virtual TypedComponent.DockerReferenceComponent ToTypedDockerReferenceComponent()
|
||||
{
|
||||
throw new System.NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
public enum DockerReferenceKind
|
||||
{
|
||||
Canonical = 0,
|
||||
Repository = 1,
|
||||
Tagged = 2,
|
||||
Dual = 3,
|
||||
Digest = 4,
|
||||
}
|
||||
|
||||
public class Reference
|
||||
{
|
||||
public string Tag { get; set; }
|
||||
|
@ -91,10 +91,10 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
// sha256:abc123...
|
||||
public class DigestReference : DockerReference
|
||||
{
|
||||
public override DockerReferenceKind Kind { get; } = DockerReferenceKind.Digest;
|
||||
|
||||
public string Digest;
|
||||
|
||||
public override DockerReferenceKind Kind { get; } = DockerReferenceKind.Digest;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Digest}";
|
||||
|
@ -112,14 +112,14 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
// docker.io/library/ubuntu@sha256:abc123...
|
||||
public class CanonicalReference : DockerReference
|
||||
{
|
||||
public override DockerReferenceKind Kind { get; } = DockerReferenceKind.Canonical;
|
||||
|
||||
public string Domain;
|
||||
|
||||
public string Repository;
|
||||
|
||||
public string Digest;
|
||||
|
||||
public override DockerReferenceKind Kind { get; } = DockerReferenceKind.Canonical;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Domain}/{this.Repository}@${this.Digest}";
|
||||
|
@ -139,12 +139,12 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
// docker.io/library/ubuntu
|
||||
public class RepositoryReference : DockerReference
|
||||
{
|
||||
public override DockerReferenceKind Kind { get; } = DockerReferenceKind.Repository;
|
||||
|
||||
public string Domain;
|
||||
|
||||
public string Repository;
|
||||
|
||||
public override DockerReferenceKind Kind { get; } = DockerReferenceKind.Repository;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Repository}";
|
||||
|
@ -163,14 +163,14 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
// docker.io/library/ubuntu:latest
|
||||
public class TaggedReference : DockerReference
|
||||
{
|
||||
public override DockerReferenceKind Kind { get; } = DockerReferenceKind.Tagged;
|
||||
|
||||
public string Domain;
|
||||
|
||||
public string Repository;
|
||||
|
||||
public string Tag;
|
||||
|
||||
public override DockerReferenceKind Kind { get; } = DockerReferenceKind.Tagged;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Domain}/{this.Repository}:${this.Tag}";
|
||||
|
@ -190,8 +190,6 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
// docker.io/library/ubuntu:latest@sha256:abc123...
|
||||
public class DualReference : DockerReference
|
||||
{
|
||||
public override DockerReferenceKind Kind { get; } = DockerReferenceKind.Dual;
|
||||
|
||||
public string Domain;
|
||||
|
||||
public string Repository;
|
||||
|
@ -200,6 +198,8 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
|
||||
public string Digest;
|
||||
|
||||
public override DockerReferenceKind Kind { get; } = DockerReferenceKind.Dual;
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
return $"{this.Domain}/{this.Repository}:${this.Tag}@${this.Digest}";
|
||||
|
|
|
@ -40,11 +40,26 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
/// <summary>Gets the version of this component detector. </summary>
|
||||
public abstract int Version { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder names that will be skipped by the Component Detector.
|
||||
/// </summary>
|
||||
protected virtual IList<string> SkippedFolders => new List<string> { };
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the active scan request -- only populated after a ScanDirectoryAsync is invoked. If ScanDirectoryAsync is overridden,
|
||||
/// the overrider should ensure this property is populated.
|
||||
/// </summary>
|
||||
protected ScanRequest CurrentScanRequest { get; set; }
|
||||
|
||||
[Import]
|
||||
public IObservableDirectoryWalkerFactory Scanner { get; set; }
|
||||
|
||||
public bool NeedsAutomaticRootDependencyCalculation { get; protected set; }
|
||||
|
||||
protected Dictionary<string, string> Telemetry { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
protected IObservable<IComponentStream> ComponentStreams { get; private set; }
|
||||
|
||||
/// <inheritdoc />
|
||||
public async virtual Task<IndividualDetectorScanResult> ExecuteDetectorAsync(ScanRequest request)
|
||||
{
|
||||
|
@ -63,8 +78,6 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
return this.ProcessAsync(filteredObservable, request.DetectorArgs);
|
||||
}
|
||||
|
||||
protected Dictionary<string, string> Telemetry { get; set; } = new Dictionary<string, string>();
|
||||
|
||||
/// <summary>
|
||||
/// Gets the file streams for the Detector's declared <see cref="SearchPatterns"/> as an <see cref="IEnumerable{IComponentStream}"/>.
|
||||
/// </summary>
|
||||
|
@ -97,8 +110,6 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
};
|
||||
}
|
||||
|
||||
protected IObservable<IComponentStream> ComponentStreams { get; private set; }
|
||||
|
||||
protected virtual Task<IObservable<ProcessRequest>> OnPrepareDetection(IObservable<ProcessRequest> processRequests, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
return Task.FromResult(processRequests);
|
||||
|
@ -110,16 +121,5 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the folder names that will be skipped by the Component Detector.
|
||||
/// </summary>
|
||||
protected virtual IList<string> SkippedFolders => new List<string> { };
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the active scan request -- only populated after a ScanDirectoryAsync is invoked. If ScanDirectoryAsync is overridden,
|
||||
/// the overrider should ensure this property is populated.
|
||||
/// </summary>
|
||||
protected ScanRequest CurrentScanRequest { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,16 +30,16 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
/// </summary>
|
||||
int Version { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this detector needs automatic root dependency calculation or is going to be specified as part of RegisterUsage.
|
||||
/// </summary>
|
||||
bool NeedsAutomaticRootDependencyCalculation { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Run the detector and return the result set of components found.
|
||||
/// </summary>
|
||||
/// <returns> Awaitable task with result of components found. </returns>
|
||||
Task<IndividualDetectorScanResult> ExecuteDetectorAsync(ScanRequest request);
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether this detector needs automatic root dependency calculation or is going to be specified as part of RegisterUsage.
|
||||
/// </summary>
|
||||
bool NeedsAutomaticRootDependencyCalculation { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
|
|
@ -18,6 +18,8 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
{
|
||||
string ManifestFileLocation { get; }
|
||||
|
||||
IDependencyGraph DependencyGraph { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Add or Update a component. In case that a parent componentId is specified
|
||||
/// an edge is created between those components in the dependency graph.
|
||||
|
@ -41,8 +43,6 @@ namespace Microsoft.ComponentDetection.Contracts
|
|||
IReadOnlyDictionary<string, DetectedComponent> GetDetectedComponents();
|
||||
|
||||
IComponentRecorder GetParentComponentRecorder();
|
||||
|
||||
IDependencyGraph DependencyGraph { get; }
|
||||
}
|
||||
|
||||
public interface IDependencyGraph
|
||||
|
|
|
@ -12,6 +12,16 @@ namespace Microsoft.ComponentDetection.Contracts.Internal
|
|||
// It also makes a little bit of sense because everything that IComponentDetectors can inject is in this file :).
|
||||
internal class InjectionParameters
|
||||
{
|
||||
private static ILogger loggerStatic;
|
||||
private static IComponentStreamEnumerableFactory factoryStatic;
|
||||
private static IPathUtilityService pathUtilityServiceStatic;
|
||||
private static ICommandLineInvocationService commandLineInvocationServiceStatic;
|
||||
private static IFileUtilityService fileUtilityServiceStatic;
|
||||
private static IObservableDirectoryWalkerFactory observableDirectoryWalkerFactoryServiceStatic;
|
||||
private static IDockerService dockerServiceStatic;
|
||||
|
||||
private static IEnvironmentVariableService environmentVariableServiceStatic;
|
||||
|
||||
public InjectionParameters()
|
||||
{
|
||||
}
|
||||
|
@ -28,16 +38,6 @@ namespace Microsoft.ComponentDetection.Contracts.Internal
|
|||
environmentVariableServiceStatic = detectorDependencies.EnvironmentVariableService;
|
||||
}
|
||||
|
||||
private static ILogger loggerStatic;
|
||||
private static IComponentStreamEnumerableFactory factoryStatic;
|
||||
private static IPathUtilityService pathUtilityServiceStatic;
|
||||
private static ICommandLineInvocationService commandLineInvocationServiceStatic;
|
||||
private static IFileUtilityService fileUtilityServiceStatic;
|
||||
private static IObservableDirectoryWalkerFactory observableDirectoryWalkerFactoryServiceStatic;
|
||||
private static IDockerService dockerServiceStatic;
|
||||
|
||||
private static IEnvironmentVariableService environmentVariableServiceStatic;
|
||||
|
||||
[Export(typeof(ILogger))]
|
||||
public ILogger Logger => loggerStatic;
|
||||
|
||||
|
|
|
@ -4,6 +4,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
public class CargoComponent : TypedComponent
|
||||
{
|
||||
private CargoComponent()
|
||||
{
|
||||
// reserved for deserialization
|
||||
}
|
||||
|
||||
public CargoComponent(string name, string version)
|
||||
{
|
||||
this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.Cargo));
|
||||
|
@ -19,10 +24,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public override string Id => $"{this.Name} {this.Version} - {this.Type}";
|
||||
|
||||
public override PackageURL PackageUrl => new PackageURL("cargo", string.Empty, this.Name, this.Version, null, string.Empty);
|
||||
|
||||
private CargoComponent()
|
||||
{
|
||||
// reserved for deserialization
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
this.MD5 = md5;
|
||||
}
|
||||
|
||||
private CondaComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public string Build { get; set; }
|
||||
|
||||
public string Channel { get; set; }
|
||||
|
@ -33,10 +38,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public override ComponentType Type => ComponentType.Conda;
|
||||
|
||||
public override string Id => $"{this.Name} {this.Version} {this.Build} {this.Channel} {this.Subdir} {this.Namespace} {this.Url} {this.MD5} - {this.Type}";
|
||||
|
||||
private CondaComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
public class DockerImageComponent : TypedComponent
|
||||
{
|
||||
private DockerImageComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public DockerImageComponent(string hash, string name = null, string tag = null)
|
||||
{
|
||||
this.Digest = this.ValidateRequiredInput(hash, nameof(this.Digest), nameof(ComponentType.DockerImage));
|
||||
|
@ -18,10 +23,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public override ComponentType Type => ComponentType.DockerImage;
|
||||
|
||||
public override string Id => $"{this.Name} {this.Tag} {this.Digest}";
|
||||
|
||||
private DockerImageComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
}
|
||||
|
||||
private DockerReferenceComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public string Repository { get; set; }
|
||||
|
||||
public string Digest { get; set; }
|
||||
|
@ -32,10 +37,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
}
|
||||
|
||||
public override string Id => $"{this.Repository} {this.Tag} {this.Digest}";
|
||||
|
||||
private DockerReferenceComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
this.Tag = tag;
|
||||
}
|
||||
|
||||
private GitComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public Uri RepositoryUrl { get; set; }
|
||||
|
||||
public string CommitHash { get; set; }
|
||||
|
@ -25,10 +30,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public override ComponentType Type => ComponentType.Git;
|
||||
|
||||
public override string Id => $"{this.RepositoryUrl} : {this.CommitHash} - {this.Type}";
|
||||
|
||||
private GitComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,21 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
this.Hash = this.ValidateRequiredInput(hash, nameof(this.Hash), nameof(ComponentType.Go));
|
||||
}
|
||||
|
||||
private GoComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
public string Hash { get; set; }
|
||||
|
||||
// Commit should be used in place of version when available
|
||||
// https://github.com/package-url/purl-spec/blame/180c46d266c45aa2bd81a2038af3f78e87bb4a25/README.rst#L610
|
||||
public override PackageURL PackageUrl => new PackageURL("golang", null, this.Name, string.IsNullOrWhiteSpace(this.Hash) ? this.Version : this.Hash, null, null);
|
||||
|
||||
public override ComponentType Type => ComponentType.Go;
|
||||
|
||||
public override string Id => $"{this.Name} {this.Version} - {this.Type}";
|
||||
|
@ -49,14 +58,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
return this.Name.GetHashCode() ^ this.Version.GetHashCode() ^ this.Hash.GetHashCode();
|
||||
}
|
||||
|
||||
// Commit should be used in place of version when available
|
||||
// https://github.com/package-url/purl-spec/blame/180c46d266c45aa2bd81a2038af3f78e87bb4a25/README.rst#L610
|
||||
public override PackageURL PackageUrl => new PackageURL("golang", null, this.Name, string.IsNullOrWhiteSpace(this.Hash) ? this.Version : this.Hash, null, null);
|
||||
|
||||
private GoComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
public class LinuxComponent : TypedComponent
|
||||
{
|
||||
private LinuxComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public LinuxComponent(string distribution, string release, string name, string version)
|
||||
{
|
||||
this.Distribution = this.ValidateRequiredInput(distribution, nameof(this.Distribution), nameof(ComponentType.Linux));
|
||||
|
@ -48,11 +53,6 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
}
|
||||
}
|
||||
|
||||
private LinuxComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
private bool IsUbuntu()
|
||||
{
|
||||
return this.Distribution.ToLowerInvariant() == "ubuntu";
|
||||
|
|
|
@ -11,6 +11,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
this.Version = this.ValidateRequiredInput(version, nameof(this.Version), nameof(ComponentType.Maven));
|
||||
}
|
||||
|
||||
private MavenComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public string GroupId { get; set; }
|
||||
|
||||
public string ArtifactId { get; set; }
|
||||
|
@ -22,10 +27,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public override string Id => $"{this.GroupId} {this.ArtifactId} {this.Version} - {this.Type}";
|
||||
|
||||
public override PackageURL PackageUrl => new PackageURL("maven", this.GroupId, this.ArtifactId, this.Version, null, null);
|
||||
|
||||
private MavenComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
public class NpmComponent : TypedComponent
|
||||
{
|
||||
private NpmComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public NpmComponent(string name, string version, string hash = null, NpmAuthor author = null)
|
||||
{
|
||||
this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.Npm));
|
||||
|
@ -26,10 +31,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public override string Id => $"{this.Name} {this.Version} - {this.Type}";
|
||||
|
||||
public override PackageURL PackageUrl => new PackageURL("npm", null, this.Name, this.Version, null, null);
|
||||
|
||||
private NpmComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
public class NuGetComponent : TypedComponent
|
||||
{
|
||||
private NuGetComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public NuGetComponent(string name, string version, string[] authors = null)
|
||||
{
|
||||
this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.NuGet));
|
||||
|
@ -22,10 +27,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public override string Id => $"{this.Name} {this.Version} - {this.Type}";
|
||||
|
||||
public override PackageURL PackageUrl => new PackageURL("nuget", null, this.Name, this.Version, null, null);
|
||||
|
||||
private NuGetComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
public class OtherComponent : TypedComponent
|
||||
{
|
||||
private OtherComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public OtherComponent(string name, string version, Uri downloadUrl, string hash)
|
||||
{
|
||||
this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.Other));
|
||||
|
@ -23,10 +28,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public override ComponentType Type => ComponentType.Other;
|
||||
|
||||
public override string Id => $"{this.Name} {this.Version} {this.DownloadUrl} - {this.Type}";
|
||||
|
||||
private OtherComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
public class PipComponent : TypedComponent
|
||||
{
|
||||
private PipComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public PipComponent(string name, string version)
|
||||
{
|
||||
this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.Pip));
|
||||
|
@ -19,10 +24,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public override string Id => $"{this.Name} {this.Version} - {this.Type}".ToLowerInvariant();
|
||||
|
||||
public override PackageURL PackageUrl => new PackageURL("pypi", null, this.Name, this.Version, null, null);
|
||||
|
||||
private PipComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
public class PodComponent : TypedComponent
|
||||
{
|
||||
private PodComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public PodComponent(string name, string version, string specRepo = "")
|
||||
{
|
||||
this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.Pod));
|
||||
|
@ -35,10 +40,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
return new PackageURL("cocoapods", null, this.Name, this.Version, qualifiers, null);
|
||||
}
|
||||
}
|
||||
|
||||
private PodComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
public class RubyGemsComponent : TypedComponent
|
||||
{
|
||||
private RubyGemsComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public RubyGemsComponent(string name, string version, string source = "")
|
||||
{
|
||||
this.Name = this.ValidateRequiredInput(name, nameof(this.Name), nameof(ComponentType.RubyGems));
|
||||
|
@ -22,10 +27,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public override string Id => $"{this.Name} {this.Version} - {this.Type}";
|
||||
|
||||
public override PackageURL PackageUrl => new PackageURL("gem", null, this.Name, this.Version, null, null);
|
||||
|
||||
private RubyGemsComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
{
|
||||
public class SpdxComponent : TypedComponent
|
||||
{
|
||||
private SpdxComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
|
||||
public SpdxComponent(string spdxVersion, Uri documentNamespace, string name, string checksum, string rootElementId, string path)
|
||||
{
|
||||
this.SpdxVersion = this.ValidateRequiredInput(spdxVersion, nameof(this.SpdxVersion), nameof(ComponentType.Spdx));
|
||||
|
@ -29,10 +34,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
public string Path { get; }
|
||||
|
||||
public override string Id => $"{this.Name}-{this.SpdxVersion}-{this.Checksum}";
|
||||
|
||||
private SpdxComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -4,6 +4,11 @@ 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)
|
||||
{
|
||||
int.TryParse(portVersion, out var port);
|
||||
|
@ -66,10 +71,5 @@ namespace Microsoft.ComponentDetection.Contracts.TypedComponent
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
private VcpkgComponent()
|
||||
{
|
||||
/* Reserved for deserialization */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -27,133 +27,6 @@ namespace Microsoft.ComponentDetection.Detectors.CocoaPods
|
|||
|
||||
public override int Version { get; } = 2;
|
||||
|
||||
private class Pod : IYamlConvertible
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
public IList<PodDependency> Dependencies { get; set; }
|
||||
|
||||
public string Podspec => this.Name.Split('/', 2)[0];
|
||||
|
||||
public bool IsSubspec => this.Name != this.Podspec;
|
||||
|
||||
public void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer)
|
||||
{
|
||||
var hasDependencies = parser.Accept<MappingStart>(out _);
|
||||
if (hasDependencies)
|
||||
{
|
||||
parser.Consume<MappingStart>();
|
||||
}
|
||||
|
||||
var podInfo = parser.Consume<Scalar>();
|
||||
var components = podInfo.Value.Split(new char[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
this.Name = components[0].Trim();
|
||||
this.Version = components[1].Trim();
|
||||
|
||||
if (hasDependencies)
|
||||
{
|
||||
this.Dependencies = (IList<PodDependency>)nestedObjectDeserializer(typeof(IList<PodDependency>));
|
||||
|
||||
parser.Consume<MappingEnd>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Dependencies = Array.Empty<PodDependency>();
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
private class PodDependency : IYamlConvertible
|
||||
{
|
||||
public string PodName { get; set; }
|
||||
|
||||
public string PodVersion { get; set; }
|
||||
|
||||
public string Podspec => this.PodName.Split('/', 2)[0];
|
||||
|
||||
public bool IsSubspec => this.PodName != this.Podspec;
|
||||
|
||||
public void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer)
|
||||
{
|
||||
var scalar = parser.Consume<Scalar>();
|
||||
var components = scalar.Value.Split(new char[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
this.PodName = components[0].Trim();
|
||||
this.PodVersion = components.Length > 1 ? components[1].Trim() : null;
|
||||
}
|
||||
|
||||
public void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
private class PodfileLock
|
||||
{
|
||||
[YamlMember(Alias = "PODFILE CHECKSUM", ApplyNamingConventions = false)]
|
||||
public string Checksum { get; set; }
|
||||
|
||||
[YamlMember(Alias = "COCOAPODS", ApplyNamingConventions = false)]
|
||||
public string CocoapodsVersion { get; set; }
|
||||
|
||||
[YamlMember(Alias = "DEPENDENCIES", ApplyNamingConventions = false)]
|
||||
public IList<PodDependency> Dependencies { get; set; }
|
||||
|
||||
[YamlMember(Alias = "SPEC REPOS", ApplyNamingConventions = false)]
|
||||
public IDictionary<string, IList<string>> PodspecRepositories { get; set; }
|
||||
|
||||
[YamlMember(Alias = "SPEC CHECKSUMS", ApplyNamingConventions = false)]
|
||||
public IDictionary<string, string> PodspecChecksums { get; set; }
|
||||
|
||||
[YamlMember(Alias = "EXTERNAL SOURCES", ApplyNamingConventions = false)]
|
||||
public IDictionary<string, IDictionary<string, string>> ExternalSources { get; set; }
|
||||
|
||||
[YamlMember(Alias = "CHECKOUT OPTIONS", ApplyNamingConventions = false)]
|
||||
public IDictionary<string, IDictionary<string, string>> CheckoutOptions { get; set; }
|
||||
|
||||
[YamlMember(Alias = "PODS", ApplyNamingConventions = false)]
|
||||
public IList<Pod> Pods { get; set; }
|
||||
|
||||
public PodfileLock()
|
||||
{
|
||||
this.Dependencies = Array.Empty<PodDependency>();
|
||||
this.PodspecRepositories = new Dictionary<string, IList<string>>();
|
||||
this.PodspecChecksums = new Dictionary<string, string>();
|
||||
this.ExternalSources = new Dictionary<string, IDictionary<string, string>>();
|
||||
this.CheckoutOptions = new Dictionary<string, IDictionary<string, string>>();
|
||||
this.Pods = Array.Empty<Pod>();
|
||||
}
|
||||
|
||||
public string GetSpecRepositoryOfSpec(string specName)
|
||||
{
|
||||
foreach (var repository in this.PodspecRepositories)
|
||||
{
|
||||
if (repository.Value.Contains(specName))
|
||||
{
|
||||
// CocoaPods specs are stored in a git repo but depending on settings/CocoaPods version
|
||||
// the repo is shown differently in the Podfile.lock
|
||||
switch (repository.Key.ToLowerInvariant())
|
||||
{
|
||||
case "trunk":
|
||||
case "https://github.com/cocoapods/specs.git":
|
||||
return "trunk";
|
||||
|
||||
default:
|
||||
return repository.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
protected override async Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
|
||||
|
@ -419,5 +292,132 @@ namespace Microsoft.ComponentDetection.Detectors.CocoaPods
|
|||
isExplicitReferencedDependency: true);
|
||||
}
|
||||
}
|
||||
|
||||
private class Pod : IYamlConvertible
|
||||
{
|
||||
public string Name { get; set; }
|
||||
|
||||
public string Version { get; set; }
|
||||
|
||||
public IList<PodDependency> Dependencies { get; set; }
|
||||
|
||||
public string Podspec => this.Name.Split('/', 2)[0];
|
||||
|
||||
public bool IsSubspec => this.Name != this.Podspec;
|
||||
|
||||
public void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer)
|
||||
{
|
||||
var hasDependencies = parser.Accept<MappingStart>(out _);
|
||||
if (hasDependencies)
|
||||
{
|
||||
parser.Consume<MappingStart>();
|
||||
}
|
||||
|
||||
var podInfo = parser.Consume<Scalar>();
|
||||
var components = podInfo.Value.Split(new char[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
this.Name = components[0].Trim();
|
||||
this.Version = components[1].Trim();
|
||||
|
||||
if (hasDependencies)
|
||||
{
|
||||
this.Dependencies = (IList<PodDependency>)nestedObjectDeserializer(typeof(IList<PodDependency>));
|
||||
|
||||
parser.Consume<MappingEnd>();
|
||||
}
|
||||
else
|
||||
{
|
||||
this.Dependencies = Array.Empty<PodDependency>();
|
||||
}
|
||||
}
|
||||
|
||||
public void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
private class PodDependency : IYamlConvertible
|
||||
{
|
||||
public string PodName { get; set; }
|
||||
|
||||
public string PodVersion { get; set; }
|
||||
|
||||
public string Podspec => this.PodName.Split('/', 2)[0];
|
||||
|
||||
public bool IsSubspec => this.PodName != this.Podspec;
|
||||
|
||||
public void Read(IParser parser, Type expectedType, ObjectDeserializer nestedObjectDeserializer)
|
||||
{
|
||||
var scalar = parser.Consume<Scalar>();
|
||||
var components = scalar.Value.Split(new char[] { '(', ')' }, StringSplitOptions.RemoveEmptyEntries);
|
||||
this.PodName = components[0].Trim();
|
||||
this.PodVersion = components.Length > 1 ? components[1].Trim() : null;
|
||||
}
|
||||
|
||||
public void Write(IEmitter emitter, ObjectSerializer nestedObjectSerializer)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
|
||||
private class PodfileLock
|
||||
{
|
||||
public PodfileLock()
|
||||
{
|
||||
this.Dependencies = Array.Empty<PodDependency>();
|
||||
this.PodspecRepositories = new Dictionary<string, IList<string>>();
|
||||
this.PodspecChecksums = new Dictionary<string, string>();
|
||||
this.ExternalSources = new Dictionary<string, IDictionary<string, string>>();
|
||||
this.CheckoutOptions = new Dictionary<string, IDictionary<string, string>>();
|
||||
this.Pods = Array.Empty<Pod>();
|
||||
}
|
||||
|
||||
[YamlMember(Alias = "PODFILE CHECKSUM", ApplyNamingConventions = false)]
|
||||
public string Checksum { get; set; }
|
||||
|
||||
[YamlMember(Alias = "COCOAPODS", ApplyNamingConventions = false)]
|
||||
public string CocoapodsVersion { get; set; }
|
||||
|
||||
[YamlMember(Alias = "DEPENDENCIES", ApplyNamingConventions = false)]
|
||||
public IList<PodDependency> Dependencies { get; set; }
|
||||
|
||||
[YamlMember(Alias = "SPEC REPOS", ApplyNamingConventions = false)]
|
||||
public IDictionary<string, IList<string>> PodspecRepositories { get; set; }
|
||||
|
||||
[YamlMember(Alias = "SPEC CHECKSUMS", ApplyNamingConventions = false)]
|
||||
public IDictionary<string, string> PodspecChecksums { get; set; }
|
||||
|
||||
[YamlMember(Alias = "EXTERNAL SOURCES", ApplyNamingConventions = false)]
|
||||
public IDictionary<string, IDictionary<string, string>> ExternalSources { get; set; }
|
||||
|
||||
[YamlMember(Alias = "CHECKOUT OPTIONS", ApplyNamingConventions = false)]
|
||||
public IDictionary<string, IDictionary<string, string>> CheckoutOptions { get; set; }
|
||||
|
||||
[YamlMember(Alias = "PODS", ApplyNamingConventions = false)]
|
||||
public IList<Pod> Pods { get; set; }
|
||||
|
||||
public string GetSpecRepositoryOfSpec(string specName)
|
||||
{
|
||||
foreach (var repository in this.PodspecRepositories)
|
||||
{
|
||||
if (repository.Value.Contains(specName))
|
||||
{
|
||||
// CocoaPods specs are stored in a git repo but depending on settings/CocoaPods version
|
||||
// the repo is shown differently in the Podfile.lock
|
||||
switch (repository.Key.ToLowerInvariant())
|
||||
{
|
||||
case "trunk":
|
||||
case "https://github.com/cocoapods/specs.git":
|
||||
return "trunk";
|
||||
|
||||
default:
|
||||
return repository.Key;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -16,6 +16,8 @@ namespace Microsoft.ComponentDetection.Detectors.Dockerfile
|
|||
[Export(typeof(IComponentDetector))]
|
||||
public class DockerfileComponentDetector : FileComponentDetector, IDefaultOffComponentDetector
|
||||
{
|
||||
private HashSet<string> projectRoots = new HashSet<string>();
|
||||
|
||||
[Import]
|
||||
public ICommandLineInvocationService CommandLineInvocationService { get; set; }
|
||||
|
||||
|
@ -32,8 +34,6 @@ namespace Microsoft.ComponentDetection.Detectors.Dockerfile
|
|||
|
||||
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;
|
||||
|
|
|
@ -16,16 +16,18 @@ namespace Microsoft.ComponentDetection.Detectors.Go
|
|||
[Export(typeof(IComponentDetector))]
|
||||
public class GoComponentDetector : FileComponentDetector
|
||||
{
|
||||
private static readonly Regex GoSumRegex = new Regex(
|
||||
@"(?<name>.*)\s+(?<version>.*?)(/go\.mod)?\s+(?<hash>.*)",
|
||||
RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase);
|
||||
|
||||
private HashSet<string> projectRoots = new HashSet<string>();
|
||||
|
||||
[Import]
|
||||
public ICommandLineInvocationService CommandLineInvocationService { get; set; }
|
||||
|
||||
[Import]
|
||||
public IEnvironmentVariableService EnvVarService { get; set; }
|
||||
|
||||
private static readonly Regex GoSumRegex = new Regex(
|
||||
@"(?<name>.*)\s+(?<version>.*?)(/go\.mod)?\s+(?<hash>.*)",
|
||||
RegexOptions.Compiled | RegexOptions.ExplicitCapture | RegexOptions.IgnoreCase);
|
||||
|
||||
public override string Id { get; } = "Go";
|
||||
|
||||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.GoMod) };
|
||||
|
@ -36,8 +38,6 @@ namespace Microsoft.ComponentDetection.Detectors.Go
|
|||
|
||||
public override int Version => 6;
|
||||
|
||||
private HashSet<string> projectRoots = new HashSet<string>();
|
||||
|
||||
protected override async Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
|
||||
|
|
|
@ -13,6 +13,8 @@ namespace Microsoft.ComponentDetection.Detectors.Gradle
|
|||
[Export(typeof(IComponentDetector))]
|
||||
public class GradleComponentDetector : FileComponentDetector, IComponentDetector
|
||||
{
|
||||
private static readonly Regex StartsWithLetterRegex = new Regex("^[A-Za-z]", RegexOptions.Compiled);
|
||||
|
||||
public override string Id { get; } = "Gradle";
|
||||
|
||||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.Maven) };
|
||||
|
@ -23,8 +25,6 @@ namespace Microsoft.ComponentDetection.Detectors.Gradle
|
|||
|
||||
public override int Version { get; } = 2;
|
||||
|
||||
private static readonly Regex StartsWithLetterRegex = new Regex("^[A-Za-z]", RegexOptions.Compiled);
|
||||
|
||||
protected override Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
|
||||
|
|
|
@ -39,6 +39,12 @@ namespace Microsoft.ComponentDetection.Detectors.Ivy
|
|||
[Export(typeof(IComponentDetector))]
|
||||
public class IvyDetector : FileComponentDetector, IExperimentalDetector
|
||||
{
|
||||
internal const string PrimaryCommand = "ant.bat";
|
||||
|
||||
internal static readonly string[] AdditionalValidCommands = { "ant" };
|
||||
|
||||
internal const string AntVersionArgument = "-version";
|
||||
|
||||
public override string Id => "Ivy";
|
||||
|
||||
public override IList<string> SearchPatterns => new List<string> { "ivy.xml" };
|
||||
|
@ -49,12 +55,6 @@ namespace Microsoft.ComponentDetection.Detectors.Ivy
|
|||
|
||||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.Maven) };
|
||||
|
||||
internal const string PrimaryCommand = "ant.bat";
|
||||
|
||||
internal static readonly string[] AdditionalValidCommands = { "ant" };
|
||||
|
||||
internal const string AntVersionArgument = "-version";
|
||||
|
||||
[Import]
|
||||
public ICommandLineInvocationService CommandLineInvocationService { get; set; }
|
||||
|
||||
|
|
|
@ -10,6 +10,12 @@ namespace Microsoft.ComponentDetection.Detectors.Maven
|
|||
[Export(typeof(IMavenCommandService))]
|
||||
public class MavenCommandService : IMavenCommandService
|
||||
{
|
||||
internal const string PrimaryCommand = "mvn";
|
||||
|
||||
internal const string MvnVersionArgument = "--version";
|
||||
|
||||
internal static readonly string[] AdditionalValidCommands = new[] { "mvn.cmd" };
|
||||
|
||||
[Import]
|
||||
public ICommandLineInvocationService CommandLineInvocationService { get; set; }
|
||||
|
||||
|
@ -21,12 +27,6 @@ namespace Microsoft.ComponentDetection.Detectors.Maven
|
|||
|
||||
public string BcdeMvnDependencyFileName => "bcde.mvndeps";
|
||||
|
||||
internal const string PrimaryCommand = "mvn";
|
||||
|
||||
internal const string MvnVersionArgument = "--version";
|
||||
|
||||
internal static readonly string[] AdditionalValidCommands = new[] { "mvn.cmd" };
|
||||
|
||||
public async Task<bool> MavenCLIExists()
|
||||
{
|
||||
return await this.CommandLineInvocationService.CanCommandBeLocated(PrimaryCommand, AdditionalValidCommands, MvnVersionArgument);
|
||||
|
|
|
@ -11,14 +11,14 @@ namespace Microsoft.ComponentDetection.Detectors.Maven
|
|||
|
||||
private static readonly string[] ComponentSplitters = new[] { "+-", "\\-" };
|
||||
|
||||
public GraphNode<string> DependencyCategory { get; private set; }
|
||||
|
||||
private Stack<GraphNodeAtLevel<string>> stack = new Stack<GraphNodeAtLevel<string>>();
|
||||
|
||||
private Stack<(int ParseLevel, DetectedComponent Component)> tupleStack = new Stack<(int, DetectedComponent)>();
|
||||
|
||||
private DetectedComponent topLevelComponent = null;
|
||||
|
||||
public GraphNode<string> DependencyCategory { get; private set; }
|
||||
|
||||
public GraphNode<string> Parse(string[] lines)
|
||||
{
|
||||
foreach (var line in lines)
|
||||
|
@ -135,13 +135,13 @@ namespace Microsoft.ComponentDetection.Detectors.Maven
|
|||
|
||||
private class GraphNodeAtLevel<T> : GraphNode<T>
|
||||
{
|
||||
public int ParseLevel { get; }
|
||||
|
||||
public GraphNodeAtLevel(int level, T value)
|
||||
: base(value)
|
||||
{
|
||||
this.ParseLevel = level;
|
||||
}
|
||||
|
||||
public int ParseLevel { get; }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,6 +15,11 @@ namespace Microsoft.ComponentDetection.Detectors.Npm
|
|||
[Export(typeof(IComponentDetector))]
|
||||
public class NpmComponentDetector : FileComponentDetector
|
||||
{
|
||||
/// <summary>Common delegate for Package.json JToken processing.</summary>
|
||||
/// <param name="token">A JToken, usually corresponding to a package.json file.</param>
|
||||
/// <returns>Used in scenarios where one file path creates multiple JTokens, a false value indicates processing additional JTokens should be halted, proceed otherwise.</returns>
|
||||
protected delegate bool JTokenProcessingDelegate(JToken token);
|
||||
|
||||
public override string Id { get; } = "Npm";
|
||||
|
||||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.Npm) };
|
||||
|
@ -25,11 +30,6 @@ namespace Microsoft.ComponentDetection.Detectors.Npm
|
|||
|
||||
public override int Version { get; } = 2;
|
||||
|
||||
/// <summary>Common delegate for Package.json JToken processing.</summary>
|
||||
/// <param name="token">A JToken, usually corresponding to a package.json file.</param>
|
||||
/// <returns>Used in scenarios where one file path creates multiple JTokens, a false value indicates processing additional JTokens should be halted, proceed otherwise.</returns>
|
||||
protected delegate bool JTokenProcessingDelegate(JToken token);
|
||||
|
||||
protected override async Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
|
||||
|
|
|
@ -17,6 +17,17 @@ namespace Microsoft.ComponentDetection.Detectors.Npm
|
|||
[Export(typeof(IComponentDetector))]
|
||||
public class NpmComponentDetectorWithRoots : FileComponentDetector
|
||||
{
|
||||
private const string NpmRegistryHost = "registry.npmjs.org";
|
||||
|
||||
private readonly object lernaFilesLock = new object();
|
||||
|
||||
public const string LernaSearchPattern = "lerna.json";
|
||||
|
||||
/// <summary>Common delegate for Package.json JToken processing.</summary>
|
||||
/// <param name="token">A JToken, usually corresponding to a package.json file.</param>
|
||||
/// <returns>Used in scenarios where one file path creates multiple JTokens, a false value indicates processing additional JTokens should be halted, proceed otherwise.</returns>
|
||||
protected delegate bool JTokenProcessingDelegate(JToken token);
|
||||
|
||||
/// <summary>Gets or sets the logger for writing basic logging message to both console and file. Injected automatically by MEF composition.</summary>
|
||||
[Import]
|
||||
public IPathUtilityService PathUtilityService { get; set; }
|
||||
|
@ -31,17 +42,6 @@ namespace Microsoft.ComponentDetection.Detectors.Npm
|
|||
|
||||
public override int Version { get; } = 2;
|
||||
|
||||
private const string NpmRegistryHost = "registry.npmjs.org";
|
||||
|
||||
private readonly object lernaFilesLock = new object();
|
||||
|
||||
/// <summary>Common delegate for Package.json JToken processing.</summary>
|
||||
/// <param name="token">A JToken, usually corresponding to a package.json file.</param>
|
||||
/// <returns>Used in scenarios where one file path creates multiple JTokens, a false value indicates processing additional JTokens should be halted, proceed otherwise.</returns>
|
||||
protected delegate bool JTokenProcessingDelegate(JToken token);
|
||||
|
||||
public const string LernaSearchPattern = "lerna.json";
|
||||
|
||||
public List<ProcessRequest> LernaFiles { get; set; } = new List<ProcessRequest>();
|
||||
|
||||
/// <inheritdoc />
|
||||
|
|
|
@ -20,6 +20,10 @@ namespace Microsoft.ComponentDetection.Detectors.NuGet
|
|||
{
|
||||
private static readonly IEnumerable<string> LowConfidencePackages = new[] { "Newtonsoft.Json" };
|
||||
|
||||
public const string NugetConfigFileName = "nuget.config";
|
||||
|
||||
private readonly IList<string> repositoryPathKeyNames = new List<string> { "repositorypath", "globalpackagesfolder" };
|
||||
|
||||
public override string Id { get; } = "NuGet";
|
||||
|
||||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.NuGet) };
|
||||
|
@ -30,10 +34,6 @@ namespace Microsoft.ComponentDetection.Detectors.NuGet
|
|||
|
||||
public override int Version { get; } = 2;
|
||||
|
||||
public const string NugetConfigFileName = "nuget.config";
|
||||
|
||||
private readonly IList<string> repositoryPathKeyNames = new List<string> { "repositorypath", "globalpackagesfolder" };
|
||||
|
||||
protected override async Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
var stream = processRequest.ComponentStream;
|
||||
|
|
|
@ -18,16 +18,6 @@ namespace Microsoft.ComponentDetection.Detectors.NuGet
|
|||
[Export(typeof(IComponentDetector))]
|
||||
public class NuGetProjectModelProjectCentricComponentDetector : FileComponentDetector
|
||||
{
|
||||
public override string Id { get; } = "NuGetProjectCentric";
|
||||
|
||||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.NuGet) };
|
||||
|
||||
public override IList<string> SearchPatterns { get; } = new List<string> { "project.assets.json" };
|
||||
|
||||
public override IEnumerable<ComponentType> SupportedComponentTypes { get; } = new[] { ComponentType.NuGet };
|
||||
|
||||
public override int Version { get; } = 1;
|
||||
|
||||
public const string OmittedFrameworkComponentsTelemetryKey = "OmittedFrameworkComponents";
|
||||
|
||||
public const string ProjectDependencyType = "project";
|
||||
|
@ -37,6 +27,174 @@ namespace Microsoft.ComponentDetection.Detectors.NuGet
|
|||
private readonly List<string> netCoreFrameworkNames = new List<string> { "Microsoft.AspNetCore.App", "Microsoft.AspNetCore.Razor.Design", "Microsoft.NETCore.App" };
|
||||
|
||||
private readonly HashSet<string> alreadyLoggedWarnings = new HashSet<string>();
|
||||
// This list is meant to encompass all net standard dependencies, but likely contains some net core app 1.x ones, too.
|
||||
// The specific guidance we got around populating this list is to do so based on creating a dotnet core 1.x app to make sure we had the complete
|
||||
// set of netstandard.library files that could show up in later sdk versions.
|
||||
private readonly string[] netStandardDependencies = new[]
|
||||
{
|
||||
"Libuv",
|
||||
"Microsoft.CodeAnalysis.Analyzers",
|
||||
"Microsoft.CodeAnalysis.Common",
|
||||
"Microsoft.CodeAnalysis.CSharp",
|
||||
"Microsoft.CodeAnalysis.VisualBasic",
|
||||
"Microsoft.CSharp",
|
||||
"Microsoft.DiaSymReader.Native",
|
||||
"Microsoft.NETCore.DotNetHost",
|
||||
"Microsoft.NETCore.DotNetHostPolicy",
|
||||
"Microsoft.NETCore.DotNetHostResolver",
|
||||
"Microsoft.NETCore.Jit",
|
||||
"Microsoft.NETCore.Platforms",
|
||||
"Microsoft.NETCore.Runtime.CoreCLR",
|
||||
"Microsoft.NETCore.Targets",
|
||||
"Microsoft.NETCore.Windows.ApiSets",
|
||||
"Microsoft.VisualBasic",
|
||||
"Microsoft.Win32.Primitives",
|
||||
"Microsoft.Win32.Registry",
|
||||
"NETStandard.Library",
|
||||
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.native.System",
|
||||
"runtime.native.System.IO.Compression",
|
||||
"runtime.native.System.Net.Http",
|
||||
"runtime.native.System.Net.Security",
|
||||
"runtime.native.System.Security.Cryptography.Apple",
|
||||
"runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple",
|
||||
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"System.AppContext",
|
||||
"System.Buffers",
|
||||
"System.Collections",
|
||||
"System.Collections.Concurrent",
|
||||
"System.Collections.Immutable",
|
||||
"System.Collections.NonGeneric",
|
||||
"System.Collections.Specialized",
|
||||
"System.ComponentModel",
|
||||
"System.ComponentModel.Annotations",
|
||||
"System.ComponentModel.EventBasedAsync",
|
||||
"System.ComponentModel.Primitives",
|
||||
"System.ComponentModel.TypeConverter",
|
||||
"System.Console",
|
||||
"System.Data.Common",
|
||||
"System.Diagnostics.Contracts",
|
||||
"System.Diagnostics.Debug",
|
||||
"System.Diagnostics.DiagnosticSource",
|
||||
"System.Diagnostics.FileVersionInfo",
|
||||
"System.Diagnostics.Process",
|
||||
"System.Diagnostics.StackTrace",
|
||||
"System.Diagnostics.TextWriterTraceListener",
|
||||
"System.Diagnostics.Tools",
|
||||
"System.Diagnostics.TraceSource",
|
||||
"System.Diagnostics.Tracing",
|
||||
"System.Drawing.Primitives",
|
||||
"System.Dynamic.Runtime",
|
||||
"System.Globalization",
|
||||
"System.Globalization.Calendars",
|
||||
"System.Globalization.Extensions",
|
||||
"System.IO",
|
||||
"System.IO.Compression",
|
||||
"System.IO.Compression.ZipFile",
|
||||
"System.IO.FileSystem",
|
||||
"System.IO.FileSystem.DriveInfo",
|
||||
"System.IO.FileSystem.Primitives",
|
||||
"System.IO.FileSystem.Watcher",
|
||||
"System.IO.IsolatedStorage",
|
||||
"System.IO.MemoryMappedFiles",
|
||||
"System.IO.Pipes",
|
||||
"System.IO.UnmanagedMemoryStream",
|
||||
"System.Linq",
|
||||
"System.Linq.Expressions",
|
||||
"System.Linq.Parallel",
|
||||
"System.Linq.Queryable",
|
||||
"System.Net.Http",
|
||||
"System.Net.HttpListener",
|
||||
"System.Net.Mail",
|
||||
"System.Net.NameResolution",
|
||||
"System.Net.NetworkInformation",
|
||||
"System.Net.Ping",
|
||||
"System.Net.Primitives",
|
||||
"System.Net.Requests",
|
||||
"System.Net.Security",
|
||||
"System.Net.ServicePoint",
|
||||
"System.Net.Sockets",
|
||||
"System.Net.WebClient",
|
||||
"System.Net.WebHeaderCollection",
|
||||
"System.Net.WebProxy",
|
||||
"System.Net.WebSockets",
|
||||
"System.Net.WebSockets.Client",
|
||||
"System.Numerics.Vectors",
|
||||
"System.ObjectModel",
|
||||
"System.Reflection",
|
||||
"System.Reflection.DispatchProxy",
|
||||
"System.Reflection.Emit",
|
||||
"System.Reflection.Emit.ILGeneration",
|
||||
"System.Reflection.Emit.Lightweight",
|
||||
"System.Reflection.Extensions",
|
||||
"System.Reflection.Metadata",
|
||||
"System.Reflection.Primitives",
|
||||
"System.Reflection.TypeExtensions",
|
||||
"System.Resources.Reader",
|
||||
"System.Resources.ResourceManager",
|
||||
"System.Resources.Writer",
|
||||
"System.Runtime",
|
||||
"System.Runtime.CompilerServices.VisualC",
|
||||
"System.Runtime.Extensions",
|
||||
"System.Runtime.Handles",
|
||||
"System.Runtime.InteropServices",
|
||||
"System.Runtime.InteropServices.RuntimeInformation",
|
||||
"System.Runtime.Loader",
|
||||
"System.Runtime.Numerics",
|
||||
"System.Runtime.Serialization.Formatters",
|
||||
"System.Runtime.Serialization.Json",
|
||||
"System.Runtime.Serialization.Primitives",
|
||||
"System.Runtime.Serialization.Xml",
|
||||
"System.Security.Claims",
|
||||
"System.Security.Cryptography.Algorithms",
|
||||
"System.Security.Cryptography.Cng",
|
||||
"System.Security.Cryptography.Csp",
|
||||
"System.Security.Cryptography.Encoding",
|
||||
"System.Security.Cryptography.OpenSsl",
|
||||
"System.Security.Cryptography.Primitives",
|
||||
"System.Security.Cryptography.X509Certificates",
|
||||
"System.Security.Principal",
|
||||
"System.Security.Principal.Windows",
|
||||
"System.Text.Encoding",
|
||||
"System.Text.Encoding.CodePages",
|
||||
"System.Text.Encoding.Extensions",
|
||||
"System.Text.RegularExpressions",
|
||||
"System.Threading",
|
||||
"System.Threading.Overlapped",
|
||||
"System.Threading.Tasks",
|
||||
"System.Threading.Tasks.Dataflow",
|
||||
"System.Threading.Tasks.Extensions",
|
||||
"System.Threading.Tasks.Parallel",
|
||||
"System.Threading.Thread",
|
||||
"System.Threading.ThreadPool",
|
||||
"System.Threading.Timer",
|
||||
"System.Web.HttpUtility",
|
||||
"System.Xml.ReaderWriter",
|
||||
"System.Xml.XDocument",
|
||||
"System.Xml.XmlDocument",
|
||||
"System.Xml.XmlSerializer",
|
||||
"System.Xml.XPath",
|
||||
"System.Xml.XPath.XDocument",
|
||||
};
|
||||
|
||||
public override string Id { get; } = "NuGetProjectCentric";
|
||||
|
||||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.NuGet) };
|
||||
|
||||
public override IList<string> SearchPatterns { get; } = new List<string> { "project.assets.json" };
|
||||
|
||||
public override IEnumerable<ComponentType> SupportedComponentTypes { get; } = new[] { ComponentType.NuGet };
|
||||
|
||||
public override int Version { get; } = 1;
|
||||
|
||||
[Import]
|
||||
public IFileUtilityService FileUtilityService { get; set; }
|
||||
|
@ -284,164 +442,5 @@ namespace Microsoft.ComponentDetection.Detectors.NuGet
|
|||
|
||||
return currentComponents;
|
||||
}
|
||||
|
||||
// This list is meant to encompass all net standard dependencies, but likely contains some net core app 1.x ones, too.
|
||||
// The specific guidance we got around populating this list is to do so based on creating a dotnet core 1.x app to make sure we had the complete
|
||||
// set of netstandard.library files that could show up in later sdk versions.
|
||||
private readonly string[] netStandardDependencies = new[]
|
||||
{
|
||||
"Libuv",
|
||||
"Microsoft.CodeAnalysis.Analyzers",
|
||||
"Microsoft.CodeAnalysis.Common",
|
||||
"Microsoft.CodeAnalysis.CSharp",
|
||||
"Microsoft.CodeAnalysis.VisualBasic",
|
||||
"Microsoft.CSharp",
|
||||
"Microsoft.DiaSymReader.Native",
|
||||
"Microsoft.NETCore.DotNetHost",
|
||||
"Microsoft.NETCore.DotNetHostPolicy",
|
||||
"Microsoft.NETCore.DotNetHostResolver",
|
||||
"Microsoft.NETCore.Jit",
|
||||
"Microsoft.NETCore.Platforms",
|
||||
"Microsoft.NETCore.Runtime.CoreCLR",
|
||||
"Microsoft.NETCore.Targets",
|
||||
"Microsoft.NETCore.Windows.ApiSets",
|
||||
"Microsoft.VisualBasic",
|
||||
"Microsoft.Win32.Primitives",
|
||||
"Microsoft.Win32.Registry",
|
||||
"NETStandard.Library",
|
||||
"runtime.debian.8-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.fedora.23-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.fedora.24-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.native.System",
|
||||
"runtime.native.System.IO.Compression",
|
||||
"runtime.native.System.Net.Http",
|
||||
"runtime.native.System.Net.Security",
|
||||
"runtime.native.System.Security.Cryptography.Apple",
|
||||
"runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.opensuse.13.2-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.opensuse.42.1-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.Apple",
|
||||
"runtime.osx.10.10-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.rhel.7-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.ubuntu.14.04-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.ubuntu.16.04-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"runtime.ubuntu.16.10-x64.runtime.native.System.Security.Cryptography.OpenSsl",
|
||||
"System.AppContext",
|
||||
"System.Buffers",
|
||||
"System.Collections",
|
||||
"System.Collections.Concurrent",
|
||||
"System.Collections.Immutable",
|
||||
"System.Collections.NonGeneric",
|
||||
"System.Collections.Specialized",
|
||||
"System.ComponentModel",
|
||||
"System.ComponentModel.Annotations",
|
||||
"System.ComponentModel.EventBasedAsync",
|
||||
"System.ComponentModel.Primitives",
|
||||
"System.ComponentModel.TypeConverter",
|
||||
"System.Console",
|
||||
"System.Data.Common",
|
||||
"System.Diagnostics.Contracts",
|
||||
"System.Diagnostics.Debug",
|
||||
"System.Diagnostics.DiagnosticSource",
|
||||
"System.Diagnostics.FileVersionInfo",
|
||||
"System.Diagnostics.Process",
|
||||
"System.Diagnostics.StackTrace",
|
||||
"System.Diagnostics.TextWriterTraceListener",
|
||||
"System.Diagnostics.Tools",
|
||||
"System.Diagnostics.TraceSource",
|
||||
"System.Diagnostics.Tracing",
|
||||
"System.Drawing.Primitives",
|
||||
"System.Dynamic.Runtime",
|
||||
"System.Globalization",
|
||||
"System.Globalization.Calendars",
|
||||
"System.Globalization.Extensions",
|
||||
"System.IO",
|
||||
"System.IO.Compression",
|
||||
"System.IO.Compression.ZipFile",
|
||||
"System.IO.FileSystem",
|
||||
"System.IO.FileSystem.DriveInfo",
|
||||
"System.IO.FileSystem.Primitives",
|
||||
"System.IO.FileSystem.Watcher",
|
||||
"System.IO.IsolatedStorage",
|
||||
"System.IO.MemoryMappedFiles",
|
||||
"System.IO.Pipes",
|
||||
"System.IO.UnmanagedMemoryStream",
|
||||
"System.Linq",
|
||||
"System.Linq.Expressions",
|
||||
"System.Linq.Parallel",
|
||||
"System.Linq.Queryable",
|
||||
"System.Net.Http",
|
||||
"System.Net.HttpListener",
|
||||
"System.Net.Mail",
|
||||
"System.Net.NameResolution",
|
||||
"System.Net.NetworkInformation",
|
||||
"System.Net.Ping",
|
||||
"System.Net.Primitives",
|
||||
"System.Net.Requests",
|
||||
"System.Net.Security",
|
||||
"System.Net.ServicePoint",
|
||||
"System.Net.Sockets",
|
||||
"System.Net.WebClient",
|
||||
"System.Net.WebHeaderCollection",
|
||||
"System.Net.WebProxy",
|
||||
"System.Net.WebSockets",
|
||||
"System.Net.WebSockets.Client",
|
||||
"System.Numerics.Vectors",
|
||||
"System.ObjectModel",
|
||||
"System.Reflection",
|
||||
"System.Reflection.DispatchProxy",
|
||||
"System.Reflection.Emit",
|
||||
"System.Reflection.Emit.ILGeneration",
|
||||
"System.Reflection.Emit.Lightweight",
|
||||
"System.Reflection.Extensions",
|
||||
"System.Reflection.Metadata",
|
||||
"System.Reflection.Primitives",
|
||||
"System.Reflection.TypeExtensions",
|
||||
"System.Resources.Reader",
|
||||
"System.Resources.ResourceManager",
|
||||
"System.Resources.Writer",
|
||||
"System.Runtime",
|
||||
"System.Runtime.CompilerServices.VisualC",
|
||||
"System.Runtime.Extensions",
|
||||
"System.Runtime.Handles",
|
||||
"System.Runtime.InteropServices",
|
||||
"System.Runtime.InteropServices.RuntimeInformation",
|
||||
"System.Runtime.Loader",
|
||||
"System.Runtime.Numerics",
|
||||
"System.Runtime.Serialization.Formatters",
|
||||
"System.Runtime.Serialization.Json",
|
||||
"System.Runtime.Serialization.Primitives",
|
||||
"System.Runtime.Serialization.Xml",
|
||||
"System.Security.Claims",
|
||||
"System.Security.Cryptography.Algorithms",
|
||||
"System.Security.Cryptography.Cng",
|
||||
"System.Security.Cryptography.Csp",
|
||||
"System.Security.Cryptography.Encoding",
|
||||
"System.Security.Cryptography.OpenSsl",
|
||||
"System.Security.Cryptography.Primitives",
|
||||
"System.Security.Cryptography.X509Certificates",
|
||||
"System.Security.Principal",
|
||||
"System.Security.Principal.Windows",
|
||||
"System.Text.Encoding",
|
||||
"System.Text.Encoding.CodePages",
|
||||
"System.Text.Encoding.Extensions",
|
||||
"System.Text.RegularExpressions",
|
||||
"System.Threading",
|
||||
"System.Threading.Overlapped",
|
||||
"System.Threading.Tasks",
|
||||
"System.Threading.Tasks.Dataflow",
|
||||
"System.Threading.Tasks.Extensions",
|
||||
"System.Threading.Tasks.Parallel",
|
||||
"System.Threading.Thread",
|
||||
"System.Threading.ThreadPool",
|
||||
"System.Threading.Timer",
|
||||
"System.Web.HttpUtility",
|
||||
"System.Xml.ReaderWriter",
|
||||
"System.Xml.XDocument",
|
||||
"System.Xml.XmlDocument",
|
||||
"System.Xml.XmlSerializer",
|
||||
"System.Xml.XPath",
|
||||
"System.Xml.XPath.XDocument",
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,12 +29,6 @@ namespace Microsoft.ComponentDetection.Detectors.Pip
|
|||
[Export(typeof(IPyPiClient))]
|
||||
public class PyPiClient : IPyPiClient
|
||||
{
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
[Import]
|
||||
public IEnvironmentVariableService EnvironmentVariableService { get; set; }
|
||||
|
||||
private static HttpClientHandler httpClientHandler = new HttpClientHandler() { CheckCertificateRevocationList = true };
|
||||
|
||||
[SuppressMessage("StyleCop.CSharp.OrderingRules", "SA1202:ElementsMustBeOrderedByAccess", Justification = "Field needs to be declared before use so order can not follow Access Levels.")]
|
||||
|
@ -63,6 +57,27 @@ namespace Microsoft.ComponentDetection.Detectors.Pip
|
|||
// Keep telemetry on how the cache is being used for future refinements
|
||||
private PypiCacheTelemetryRecord cacheTelemetry;
|
||||
|
||||
public PyPiClient()
|
||||
{
|
||||
this.cacheTelemetry = new PypiCacheTelemetryRecord()
|
||||
{
|
||||
NumCacheHits = 0,
|
||||
FinalCacheSize = 0,
|
||||
};
|
||||
}
|
||||
|
||||
~PyPiClient()
|
||||
{
|
||||
this.cacheTelemetry.FinalCacheSize = this.cachedResponses.Count;
|
||||
this.cacheTelemetry.Dispose();
|
||||
}
|
||||
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
[Import]
|
||||
public IEnvironmentVariableService EnvironmentVariableService { get; set; }
|
||||
|
||||
public async Task<IList<PipDependencySpecification>> FetchPackageDependencies(string name, string version, PythonProjectRelease release)
|
||||
{
|
||||
var dependencies = new List<PipDependencySpecification>();
|
||||
|
@ -195,21 +210,6 @@ namespace Microsoft.ComponentDetection.Detectors.Pip
|
|||
return versions;
|
||||
}
|
||||
|
||||
public PyPiClient()
|
||||
{
|
||||
this.cacheTelemetry = new PypiCacheTelemetryRecord()
|
||||
{
|
||||
NumCacheHits = 0,
|
||||
FinalCacheSize = 0,
|
||||
};
|
||||
}
|
||||
|
||||
~PyPiClient()
|
||||
{
|
||||
this.cacheTelemetry.FinalCacheSize = this.cachedResponses.Count;
|
||||
this.cacheTelemetry.Dispose();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns a cached response if it exists, otherwise returns the response from PyPi REST call.
|
||||
/// The response from PyPi is automatically added to the cache.
|
||||
|
|
|
@ -11,18 +11,6 @@ namespace Microsoft.ComponentDetection.Detectors.Pip
|
|||
[DebuggerDisplay("{DebuggerDisplay,nq}")]
|
||||
public class PipDependencySpecification
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the package <see cref="Name"/> (ex: pyyaml).
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the set of dependency specifications that constrain the overall dependency request (ex: ==1.0, >=2.0).
|
||||
/// </summary>
|
||||
public IList<string> DependencySpecifiers { get; set; } = new List<string>();
|
||||
|
||||
private string DebuggerDisplay => $"{this.Name} ({string.Join(';', this.DependencySpecifiers)})";
|
||||
|
||||
// Extracts name and version from a Requires-Dist string that is found in a metadata file
|
||||
public static readonly Regex RequiresDistRegex = new Regex(
|
||||
@"Requires-Dist:\s*(?:(.*?)\s*\((.*?)\)|([^\s;]*))",
|
||||
|
@ -52,15 +40,6 @@ namespace Microsoft.ComponentDetection.Detectors.Pip
|
|||
@"((?=<)|(?=>)|(?=>=)|(?=<=)|(?===)|(?=!=)|(?=~=)|(?====))(.*)",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the package is safe to resolve based on the packagesToIgnore.
|
||||
/// </summary>
|
||||
/// <returns> True if the package is unsafe, otherwise false. </returns>
|
||||
public bool PackageIsUnsafe()
|
||||
{
|
||||
return PackagesToIgnore.Contains(this.Name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This constructor is used in test code.
|
||||
/// </summary>
|
||||
|
@ -118,5 +97,26 @@ namespace Microsoft.ComponentDetection.Detectors.Pip
|
|||
|
||||
this.DependencySpecifiers = this.DependencySpecifiers.Where(x => !x.Contains("python_version")).ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the package <see cref="Name"/> (ex: pyyaml).
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the set of dependency specifications that constrain the overall dependency request (ex: ==1.0, >=2.0).
|
||||
/// </summary>
|
||||
public IList<string> DependencySpecifiers { get; set; } = new List<string>();
|
||||
|
||||
private string DebuggerDisplay => $"{this.Name} ({string.Join(';', this.DependencySpecifiers)})";
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not the package is safe to resolve based on the packagesToIgnore.
|
||||
/// </summary>
|
||||
/// <returns> True if the package is unsafe, otherwise false. </returns>
|
||||
public bool PackageIsUnsafe()
|
||||
{
|
||||
return PackagesToIgnore.Contains(this.Name);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -213,9 +213,9 @@ namespace Microsoft.ComponentDetection.Detectors.Pip
|
|||
|
||||
public readonly Queue<(string, PipDependencySpecification)> ProcessingQueue = new Queue<(string, PipDependencySpecification)>();
|
||||
|
||||
public IList<PipGraphNode> Roots { get; } = new List<PipGraphNode>();
|
||||
|
||||
public readonly IDictionary<string, PipGraphNode> NodeReferences = new Dictionary<string, PipGraphNode>(StringComparer.OrdinalIgnoreCase);
|
||||
|
||||
public IList<PipGraphNode> Roots { get; } = new List<PipGraphNode>();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,26 +14,6 @@ namespace Microsoft.ComponentDetection.Detectors.Pip
|
|||
|
||||
private static Dictionary<string, int> preReleaseMapping = new Dictionary<string, int> { { "a", 0 }, { "alpha", 0 }, { "b", 1 }, { "beta", 1 }, { "c", 2 }, { "rc", 2 }, { "pre", 2 }, { "preview", 2 } };
|
||||
|
||||
public bool Valid { get; set; }
|
||||
|
||||
public bool IsReleasedPackage => string.IsNullOrEmpty(this.PreReleaseLabel) && !this.PreReleaseNumber.HasValue && !this.DevNumber.HasValue;
|
||||
|
||||
public int Epoch { get; set; }
|
||||
|
||||
public string Release { get; set; }
|
||||
|
||||
public string PreReleaseLabel { get; set; }
|
||||
|
||||
public int? PreReleaseNumber { get; set; }
|
||||
|
||||
public int? PostNumber { get; set; }
|
||||
|
||||
public string DevLabel { get; set; }
|
||||
|
||||
public int? DevNumber { get; set; }
|
||||
|
||||
public bool Floating { get; set; } = false;
|
||||
|
||||
private Match match;
|
||||
|
||||
public PythonVersion(string version)
|
||||
|
@ -97,6 +77,26 @@ namespace Microsoft.ComponentDetection.Detectors.Pip
|
|||
this.Valid = true;
|
||||
}
|
||||
|
||||
public bool Valid { get; set; }
|
||||
|
||||
public bool IsReleasedPackage => string.IsNullOrEmpty(this.PreReleaseLabel) && !this.PreReleaseNumber.HasValue && !this.DevNumber.HasValue;
|
||||
|
||||
public int Epoch { get; set; }
|
||||
|
||||
public string Release { get; set; }
|
||||
|
||||
public string PreReleaseLabel { get; set; }
|
||||
|
||||
public int? PreReleaseNumber { get; set; }
|
||||
|
||||
public int? PostNumber { get; set; }
|
||||
|
||||
public string DevLabel { get; set; }
|
||||
|
||||
public int? DevNumber { get; set; }
|
||||
|
||||
public bool Floating { get; set; } = false;
|
||||
|
||||
public static bool operator >(PythonVersion operand1, PythonVersion operand2)
|
||||
{
|
||||
return operand1.CompareTo(operand2) == 1;
|
||||
|
|
|
@ -12,6 +12,11 @@ namespace Microsoft.ComponentDetection.Detectors.Pnpm
|
|||
[Export(typeof(IComponentDetector))]
|
||||
public class PnpmComponentDetector : FileComponentDetector
|
||||
{
|
||||
public PnpmComponentDetector()
|
||||
{
|
||||
this.NeedsAutomaticRootDependencyCalculation = true;
|
||||
}
|
||||
|
||||
public override string Id { get; } = "Pnpm";
|
||||
|
||||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.Npm) };
|
||||
|
@ -25,11 +30,6 @@ namespace Microsoft.ComponentDetection.Detectors.Pnpm
|
|||
/// <inheritdoc />
|
||||
protected override IList<string> SkippedFolders => new List<string> { "node_modules", "pnpm-store" };
|
||||
|
||||
public PnpmComponentDetector()
|
||||
{
|
||||
this.NeedsAutomaticRootDependencyCalculation = true;
|
||||
}
|
||||
|
||||
protected override async Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
|
||||
|
|
|
@ -44,6 +44,18 @@ namespace Microsoft.ComponentDetection.Detectors.Ruby
|
|||
private static readonly Regex DependencyDefinitionRegex = new Regex("^ {4}[A-Za-z-]+", RegexOptions.Compiled);
|
||||
private static readonly Regex SubDependencyRegex = new Regex("^ {6}[A-Za-z-]+", RegexOptions.Compiled);
|
||||
|
||||
public RubyComponentDetector()
|
||||
{
|
||||
this.NeedsAutomaticRootDependencyCalculation = true;
|
||||
}
|
||||
|
||||
private enum SectionType
|
||||
{
|
||||
GEM,
|
||||
GIT,
|
||||
PATH,
|
||||
}
|
||||
|
||||
public override string Id { get; } = "Ruby";
|
||||
|
||||
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.RubyGems) };
|
||||
|
@ -54,33 +66,6 @@ namespace Microsoft.ComponentDetection.Detectors.Ruby
|
|||
|
||||
public override int Version { get; } = 3;
|
||||
|
||||
private enum SectionType
|
||||
{
|
||||
GEM,
|
||||
GIT,
|
||||
PATH,
|
||||
}
|
||||
|
||||
private class Dependency
|
||||
{
|
||||
public string Name { get; }
|
||||
|
||||
public string Location { get; }
|
||||
|
||||
public string Id => $"{this.Name}:{this.Location}";
|
||||
|
||||
public Dependency(string name, string location)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Location = location;
|
||||
}
|
||||
}
|
||||
|
||||
public RubyComponentDetector()
|
||||
{
|
||||
this.NeedsAutomaticRootDependencyCalculation = true;
|
||||
}
|
||||
|
||||
protected override Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
|
||||
|
@ -268,5 +253,20 @@ namespace Microsoft.ComponentDetection.Detectors.Ruby
|
|||
{
|
||||
return version.StartsWith("~") || version.StartsWith("=");
|
||||
}
|
||||
|
||||
private class Dependency
|
||||
{
|
||||
public Dependency(string name, string location)
|
||||
{
|
||||
this.Name = name;
|
||||
this.Location = location;
|
||||
}
|
||||
|
||||
public string Name { get; }
|
||||
|
||||
public string Location { get; }
|
||||
|
||||
public string Id => $"{this.Name}:{this.Location}";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,6 +24,16 @@ namespace Microsoft.ComponentDetection.Detectors.Rust
|
|||
@"^(?<packageName>[^ ]+)(?: (?<version>[^ ]+))?(?: \((?<source>[^()]*)\))?$",
|
||||
RegexOptions.Compiled);
|
||||
|
||||
public override string Id => "RustCrateDetector";
|
||||
|
||||
public override IList<string> SearchPatterns => new List<string> { CargoLockSearchPattern };
|
||||
|
||||
public override IEnumerable<ComponentType> SupportedComponentTypes => new[] { ComponentType.Cargo };
|
||||
|
||||
public override int Version { get; } = 8;
|
||||
|
||||
public override IEnumerable<string> Categories => new List<string> { "Rust" };
|
||||
|
||||
private static bool ParseDependency(string dependency, out string packageName, out string version, out string source)
|
||||
{
|
||||
var match = DependencyFormatRegex.Match(dependency);
|
||||
|
@ -45,16 +55,6 @@ namespace Microsoft.ComponentDetection.Detectors.Rust
|
|||
|
||||
private static bool IsLocalPackage(CargoPackage package) => package.source == null;
|
||||
|
||||
public override string Id => "RustCrateDetector";
|
||||
|
||||
public override IList<string> SearchPatterns => new List<string> { CargoLockSearchPattern };
|
||||
|
||||
public override IEnumerable<ComponentType> SupportedComponentTypes => new[] { ComponentType.Cargo };
|
||||
|
||||
public override int Version { get; } = 8;
|
||||
|
||||
public override IEnumerable<string> Categories => new List<string> { "Rust" };
|
||||
|
||||
protected override Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
|
||||
|
|
|
@ -107,6 +107,15 @@ namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer
|
|||
this.Version = comparatorVersion ?? throw new NullReferenceException("Null comparator version");
|
||||
}
|
||||
|
||||
public enum Operator
|
||||
{
|
||||
Equal = 0,
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
GreaterThan,
|
||||
GreaterThanOrEqual,
|
||||
}
|
||||
|
||||
public static Tuple<int, Comparator> TryParse(string input)
|
||||
{
|
||||
var match = RangePatternRegex.Match(input);
|
||||
|
@ -171,15 +180,6 @@ namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer
|
|||
return false;
|
||||
}
|
||||
|
||||
public enum Operator
|
||||
{
|
||||
Equal = 0,
|
||||
LessThan,
|
||||
LessThanOrEqual,
|
||||
GreaterThan,
|
||||
GreaterThanOrEqual,
|
||||
}
|
||||
|
||||
public override string ToString()
|
||||
{
|
||||
string operatorString = null;
|
||||
|
|
|
@ -18,14 +18,6 @@ namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer
|
|||
// number, for use in ranges like "^1.2" or "2.x"
|
||||
internal class PartialVersion
|
||||
{
|
||||
public int? Major { get; set; }
|
||||
|
||||
public int? Minor { get; set; }
|
||||
|
||||
public int? Patch { get; set; }
|
||||
|
||||
public string PreRelease { get; set; }
|
||||
|
||||
private static readonly Regex VersionRegex = new Regex(
|
||||
@"^
|
||||
[v=\s]*
|
||||
|
@ -98,6 +90,14 @@ namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer
|
|||
}
|
||||
}
|
||||
|
||||
public int? Major { get; set; }
|
||||
|
||||
public int? Minor { get; set; }
|
||||
|
||||
public int? Patch { get; set; }
|
||||
|
||||
public string PreRelease { get; set; }
|
||||
|
||||
public SemVersion ToZeroVersion()
|
||||
{
|
||||
return new SemVersion(this.Major ?? 0, this.Minor ?? 0, this.Patch ?? 0, this.PreRelease);
|
||||
|
|
|
@ -23,6 +23,40 @@ namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer
|
|||
|
||||
private readonly string rangeSpec;
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new range from a range specification.
|
||||
/// </summary>
|
||||
/// <param name="rangeSpec">The range specification string.</param>
|
||||
/// <param name="loose">When true, be more forgiving of some invalid version specifications.</param>
|
||||
/// <exception cref="System.ArgumentException">Thrown when the range specification is invalid.</exception>
|
||||
public Range(string rangeSpec, bool loose = false)
|
||||
{
|
||||
this.rangeSpec = rangeSpec;
|
||||
var comparatorSetSpecs = rangeSpec.Split(new[] { "||" }, StringSplitOptions.None);
|
||||
this.comparatorSets = comparatorSetSpecs.Select(s => new ComparatorSet(s)).ToArray();
|
||||
}
|
||||
|
||||
private Range(IEnumerable<ComparatorSet> comparatorSets)
|
||||
{
|
||||
this.comparatorSets = comparatorSets.ToArray();
|
||||
this.rangeSpec = string.Join(" || ", comparatorSets.Select(cs => cs.ToString()).ToArray());
|
||||
}
|
||||
|
||||
public static bool operator ==(Range a, Range b)
|
||||
{
|
||||
if (a is null)
|
||||
{
|
||||
return b is null;
|
||||
}
|
||||
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
public static bool operator !=(Range a, Range b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
// Static convenience methods
|
||||
|
||||
/// <summary>
|
||||
|
@ -87,25 +121,6 @@ namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer
|
|||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Construct a new range from a range specification.
|
||||
/// </summary>
|
||||
/// <param name="rangeSpec">The range specification string.</param>
|
||||
/// <param name="loose">When true, be more forgiving of some invalid version specifications.</param>
|
||||
/// <exception cref="System.ArgumentException">Thrown when the range specification is invalid.</exception>
|
||||
public Range(string rangeSpec, bool loose = false)
|
||||
{
|
||||
this.rangeSpec = rangeSpec;
|
||||
var comparatorSetSpecs = rangeSpec.Split(new[] { "||" }, StringSplitOptions.None);
|
||||
this.comparatorSets = comparatorSetSpecs.Select(s => new ComparatorSet(s)).ToArray();
|
||||
}
|
||||
|
||||
private Range(IEnumerable<ComparatorSet> comparatorSets)
|
||||
{
|
||||
this.comparatorSets = comparatorSets.ToArray();
|
||||
this.rangeSpec = string.Join(" || ", comparatorSets.Select(cs => cs.ToString()).ToArray());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determine whether the given version satisfies this range.
|
||||
/// </summary>
|
||||
|
@ -225,21 +240,6 @@ namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer
|
|||
return this.Equals(other as Range);
|
||||
}
|
||||
|
||||
public static bool operator ==(Range a, Range b)
|
||||
{
|
||||
if (a is null)
|
||||
{
|
||||
return b is null;
|
||||
}
|
||||
|
||||
return a.Equals(b);
|
||||
}
|
||||
|
||||
public static bool operator !=(Range a, Range b)
|
||||
{
|
||||
return !(a == b);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
// XOR is commutative, so this hash code is independent
|
||||
|
|
|
@ -20,19 +20,19 @@ namespace Microsoft.ComponentDetection.Detectors.Spdx
|
|||
[Export(typeof(IComponentDetector))]
|
||||
public class Spdx22ComponentDetector : FileComponentDetector, IDefaultOffComponentDetector
|
||||
{
|
||||
public override string Id => "SPDX22SBOM";
|
||||
private readonly IEnumerable<string> supportedSPDXVersions = new List<string> { "SPDX-2.2" };
|
||||
|
||||
public override IEnumerable<string> Categories =>
|
||||
new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.Spdx) };
|
||||
|
||||
public override string Id => "SPDX22SBOM";
|
||||
|
||||
public override IEnumerable<ComponentType> SupportedComponentTypes { get; } = new[] { ComponentType.Spdx };
|
||||
|
||||
public override int Version => 1;
|
||||
|
||||
public override IList<string> SearchPatterns { get; } = new List<string> { "*.spdx.json" };
|
||||
|
||||
private readonly IEnumerable<string> supportedSPDXVersions = new List<string> { "SPDX-2.2" };
|
||||
|
||||
protected override Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
this.Logger.LogVerbose($"Discovered SPDX2.2 manifest file at: {processRequest.ComponentStream.Location}");
|
||||
|
|
|
@ -15,6 +15,8 @@ namespace Microsoft.ComponentDetection.Detectors.Vcpkg
|
|||
[Export(typeof(IComponentDetector))]
|
||||
public class VcpkgComponentDetector : FileComponentDetector, IExperimentalDetector
|
||||
{
|
||||
private HashSet<string> projectRoots = new HashSet<string>();
|
||||
|
||||
[Import]
|
||||
public ICommandLineInvocationService CommandLineInvocationService { get; set; }
|
||||
|
||||
|
@ -31,8 +33,6 @@ namespace Microsoft.ComponentDetection.Detectors.Vcpkg
|
|||
|
||||
public override int Version => 2;
|
||||
|
||||
private HashSet<string> projectRoots = new HashSet<string>();
|
||||
|
||||
protected override async Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
|
||||
|
|
|
@ -49,10 +49,6 @@ namespace Microsoft.ComponentDetection.Detectors.Yarn.Parsers
|
|||
|
||||
private int fileLineIndex = 0;
|
||||
|
||||
public string VersionHeader { get; set; }
|
||||
|
||||
public YarnLockVersion YarnLockVersion { get; set; }
|
||||
|
||||
private YarnBlockFile(IList<string> parsedFileLines)
|
||||
{
|
||||
this.fileLines = parsedFileLines;
|
||||
|
@ -68,6 +64,10 @@ namespace Microsoft.ComponentDetection.Detectors.Yarn.Parsers
|
|||
}
|
||||
}
|
||||
|
||||
public string VersionHeader { get; set; }
|
||||
|
||||
public YarnLockVersion YarnLockVersion { get; set; }
|
||||
|
||||
public static async Task<YarnBlockFile> CreateBlockFileAsync(Stream stream)
|
||||
{
|
||||
if (stream == null)
|
||||
|
|
|
@ -18,14 +18,14 @@ namespace Microsoft.ComponentDetection.Detectors.Yarn.Parsers
|
|||
|
||||
private const string OptionalDependencies = "optionalDependencies";
|
||||
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public static string NormalizeVersion(string version)
|
||||
{
|
||||
return version.StartsWith("npm:") ? version : $"npm:{version}";
|
||||
}
|
||||
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public bool CanParse(YarnLockVersion yarnLockVersion)
|
||||
{
|
||||
return SupportedVersions.Contains(yarnLockVersion);
|
||||
|
|
|
@ -8,13 +8,13 @@ namespace Microsoft.ComponentDetection.Detectors.Yarn
|
|||
{
|
||||
public static class YarnLockFileFactory
|
||||
{
|
||||
public static IList<IYarnLockParser> Parsers { get; }
|
||||
|
||||
static YarnLockFileFactory()
|
||||
{
|
||||
Parsers = new List<IYarnLockParser> { new YarnLockParser() };
|
||||
}
|
||||
|
||||
public static IList<IYarnLockParser> Parsers { get; }
|
||||
|
||||
public static async Task<YarnLockFile> ParseYarnLockFileAsync(Stream file, ILogger logger)
|
||||
{
|
||||
var blockFile = await YarnBlockFile.CreateBlockFileAsync(file);
|
||||
|
|
|
@ -9,6 +9,11 @@ namespace Microsoft.ComponentDetection.Orchestrator
|
|||
[Export(typeof(IArgumentHelper))]
|
||||
public class ArgumentHelper : IArgumentHelper
|
||||
{
|
||||
public ArgumentHelper()
|
||||
{
|
||||
this.ArgumentSets = Enumerable.Empty<IScanArguments>();
|
||||
}
|
||||
|
||||
[ImportMany]
|
||||
public IEnumerable<IScanArguments> ArgumentSets { get; set; }
|
||||
|
||||
|
@ -31,11 +36,6 @@ namespace Microsoft.ComponentDetection.Orchestrator
|
|||
return detectorArgs;
|
||||
}
|
||||
|
||||
public ArgumentHelper()
|
||||
{
|
||||
this.ArgumentSets = Enumerable.Empty<IScanArguments>();
|
||||
}
|
||||
|
||||
public ParserResult<object> ParseArguments(string[] args)
|
||||
{
|
||||
return Parser.Default.ParseArguments(args, this.ArgumentSets.Select(x => x.GetType()).ToArray());
|
||||
|
|
|
@ -7,13 +7,13 @@ namespace Microsoft.ComponentDetection.Orchestrator
|
|||
[Export]
|
||||
public class CommandLineArgumentsExporter
|
||||
{
|
||||
public static IScanArguments ArgumentsForDelayedInjection { get; set; }
|
||||
|
||||
public CommandLineArgumentsExporter()
|
||||
{
|
||||
this.DelayedInjectionLazy = new Lazy<IScanArguments>(() => ArgumentsForDelayedInjection);
|
||||
}
|
||||
|
||||
public static IScanArguments ArgumentsForDelayedInjection { get; set; }
|
||||
|
||||
[Export("InjectableDetectionArguments")]
|
||||
public Lazy<IScanArguments> DelayedInjectionLazy { get; set; }
|
||||
}
|
||||
|
|
|
@ -27,6 +27,18 @@ namespace Microsoft.ComponentDetection.Orchestrator
|
|||
{
|
||||
private static readonly bool IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
|
||||
|
||||
[ImportMany]
|
||||
private static IEnumerable<IArgumentHandlingService> ArgumentHandlers { get; set; }
|
||||
|
||||
[Import]
|
||||
private static Logger Logger { get; set; }
|
||||
|
||||
[Import]
|
||||
private static FileWritingService FileWritingService { get; set; }
|
||||
|
||||
[Import]
|
||||
private static IArgumentHelper ArgumentHelper { get; set; }
|
||||
|
||||
public async Task<ScanResult> LoadAsync(string[] args, CancellationToken cancellationToken = default)
|
||||
{
|
||||
var argumentHelper = new ArgumentHelper { ArgumentSets = new[] { new BaseArguments() } };
|
||||
|
@ -115,18 +127,6 @@ namespace Microsoft.ComponentDetection.Orchestrator
|
|||
.ForEach(service => containerConfiguration = containerConfiguration.WithPart(service));
|
||||
}
|
||||
|
||||
[ImportMany]
|
||||
private static IEnumerable<IArgumentHandlingService> ArgumentHandlers { get; set; }
|
||||
|
||||
[Import]
|
||||
private static Logger Logger { get; set; }
|
||||
|
||||
[Import]
|
||||
private static FileWritingService FileWritingService { get; set; }
|
||||
|
||||
[Import]
|
||||
private static IArgumentHelper ArgumentHelper { get; set; }
|
||||
|
||||
public async Task<ScanResult> HandleCommandAsync(
|
||||
string[] args,
|
||||
BcdeExecutionTelemetryRecord telemetryRecord,
|
||||
|
|
|
@ -10,12 +10,12 @@ namespace Microsoft.ComponentDetection.Orchestrator.Services
|
|||
[Export(typeof(IDetectorRestrictionService))]
|
||||
public class DetectorRestrictionService : IDetectorRestrictionService
|
||||
{
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
private IList<string> oldDetectorIds = new List<string> { "MSLicenseDevNpm", "MSLicenseDevNpmList", "MSLicenseNpm", "MSLicenseNpmList" };
|
||||
private string newDetectorId = "NpmWithRoots";
|
||||
|
||||
[Import]
|
||||
public ILogger Logger { get; set; }
|
||||
|
||||
public IEnumerable<IComponentDetector> ApplyRestrictions(DetectorRestrictions argSpecifiedRestrictions, IEnumerable<IComponentDetector> detectors)
|
||||
{
|
||||
// Get a list of our default off detectors beforehand so that they can always be considered
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using System;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
|
@ -17,6 +17,36 @@ namespace Microsoft.ComponentDetection.Detectors.Tests
|
|||
[TestCategory("Governance/ComponentDetection")]
|
||||
public class PythonCommandServiceTests
|
||||
{
|
||||
private readonly string requirementstxtBasicGitComponent = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d67553";
|
||||
|
||||
private readonly string requirementstxtGitComponentAndEnvironmentMarker = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d67553 ; python_version >= ""3.6""";
|
||||
|
||||
private readonly string requirementstxtGitComponentAndComment = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d67553 # this is a comment";
|
||||
|
||||
private readonly string requirementstxtGitComponentAndCommentAndEnvironmentMarker = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d67553 ; python_version >= {""3.6"" # via -r requirements.in";
|
||||
|
||||
private readonly string requirementstxtGitComponentBranchInsteadOfCommitId = @"
|
||||
git+git://github.com/path/to/package-two@master#egg=package-two";
|
||||
|
||||
private readonly string requirementstxtGitComponentReleaseInsteadOfCommitId = @"
|
||||
git+git://github.com/path/to/package-two@0.1#egg=package-two";
|
||||
|
||||
private readonly string requirementstxtGitComponentCommitIdWrongLength = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d6755300000000000";
|
||||
|
||||
private readonly string requirementstxtDoubleGitComponents = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d67553 ; python_version >= {""3.6"" # via -r requirements.in
|
||||
git+git://github.com/path/to/package-two@41b95ec#egg=package-two";
|
||||
|
||||
private readonly string requirementstxtGitComponentWrappedinRegularComponents = @"
|
||||
something=1.3
|
||||
git+git://github.com/path/to/package-two@41b95ec#egg=package-two
|
||||
other=2.1";
|
||||
|
||||
private Mock<ICommandLineInvocationService> commandLineInvokationService;
|
||||
|
||||
[TestInitialize]
|
||||
|
@ -347,35 +377,5 @@ namespace Microsoft.ComponentDetection.Detectors.Tests
|
|||
|
||||
return 0;
|
||||
}
|
||||
|
||||
private readonly string requirementstxtBasicGitComponent = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d67553";
|
||||
|
||||
private readonly string requirementstxtGitComponentAndEnvironmentMarker = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d67553 ; python_version >= ""3.6""";
|
||||
|
||||
private readonly string requirementstxtGitComponentAndComment = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d67553 # this is a comment";
|
||||
|
||||
private readonly string requirementstxtGitComponentAndCommentAndEnvironmentMarker = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d67553 ; python_version >= {""3.6"" # via -r requirements.in";
|
||||
|
||||
private readonly string requirementstxtGitComponentBranchInsteadOfCommitId = @"
|
||||
git+git://github.com/path/to/package-two@master#egg=package-two";
|
||||
|
||||
private readonly string requirementstxtGitComponentReleaseInsteadOfCommitId = @"
|
||||
git+git://github.com/path/to/package-two@0.1#egg=package-two";
|
||||
|
||||
private readonly string requirementstxtGitComponentCommitIdWrongLength = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d6755300000000000";
|
||||
|
||||
private readonly string requirementstxtDoubleGitComponents = @"
|
||||
git+git://github.com/vscode-python/jedi-language-server@42823a2598d4b6369e9273c5ad237a48c5d67553 ; python_version >= {""3.6"" # via -r requirements.in
|
||||
git+git://github.com/path/to/package-two@41b95ec#egg=package-two";
|
||||
|
||||
private readonly string requirementstxtGitComponentWrappedinRegularComponents = @"
|
||||
something=1.3
|
||||
git+git://github.com/path/to/package-two@41b95ec#egg=package-two
|
||||
other=2.1";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,6 +19,217 @@ namespace Microsoft.ComponentDetection.Detectors.Tests
|
|||
[TestCategory("Governance/ComponentDetection")]
|
||||
public class RustCrateDetectorTests
|
||||
{
|
||||
private readonly string testCargoLockString = @"
|
||||
[[package]]
|
||||
name = ""my_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency""
|
||||
version = ""0.4.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency 0.1.12-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency_dependency""
|
||||
version = ""0.1.12-alpha.6""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""my_dev_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency 0.1.12-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""dev_dependency_dependency 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""dev_dependency_dependency""
|
||||
version = ""0.2.23""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""one_more_dev_dep 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""one_more_dev_dep""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""my_other_package""
|
||||
version = ""1.0.0""
|
||||
|
||||
[[package]]
|
||||
name = ""my_test_package""
|
||||
version = ""1.2.3""
|
||||
dependencies = [
|
||||
""my_dependency 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""my_other_package 1.0.0"",
|
||||
""other_dependency 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""my_dev_dependency 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
";
|
||||
|
||||
private readonly string testCargoLockV2String = @"
|
||||
[[package]]
|
||||
name = ""my_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""same_package 1.0.0""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency""
|
||||
version = ""0.4.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency_dependency""
|
||||
version = ""0.1.12-alpha.6""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""my_dev_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency 0.1.12-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""dev_dependency_dependency 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""dev_dependency_dependency""
|
||||
version = ""0.2.23""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""same_package 2.0.0""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""my_other_package""
|
||||
version = ""1.0.0""
|
||||
|
||||
[[package]]
|
||||
name = ""my_test_package""
|
||||
version = ""1.2.3""
|
||||
dependencies = [
|
||||
""my_dependency 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""my_other_package 1.0.0"",
|
||||
""other_dependency 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""my_dev_dependency 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""same_package""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""same_package""
|
||||
version = ""2.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
";
|
||||
|
||||
private readonly string testWorkspaceLockV1NoBaseString = @"[[package]]
|
||||
name = ""dev_dependency_dependency""
|
||||
version = ""0.2.23""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""one_more_dev_dep 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""one_more_dev_dep""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency""
|
||||
version = ""0.4.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency 0.1.12-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency_dependency""
|
||||
version = ""0.1.12-alpha.6""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""my_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""same_package 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""same_package""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[metadata]
|
||||
";
|
||||
|
||||
private readonly string testWorkspaceLockV2NoBaseString = @"[[package]]
|
||||
name = ""dev_dependency_dependency""
|
||||
version = ""0.2.23""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""one_more_dev_dep 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""one_more_dev_dep""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency""
|
||||
version = ""0.4.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency 0.1.12-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency_dependency""
|
||||
version = ""0.1.12-alpha.6""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""my_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""same_package 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""same_package""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
";
|
||||
|
||||
private readonly string testWorkspaceLockBaseDependency = @"
|
||||
[[package]]
|
||||
name = ""test_package""
|
||||
version = ""2.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
";
|
||||
|
||||
private DetectorTestUtility<RustCrateDetector> detectorTestUtility;
|
||||
|
||||
[TestInitialize]
|
||||
|
@ -642,216 +853,5 @@ source = ""registry+sparse+https://other.registry/index/""
|
|||
|
||||
componentIds.ForEach(componentId => dependencyGraph.Contains(componentId).Should().BeTrue());
|
||||
}
|
||||
|
||||
private readonly string testCargoLockString = @"
|
||||
[[package]]
|
||||
name = ""my_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency""
|
||||
version = ""0.4.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency 0.1.12-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency_dependency""
|
||||
version = ""0.1.12-alpha.6""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""my_dev_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency 0.1.12-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""dev_dependency_dependency 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""dev_dependency_dependency""
|
||||
version = ""0.2.23""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""one_more_dev_dep 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""one_more_dev_dep""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""my_other_package""
|
||||
version = ""1.0.0""
|
||||
|
||||
[[package]]
|
||||
name = ""my_test_package""
|
||||
version = ""1.2.3""
|
||||
dependencies = [
|
||||
""my_dependency 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""my_other_package 1.0.0"",
|
||||
""other_dependency 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""my_dev_dependency 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[metadata]
|
||||
";
|
||||
|
||||
private readonly string testCargoLockV2String = @"
|
||||
[[package]]
|
||||
name = ""my_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""same_package 1.0.0""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency""
|
||||
version = ""0.4.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency_dependency""
|
||||
version = ""0.1.12-alpha.6""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""my_dev_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency 0.1.12-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""dev_dependency_dependency 0.2.23 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""dev_dependency_dependency""
|
||||
version = ""0.2.23""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""same_package 2.0.0""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""my_other_package""
|
||||
version = ""1.0.0""
|
||||
|
||||
[[package]]
|
||||
name = ""my_test_package""
|
||||
version = ""1.2.3""
|
||||
dependencies = [
|
||||
""my_dependency 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""my_other_package 1.0.0"",
|
||||
""other_dependency 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
""my_dev_dependency 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""same_package""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""same_package""
|
||||
version = ""2.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
";
|
||||
|
||||
private readonly string testWorkspaceLockV1NoBaseString = @"[[package]]
|
||||
name = ""dev_dependency_dependency""
|
||||
version = ""0.2.23""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""one_more_dev_dep 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""one_more_dev_dep""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency""
|
||||
version = ""0.4.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency 0.1.12-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency_dependency""
|
||||
version = ""0.1.12-alpha.6""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""my_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""same_package 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""same_package""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[metadata]
|
||||
";
|
||||
|
||||
private readonly string testWorkspaceLockV2NoBaseString = @"[[package]]
|
||||
name = ""dev_dependency_dependency""
|
||||
version = ""0.2.23""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""one_more_dev_dep 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""one_more_dev_dep""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency""
|
||||
version = ""0.4.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""other_dependency_dependency 0.1.12-alpha.6 (registry+https://github.com/rust-lang/crates.io-index)"",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""other_dependency_dependency""
|
||||
version = ""0.1.12-alpha.6""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
|
||||
[[package]]
|
||||
name = ""my_dependency""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
dependencies = [
|
||||
""same_package 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)""
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = ""same_package""
|
||||
version = ""1.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
";
|
||||
|
||||
private readonly string testWorkspaceLockBaseDependency = @"
|
||||
[[package]]
|
||||
name = ""test_package""
|
||||
version = ""2.0.0""
|
||||
source = ""registry+https://github.com/rust-lang/crates.io-index""
|
||||
";
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ namespace Microsoft.ComponentDetection.Orchestrator.Tests.Services
|
|||
[TestCategory("Governance/ComponentDetection")]
|
||||
public class DetectorProcessingServiceTests
|
||||
{
|
||||
private static DirectoryInfo defaultSourceDirectory = new DirectoryInfo(Path.Combine(Environment.CurrentDirectory, "SomeSource", "Directory"));
|
||||
private static BcdeArguments defaultArgs = new BcdeArguments { SourceDirectory = defaultSourceDirectory, DetectorArgs = Enumerable.Empty<string>() };
|
||||
|
||||
private readonly Dictionary<string, DetectedComponent> componentDictionary = new Dictionary<string, DetectedComponent>()
|
||||
{
|
||||
{ "firstFileDetectorId", new DetectedComponent(new NpmComponent($"{Guid.NewGuid()}", "FileComponentVersion1")) },
|
||||
|
@ -41,6 +44,8 @@ namespace Microsoft.ComponentDetection.Orchestrator.Tests.Services
|
|||
private Mock<IComponentDetector> secondCommandComponentDetectorMock;
|
||||
private Mock<FileComponentDetector> experimentalFileComponentDetectorMock;
|
||||
|
||||
private bool isWin;
|
||||
|
||||
private IndividualDetectorScanResult ExpectedResultForDetector(string detectorId)
|
||||
{
|
||||
return new IndividualDetectorScanResult
|
||||
|
@ -50,11 +55,6 @@ namespace Microsoft.ComponentDetection.Orchestrator.Tests.Services
|
|||
};
|
||||
}
|
||||
|
||||
private static DirectoryInfo defaultSourceDirectory = new DirectoryInfo(Path.Combine(Environment.CurrentDirectory, "SomeSource", "Directory"));
|
||||
private static BcdeArguments defaultArgs = new BcdeArguments { SourceDirectory = defaultSourceDirectory, DetectorArgs = Enumerable.Empty<string>() };
|
||||
|
||||
private bool isWin;
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInit()
|
||||
{
|
||||
|
|
Загрузка…
Ссылка в новой задаче