65 lines
2.5 KiB
C#
65 lines
2.5 KiB
C#
using System;
|
|
using System.IO;
|
|
using Xunit.Abstractions;
|
|
|
|
namespace Templates.Test.Helpers
|
|
{
|
|
public static class Npm
|
|
{
|
|
private static object NpmInstallLock = new object();
|
|
|
|
public static void RestoreWithRetry(ITestOutputHelper output, string workingDirectory)
|
|
{
|
|
// "npm restore" sometimes fails randomly in AppVeyor with errors like:
|
|
// EPERM: operation not permitted, scandir <path>...
|
|
// This appears to be a general NPM reliability issue on Windows which has
|
|
// been reported many times (e.g., https://github.com/npm/npm/issues/18380)
|
|
// So, allow multiple attempts at the restore.
|
|
const int maxAttempts = 3;
|
|
var attemptNumber = 0;
|
|
while (true)
|
|
{
|
|
try
|
|
{
|
|
attemptNumber++;
|
|
Restore(output, workingDirectory);
|
|
break; // Success
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (attemptNumber < maxAttempts)
|
|
{
|
|
output.WriteLine(
|
|
$"NPM restore in {workingDirectory} failed on attempt {attemptNumber} of {maxAttempts}. " +
|
|
$"Error was: {ex}");
|
|
|
|
// Clean up the possibly-incomplete node_modules dir before retrying
|
|
var nodeModulesDir = Path.Combine(workingDirectory, "node_modules");
|
|
if (Directory.Exists(nodeModulesDir))
|
|
{
|
|
Directory.Delete(nodeModulesDir, recursive: true);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
output.WriteLine(
|
|
$"Giving up attempting NPM restore in {workingDirectory} after {attemptNumber} attempts.");
|
|
throw;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
private static void Restore(ITestOutputHelper output, string workingDirectory)
|
|
{
|
|
// It's not safe to run multiple NPM installs in parallel
|
|
// https://github.com/npm/npm/issues/2500
|
|
lock (NpmInstallLock)
|
|
{
|
|
output.WriteLine($"Restoring NPM packages in '{workingDirectory}' using npm...");
|
|
ProcessEx.RunViaShell(output, workingDirectory, "npm install");
|
|
}
|
|
}
|
|
}
|
|
}
|