Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Pass project path when performing a restore. #2593

Merged
merged 1 commit into from Dec 30, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
53 changes: 28 additions & 25 deletions src/OmniSharp.Host/Services/DotNetCliService.cs
Expand Up @@ -20,7 +20,7 @@ internal class DotNetCliService : IDotNetCliService

private readonly ILogger _logger;
private readonly IEventEmitter _eventEmitter;
private readonly ConcurrentDictionary<string, object> _locks;
private readonly ConcurrentDictionary<(string WorkingDirectory, string Arguments), Task> _restoreTasks;
private readonly SemaphoreSlim _semaphore;

public string DotNetPath { get; }
Expand All @@ -29,7 +29,7 @@ public DotNetCliService(ILoggerFactory loggerFactory, IEventEmitter eventEmitter
{
_logger = loggerFactory.CreateLogger<DotNetCliService>();
_eventEmitter = eventEmitter;
_locks = new ConcurrentDictionary<string, object>();
_restoreTasks = new();
_semaphore = new SemaphoreSlim(Environment.ProcessorCount / 2);

// Check if any of the provided paths have a dotnet executable.
Expand Down Expand Up @@ -78,39 +78,42 @@ private static void RemoveMSBuildEnvironmentVariables(IDictionary<string, string
}

public Task RestoreAsync(string workingDirectory, string arguments = null, Action onFailure = null)
{
return _restoreTasks.GetOrAdd((workingDirectory, arguments), RestoreAsync, onFailure);
}

private Task RestoreAsync((string WorkingDirectory, string Arguments) key, Action onFailure = null)
{
return Task.Factory.StartNew(() =>
{
var (workingDirectory, arguments) = key;

_logger.LogInformation($"Begin dotnet restore in '{workingDirectory}'");

var restoreLock = _locks.GetOrAdd(workingDirectory, new object());
lock (restoreLock)
var exitStatus = new ProcessExitStatus(-1);
_eventEmitter.RestoreStarted(workingDirectory);
_semaphore.Wait();
try
{
var exitStatus = new ProcessExitStatus(-1);
_eventEmitter.RestoreStarted(workingDirectory);
_semaphore.Wait();
try
{
// A successful restore will update the project lock file which is monitored
// by the dotnet project system which eventually update the Roslyn model
exitStatus = ProcessHelper.Run(DotNetPath, $"restore {arguments}", workingDirectory, updateEnvironment: RemoveMSBuildEnvironmentVariables,
outputDataReceived: (data) => _logger.LogDebug(data), errorDataReceived: (data) => _logger.LogDebug(data));
}
finally
{
_semaphore.Release();

_locks.TryRemove(workingDirectory, out _);
// A successful restore will update the project lock file which is monitored
// by the dotnet project system which eventually update the Roslyn model
exitStatus = ProcessHelper.Run(DotNetPath, $"restore {arguments}", workingDirectory, updateEnvironment: RemoveMSBuildEnvironmentVariables,
outputDataReceived: (data) => _logger.LogDebug(data), errorDataReceived: (data) => _logger.LogDebug(data));
}
finally
{
_semaphore.Release();

_eventEmitter.RestoreFinished(workingDirectory, exitStatus.Succeeded);
_restoreTasks.TryRemove(key, out _);

if (exitStatus.Failed && onFailure != null)
{
onFailure();
}
_eventEmitter.RestoreFinished(workingDirectory, exitStatus.Succeeded);

_logger.LogInformation($"Finish restoring project {workingDirectory}. Exit code {exitStatus}");
if (exitStatus.Failed && onFailure != null)
{
onFailure();
}

_logger.LogInformation($"Finish restoring project {workingDirectory}. Exit code {exitStatus}");
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/OmniSharp.MSBuild/PackageDependencyChecker.cs
Expand Up @@ -45,7 +45,7 @@ public void CheckForUnresolvedDependences(ProjectFileInfo projectFile, bool allo

if (allowAutoRestore && _options.EnablePackageAutoRestore)
{
_dotNetCli.RestoreAsync(projectFile.Directory, onFailure: () =>
_dotNetCli.RestoreAsync(projectFile.Directory, projectFile.FilePath, onFailure: () =>
{
_eventEmitter.UnresolvedDepdendencies(projectFile.FilePath, unresolvedDependencies);
});
Expand Down