private async Task RestorePackageSpecProjectsAsync( List <IDependencyGraphProject> projects, bool forceRestore, bool isSolutionAvailable, RestoreOperationSource restoreSource, CancellationToken token) { // Only continue if there are some build integrated type projects. if (!(projects.Any(project => project is BuildIntegratedNuGetProject))) { return; } if (_packageRestoreConsent.IsGranted) { if (!isSolutionAvailable) { var globalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(_settings); if (!Path.IsPathRooted(globalPackagesFolder)) { await _logger.DoAsync((l, _) => { var message = string.Format( CultureInfo.CurrentCulture, Resources.RelativeGlobalPackagesFolder, globalPackagesFolder); l.WriteLine(VerbosityLevel.Quiet, message); }); // Cannot restore packages since globalPackagesFolder is a relative path // and the solution is not available return; } } // Cache p2ps discovered from DTE var cacheContext = new DependencyGraphCacheContext(_logger, _settings); var pathContext = NuGetPathContext.Create(_settings); // Get full dg spec // TODO: pass this down instead of creating it twice. var dgSpec = await DependencyGraphRestoreUtility.GetSolutionRestoreSpec(_solutionManager, cacheContext); // Avoid restoring solutions with zero potential PackageReference projects. if (DependencyGraphRestoreUtility.IsRestoreRequired(dgSpec)) { // NOTE: During restore for build integrated projects, // We might show the dialog even if there are no packages to restore // When both currentStep and totalSteps are 0, we get a marquee on the dialog await _logger.RunWithProgressAsync( async (l, _, t) => { // Display the restore opt out message if it has not been shown yet await l.WriteHeaderAsync(); var sources = _sourceRepositoryProvider .GetRepositories() .ToList(); var providerCache = new RestoreCommandProvidersCache(); Action <SourceCacheContext> cacheModifier = (cache) => { }; var restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( _solutionManager, cacheContext, providerCache, cacheModifier, sources, forceRestore, dgSpec, l, t); _packageCount += restoreSummaries.Select(summary => summary.InstallCount).Sum(); var isRestoreFailed = restoreSummaries.Any(summary => summary.Success == false); _noOpProjectsCount = restoreSummaries.Where(summary => summary.NoOpRestore == true).Count(); if (isRestoreFailed) { _status = NuGetOperationStatus.Failed; } else if (_noOpProjectsCount < restoreSummaries.Count) { _status = NuGetOperationStatus.Succeeded; } }, token); } } else if (restoreSource == RestoreOperationSource.Explicit) { // Log an error when restore is disabled and user explicitly restore. await _logger.DoAsync((l, _) => { l.ShowError(Resources.PackageRefNotRestoredBecauseOfNoConsent); }); } }
private async Task RestorePackageSpecProjectsAsync( List <IDependencyGraphProject> projects, bool forceRestore, bool isSolutionAvailable, RestoreOperationSource restoreSource, IntervalTracker intervalTracker, CancellationToken token) { // Only continue if there are some build integrated type projects. if (!(projects.Any(project => project is BuildIntegratedNuGetProject))) { return; } if (_packageRestoreConsent.IsGranted) { if (!isSolutionAvailable) { var globalPackagesFolder = SettingsUtility.GetGlobalPackagesFolder(_settings); if (!Path.IsPathRooted(globalPackagesFolder)) { var message = string.Format( CultureInfo.CurrentCulture, Resources.RelativeGlobalPackagesFolder, globalPackagesFolder); await _logger.WriteLineAsync(VerbosityLevel.Quiet, message); // Cannot restore packages since globalPackagesFolder is a relative path // and the solution is not available return; } } DependencyGraphCacheContext cacheContext; DependencyGraphSpec originalDgSpec; DependencyGraphSpec dgSpec; IReadOnlyList <IAssetsLogMessage> additionalMessages; using (intervalTracker.Start(RestoreTelemetryEvent.SolutionDependencyGraphSpecCreation)) { // Cache p2ps discovered from DTE cacheContext = new DependencyGraphCacheContext(_logger, _settings); var pathContext = NuGetPathContext.Create(_settings); // Get full dg spec (originalDgSpec, additionalMessages) = await DependencyGraphRestoreUtility.GetSolutionRestoreSpecAndAdditionalMessages(_solutionManager, cacheContext); } using (intervalTracker.Start(RestoreTelemetryEvent.SolutionUpToDateCheck)) { // Run solution based up to date check. var projectsNeedingRestore = _solutionUpToDateChecker.PerformUpToDateCheck(originalDgSpec, _logger).AsList(); var specialReferencesCount = originalDgSpec.Projects .Where(x => x.RestoreMetadata.ProjectStyle != ProjectStyle.PackageReference && x.RestoreMetadata.ProjectStyle != ProjectStyle.PackagesConfig && x.RestoreMetadata.ProjectStyle != ProjectStyle.ProjectJson) .Count(); dgSpec = originalDgSpec; // Only use the optimization results if the restore is not `force`. // Still run the optimization check anyways to prep the cache. if (!forceRestore) { // Update the dg spec. dgSpec = originalDgSpec.WithoutRestores(); foreach (var uniqueProjectId in projectsNeedingRestore) { dgSpec.AddRestore(uniqueProjectId); // Fill DGSpec copy only with restore-needed projects } // Calculate the number of up to date projects _upToDateProjectCount = originalDgSpec.Restore.Count - specialReferencesCount - projectsNeedingRestore.Count; _noOpProjectsCount = _upToDateProjectCount; } } using (intervalTracker.Start(RestoreTelemetryEvent.PackageReferenceRestoreDuration)) { // Avoid restoring if all the projects are up to date, or the solution does not have build integrated projects. if (DependencyGraphRestoreUtility.IsRestoreRequired(dgSpec)) { // NOTE: During restore for build integrated projects, // We might show the dialog even if there are no packages to restore // When both currentStep and totalSteps are 0, we get a marquee on the dialog await _logger.RunWithProgressAsync( async (l, _, t) => { // Display the restore opt out message if it has not been shown yet await l.WriteHeaderAsync(); var sources = _sourceRepositoryProvider .GetRepositories() .ToList(); var providerCache = new RestoreCommandProvidersCache(); Action <SourceCacheContext> cacheModifier = (cache) => { }; var isRestoreOriginalAction = true; var isRestoreSucceeded = true; IReadOnlyList <RestoreSummary> restoreSummaries = null; try { restoreSummaries = await DependencyGraphRestoreUtility.RestoreAsync( _solutionManager, dgSpec, cacheContext, providerCache, cacheModifier, sources, _nuGetProjectContext.OperationId, forceRestore, isRestoreOriginalAction, additionalMessages, l, t); _packageCount += restoreSummaries.Select(summary => summary.InstallCount).Sum(); isRestoreSucceeded = restoreSummaries.All(summary => summary.Success == true); _noOpProjectsCount += restoreSummaries.Where(summary => summary.NoOpRestore == true).Count(); _solutionUpToDateChecker.SaveRestoreStatus(restoreSummaries); } catch { isRestoreSucceeded = false; throw; } finally { if (isRestoreSucceeded) { if (_noOpProjectsCount < restoreSummaries.Count) { _status = NuGetOperationStatus.Succeeded; } else { _status = NuGetOperationStatus.NoOp; } } else { _status = NuGetOperationStatus.Failed; } } }, token); } } } else if (restoreSource == RestoreOperationSource.Explicit) { await _logger.ShowErrorAsync(Resources.PackageRefNotRestoredBecauseOfNoConsent); } }