Skip to content

Commit

Permalink
Adding Support for Relative Paths Go Replace Detector (#1254)
Browse files Browse the repository at this point in the history
* adding go tests

* upgrade version

* unused using statement

* nit changes

* nit

* make tests more generic

* simplifying conditional statements

* simplifying

---------

Co-authored-by: Amitla Vannikumar <avannikumar@microsoft.com>
  • Loading branch information
amitla1 and Amitla Vannikumar authored Sep 30, 2024
1 parent 809f458 commit 79ff9ed
Show file tree
Hide file tree
Showing 3 changed files with 507 additions and 5 deletions.
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

0 comments on commit 79ff9ed

Please sign in to comment.