Skip to content

Commit 79ff9ed

Browse files
amitla1Amitla Vannikumar
andauthored
Adding Support for Relative Paths Go Replace Detector (#1254)
* adding go tests * upgrade version * unused using statement * nit changes * nit * make tests more generic * simplifying conditional statements * simplifying --------- Co-authored-by: Amitla Vannikumar <[email protected]>
1 parent 809f458 commit 79ff9ed

File tree

3 files changed

+507
-5
lines changed

3 files changed

+507
-5
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
namespace Microsoft.ComponentDetection.Common.Telemetry.Records;
2+
3+
public class GoReplaceTelemetryRecord : BaseDetectionTelemetryRecord
4+
{
5+
public override string RecordName => "GoReplace";
6+
7+
public string GoModPathAndVersion { get; set; }
8+
9+
public string GoModReplacement { get; set; }
10+
}

src/Microsoft.ComponentDetection.Detectors/go/GoComponentWithReplaceDetector.cs

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -27,19 +27,22 @@ public class GoComponentWithReplaceDetector : FileComponentDetector, IExperiment
2727

2828
private readonly ICommandLineInvocationService commandLineInvocationService;
2929
private readonly IEnvironmentVariableService envVarService;
30+
private readonly IFileUtilityService fileUtilityService;
3031

3132
public GoComponentWithReplaceDetector(
3233
IComponentStreamEnumerableFactory componentStreamEnumerableFactory,
3334
IObservableDirectoryWalkerFactory walkerFactory,
3435
ICommandLineInvocationService commandLineInvocationService,
3536
IEnvironmentVariableService envVarService,
36-
ILogger<GoComponentWithReplaceDetector> logger)
37+
ILogger<GoComponentWithReplaceDetector> logger,
38+
IFileUtilityService fileUtilityService)
3739
{
3840
this.ComponentStreamEnumerableFactory = componentStreamEnumerableFactory;
3941
this.Scanner = walkerFactory;
4042
this.commandLineInvocationService = commandLineInvocationService;
4143
this.envVarService = envVarService;
4244
this.Logger = logger;
45+
this.fileUtilityService = fileUtilityService;
4346
}
4447

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

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

53-
public override int Version => 1;
56+
public override int Version => 2;
5457

5558
protected override Task<IObservable<ProcessRequest>> OnPrepareDetectionAsync(
5659
IObservable<ProcessRequest> processRequests,
@@ -246,7 +249,7 @@ private async Task<bool> UseGoCliToScanAsync(string location, ISingleFileCompone
246249
return false;
247250
}
248251

249-
this.RecordBuildDependencies(goDependenciesProcess.StdOut, singleFileComponentRecorder);
252+
this.RecordBuildDependencies(goDependenciesProcess.StdOut, singleFileComponentRecorder, projectRootDirectory.FullName);
250253

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

425-
private void RecordBuildDependencies(string goListOutput, ISingleFileComponentRecorder singleFileComponentRecorder)
428+
private void RecordBuildDependencies(string goListOutput, ISingleFileComponentRecorder singleFileComponentRecorder, string projectRootDirectoryFullName)
426429
{
427430
var goBuildModules = new List<GoBuildModule>();
428431
var reader = new JsonTextReader(new StringReader(goListOutput))
429432
{
430433
SupportMultipleContent = true,
431434
};
432435

436+
using var record = new GoReplaceTelemetryRecord();
437+
433438
while (reader.Read())
434439
{
435440
var serializer = new JsonSerializer();
@@ -440,16 +445,40 @@ private void RecordBuildDependencies(string goListOutput, ISingleFileComponentRe
440445

441446
foreach (var dependency in goBuildModules)
442447
{
448+
var dependencyName = $"{dependency.Path} {dependency.Version}";
449+
443450
if (dependency.Main)
444451
{
445452
// main is the entry point module (superfluous as we already have the file location)
446453
continue;
447454
}
448455

456+
if (dependency.Replace?.Path != null && dependency.Replace.Version == null)
457+
{
458+
var dirName = projectRootDirectoryFullName;
459+
var combinedPath = Path.Combine(dirName, dependency.Replace.Path, "go.mod");
460+
var goModFilePath = Path.GetFullPath(combinedPath);
461+
if (this.fileUtilityService.Exists(goModFilePath))
462+
{
463+
this.Logger.LogInformation("go Module {GoModule} is being replaced with module at path {GoModFilePath}", dependencyName, goModFilePath);
464+
record.GoModPathAndVersion = dependencyName;
465+
record.GoModReplacement = goModFilePath;
466+
continue;
467+
}
468+
469+
this.Logger.LogWarning("go.mod file {GoModFilePath} does not exist in the relative path given for replacement", goModFilePath);
470+
record.GoModPathAndVersion = goModFilePath;
471+
record.GoModReplacement = null;
472+
}
473+
449474
GoComponent goComponent;
450-
if (dependency.Replace != null)
475+
if (dependency.Replace?.Path != null && dependency.Replace.Version != null)
451476
{
477+
var dependencyReplacementName = $"{dependency.Replace.Path} {dependency.Replace.Version}";
452478
goComponent = new GoComponent(dependency.Replace.Path, dependency.Replace.Version);
479+
this.Logger.LogInformation("go Module {GoModule} being replaced with module {GoModuleReplacement}", dependencyName, dependencyReplacementName);
480+
record.GoModPathAndVersion = dependencyName;
481+
record.GoModReplacement = dependencyReplacementName;
453482
}
454483
else
455484
{

0 commit comments

Comments
 (0)