Allow opt-in go cli scanning (#12)
* Wrap up opt-in behavior * Verify needs to be called after * 🎨 * 🎨 * Fix service creation * 🛠️ * 🐛 fix
This commit is contained in:
Родитель
11935c1cc3
Коммит
70c149cd3c
|
@ -10,7 +10,7 @@
|
|||
"request": "launch",
|
||||
"preLaunchTask": "build",
|
||||
// If you have changed target frameworks, make sure to update the program path.
|
||||
"program": "${workspaceFolder}/src/Microsoft.ComponentDetection/bin/Debug/net6.0/Microsoft.ComponentDetection.dll",
|
||||
"program": "${workspaceFolder}/src/Microsoft.ComponentDetection/bin/Debug/netcoreapp3.1/Microsoft.ComponentDetection.dll",
|
||||
"args": ["scan", "--Debug", "--Verbosity", "Verbose", "--Output", "${workspaceFolder}/scan-output", "--SourceDirectory", "${workspaceFolder}"],
|
||||
"cwd": "${workspaceFolder}/src/Microsoft.ComponentDetection",
|
||||
// For more information about the 'console' field, see https://aka.ms/VSCode-CS-LaunchJson-Console
|
||||
|
|
|
@ -26,5 +26,8 @@ namespace Microsoft.ComponentDetection.Common
|
|||
|
||||
[Import]
|
||||
public IDockerService DockerService { get; set; }
|
||||
|
||||
[Import]
|
||||
public IEnvironmentVariableService EnvironmentVariableService { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,16 @@
|
|||
using System;
|
||||
using System.Composition;
|
||||
using Microsoft.ComponentDetection.Contracts;
|
||||
|
||||
namespace Microsoft.ComponentDetection.Common
|
||||
{
|
||||
[Export(typeof(IEnvironmentVariableService))]
|
||||
public class EnvironmentVariableService : IEnvironmentVariableService
|
||||
{
|
||||
public bool DoesEnvironmentVariableExist(string name)
|
||||
{
|
||||
var enabledVar = Environment.GetEnvironmentVariable(name);
|
||||
return !string.IsNullOrEmpty(enabledVar);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -15,5 +15,7 @@
|
|||
IObservableDirectoryWalkerFactory DirectoryWalkerFactory { get; set; }
|
||||
|
||||
IDockerService DockerService { get; set; }
|
||||
|
||||
IEnvironmentVariableService EnvironmentVariableService { get; set; }
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
namespace Microsoft.ComponentDetection.Contracts
|
||||
{
|
||||
public interface IEnvironmentVariableService
|
||||
{
|
||||
bool DoesEnvironmentVariableExist(string name);
|
||||
}
|
||||
}
|
|
@ -25,6 +25,7 @@ namespace Microsoft.ComponentDetection.Contracts.Internal
|
|||
fileUtilityServiceStatic = detectorDependencies.FileUtilityService;
|
||||
observableDirectoryWalkerFactoryServiceStatic = detectorDependencies.DirectoryWalkerFactory;
|
||||
dockerServiceStatic = detectorDependencies.DockerService;
|
||||
environmentVariableServiceStatic = detectorDependencies.EnvironmentVariableService;
|
||||
}
|
||||
|
||||
private static ILogger loggerStatic;
|
||||
|
@ -35,6 +36,8 @@ namespace Microsoft.ComponentDetection.Contracts.Internal
|
|||
private static IObservableDirectoryWalkerFactory observableDirectoryWalkerFactoryServiceStatic;
|
||||
private static IDockerService dockerServiceStatic;
|
||||
|
||||
private static IEnvironmentVariableService environmentVariableServiceStatic;
|
||||
|
||||
[Export(typeof(ILogger))]
|
||||
public ILogger Logger => loggerStatic;
|
||||
|
||||
|
@ -55,5 +58,8 @@ namespace Microsoft.ComponentDetection.Contracts.Internal
|
|||
|
||||
[Export(typeof(IDockerService))]
|
||||
public IDockerService DockerService => dockerServiceStatic;
|
||||
|
||||
[Export(typeof(IEnvironmentVariableService))]
|
||||
public IEnvironmentVariableService EnvironmentVariableService => environmentVariableServiceStatic;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ using System.IO;
|
|||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.ComponentDetection.Common;
|
||||
using Microsoft.ComponentDetection.Common.Telemetry.Records;
|
||||
using Microsoft.ComponentDetection.Contracts;
|
||||
using Microsoft.ComponentDetection.Contracts.Internal;
|
||||
|
@ -18,6 +19,9 @@ namespace Microsoft.ComponentDetection.Detectors.Go
|
|||
[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);
|
||||
|
@ -34,35 +38,62 @@ namespace Microsoft.ComponentDetection.Detectors.Go
|
|||
|
||||
private HashSet<string> projectRoots = new HashSet<string>();
|
||||
|
||||
protected override Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
protected override async Task OnFileFound(ProcessRequest processRequest, IDictionary<string, string> detectorArgs)
|
||||
{
|
||||
var singleFileComponentRecorder = processRequest.SingleFileComponentRecorder;
|
||||
var file = processRequest.ComponentStream;
|
||||
|
||||
var fileExtension = Path.GetExtension(file.Location).ToLowerInvariant();
|
||||
switch (fileExtension)
|
||||
{
|
||||
case ".mod":
|
||||
{
|
||||
Logger.LogVerbose("Found Go.mod: " + file.Location);
|
||||
ParseGoModFile(singleFileComponentRecorder, file);
|
||||
break;
|
||||
}
|
||||
|
||||
case ".sum":
|
||||
{
|
||||
Logger.LogVerbose("Found Go.sum: " + file.Location);
|
||||
ParseGoSumFile(singleFileComponentRecorder, file);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw new Exception("Unexpected file type detected in go detector");
|
||||
}
|
||||
}
|
||||
|
||||
return Task.CompletedTask;
|
||||
var projectRootDirectory = Directory.GetParent(file.Location);
|
||||
if (projectRoots.Any(path => projectRootDirectory.FullName.StartsWith(path)))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var wasGoCliScanSuccessful = false;
|
||||
try
|
||||
{
|
||||
if (IsGoCliManuallyEnabled())
|
||||
{
|
||||
Logger.LogInfo("Go cli scan was manually enabled");
|
||||
wasGoCliScanSuccessful = await UseGoCliToScan(file.Location, singleFileComponentRecorder);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
Logger.LogInfo("Failed to detect components using go cli.");
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (wasGoCliScanSuccessful)
|
||||
{
|
||||
projectRoots.Add(projectRootDirectory.FullName);
|
||||
}
|
||||
else
|
||||
{
|
||||
var fileExtension = Path.GetExtension(file.Location).ToLowerInvariant();
|
||||
switch (fileExtension)
|
||||
{
|
||||
case ".mod":
|
||||
{
|
||||
Logger.LogVerbose("Found Go.mod: " + file.Location);
|
||||
ParseGoModFile(singleFileComponentRecorder, file);
|
||||
break;
|
||||
}
|
||||
|
||||
case ".sum":
|
||||
{
|
||||
Logger.LogVerbose("Found Go.sum: " + file.Location);
|
||||
ParseGoSumFile(singleFileComponentRecorder, file);
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
{
|
||||
throw new Exception("Unexpected file type detected in go detector");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private async Task<bool> UseGoCliToScan(string location, ISingleFileComponentRecorder singleFileComponentRecorder)
|
||||
|
@ -223,5 +254,10 @@ namespace Microsoft.ComponentDetection.Detectors.Go
|
|||
goComponent = new GoComponent(componentParts[0], componentParts[1]);
|
||||
return true;
|
||||
}
|
||||
|
||||
private bool IsGoCliManuallyEnabled()
|
||||
{
|
||||
return EnvVarService.DoesEnvironmentVariableExist("EnableGoCliScan");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ using Microsoft.ComponentDetection.Detectors.Go;
|
|||
using Microsoft.VisualStudio.TestTools.UnitTesting;
|
||||
using Moq;
|
||||
using Microsoft.ComponentDetection.TestsUtilities;
|
||||
using Microsoft.ComponentDetection.Common;
|
||||
|
||||
namespace Microsoft.ComponentDetection.Detectors.Tests
|
||||
{
|
||||
|
@ -21,18 +22,25 @@ namespace Microsoft.ComponentDetection.Detectors.Tests
|
|||
{
|
||||
private DetectorTestUtility<GoComponentDetector> detectorTestUtility;
|
||||
private Mock<ICommandLineInvocationService> commandLineMock;
|
||||
|
||||
private Mock<IEnvironmentVariableService> envVarService;
|
||||
private ScanRequest scanRequest;
|
||||
|
||||
[TestInitialize]
|
||||
public void TestInitialize()
|
||||
{
|
||||
commandLineMock = new Mock<ICommandLineInvocationService>();
|
||||
envVarService = new Mock<IEnvironmentVariableService>();
|
||||
|
||||
var loggerMock = new Mock<ILogger>();
|
||||
|
||||
envVarService.Setup(x => x.DoesEnvironmentVariableExist("EnableGoCliScan")).Returns(false);
|
||||
|
||||
var detector = new GoComponentDetector
|
||||
{
|
||||
CommandLineInvocationService = commandLineMock.Object,
|
||||
Logger = loggerMock.Object,
|
||||
EnvVarService = envVarService.Object,
|
||||
};
|
||||
|
||||
var tempPath = Path.GetTempPath();
|
||||
|
@ -254,6 +262,8 @@ replace (
|
|||
commandLineMock.Setup(x => x.CanCommandBeLocated("go", null, It.IsAny<DirectoryInfo>(), It.IsAny<string[]>()))
|
||||
.ReturnsAsync(false);
|
||||
|
||||
envVarService.Setup(x => x.DoesEnvironmentVariableExist("EnableGoCliScan")).Returns(true);
|
||||
|
||||
await TestGoSumDetectorWithValidFile_ReturnsSuccessfully();
|
||||
}
|
||||
|
||||
|
@ -263,6 +273,8 @@ replace (
|
|||
commandLineMock.Setup(x => x.CanCommandBeLocated("go", null, It.IsAny<DirectoryInfo>(), It.IsAny<string[]>()))
|
||||
.ReturnsAsync(() => throw new Exception("Some horrible error occured"));
|
||||
|
||||
envVarService.Setup(x => x.DoesEnvironmentVariableExist("EnableGoCliScan")).Returns(true);
|
||||
|
||||
await TestGoSumDetectorWithValidFile_ReturnsSuccessfully();
|
||||
}
|
||||
|
||||
|
@ -278,6 +290,8 @@ replace (
|
|||
ExitCode = 1,
|
||||
});
|
||||
|
||||
envVarService.Setup(x => x.DoesEnvironmentVariableExist("EnableGoCliScan")).Returns(true);
|
||||
|
||||
await TestGoSumDetectorWithValidFile_ReturnsSuccessfully();
|
||||
}
|
||||
|
||||
|
@ -290,6 +304,8 @@ replace (
|
|||
commandLineMock.Setup(x => x.ExecuteCommand("go mod graph", null, It.IsAny<DirectoryInfo>(), It.IsAny<string>()))
|
||||
.ReturnsAsync(() => throw new Exception("Some horrible error occured"));
|
||||
|
||||
envVarService.Setup(x => x.DoesEnvironmentVariableExist("EnableGoCliScan")).Returns(true);
|
||||
|
||||
await TestGoSumDetectorWithValidFile_ReturnsSuccessfully();
|
||||
}
|
||||
|
||||
|
@ -308,6 +324,8 @@ replace (
|
|||
StdOut = goGraph,
|
||||
});
|
||||
|
||||
envVarService.Setup(x => x.DoesEnvironmentVariableExist("EnableGoCliScan")).Returns(true);
|
||||
|
||||
var (scanResult, componentRecorder) = await detectorTestUtility
|
||||
.WithFile("go.mod", string.Empty)
|
||||
.ExecuteDetector();
|
||||
|
@ -315,7 +333,15 @@ replace (
|
|||
Assert.AreEqual(ProcessingResultCode.Success, scanResult.ResultCode);
|
||||
|
||||
var detectedComponents = componentRecorder.GetDetectedComponents();
|
||||
Assert.AreEqual(0, detectedComponents.Count());
|
||||
Assert.AreEqual(4, detectedComponents.Count());
|
||||
}
|
||||
|
||||
[TestMethod]
|
||||
public async Task TestGoDetector_GoCliRequiresEnvVarToRun()
|
||||
{
|
||||
await TestGoSumDetectorWithValidFile_ReturnsSuccessfully();
|
||||
|
||||
commandLineMock.Verify(x => x.CanCommandBeLocated("go", null, It.IsAny<DirectoryInfo>(), It.IsAny<string[]>()), Times.Never);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Загрузка…
Ссылка в новой задаче