Skip to content

Commit de4e396

Browse files
committed
C#: Try fallback nuget restore without nuget.config
1 parent 7c290ee commit de4e396

File tree

6 files changed

+47
-18
lines changed

6 files changed

+47
-18
lines changed

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DependencyManager.cs

Lines changed: 15 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -650,12 +650,6 @@ private void AnalyseProject(FileInfo project)
650650

651651
}
652652

653-
private bool RestoreProject(string project, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null) =>
654-
dotnet.RestoreProjectToDirectory(project, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching, out assets, pathToNugetConfig);
655-
656-
private bool RestoreSolution(string solution, out IEnumerable<string> projects, out IEnumerable<string> assets) =>
657-
dotnet.RestoreSolutionToDirectory(solution, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: true, out projects, out assets);
658-
659653
/// <summary>
660654
/// Executes `dotnet restore` on all solution files in solutions.
661655
/// As opposed to RestoreProjects this is not run in parallel using PLINQ
@@ -670,7 +664,7 @@ private IEnumerable<string> RestoreSolutions(IEnumerable<string> solutions, out
670664
var assetFiles = new List<string>();
671665
var projects = solutions.SelectMany(solution =>
672666
{
673-
RestoreSolution(solution, out var restoredProjects, out var a);
667+
dotnet.RestoreSolutionToDirectory(solution, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: true, out var restoredProjects, out var a);
674668
assetFiles.AddRange(a);
675669
return restoredProjects;
676670
});
@@ -689,7 +683,7 @@ private void RestoreProjects(IEnumerable<string> projects, out IEnumerable<strin
689683
var assetFiles = new List<string>();
690684
Parallel.ForEach(projects, new ParallelOptions { MaxDegreeOfParallelism = options.Threads }, project =>
691685
{
692-
RestoreProject(project, forceDotnetRefAssemblyFetching: true, out var a);
686+
dotnet.RestoreProjectToDirectory(project, packageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: true, out var a, out var _);
693687
assetFiles.AddRange(a);
694688
});
695689
assets = assetFiles;
@@ -736,11 +730,21 @@ private void DownloadMissingPackages(List<FileInfo> allFiles, ISet<string> dllPa
736730
return;
737731
}
738732

739-
dotnet.RestoreProjectToDirectory(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: false, out var _, pathToNugetConfig: nugetConfig);
740-
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
733+
success = dotnet.RestoreProjectToDirectory(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: false, out var _, out var outputLines, pathToNugetConfig: nugetConfig);
741734
if (!success)
742735
{
743-
progressMonitor.FailedToRestoreNugetPackage(package);
736+
if (outputLines?.Any(s => s.Contains("NU1301")) == true)
737+
{
738+
// Restore could not be completed because the listed source is unavailable. Try without the nuget.config:
739+
success = dotnet.RestoreProjectToDirectory(tempDir.DirInfo.FullName, missingPackageDirectory.DirInfo.FullName, forceDotnetRefAssemblyFetching: false, out var _, out var _, pathToNugetConfig: null, force: true);
740+
}
741+
742+
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
743+
744+
if (!success)
745+
{
746+
progressMonitor.FailedToRestoreNugetPackage(package);
747+
}
744748
}
745749
});
746750

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/DotNet.cs

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,16 +72,21 @@ private static IEnumerable<string> GetAssetsFilePaths(IEnumerable<string> lines)
7272
private static IEnumerable<string> GetRestoredProjects(IEnumerable<string> lines) =>
7373
GetFirstGroupOnMatch(RestoredProjectRegex(), lines);
7474

75-
public bool RestoreProjectToDirectory(string projectFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null)
75+
public bool RestoreProjectToDirectory(string projectFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, out IList<string> outputLines, string? pathToNugetConfig = null, bool force = false)
7676
{
7777
var args = GetRestoreArgs(projectFile, packageDirectory, forceDotnetRefAssemblyFetching);
7878
if (pathToNugetConfig != null)
7979
{
8080
args += $" --configfile \"{pathToNugetConfig}\"";
8181
}
8282

83-
var success = dotnetCliInvoker.RunCommand(args, out var output);
84-
assets = success ? GetAssetsFilePaths(output) : Array.Empty<string>();
83+
if (force)
84+
{
85+
args += " --force";
86+
}
87+
88+
var success = dotnetCliInvoker.RunCommand(args, out outputLines);
89+
assets = success ? GetAssetsFilePaths(outputLines) : Array.Empty<string>();
8590
return success;
8691
}
8792

csharp/extractor/Semmle.Extraction.CSharp.DependencyFetching/IDotNet.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
44
{
55
internal interface IDotNet
66
{
7-
bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null);
7+
bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, out IList<string> outputLines, string? pathToNugetConfig = null, bool force = false);
88
bool RestoreSolutionToDirectory(string solutionFile, string packageDirectory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> projects, out IEnumerable<string> assets);
99
bool New(string folder);
1010
bool AddPackage(string folder, string package);

csharp/extractor/Semmle.Extraction.Tests/DotNet.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ public void TestDotnetRestoreProjectToDirectory1()
101101
var dotnet = MakeDotnet(dotnetCliInvoker);
102102

103103
// Execute
104-
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets);
104+
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets, out var _);
105105

106106
// Verify
107107
var lastArgs = dotnetCliInvoker.GetLastArgs();
@@ -116,7 +116,7 @@ public void TestDotnetRestoreProjectToDirectory2()
116116
var dotnet = MakeDotnet(dotnetCliInvoker);
117117

118118
// Execute
119-
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets, "myconfig.config");
119+
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets, out var _, pathToNugetConfig: "myconfig.config");
120120

121121
// Verify
122122
var lastArgs = dotnetCliInvoker.GetLastArgs();
@@ -126,6 +126,24 @@ public void TestDotnetRestoreProjectToDirectory2()
126126
Assert.Contains("/path/to/project2.assets.json", assets);
127127
}
128128

129+
[Fact]
130+
public void TestDotnetRestoreProjectToDirectory3()
131+
{
132+
// Setup
133+
var dotnetCliInvoker = new DotNetCliInvokerStub(MakeDotnetRestoreOutput());
134+
var dotnet = MakeDotnet(dotnetCliInvoker);
135+
136+
// Execute
137+
dotnet.RestoreProjectToDirectory("myproject.csproj", "mypackages", false, out var assets, out var _, pathToNugetConfig: "myconfig.config", force: true);
138+
139+
// Verify
140+
var lastArgs = dotnetCliInvoker.GetLastArgs();
141+
Assert.Equal("restore --no-dependencies \"myproject.csproj\" --packages \"mypackages\" /p:DisableImplicitNuGetFallbackFolder=true --verbosity normal --configfile \"myconfig.config\" --force", lastArgs);
142+
Assert.Equal(2, assets.Count());
143+
Assert.Contains("/path/to/project.assets.json", assets);
144+
Assert.Contains("/path/to/project2.assets.json", assets);
145+
}
146+
129147
[Fact]
130148
public void TestDotnetRestoreSolutionToDirectory1()
131149
{

csharp/extractor/Semmle.Extraction.Tests/Runtime.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,10 @@ public DotNetStub(IList<string> runtimes, IList<string> sdks)
1919

2020
public bool New(string folder) => true;
2121

22-
public bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, string? pathToNugetConfig = null)
22+
public bool RestoreProjectToDirectory(string project, string directory, bool forceDotnetRefAssemblyFetching, out IEnumerable<string> assets, out IList<string> outputLines, string? pathToNugetConfig = null, bool force = false)
2323
{
2424
assets = Array.Empty<string>();
25+
outputLines = Array.Empty<string>();
2526
return true;
2627
}
2728

Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
| newtonsoft.json/13.0.3/lib/net6.0/Newtonsoft.Json.dll |

0 commit comments

Comments
 (0)