Skip to content

Commit dfd7f1e

Browse files
committed
C#: Parallelize restore logic of missing packages
1 parent fc3bc95 commit dfd7f1e

File tree

5 files changed

+59
-36
lines changed

5 files changed

+59
-36
lines changed

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

Lines changed: 31 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -499,29 +499,38 @@ private void DownloadMissingPackages(List<FileInfo> allFiles)
499499
var alreadyDownloadedPackages = Directory.GetDirectories(packageDirectory.DirInfo.FullName)
500500
.Select(d => Path.GetFileName(d).ToLowerInvariant());
501501
var notYetDownloadedPackages = fileContent.AllPackages.Except(alreadyDownloadedPackages);
502-
foreach (var package in notYetDownloadedPackages)
503-
{
504-
progressMonitor.NugetInstall(package);
505-
using var tempDir = new TemporaryDirectory(GetTemporaryWorkingDirectory(package));
506-
var success = dotnet.New(tempDir.DirInfo.FullName);
507-
if (!success)
508-
{
509-
continue;
510-
}
511-
success = dotnet.AddPackage(tempDir.DirInfo.FullName, package);
512-
if (!success)
513-
{
514-
continue;
515-
}
516-
517-
success = RestoreProject(tempDir.DirInfo.FullName, out var stdout, nugetConfig);
518-
Console.WriteLine(stdout);
519502

520-
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
521-
if (!success)
522-
{
523-
progressMonitor.FailedToRestoreNugetPackage(package);
524-
}
503+
var stdoutLines = notYetDownloadedPackages
504+
.AsParallel()
505+
.WithDegreeOfParallelism(options.Threads)
506+
.Select(package =>
507+
{
508+
progressMonitor.NugetInstall(package);
509+
using var tempDir = new TemporaryDirectory(ComputeTempDirectory(package));
510+
var success = dotnet.New(tempDir.DirInfo.FullName, out var stdout1);
511+
if (!success)
512+
{
513+
return new[] { stdout1 };
514+
}
515+
516+
success = dotnet.AddPackage(tempDir.DirInfo.FullName, package, out var stdout2);
517+
if (!success)
518+
{
519+
return new[] { stdout1, stdout2 };
520+
}
521+
522+
success = RestoreProject(tempDir.DirInfo.FullName, out var stdout3, nugetConfig);
523+
// TODO: the restore might fail, we could retry with a prerelease (*-* instead of *) version of the package.
524+
if (!success)
525+
{
526+
progressMonitor.FailedToRestoreNugetPackage(package);
527+
}
528+
return new[] { stdout1, stdout2, stdout3 };
529+
})
530+
.ToList();
531+
foreach (var line in stdoutLines.SelectMany(l => l))
532+
{
533+
Console.WriteLine(line);
525534
}
526535
}
527536

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,13 @@ private void Info()
3737
}
3838
}
3939

40+
private bool RunCommand(string args, out string stdout)
41+
{
42+
var success = dotnetCliInvoker.RunCommand(args, out var output);
43+
stdout = string.Join("\n", output);
44+
return success;
45+
}
46+
4047
private static string GetRestoreArgs(string projectOrSolutionFile, string packageDirectory) =>
4148
$"restore --no-dependencies \"{projectOrSolutionFile}\" --packages \"{packageDirectory}\" /p:DisableImplicitNuGetFallbackFolder=true";
4249

@@ -47,9 +54,8 @@ public bool RestoreProjectToDirectory(string projectFile, string packageDirector
4754
{
4855
args += $" --configfile \"{pathToNugetConfig}\"";
4956
}
50-
var success = dotnetCliInvoker.RunCommand(args, out var output);
51-
stdout = string.Join("\n", output);
52-
return success;
57+
58+
return RunCommand(args, out stdout);
5359
}
5460

5561
public bool RestoreSolutionToDirectory(string solutionFile, string packageDirectory, out IEnumerable<string> projects)
@@ -70,16 +76,16 @@ public bool RestoreSolutionToDirectory(string solutionFile, string packageDirect
7076
return false;
7177
}
7278

73-
public bool New(string folder)
79+
public bool New(string folder, out string stdout)
7480
{
7581
var args = $"new console --no-restore --output \"{folder}\"";
76-
return dotnetCliInvoker.RunCommand(args);
82+
return RunCommand(args, out stdout);
7783
}
7884

79-
public bool AddPackage(string folder, string package)
85+
public bool AddPackage(string folder, string package, out string stdout)
8086
{
8187
var args = $"add \"{folder}\" package \"{package}\" --no-restore";
82-
return dotnetCliInvoker.RunCommand(args);
88+
return RunCommand(args, out stdout);
8389
}
8490

8591
public IList<string> GetListedRuntimes() => GetListed("--list-runtimes", "runtime");
@@ -88,7 +94,7 @@ public bool AddPackage(string folder, string package)
8894

8995
private IList<string> GetListed(string args, string artifact)
9096
{
91-
if (dotnetCliInvoker.RunCommand(args, out var artifacts))
97+
if (dotnetCliInvoker.RunCommand(args, out IList<string> artifacts))
9298
{
9399
progressMonitor.LogInfo($"Found {artifact}s: {string.Join("\n", artifacts)}");
94100
return artifacts;

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ internal interface IDotNet
66
{
77
bool RestoreProjectToDirectory(string project, string directory, out string stdout, string? pathToNugetConfig = null);
88
bool RestoreSolutionToDirectory(string solutionFile, string packageDirectory, out IEnumerable<string> projects);
9-
bool New(string folder);
10-
bool AddPackage(string folder, string package);
9+
bool New(string folder, out string stdout);
10+
bool AddPackage(string folder, string package, out string stdout);
1111
IList<string> GetListedRuntimes();
1212
IList<string> GetListedSdks();
1313
bool Exec(string execArgs);

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ public void TestDotnetNew()
164164
var dotnet = MakeDotnet(dotnetCliInvoker);
165165

166166
// Execute
167-
dotnet.New("myfolder");
167+
dotnet.New("myfolder", out var _);
168168

169169
// Verify
170170
var lastArgs = dotnetCliInvoker.GetLastArgs();
@@ -179,7 +179,7 @@ public void TestDotnetAddPackage()
179179
var dotnet = MakeDotnet(dotnetCliInvoker);
180180

181181
// Execute
182-
dotnet.AddPackage("myfolder", "mypackage");
182+
dotnet.AddPackage("myfolder", "mypackage", out var _);
183183

184184
// Verify
185185
var lastArgs = dotnetCliInvoker.GetLastArgs();

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

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,17 @@ public DotNetStub(IList<string> runtimes, IList<string> sdks)
1515
this.runtimes = runtimes;
1616
this.sdks = sdks;
1717
}
18-
public bool AddPackage(string folder, string package) => true;
18+
public bool AddPackage(string folder, string package, out string stdout)
19+
{
20+
stdout = "";
21+
return true;
22+
}
1923

20-
public bool New(string folder) => true;
24+
public bool New(string folder, out string stdout)
25+
{
26+
stdout = "";
27+
return true;
28+
}
2129

2230
public bool RestoreProjectToDirectory(string project, string directory, out string stdout, string? pathToNugetConfig = null)
2331
{

0 commit comments

Comments
 (0)