Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Microsoft.ComponentDetection.Common.Telemetry.Records;

public class GoReplaceTelemetryRecord : BaseDetectionTelemetryRecord
{
public override string RecordName => "GoReplace";

public string GoModPathAndVersion { get; set; }

public string GoModReplacement { get; set; }
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,19 +27,22 @@ public class GoComponentWithReplaceDetector : FileComponentDetector, IExperiment

private readonly ICommandLineInvocationService commandLineInvocationService;
private readonly IEnvironmentVariableService envVarService;
private readonly IFileUtilityService fileUtilityService;

public GoComponentWithReplaceDetector(
IComponentStreamEnumerableFactory componentStreamEnumerableFactory,
IObservableDirectoryWalkerFactory walkerFactory,
ICommandLineInvocationService commandLineInvocationService,
IEnvironmentVariableService envVarService,
ILogger<GoComponentWithReplaceDetector> logger)
ILogger<GoComponentWithReplaceDetector> logger,
IFileUtilityService fileUtilityService)
{
this.ComponentStreamEnumerableFactory = componentStreamEnumerableFactory;
this.Scanner = walkerFactory;
this.commandLineInvocationService = commandLineInvocationService;
this.envVarService = envVarService;
this.Logger = logger;
this.fileUtilityService = fileUtilityService;
}

public override string Id => "GoWithReplace";
Expand All @@ -50,7 +53,7 @@ public GoComponentWithReplaceDetector(

public override IEnumerable<ComponentType> SupportedComponentTypes { get; } = [ComponentType.Go];

public override int Version => 1;
public override int Version => 2;

protected override Task<IObservable<ProcessRequest>> OnPrepareDetectionAsync(
IObservable<ProcessRequest> processRequests,
Expand Down Expand Up @@ -246,7 +249,7 @@ private async Task<bool> UseGoCliToScanAsync(string location, ISingleFileCompone
return false;
}

this.RecordBuildDependencies(goDependenciesProcess.StdOut, singleFileComponentRecorder);
this.RecordBuildDependencies(goDependenciesProcess.StdOut, singleFileComponentRecorder, projectRootDirectory.FullName);

var generateGraphProcess = await this.commandLineInvocationService.ExecuteCommandAsync("go", null, workingDirectory: projectRootDirectory, new List<string> { "mod", "graph" }.ToArray());
if (generateGraphProcess.ExitCode == 0)
Expand Down Expand Up @@ -422,14 +425,16 @@ private bool IsModuleInBuildList(ISingleFileComponentRecorder singleFileComponen
return singleFileComponentRecorder.GetComponent(component.Id) != null;
}

private void RecordBuildDependencies(string goListOutput, ISingleFileComponentRecorder singleFileComponentRecorder)
private void RecordBuildDependencies(string goListOutput, ISingleFileComponentRecorder singleFileComponentRecorder, string projectRootDirectoryFullName)
{
var goBuildModules = new List<GoBuildModule>();
var reader = new JsonTextReader(new StringReader(goListOutput))
{
SupportMultipleContent = true,
};

using var record = new GoReplaceTelemetryRecord();

while (reader.Read())
{
var serializer = new JsonSerializer();
Expand All @@ -440,16 +445,40 @@ private void RecordBuildDependencies(string goListOutput, ISingleFileComponentRe

foreach (var dependency in goBuildModules)
{
var dependencyName = $"{dependency.Path} {dependency.Version}";

if (dependency.Main)
{
// main is the entry point module (superfluous as we already have the file location)
continue;
}

if (dependency.Replace?.Path != null && dependency.Replace.Version == null)
{
var dirName = projectRootDirectoryFullName;
var combinedPath = Path.Combine(dirName, dependency.Replace.Path, "go.mod");
var goModFilePath = Path.GetFullPath(combinedPath);
if (this.fileUtilityService.Exists(goModFilePath))
{
this.Logger.LogInformation("go Module {GoModule} is being replaced with module at path {GoModFilePath}", dependencyName, goModFilePath);
record.GoModPathAndVersion = dependencyName;
record.GoModReplacement = goModFilePath;
continue;
}

this.Logger.LogWarning("go.mod file {GoModFilePath} does not exist in the relative path given for replacement", goModFilePath);
record.GoModPathAndVersion = goModFilePath;
record.GoModReplacement = null;
}

GoComponent goComponent;
if (dependency.Replace != null)
if (dependency.Replace?.Path != null && dependency.Replace.Version != null)
{
var dependencyReplacementName = $"{dependency.Replace.Path} {dependency.Replace.Version}";
goComponent = new GoComponent(dependency.Replace.Path, dependency.Replace.Version);
this.Logger.LogInformation("go Module {GoModule} being replaced with module {GoModuleReplacement}", dependencyName, dependencyReplacementName);
record.GoModPathAndVersion = dependencyName;
record.GoModReplacement = dependencyReplacementName;
}
else
{
Expand Down
Loading
Loading