Co-authored-by: Amitla Vannikumar <avannikumar@microsoft.com>
This commit is contained in:
amitla1 2022-08-24 11:36:10 -07:00 коммит произвёл GitHub
Родитель 26a5907efc
Коммит c71e1ea5da
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
16 изменённых файлов: 300 добавлений и 303 удалений

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

@ -495,10 +495,6 @@ dotnet_diagnostic.SA1202.severity = suggestion
# 'public' members should come before 'private' members
dotnet_diagnostic.SA1203.severity = suggestion
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1204.md
# Static members should appear before non-static members
dotnet_diagnostic.SA1204.severity = suggestion
# https://github.com/DotNetAnalyzers/StyleCopAnalyzers/blob/master/documentation/SA1208.md
# Using directive for '...' should appear before directive for '...'
dotnet_diagnostic.SA1208.severity = suggestion

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

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Composition;
using System.Diagnostics;
@ -17,6 +17,39 @@ namespace Microsoft.ComponentDetection.Common
[Shared]
public class PathUtilityService : IPathUtilityService
{
[DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern SafeFileHandle CreateFile(
[In] string lpFileName,
[In] uint dwDesiredAccess,
[In] uint dwShareMode,
[In] IntPtr lpSecurityAttributes,
[In] uint dwCreationDisposition,
[In] uint dwFlagsAndAttributes,
[In] IntPtr hTemplateFile);
[DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int GetFinalPathNameByHandle([In] IntPtr hFile, [Out] StringBuilder lpszFilePath, [In] int cchFilePath, [In] int dwFlags);
/// <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"></param>
/// <param name="output"></param>
/// <returns></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"></param>
[DllImport("libc", EntryPoint = "free")]
public static extern void FreeMemoryLinux([In] IntPtr toFree);
[Import]
public ILogger Logger { get; set; }
@ -49,11 +82,31 @@ namespace Microsoft.ComponentDetection.Common
}
}
private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
private static readonly bool IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
private object isRunningOnWindowsContainerLock = new object();
private bool? isRunningOnWindowsContainer = null;
private static readonly bool IsWindows = RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
private static readonly bool IsLinux = RuntimeInformation.IsOSPlatform(OSPlatform.Linux);
public static bool MatchesPattern(string searchPattern, ref FileSystemEntry fse)
{
if (searchPattern.StartsWith("*") && fse.FileName.EndsWith(searchPattern.Substring(1), StringComparison.OrdinalIgnoreCase))
{
return true;
}
else if (searchPattern.EndsWith("*") && fse.FileName.StartsWith(searchPattern.Substring(0, searchPattern.Length - 1), StringComparison.OrdinalIgnoreCase))
{
return true;
}
else if (fse.FileName.Equals(searchPattern.AsSpan(), StringComparison.OrdinalIgnoreCase))
{
return true;
}
else
{
return false;
}
}
public string GetParentDirectory(string path)
{
@ -89,26 +142,6 @@ namespace Microsoft.ComponentDetection.Common
}
}
public static bool MatchesPattern(string searchPattern, ref FileSystemEntry fse)
{
if (searchPattern.StartsWith("*") && fse.FileName.EndsWith(searchPattern.Substring(1), StringComparison.OrdinalIgnoreCase))
{
return true;
}
else if (searchPattern.EndsWith("*") && fse.FileName.StartsWith(searchPattern.Substring(0, searchPattern.Length - 1), StringComparison.OrdinalIgnoreCase))
{
return true;
}
else if (fse.FileName.Equals(searchPattern.AsSpan(), StringComparison.OrdinalIgnoreCase))
{
return true;
}
else
{
return false;
}
}
public string ResolvePhysicalPath(string path)
{
if (IsWindows)
@ -252,38 +285,5 @@ namespace Microsoft.ComponentDetection.Common
return false;
}
}
[DllImport("kernel32.dll", EntryPoint = "CreateFileW", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern SafeFileHandle CreateFile(
[In] string lpFileName,
[In] uint dwDesiredAccess,
[In] uint dwShareMode,
[In] IntPtr lpSecurityAttributes,
[In] uint dwCreationDisposition,
[In] uint dwFlagsAndAttributes,
[In] IntPtr hTemplateFile);
[DllImport("kernel32.dll", EntryPoint = "GetFinalPathNameByHandleW", CharSet = CharSet.Unicode, SetLastError = true)]
private static extern int GetFinalPathNameByHandle([In] IntPtr hFile, [Out] StringBuilder lpszFilePath, [In] int cchFilePath, [In] int dwFlags);
/// <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"></param>
/// <param name="output"></param>
/// <returns></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"></param>
[DllImport("libc", EntryPoint = "free")]
public static extern void FreeMemoryLinux([In] IntPtr toFree);
}
}

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

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Concurrent;
using System.Composition;
using Microsoft.ComponentDetection.Common.Telemetry.Attributes;
@ -13,6 +13,8 @@ namespace Microsoft.ComponentDetection.Common.Telemetry
[TelemetryService(nameof(CommandLineTelemetryService))]
internal class CommandLineTelemetryService : ITelemetryService
{
private static ConcurrentQueue<JObject> records = new ConcurrentQueue<JObject>();
[Import]
public ILogger Logger { get; set; }
@ -23,8 +25,6 @@ namespace Microsoft.ComponentDetection.Common.Telemetry
private TelemetryMode telemetryMode = TelemetryMode.Production;
private static ConcurrentQueue<JObject> records = new ConcurrentQueue<JObject>();
public void Flush()
{
this.FileWritingService.WriteFile(TelemetryRelativePath, JsonConvert.SerializeObject(records));

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

@ -3,13 +3,6 @@ namespace Microsoft.ComponentDetection.Contracts
#pragma warning disable SA1402
public class DockerReference
{
public virtual DockerReferenceKind Kind { get; }
public virtual TypedComponent.DockerReferenceComponent ToTypedDockerReferenceComponent()
{
throw new System.NotImplementedException();
}
public static DockerReference CreateDockerReference(string repository, string domain, string digest, string tag)
{
if (!string.IsNullOrEmpty(repository) && string.IsNullOrEmpty(domain))
@ -66,6 +59,13 @@ namespace Microsoft.ComponentDetection.Contracts
};
}
}
public virtual DockerReferenceKind Kind { get; }
public virtual TypedComponent.DockerReferenceComponent ToTypedDockerReferenceComponent()
{
throw new System.NotImplementedException();
}
}
public enum DockerReferenceKind

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

@ -154,6 +154,62 @@ namespace Microsoft.ComponentDetection.Detectors.CocoaPods
}
}
private static async Task<PodfileLock> ParsePodfileLock(IComponentStream file)
{
var fileContent = await new StreamReader(file.Stream).ReadToEndAsync();
var input = new StringReader(fileContent);
var deserializer = new DeserializerBuilder()
.IgnoreUnmatchedProperties()
.Build();
return deserializer.Deserialize<PodfileLock>(input);
}
private static (Pod pod, string key, DetectedComponent detectedComponent)[] ReadPodfileLock(PodfileLock podfileLock)
{
return podfileLock.Pods.Select(pod =>
{
// Find the spec repository URL for this pod
var specRepository = podfileLock.GetSpecRepositoryOfSpec(pod.Podspec) ?? string.Empty;
// Check if the Podspec comes from a git repository or not
TypedComponent typedComponent;
string key;
if (podfileLock.CheckoutOptions.TryGetValue(pod.Podspec, out var checkoutOptions)
&& checkoutOptions.TryGetValue(":git", out var gitOption)
&& checkoutOptions.TryGetValue(":commit", out var commitOption))
{
// Create the Git component
gitOption = NormalizePodfileGitUri(gitOption);
typedComponent = new GitComponent(new Uri(gitOption), commitOption);
key = $"{commitOption}@{gitOption}";
}
else
{
// Create the Pod component
typedComponent = new PodComponent(pod.Podspec, pod.Version, specRepository);
key = $"{pod.Podspec}:{pod.Version}@{specRepository}";
}
var detectedComponent = new DetectedComponent(typedComponent);
return (pod, key, detectedComponent);
})
.ToArray();
}
private static string NormalizePodfileGitUri(string gitOption)
{
// Podfiles can be built using git@ references to .git files, but this is not a valid Uri
// schema. Normalize to https:// so Uri creation doesn't fail
if (gitOption.StartsWith("git@", StringComparison.OrdinalIgnoreCase))
{
return $"https://{gitOption[4..]}";
}
return gitOption;
}
protected override async Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
{
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
@ -173,17 +229,6 @@ namespace Microsoft.ComponentDetection.Detectors.CocoaPods
}
}
private static async Task<PodfileLock> ParsePodfileLock(IComponentStream file)
{
var fileContent = await new StreamReader(file.Stream).ReadToEndAsync();
var input = new StringReader(fileContent);
var deserializer = new DeserializerBuilder()
.IgnoreUnmatchedProperties()
.Build();
return deserializer.Deserialize<PodfileLock>(input);
}
private void ProcessPodfileLock(
ISingleFileComponentRecorder singleFileComponentRecorder,
PodfileLock podfileLock)
@ -374,50 +419,5 @@ namespace Microsoft.ComponentDetection.Detectors.CocoaPods
isExplicitReferencedDependency: true);
}
}
private static (Pod pod, string key, DetectedComponent detectedComponent)[] ReadPodfileLock(PodfileLock podfileLock)
{
return podfileLock.Pods.Select(pod =>
{
// Find the spec repository URL for this pod
var specRepository = podfileLock.GetSpecRepositoryOfSpec(pod.Podspec) ?? string.Empty;
// Check if the Podspec comes from a git repository or not
TypedComponent typedComponent;
string key;
if (podfileLock.CheckoutOptions.TryGetValue(pod.Podspec, out var checkoutOptions)
&& checkoutOptions.TryGetValue(":git", out var gitOption)
&& checkoutOptions.TryGetValue(":commit", out var commitOption))
{
// Create the Git component
gitOption = NormalizePodfileGitUri(gitOption);
typedComponent = new GitComponent(new Uri(gitOption), commitOption);
key = $"{commitOption}@{gitOption}";
}
else
{
// Create the Pod component
typedComponent = new PodComponent(pod.Podspec, pod.Version, specRepository);
key = $"{pod.Podspec}:{pod.Version}@{specRepository}";
}
var detectedComponent = new DetectedComponent(typedComponent);
return (pod, key, detectedComponent);
})
.ToArray();
}
private static string NormalizePodfileGitUri(string gitOption)
{
// Podfiles can be built using git@ references to .git files, but this is not a valid Uri
// schema. Normalize to https:// so Uri creation doesn't fail
if (gitOption.StartsWith("git@", StringComparison.OrdinalIgnoreCase))
{
return $"https://{gitOption[4..]}";
}
return gitOption;
}
}
}

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

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Composition;
using System.IO;
@ -58,6 +58,19 @@ namespace Microsoft.ComponentDetection.Detectors.Ivy
[Import]
public ICommandLineInvocationService CommandLineInvocationService { get; set; }
private static MavenComponent JsonGavToComponent(JToken gav)
{
if (gav == null)
{
return null;
}
return new MavenComponent(
gav.Value<string>("g"),
gav.Value<string>("a"),
gav.Value<string>("v"));
}
protected override async Task<IObservable<ProcessRequest>> OnPrepareDetection(IObservable<ProcessRequest> processRequests, IDictionary<string, string> detectorArgs)
{
if (await this.IsAntLocallyAvailableAsync())
@ -195,19 +208,6 @@ namespace Microsoft.ComponentDetection.Detectors.Ivy
return ret;
}
private static MavenComponent JsonGavToComponent(JToken gav)
{
if (gav == null)
{
return null;
}
return new MavenComponent(
gav.Value<string>("g"),
gav.Value<string>("a"),
gav.Value<string>("v"));
}
private void RegisterUsagesFromFile(ISingleFileComponentRecorder singleFileComponentRecorder, string instructionsFile)
{
var instructionsJson = JObject.Parse(File.ReadAllText(instructionsFile));

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

@ -38,6 +38,38 @@ namespace Microsoft.ComponentDetection.Detectors.Linux
public bool NeedsAutomaticRootDependencyCalculation => false;
/// <summary>
/// Extracts and returns the timeout defined by the user, or a default value if one is not provided.
/// </summary>
/// <param name="detectorArgs">The arguments provided by the user.</param>
/// <returns></returns>
private static TimeSpan GetTimeout(IDictionary<string, string> detectorArgs)
{
if (detectorArgs == null || !detectorArgs.TryGetValue("Linux.ScanningTimeoutSec", out var timeout))
{
return TimeSpan.FromMinutes(10);
}
return double.TryParse(timeout, out var parsedTimeout) ? TimeSpan.FromSeconds(parsedTimeout) : TimeSpan.FromMinutes(10);
}
private static IndividualDetectorScanResult EmptySuccessfulScan()
{
return new IndividualDetectorScanResult
{
ResultCode = ProcessingResultCode.Success,
};
}
private static ImageScanningResult EmptyImageScanningResult()
{
return new ImageScanningResult
{
ContainerDetails = null,
Components = Enumerable.Empty<DetectedComponent>(),
};
}
public async Task<IndividualDetectorScanResult> ExecuteDetectorAsync(ScanRequest request)
{
var imagesToProcess = request.ImagesToScan?.Where(image => !string.IsNullOrWhiteSpace(image))
@ -171,38 +203,6 @@ namespace Microsoft.ComponentDetection.Detectors.Linux
return await Task.WhenAll(scanTasks);
}
/// <summary>
/// Extracts and returns the timeout defined by the user, or a default value if one is not provided.
/// </summary>
/// <param name="detectorArgs">The arguments provided by the user.</param>
/// <returns></returns>
private static TimeSpan GetTimeout(IDictionary<string, string> detectorArgs)
{
if (detectorArgs == null || !detectorArgs.TryGetValue("Linux.ScanningTimeoutSec", out var timeout))
{
return TimeSpan.FromMinutes(10);
}
return double.TryParse(timeout, out var parsedTimeout) ? TimeSpan.FromSeconds(parsedTimeout) : TimeSpan.FromMinutes(10);
}
private static IndividualDetectorScanResult EmptySuccessfulScan()
{
return new IndividualDetectorScanResult
{
ResultCode = ProcessingResultCode.Success,
};
}
private static ImageScanningResult EmptyImageScanningResult()
{
return new ImageScanningResult
{
ContainerDetails = null,
Components = Enumerable.Empty<DetectedComponent>(),
};
}
private async Task<int> GetBaseImageLayerCount(ContainerDetails scannedImageDetails, string image, CancellationToken cancellationToken = default)
{
using var record = new LinuxContainerDetectorLayerAwareness

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

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.ComponentDetection.Contracts;
@ -7,6 +7,10 @@ namespace Microsoft.ComponentDetection.Detectors.Maven
{
public class MavenStyleDependencyGraphParser
{
private static readonly char[] TrimCharacters = new char[] { '|', ' ' };
private static readonly string[] ComponentSplitters = new[] { "+-", "\\-" };
public GraphNode<string> DependencyCategory { get; private set; }
private Stack<GraphNodeAtLevel<string>> stack = new Stack<GraphNodeAtLevel<string>>();
@ -15,10 +19,6 @@ namespace Microsoft.ComponentDetection.Detectors.Maven
private DetectedComponent topLevelComponent = null;
private static readonly char[] TrimCharacters = new char[] { '|', ' ' };
private static readonly string[] ComponentSplitters = new[] { "+-", "\\-" };
private void StartDependencyCategory(string categoryName)
{
if (this.DependencyCategory != null)

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

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Composition;
using System.IO;
@ -17,6 +17,8 @@ namespace Microsoft.ComponentDetection.Detectors.NuGet
[Export(typeof(IComponentDetector))]
public class NuGetComponentDetector : FileComponentDetector
{
private static readonly IEnumerable<string> LowConfidencePackages = new[] { "Newtonsoft.Json" };
public override string Id { get; } = "NuGet";
public override IEnumerable<string> Categories => new[] { Enum.GetName(typeof(DetectorClass), DetectorClass.NuGet) };
@ -31,8 +33,6 @@ namespace Microsoft.ComponentDetection.Detectors.NuGet
private readonly IList<string> repositoryPathKeyNames = new List<string> { "repositorypath", "globalpackagesfolder" };
private static readonly IEnumerable<string> LowConfidencePackages = new[] { "Newtonsoft.Json" };
protected override async Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
{
var stream = processRequest.ComponentStream;

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

@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Composition;
using System.IO;
@ -38,14 +38,14 @@ namespace Microsoft.ComponentDetection.Detectors.Pip
internal static HttpClient HttpClient = new HttpClient(httpClientHandler);
// time to wait before retrying a failed call to pypi.org
private static readonly TimeSpan RETRYDELAY = TimeSpan.FromSeconds(1);
// Values used for cache creation
private const long CACHEINTERVALSECONDS = 60;
private const long DEFAULTCACHEENTRIES = 128;
private bool checkedMaxEntriesVariable = false;
// time to wait before retrying a failed call to pypi.org
private static readonly TimeSpan RETRYDELAY = TimeSpan.FromSeconds(1);
// max number of retries allowed, to cap the total delay period
private const long MAXRETRIES = 15;

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

@ -1,4 +1,4 @@
// This file was copied from the SemanticVersioning package found at https://github.com/adamreeve/semver.net.
// This file was copied from the SemanticVersioning package found at https://github.com/adamreeve/semver.net.
// The range logic from SemanticVersioning is needed in the Rust detector to supplement the Semver versioning package
// that is used elsewhere in this project.
//
@ -23,6 +23,70 @@ namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer
private readonly string rangeSpec;
// Static convenience methods
/// <summary>
/// Determine whether the given version satisfies a given range.
/// With an invalid version this method returns false.
/// </summary>
/// <param name="rangeSpec">The range specification.</param>
/// <param name="versionString">The version to check.</param>
/// <param name="loose">When true, be more forgiving of some invalid version specifications.</param>
/// <returns>true if the range is satisfied by the version.</returns>
public static bool IsSatisfied(string rangeSpec, string versionString, bool loose = false)
{
var range = new Range(rangeSpec);
return range.IsSatisfied(versionString);
}
/// <summary>
/// Return the set of version strings that satisfy a given range.
/// Invalid version specifications are skipped.
/// </summary>
/// <param name="rangeSpec">The range specification.</param>
/// <param name="versions">The version strings to check.</param>
/// <param name="loose">When true, be more forgiving of some invalid version specifications.</param>
/// <returns>An IEnumerable of satisfying version strings.</returns>
public static IEnumerable<string> Satisfying(string rangeSpec, IEnumerable<string> versions, bool loose = false)
{
var range = new Range(rangeSpec);
return range.Satisfying(versions);
}
/// <summary>
/// Return the maximum version that satisfies a given range.
/// </summary>
/// <param name="rangeSpec">The range specification.</param>
/// <param name="versionStrings">The version strings to select from.</param>
/// <param name="loose">When true, be more forgiving of some invalid version specifications.</param>
/// <returns>The maximum satisfying version string, or null if no versions satisfied this range.</returns>
public static string MaxSatisfying(string rangeSpec, IEnumerable<string> versionStrings, bool loose = false)
{
var range = new Range(rangeSpec);
return range.MaxSatisfying(versionStrings);
}
private IEnumerable<SemVersion> ValidVersions(IEnumerable<string> versionStrings, bool loose)
{
foreach (var v in versionStrings)
{
SemVersion version = null;
try
{
SemVersion.TryParse(v, out version, loose);
}
catch (ArgumentException)
{
// Skip
}
if (version != null)
{
yield return version;
}
}
}
/// <summary>
/// Construct a new range from a range specification.
/// </summary>
@ -182,69 +246,5 @@ namespace Microsoft.ComponentDetection.Detectors.Rust.SemVer
// of the order of comparators.
return this.comparatorSets.Aggregate(0, (accum, next) => accum ^ next.GetHashCode());
}
// Static convenience methods
/// <summary>
/// Determine whether the given version satisfies a given range.
/// With an invalid version this method returns false.
/// </summary>
/// <param name="rangeSpec">The range specification.</param>
/// <param name="versionString">The version to check.</param>
/// <param name="loose">When true, be more forgiving of some invalid version specifications.</param>
/// <returns>true if the range is satisfied by the version.</returns>
public static bool IsSatisfied(string rangeSpec, string versionString, bool loose = false)
{
var range = new Range(rangeSpec);
return range.IsSatisfied(versionString);
}
/// <summary>
/// Return the set of version strings that satisfy a given range.
/// Invalid version specifications are skipped.
/// </summary>
/// <param name="rangeSpec">The range specification.</param>
/// <param name="versions">The version strings to check.</param>
/// <param name="loose">When true, be more forgiving of some invalid version specifications.</param>
/// <returns>An IEnumerable of satisfying version strings.</returns>
public static IEnumerable<string> Satisfying(string rangeSpec, IEnumerable<string> versions, bool loose = false)
{
var range = new Range(rangeSpec);
return range.Satisfying(versions);
}
/// <summary>
/// Return the maximum version that satisfies a given range.
/// </summary>
/// <param name="rangeSpec">The range specification.</param>
/// <param name="versionStrings">The version strings to select from.</param>
/// <param name="loose">When true, be more forgiving of some invalid version specifications.</param>
/// <returns>The maximum satisfying version string, or null if no versions satisfied this range.</returns>
public static string MaxSatisfying(string rangeSpec, IEnumerable<string> versionStrings, bool loose = false)
{
var range = new Range(rangeSpec);
return range.MaxSatisfying(versionStrings);
}
private IEnumerable<SemVersion> ValidVersions(IEnumerable<string> versionStrings, bool loose)
{
foreach (var v in versionStrings)
{
SemVersion version = null;
try
{
SemVersion.TryParse(v, out version, loose);
}
catch (ArgumentException)
{
// Skip
}
if (version != null)
{
yield return version;
}
}
}
}
}

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

@ -1,4 +1,4 @@
using System.Collections.Generic;
using System.Collections.Generic;
using System.Composition;
using System.Linq;
using CommandLine;
@ -12,6 +12,25 @@ namespace Microsoft.ComponentDetection.Orchestrator
[ImportMany]
public IEnumerable<IScanArguments> ArgumentSets { get; set; }
public static IDictionary<string, string> GetDetectorArgs(IEnumerable<string> detectorArgsList)
{
var detectorArgs = new Dictionary<string, string>();
foreach (var arg in detectorArgsList)
{
var keyValue = arg.Split('=');
if (keyValue.Length != 2)
{
continue;
}
detectorArgs.Add(keyValue[0], keyValue[1]);
}
return detectorArgs;
}
public ArgumentHelper()
{
this.ArgumentSets = Enumerable.Empty<IScanArguments>();
@ -34,24 +53,5 @@ namespace Microsoft.ComponentDetection.Orchestrator
return p.ParseArguments<T>(args);
}
public static IDictionary<string, string> GetDetectorArgs(IEnumerable<string> detectorArgsList)
{
var detectorArgs = new Dictionary<string, string>();
foreach (var arg in detectorArgsList)
{
var keyValue = arg.Split('=');
if (keyValue.Length != 2)
{
continue;
}
detectorArgs.Add(keyValue[0], keyValue[1]);
}
return detectorArgs;
}
}
}

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

@ -1,4 +1,4 @@
using System;
using System;
using System.Composition;
using Microsoft.ComponentDetection.Orchestrator.ArgumentSets;
@ -7,6 +7,8 @@ namespace Microsoft.ComponentDetection.Orchestrator
[Export]
public class CommandLineArgumentsExporter
{
public static IScanArguments ArgumentsForDelayedInjection { get; set; }
public CommandLineArgumentsExporter()
{
this.DelayedInjectionLazy = new Lazy<IScanArguments>(() => ArgumentsForDelayedInjection);
@ -14,7 +16,5 @@ namespace Microsoft.ComponentDetection.Orchestrator
[Export("InjectableDetectionArguments")]
public Lazy<IScanArguments> DelayedInjectionLazy { get; set; }
public static IScanArguments ArgumentsForDelayedInjection { get; set; }
}
}

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

@ -33,6 +33,25 @@ namespace Microsoft.ComponentDetection.Orchestrator.Services
[Import]
public IObservableDirectoryWalkerFactory Scanner { get; set; }
private static IDictionary<string, string> GetDetectorArgs(IEnumerable<string> detectorArgsList)
{
var detectorArgs = new Dictionary<string, string>();
foreach (var arg in detectorArgsList)
{
var keyValue = arg.Split('=');
if (keyValue.Length != 2)
{
continue;
}
detectorArgs.Add(keyValue[0], keyValue[1]);
}
return detectorArgs;
}
public async Task<DetectorProcessingResult> ProcessDetectorsAsync(IDetectionArguments detectionArguments, IEnumerable<IComponentDetector> detectors, DetectorRestrictions detectorRestrictions)
{
this.Logger.LogCreateLoggingGroup();
@ -225,25 +244,6 @@ namespace Microsoft.ComponentDetection.Orchestrator.Services
}
}
private static IDictionary<string, string> GetDetectorArgs(IEnumerable<string> detectorArgsList)
{
var detectorArgs = new Dictionary<string, string>();
foreach (var arg in detectorArgsList)
{
var keyValue = arg.Split('=');
if (keyValue.Length != 2)
{
continue;
}
detectorArgs.Add(keyValue[0], keyValue[1]);
}
return detectorArgs;
}
public ExcludeDirectoryPredicate GenerateDirectoryExclusionPredicate(string originalSourceDirectory, IEnumerable<string> directoryExclusionList, IEnumerable<string> directoryExclusionListObsolete, bool allowWindowsPaths, bool ignoreCase = true)
{
if (directoryExclusionListObsolete?.Any() != true && directoryExclusionList?.Any() != true)

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

@ -51,10 +51,11 @@ namespace Microsoft.ComponentDetection.Orchestrator.Tests.Services
};
}
private bool isWin;
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()
{

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

@ -1,4 +1,4 @@
using Moq;
using Moq;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@ -28,6 +28,16 @@ namespace Microsoft.ComponentDetection.TestsUtilities
private List<(string Name, Stream Contents, string Location, IEnumerable<string> searchPatterns)> filesToAdd = new List<(string Name, Stream Contents, string Location, IEnumerable<string> searchPatterns)>();
private static IComponentStream CreateComponentStreamForFile(string pattern, string filePath, Stream content)
{
var getFileMock = new Mock<IComponentStream>();
getFileMock.SetupGet(x => x.Stream).Returns(content);
getFileMock.SetupGet(x => x.Pattern).Returns(pattern);
getFileMock.SetupGet(x => x.Location).Returns(filePath);
return getFileMock.Object;
}
public async Task<(IndividualDetectorScanResult, IComponentRecorder)> ExecuteDetector()
{
if (this.scanRequest == null)
@ -116,16 +126,6 @@ namespace Microsoft.ComponentDetection.TestsUtilities
};
}
private static IComponentStream CreateComponentStreamForFile(string pattern, string filePath, Stream content)
{
var getFileMock = new Mock<IComponentStream>();
getFileMock.SetupGet(x => x.Stream).Returns(content);
getFileMock.SetupGet(x => x.Pattern).Returns(pattern);
getFileMock.SetupGet(x => x.Location).Returns(filePath);
return getFileMock.Object;
}
private void InitializeFileRelatedMocksUsingDefaultImplementationIfNecessary()
{
bool useDefaultObservableDirectoryWalkerFactory = false, useDefaultComponentStreamEnumerableFactory = false;