Refactor: Fix SA1204 (#219)
Co-authored-by: Amitla Vannikumar <avannikumar@microsoft.com>
This commit is contained in:
Родитель
26a5907efc
Коммит
c71e1ea5da
|
@ -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;
|
||||
|
|
Загрузка…
Ссылка в новой задаче