diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs index 8491f9f8c81..f4aa614a345 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/BuildAnalysis.cs @@ -133,9 +133,9 @@ namespace Semmle.BuildAnalyser DateTime.Now - startTime); } - private IEnumerable GetFiles(string pattern) + private IEnumerable GetFiles(string pattern, bool recurseSubdirectories = true) { - return sourceDir.GetFiles(pattern, SearchOption.AllDirectories) + return sourceDir.GetFiles(pattern, new EnumerationOptions { RecurseSubdirectories = recurseSubdirectories, MatchCasing = MatchCasing.CaseInsensitive }) .Select(d => d.FullName) .Where(d => !options.ExcludesFile(d)); } @@ -318,16 +318,16 @@ namespace Semmle.BuildAnalyser } - private bool Restore(string target) + private bool Restore(string target, string? pathToNugetConfig = null) { - return dotnet.RestoreToDirectory(target, packageDirectory.DirInfo.FullName); + return dotnet.RestoreToDirectory(target, packageDirectory.DirInfo.FullName, pathToNugetConfig); } - private void Restore(IEnumerable targets) + private void Restore(IEnumerable targets, string? pathToNugetConfig = null) { foreach (var target in targets) { - Restore(target); + Restore(target, pathToNugetConfig); } } @@ -336,7 +336,23 @@ namespace Semmle.BuildAnalyser var alreadyDownloadedPackages = Directory.GetDirectories(packageDirectory.DirInfo.FullName).Select(d => Path.GetFileName(d).ToLowerInvariant()).ToHashSet(); var notYetDownloadedPackages = new HashSet(); - var allFiles = GetFiles("*.*").ToArray(); + var nugetConfigs = GetFiles("nuget.config", recurseSubdirectories: true).ToArray(); + string? nugetConfig = null; + if (nugetConfigs.Length > 1) + { + progressMonitor.MultipleNugetConfig(nugetConfigs); + nugetConfig = GetFiles("nuget.config", recurseSubdirectories: false).FirstOrDefault(); + if (nugetConfig == null) + { + progressMonitor.NoTopLevelNugetConfig(); + } + } + else + { + nugetConfig = nugetConfigs.FirstOrDefault(); + } + + var allFiles = GetFiles("*.*"); foreach (var file in allFiles) { try @@ -390,7 +406,7 @@ namespace Semmle.BuildAnalyser continue; } - success = Restore(tempDir.DirInfo.FullName); + success = Restore(tempDir.DirInfo.FullName, nugetConfig); // TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package. diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/DotNet.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/DotNet.cs index 12237d79da7..456c0e6f939 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/DotNet.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/DotNet.cs @@ -56,9 +56,11 @@ namespace Semmle.BuildAnalyser return true; } - public bool RestoreToDirectory(string projectOrSolutionFile, string packageDirectory) + public bool RestoreToDirectory(string projectOrSolutionFile, string packageDirectory, string? pathToNugetConfig = null) { var args = $"restore --no-dependencies \"{projectOrSolutionFile}\" --packages \"{packageDirectory}\" /p:DisableImplicitNuGetFallbackFolder=true"; + if (pathToNugetConfig != null) + args += $" --configfile \"{pathToNugetConfig}\""; return RunCommand(args); } diff --git a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/ProgressMonitor.cs b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/ProgressMonitor.cs index de1c5274c37..233ba969fea 100644 --- a/csharp/extractor/Semmle.Extraction.CSharp.Standalone/ProgressMonitor.cs +++ b/csharp/extractor/Semmle.Extraction.CSharp.Standalone/ProgressMonitor.cs @@ -118,5 +118,15 @@ namespace Semmle.BuildAnalyser logger.Log(Severity.Info, $"Failed to read file {file}"); logger.Log(Severity.Debug, $"Failed to read file {file}, exception: {ex}"); } + + public void MultipleNugetConfig(string[] nugetConfigs) + { + logger.Log(Severity.Info, $"Found multiple nuget.config files: {string.Join(", ", nugetConfigs)}."); + } + + internal void NoTopLevelNugetConfig() + { + logger.Log(Severity.Info, $"Could not find a top-level nuget.config file."); + } } }