diff --git a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs index 43efcd0352f..a29079d205b 100644 --- a/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs +++ b/csharp/autobuilder/Semmle.Autobuild.CSharp/DotNetRule.cs @@ -46,7 +46,9 @@ namespace Semmle.Autobuild.CSharp return WithDotNet(builder, ensureDotNetAvailable: false, (dotNetPath, environment) => { - var ret = GetInfoCommand(builder.Actions, dotNetPath, environment); + // When a custom .NET CLI has been installed, `dotnet --info` has already been executed + // to verify the installation. + var ret = dotNetPath is null ? GetInfoCommand(builder.Actions, dotNetPath, environment) : BuildScript.Success; foreach (var projectOrSolution in builder.ProjectsOrSolutionsToBuild) { var cleanCommand = GetCleanCommand(builder.Actions, dotNetPath, environment); diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs index b8773f0ae4a..040e89dcec1 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs @@ -41,7 +41,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching private int conflictedReferences = 0; private readonly DirectoryInfo sourceDir; private string? dotnetPath; - private readonly TemporaryDirectory tempWorkingDirectory; private readonly bool cleanupTempWorkingDirectory; diff --git a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs index c1fdcc06e91..dfabb744618 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs @@ -19,17 +19,20 @@ namespace Semmle.Extraction.CSharp.DependencyFetching private readonly ILogger logger; private readonly TemporaryDirectory? tempWorkingDirectory; - private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, TemporaryDirectory? tempWorkingDirectory = null) + private DotNet(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, bool runDotnetInfo, TemporaryDirectory? tempWorkingDirectory = null) { this.tempWorkingDirectory = tempWorkingDirectory; this.dotnetCliInvoker = dotnetCliInvoker; this.logger = logger; - Info(); + if (runDotnetInfo) + { + Info(); + } } - private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, tempWorkingDirectory) { } + private DotNet(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) : this(new DotNetCliInvoker(logger, Path.Combine(dotNetPath ?? string.Empty, "dotnet"), dependabotProxy), logger, dotNetPath is null, tempWorkingDirectory) { } - internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger) => new DotNet(dotnetCliInvoker, logger); + internal static IDotNet Make(IDotNetCliInvoker dotnetCliInvoker, ILogger logger, bool runDotnetInfo) => new DotNet(dotnetCliInvoker, logger, runDotnetInfo); public static IDotNet Make(ILogger logger, string? dotNetPath, TemporaryDirectory tempWorkingDirectory, DependabotProxy? dependabotProxy) => new DotNet(logger, dotNetPath, tempWorkingDirectory, dependabotProxy); @@ -169,7 +172,10 @@ namespace Semmle.Extraction.CSharp.DependencyFetching if (versions.Count > 0) { - return DownloadDotNetVersion(actions, logger, tempWorkingDirectory, shouldCleanUp, installDir, versions); + return + DownloadDotNetVersion(actions, logger, tempWorkingDirectory, shouldCleanUp, installDir, versions) | + // if neither of the versions succeed, try the latest version + DownloadDotNetVersion(actions, logger, tempWorkingDirectory, shouldCleanUp, installDir, [LatestDotNetSdkVersion], needExactVersion: false); } if (ensureDotNetAvailable) @@ -269,6 +275,14 @@ namespace Semmle.Extraction.CSharp.DependencyFetching Argument(path).Script; } + var dotnetInfo = new CommandBuilder(actions). + RunCommand(actions.PathCombine(path, "dotnet")). + Argument("--info").Script; + + Func getInstallAndVerify = version => + // run `dotnet --info` after install, to check that it executes successfully + getInstall(version) & dotnetInfo; + var installScript = prelude & BuildScript.Failure; var attempted = new HashSet(); @@ -283,7 +297,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching // When there are multiple versions requested, we want to try to fetch them all, reporting // a successful exit code when at least one of them succeeds - return combinedExit != 0 ? getInstall(version) : BuildScript.Bind(getInstall(version), _ => BuildScript.Success); + return combinedExit != 0 ? getInstallAndVerify(version) : BuildScript.Bind(getInstallAndVerify(version), _ => BuildScript.Success); }); } diff --git a/csharp/extractor/Semmle.Extraction.Tests/DotNet.cs b/csharp/extractor/Semmle.Extraction.Tests/DotNet.cs index 3c1b41f54bf..c584b607ec8 100644 --- a/csharp/extractor/Semmle.Extraction.Tests/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.Tests/DotNet.cs @@ -45,7 +45,7 @@ namespace Semmle.Extraction.Tests public class DotNetTests { private static IDotNet MakeDotnet(IDotNetCliInvoker dotnetCliInvoker) => - DotNet.Make(dotnetCliInvoker, new LoggerStub()); + DotNet.Make(dotnetCliInvoker, new LoggerStub(), true); private static IList MakeDotnetRestoreOutput() => new List {