public static async Task <bool> RestoreAsync( DependencyGraphSpec dependencyGraphSpec, bool interactive, bool recursive, bool noCache, bool ignoreFailedSources, bool disableParallel, bool force, bool forceEvaluate, bool hideWarningsAndErrors, bool restorePC, bool cleanupAssetsForUnsupportedProjects, Common.ILogger log, CancellationToken cancellationToken) { if (dependencyGraphSpec == null) { throw new ArgumentNullException(nameof(dependencyGraphSpec)); } if (log == null) { throw new ArgumentNullException(nameof(log)); } try { DefaultCredentialServiceUtility.SetupDefaultCredentialService(log, !interactive); // Set connection limit NetworkProtocolUtility.SetConnectionLimit(); // Set user agent string used for network calls #if IS_CORECLR UserAgent.SetUserAgentString(new UserAgentStringBuilder("NuGet .NET Core MSBuild Task") .WithOSDescription(RuntimeInformation.OSDescription)); #else // OS description is set by default on Desktop UserAgent.SetUserAgentString(new UserAgentStringBuilder("NuGet Desktop MSBuild Task")); #endif X509TrustStore.InitializeForDotNetSdk(log); var restoreSummaries = new List <RestoreSummary>(); var providerCache = new RestoreCommandProvidersCache(); #if IS_DESKTOP if (restorePC && dependencyGraphSpec.Projects.Any(i => i.RestoreMetadata.ProjectStyle == ProjectStyle.PackagesConfig)) { var v2RestoreResult = await PerformNuGetV2RestoreAsync(log, dependencyGraphSpec, noCache, disableParallel, interactive); restoreSummaries.Add(v2RestoreResult); if (restoreSummaries.Count < 1) { var message = string.Format( Strings.InstallCommandNothingToInstall, "packages.config" ); log.LogMinimal(message); } if (!v2RestoreResult.Success) { v2RestoreResult .Errors .Where(l => l.Level == LogLevel.Warning) .ForEach(message => { log.LogWarning(message.Message); }); } } #endif using (var cacheContext = new SourceCacheContext()) { cacheContext.NoCache = noCache; cacheContext.IgnoreFailedSources = ignoreFailedSources; // Pre-loaded request provider containing the graph file var providers = new List <IPreLoadedRestoreRequestProvider>(); if (dependencyGraphSpec.Restore.Count > 0) { // Add all child projects if (recursive) { AddAllProjectsForRestore(dependencyGraphSpec); } providers.Add(new DependencyGraphSpecRequestProvider(providerCache, dependencyGraphSpec)); var restoreContext = new RestoreArgs() { CacheContext = cacheContext, LockFileVersion = LockFileFormat.Version, // 'dotnet restore' fails on slow machines (https://github.com/NuGet/Home/issues/6742) // The workaround is to pass the '--disable-parallel' option. // We apply the workaround by default when the system has 1 cpu. // This will fix restore failures on VMs with 1 CPU and containers with less or equal to 1 CPU assigned. DisableParallel = Environment.ProcessorCount == 1 ? true : disableParallel, Log = log, MachineWideSettings = new XPlatMachineWideSetting(), PreLoadedRequestProviders = providers, AllowNoOp = !force, HideWarningsAndErrors = hideWarningsAndErrors, RestoreForceEvaluate = forceEvaluate }; if (restoreContext.DisableParallel) { HttpSourceResourceProvider.Throttle = SemaphoreSlimThrottle.CreateBinarySemaphore(); } cancellationToken.ThrowIfCancellationRequested(); restoreSummaries.AddRange(await RestoreRunner.RunAsync(restoreContext, cancellationToken)); } if (cleanupAssetsForUnsupportedProjects) { // Restore assets are normally left on disk between restores for all projects. This can cause a condition where a project that supports PackageReference was restored // but then a user changes a branch or some other condition and now the project does not use PackageReference. Since the restore assets are left on disk, the build // consumes them which can cause build errors. The code below cleans up all of the files that we write so that they are not used during build Parallel.ForEach(dependencyGraphSpec.Projects.Where(i => !DoesProjectSupportRestore(i)), project => { if (project.RestoreMetadata == null || string.IsNullOrWhiteSpace(project.RestoreMetadata.OutputPath) || string.IsNullOrWhiteSpace(project.RestoreMetadata.ProjectPath)) { return; } // project.assets.json FileUtility.Delete(Path.Combine(project.RestoreMetadata.OutputPath, LockFileFormat.AssetsFileName)); // project.csproj.nuget.cache FileUtility.Delete(project.RestoreMetadata.CacheFilePath); // project.csproj.nuget.g.props FileUtility.Delete(BuildAssetsUtils.GetMSBuildFilePathForPackageReferenceStyleProject(project, BuildAssetsUtils.PropsExtension)); // project..csproj.nuget.g.targets FileUtility.Delete(BuildAssetsUtils.GetMSBuildFilePathForPackageReferenceStyleProject(project, BuildAssetsUtils.TargetsExtension)); // project.csproj.nuget.dgspec.json FileUtility.Delete(Path.Combine(project.RestoreMetadata.OutputPath, DependencyGraphSpec.GetDGSpecFileName(Path.GetFileName(project.RestoreMetadata.ProjectPath)))); }); } } if (restoreSummaries.Count < 1) { log.LogMinimal(Strings.NoProjectsToRestore); } else { RestoreSummary.Log(log, restoreSummaries); } return(restoreSummaries.All(x => x.Success)); } finally { // The CredentialService lifetime is for the duration of the process. We should not leave a potentially unavailable logger. // We need to update the delegating logger with a null instance // because the tear downs of the plugins and similar rely on idleness and process exit. DefaultCredentialServiceUtility.UpdateCredentialServiceDelegatingLogger(NullLogger.Instance); } }