Skip to content

Commit

Permalink
Merge pull request #16498 from tamasvajk/buildless/use-nuget-from-path
Browse files Browse the repository at this point in the history
C#: Use nuget.exe from the executing machine instead of always downlo…
  • Loading branch information
tamasvajk authored May 21, 2024
2 parents 9d21e2c + a79105e commit 1a20a62
Show file tree
Hide file tree
Showing 3 changed files with 65 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,11 @@ internal class EnvironmentVariableNames
/// </summary>
public const string FallbackNugetFeeds = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_FEEDS_FALLBACK";

/// <summary>
/// Specifies the path to the nuget executable to be used for package restoration.
/// </summary>
public const string NugetExePath = "CODEQL_EXTRACTOR_CSHARP_BUILDLESS_NUGET_PATH";

/// <summary>
/// Specifies the location of the diagnostic directory.
/// </summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ public class FileProvider
private readonly Lazy<string[]> solutions;
private readonly Lazy<string[]> dlls;
private readonly Lazy<string[]> nugetConfigs;
private readonly Lazy<string[]> nugetExes;
private readonly Lazy<string[]> globalJsons;
private readonly Lazy<string[]> packagesConfigs;
private readonly Lazy<string[]> razorViews;
Expand All @@ -45,6 +46,7 @@ public FileProvider(DirectoryInfo sourceDir, ILogger logger)
resources = new Lazy<string[]>(() => SelectTextFileNamesByExtension("resource", ".resx"));

rootNugetConfig = new Lazy<string?>(() => all.SelectRootFiles(SourceDir).SelectFileNamesByName("nuget.config").FirstOrDefault());
nugetExes = new Lazy<string[]>(() => all.SelectFileNamesByName("nuget.exe").ToArray());
}

private string[] ReturnAndLogFiles(string filetype, IEnumerable<string> files)
Expand Down Expand Up @@ -123,6 +125,7 @@ private FileInfo[] GetAllFiles()
public ICollection<string> Solutions => solutions.Value;
public IEnumerable<string> Dlls => dlls.Value;
public ICollection<string> NugetConfigs => nugetConfigs.Value;
public ICollection<string> NugetExes => nugetExes.Value;
public string? RootNugetConfig => rootNugetConfig.Value;
public IEnumerable<string> GlobalJsons => globalJsons.Value;
public ICollection<string> PackagesConfigs => packagesConfigs.Value;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,15 +17,11 @@ internal class NugetExeWrapper : IDisposable
private readonly string? nugetExe;
private readonly Util.Logging.ILogger logger;

/// <summary>
/// The list of package files.
/// </summary>
private readonly ICollection<string> packageFiles;

public int PackageCount => packageFiles.Count;
public int PackageCount => fileProvider.PackagesConfigs.Count;

private readonly string? backupNugetConfig;
private readonly string? nugetConfigPath;
private readonly FileProvider fileProvider;

/// <summary>
/// The computed packages directory.
Expand All @@ -39,15 +35,14 @@ internal class NugetExeWrapper : IDisposable
/// </summary>
public NugetExeWrapper(FileProvider fileProvider, TemporaryDirectory packageDirectory, Util.Logging.ILogger logger)
{
this.fileProvider = fileProvider;
this.packageDirectory = packageDirectory;
this.logger = logger;

packageFiles = fileProvider.PackagesConfigs;

if (packageFiles.Count > 0)
if (fileProvider.PackagesConfigs.Count > 0)
{
logger.LogInfo($"Found packages.config files, trying to use nuget.exe for package restore");
nugetExe = ResolveNugetExe(fileProvider.SourceDir.FullName);
nugetExe = ResolveNugetExe();
if (HasNoPackageSource())
{
// We only modify or add a top level nuget.config file
Expand Down Expand Up @@ -87,25 +82,44 @@ public NugetExeWrapper(FileProvider fileProvider, TemporaryDirectory packageDire
}

/// <summary>
/// Tries to find the location of `nuget.exe` in the nuget directory under the directory
/// containing the executing assembly. If it can't be found, it is downloaded to the
/// `.nuget` directory under the source directory.
/// Tries to find the location of `nuget.exe`. It looks for
/// - the environment variable specifying a location,
/// - files in the repository,
/// - tries to resolve nuget from the PATH, or
/// - downloads it if it is not found.
/// </summary>
/// <param name="sourceDir">The source directory.</param>
private string ResolveNugetExe(string sourceDir)
private string ResolveNugetExe()
{
var currentAssembly = System.Reflection.Assembly.GetExecutingAssembly().Location;
var directory = Path.GetDirectoryName(currentAssembly)
?? throw new FileNotFoundException($"Directory path '{currentAssembly}' of current assembly is null");
var envVarPath = Environment.GetEnvironmentVariable(EnvironmentVariableNames.NugetExePath);
if (!string.IsNullOrEmpty(envVarPath))
{
logger.LogInfo($"Using nuget.exe from environment variable: '{envVarPath}'");
return envVarPath;
}

var nuget = Path.Combine(directory, "nuget", "nuget.exe");
if (File.Exists(nuget))
var nugetExesInRepo = fileProvider.NugetExes;
if (nugetExesInRepo.Count > 1)
{
logger.LogInfo($"Found nuget.exe at {nuget}");
return nuget;
logger.LogInfo($"Found multiple nuget.exe files in the repository: {string.Join(", ", nugetExesInRepo.OrderBy(s => s))}");
}

return DownloadNugetExe(sourceDir);
if (nugetExesInRepo.Count > 0)
{
var path = nugetExesInRepo.First();
logger.LogInfo($"Using nuget.exe from path '{path}'");
return path;
}

var executableName = Win32.IsWindows() ? "nuget.exe" : "nuget";
var nugetPath = FileUtils.FindProgramOnPath(executableName);
if (nugetPath is not null)
{
nugetPath = Path.Combine(nugetPath, executableName);
logger.LogInfo($"Using nuget.exe from PATH: {nugetPath}");
return nugetPath;
}

return DownloadNugetExe(fileProvider.SourceDir.FullName);
}

private string DownloadNugetExe(string sourceDir)
Expand Down Expand Up @@ -135,6 +149,8 @@ private string DownloadNugetExe(string sourceDir)
}
}

private bool RunWithMono => !Win32.IsWindows() && !string.IsNullOrEmpty(Path.GetExtension(nugetExe));

/// <summary>
/// Restore all files in a specified package.
/// </summary>
Expand All @@ -150,15 +166,15 @@ private bool TryRestoreNugetPackage(string package)
*/

string exe, args;
if (Win32.IsWindows())
if (RunWithMono)
{
exe = nugetExe!;
args = $"install -OutputDirectory {packageDirectory} {package}";
exe = "mono";
args = $"{nugetExe} install -OutputDirectory {packageDirectory} {package}";
}
else
{
exe = "mono";
args = $"{nugetExe} install -OutputDirectory {packageDirectory} {package}";
exe = nugetExe!;
args = $"install -OutputDirectory {packageDirectory} {package}";
}

var pi = new ProcessStartInfo(exe, args)
Expand Down Expand Up @@ -189,7 +205,7 @@ private bool TryRestoreNugetPackage(string package)
/// </summary>
public int InstallPackages()
{
return packageFiles.Count(package => TryRestoreNugetPackage(package));
return fileProvider.PackagesConfigs.Count(package => TryRestoreNugetPackage(package));
}

private bool HasNoPackageSource()
Expand Down Expand Up @@ -219,8 +235,18 @@ private bool HasNoPackageSource()

private void RunMonoNugetCommand(string command, out IList<string> stdout)
{
var exe = "mono";
var args = $"{nugetExe} {command}";
string exe, args;
if (RunWithMono)
{
exe = "mono";
args = $"{nugetExe} {command}";
}
else
{
exe = nugetExe!;
args = command;
}

var pi = new ProcessStartInfo(exe, args)
{
RedirectStandardOutput = true,
Expand Down

0 comments on commit 1a20a62

Please sign in to comment.