Fix analyzer warnings: SA1142, SA1201 (#308)

This commit is contained in:
Rushabh 2022-10-19 09:35:56 -07:00 коммит произвёл GitHub
Родитель abd15de7f1
Коммит b1532df7a8
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
70 изменённых файлов: 1083 добавлений и 1095 удалений

Просмотреть файл

@ -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()
{