public void ApplyStandardProperties(RestoreRequest request) { request.PackageSaveMode = PackageSaveMode; if (request.ProjectStyle == ProjectStyle.PackageReference || request.ProjectStyle == ProjectStyle.DotnetToolReference || request.ProjectStyle == ProjectStyle.Standalone) { request.LockFilePath = Path.Combine(request.RestoreOutputPath, LockFileFormat.AssetsFileName); } else if (request.ProjectStyle != ProjectStyle.DotnetCliTool) { request.LockFilePath = ProjectJsonPathUtilities.GetLockFilePath(request.Project.FilePath); } if (request.Project.RestoreMetadata?.CacheFilePath == null) { request.Project.RestoreMetadata.CacheFilePath = NoOpRestoreUtilities.GetCacheFilePath(request); } request.MaxDegreeOfConcurrency = DisableParallel ? 1 : RestoreRequest.DefaultDegreeOfConcurrency; request.RequestedRuntimes.UnionWith(Runtimes); request.FallbackRuntimes.UnionWith(FallbackRuntimes); if (IsLowercaseGlobalPackagesFolder.HasValue) { request.IsLowercasePackagesDirectory = IsLowercaseGlobalPackagesFolder.Value; } if (LockFileVersion.HasValue && LockFileVersion.Value > 0) { request.LockFileVersion = LockFileVersion.Value; } // Run runtime asset checks for project.json, and for other types if enabled. if (ValidateRuntimeAssets == null) { if (request.ProjectStyle == ProjectStyle.ProjectJson || request.Project.RestoreMetadata == null) { request.ValidateRuntimeAssets = request.ProjectStyle == ProjectStyle.ProjectJson; } else { request.ValidateRuntimeAssets = request.Project.RestoreMetadata.ValidateRuntimeAssets; } } else { request.ValidateRuntimeAssets = ValidateRuntimeAssets.Value; } request.AllowNoOp = !request.CacheContext.NoCache && AllowNoOp; request.HideWarningsAndErrors = HideWarningsAndErrors; request.ParentId = ParentId; request.IsRestoreOriginalAction = IsRestoreOriginalAction; request.ReevaluateRestoreGraph = ReevaluateRestoreGraph; }
private KeyValuePair <CacheFile, bool> EvaluateCacheFile() { CacheFile cacheFile; var noOp = false; var newDgSpecHash = NoOpRestoreUtilities.GetHash(_request); if (_request.ProjectStyle == ProjectStyle.DotnetCliTool && _request.AllowNoOp) { // No need to attempt to resolve the tool if no-op is not allowed. NoOpRestoreUtilities.UpdateRequestBestMatchingToolPathsIfAvailable(_request); } if (_request.AllowNoOp && File.Exists(_request.Project.RestoreMetadata.CacheFilePath)) { cacheFile = FileUtility.SafeRead(_request.Project.RestoreMetadata.CacheFilePath, (stream, path) => CacheFileFormat.Read(stream, _logger, path)); if (cacheFile.IsValid && StringComparer.Ordinal.Equals(cacheFile.DgSpecHash, newDgSpecHash)) { _logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_RestoreNoOpFinish, _request.Project.Name)); _success = true; noOp = true; } else { cacheFile = new CacheFile(newDgSpecHash); _logger.LogVerbose(string.Format(CultureInfo.CurrentCulture, Strings.Log_RestoreNoOpDGChanged, _request.Project.Name)); } } else { cacheFile = new CacheFile(newDgSpecHash); } if (_request.ProjectStyle == ProjectStyle.DotnetCliTool) { if (noOp) // Only if the hash matches, then load the lock file. This is a performance hit, so we need to delay it as much as possible. { _request.ExistingLockFile = LockFileUtilities.GetLockFile(_request.LockFilePath, _logger); } else { // Clean up to preserve the pre no-op behavior. This should not be used, but we want to be cautious. _request.LockFilePath = null; _request.Project.RestoreMetadata.CacheFilePath = null; } } return(new KeyValuePair <CacheFile, bool>(cacheFile, noOp)); }
/// <summary> /// This method will resolve the cache/lock file paths for the tool if available in the cache /// This method will set the CacheFilePath and the LockFilePath in the RestoreMetadat if a matching tool is available /// </summary> public static void UpdateRequestBestMatchingToolPathsIfAvailable(RestoreRequest request) { if (request.ProjectStyle == ProjectStyle.DotnetCliTool) { // Resolve the lock file path if it exists var toolPathResolver = new ToolPathResolver(request.PackagesDirectory); var toolDirectory = toolPathResolver.GetBestToolDirectoryPath( ToolRestoreUtility.GetToolIdOrNullFromSpec(request.Project), request.Project.TargetFrameworks.First().Dependencies.First().LibraryRange.VersionRange, request.Project.TargetFrameworks.SingleOrDefault().FrameworkName); if (toolDirectory != null) // Only set the paths if a good enough match was found. { request.Project.RestoreMetadata.CacheFilePath = NoOpRestoreUtilities.GetToolCacheFilePath(toolDirectory, ToolRestoreUtility.GetToolIdOrNullFromSpec(request.Project)); request.LockFilePath = toolPathResolver.GetLockFilePath(toolDirectory); } } }
public async Task <RestoreResult> ExecuteAsync(CancellationToken token) { var restoreTime = Stopwatch.StartNew(); // Local package folders (non-sources) var localRepositories = new List <NuGetv3LocalRepository> { _request.DependencyProviders.GlobalPackages }; localRepositories.AddRange(_request.DependencyProviders.FallbackPackageFolders); var contextForProject = CreateRemoteWalkContext(_request, _logger); CacheFile cacheFile = null; if (NoOpRestoreUtilities.IsNoOpSupported(_request)) { var cacheFileAndStatus = EvaluateCacheFile(); cacheFile = cacheFileAndStatus.Key; if (cacheFileAndStatus.Value) { if (NoOpRestoreUtilities.VerifyAssetsAndMSBuildFilesAndPackagesArePresent(_request)) { // Replay Warnings and Errors from an existing lock file in case of a no-op. ReplayWarningsAndErrors(); restoreTime.Stop(); return(new NoOpRestoreResult( _success, _request.ExistingLockFile, _request.ExistingLockFile, _request.ExistingLockFile.Path, cacheFile, _request.Project.RestoreMetadata.CacheFilePath, _request.ProjectStyle, restoreTime.Elapsed)); } } } // Validate, for noop this will be replayed from the assets file. _success &= await ValidateProjectAsync(_request.Project, _logger); // Restore var graphs = await ExecuteRestoreAsync( _request.DependencyProviders.GlobalPackages, _request.DependencyProviders.FallbackPackageFolders, contextForProject, token); // Create assets file var assetsFile = BuildAssetsFile( _request.ExistingLockFile, _request.Project, graphs, localRepositories, contextForProject); _success &= await ValidateRestoreGraphsAsync(graphs, _logger); // Check package compatibility var checkResults = await VerifyCompatibilityAsync( _request.Project, _includeFlagGraphs, localRepositories, assetsFile, graphs, _request.ValidateRuntimeAssets, _logger); if (checkResults.Any(r => !r.Success)) { _success = false; } // Determine the lock file output path var assetsFilePath = GetAssetsFilePath(assetsFile); // Determine the cache file output path var cacheFilePath = NoOpRestoreUtilities.GetCacheFilePath(_request, assetsFile); // Tool restores are unique since the output path is not known until after restore if (_request.LockFilePath == null && _request.ProjectStyle == ProjectStyle.DotnetCliTool) { _request.LockFilePath = assetsFilePath; } // Generate Targets/Props files var msbuildOutputFiles = Enumerable.Empty <MSBuildOutputFile>(); if (contextForProject.IsMsBuildBased) { msbuildOutputFiles = BuildAssetsUtils.GetMSBuildOutputFiles( _request.Project, assetsFile, graphs, localRepositories, _request, assetsFilePath, _success, _logger); } // If the request is for a lower lock file version, downgrade it appropriately DowngradeLockFileIfNeeded(assetsFile); // Revert to the original case if needed await FixCaseForLegacyReaders(graphs, assetsFile, token); // Write the logs into the assets file var logs = _logger.Errors .Select(l => AssetsLogMessage.Create(l)) .ToList(); _success &= !logs.Any(l => l.Level == LogLevel.Error); assetsFile.LogMessages = logs; if (cacheFile != null) { cacheFile.Success = _success; } restoreTime.Stop(); // Create result return(new RestoreResult( _success, graphs, checkResults, msbuildOutputFiles, assetsFile, _request.ExistingLockFile, assetsFilePath, cacheFile, cacheFilePath, _request.ProjectStyle, restoreTime.Elapsed)); }
public async Task <RestoreResult> ExecuteAsync(CancellationToken token) { using (var telemetry = TelemetryActivity.CreateTelemetryActivityWithNewOperationIdAndEvent(parentId: ParentId, eventName: ProjectRestoreInformation)) { _operationId = telemetry.OperationId; var restoreTime = Stopwatch.StartNew(); // Local package folders (non-sources) var localRepositories = new List <NuGetv3LocalRepository> { _request.DependencyProviders.GlobalPackages }; localRepositories.AddRange(_request.DependencyProviders.FallbackPackageFolders); var contextForProject = CreateRemoteWalkContext(_request, _logger); CacheFile cacheFile = null; using (var noOpTelemetry = TelemetryActivity.CreateTelemetryActivityWithNewOperationIdAndEvent(parentId: _operationId, eventName: RestoreNoOpInformation)) { if (NoOpRestoreUtilities.IsNoOpSupported(_request)) { noOpTelemetry.StartIntervalMeasure(); var cacheFileAndStatus = EvaluateCacheFile(); noOpTelemetry.EndIntervalMeasure(CacheFileEvaluateDuration); cacheFile = cacheFileAndStatus.Key; if (cacheFileAndStatus.Value) { noOpTelemetry.StartIntervalMeasure(); var noOpSuccess = NoOpRestoreUtilities.VerifyAssetsAndMSBuildFilesAndPackagesArePresent(_request); noOpTelemetry.EndIntervalMeasure(MsbuildAssetsVerificationDuration); noOpTelemetry.TelemetryEvent[MsbuildAssetsVerificationResult] = noOpSuccess; if (noOpSuccess) { noOpTelemetry.StartIntervalMeasure(); // Replay Warnings and Errors from an existing lock file in case of a no-op. await MSBuildRestoreUtility.ReplayWarningsAndErrorsAsync(_request.ExistingLockFile, _logger); noOpTelemetry.EndIntervalMeasure(ReplayLogsDuration); restoreTime.Stop(); return(new NoOpRestoreResult( _success, _request.ExistingLockFile, _request.ExistingLockFile, _request.ExistingLockFile.Path, cacheFile, _request.Project.RestoreMetadata.CacheFilePath, _request.ProjectStyle, restoreTime.Elapsed)); } } } } IEnumerable <RestoreTargetGraph> graphs = null; using (var restoreGraphTelemetry = TelemetryActivity.CreateTelemetryActivityWithNewOperationIdAndEvent(parentId: _operationId, eventName: GenerateRestoreGraph)) { // Restore graphs = await ExecuteRestoreAsync( _request.DependencyProviders.GlobalPackages, _request.DependencyProviders.FallbackPackageFolders, contextForProject, token, restoreGraphTelemetry); } LockFile assetsFile = null; using (TelemetryActivity.CreateTelemetryActivityWithNewOperationIdAndEvent(parentId: _operationId, eventName: GenerateAssetsFile)) { // Create assets file assetsFile = BuildAssetsFile( _request.ExistingLockFile, _request.Project, graphs, localRepositories, contextForProject); } IList <CompatibilityCheckResult> checkResults = null; using (TelemetryActivity.CreateTelemetryActivityWithNewOperationIdAndEvent(parentId: _operationId, eventName: ValidateRestoreGraphs)) { _success &= await ValidateRestoreGraphsAsync(graphs, _logger); // Check package compatibility checkResults = await VerifyCompatibilityAsync( _request.Project, _includeFlagGraphs, localRepositories, assetsFile, graphs, _request.ValidateRuntimeAssets, _logger); if (checkResults.Any(r => !r.Success)) { _success = false; } } // Generate Targets/Props files var msbuildOutputFiles = Enumerable.Empty <MSBuildOutputFile>(); string assetsFilePath = null; string cacheFilePath = null; using (TelemetryActivity.CreateTelemetryActivityWithNewOperationIdAndEvent(parentId: _operationId, eventName: CreateRestoreResult)) { // Determine the lock file output path assetsFilePath = GetAssetsFilePath(assetsFile); // Determine the cache file output path cacheFilePath = NoOpRestoreUtilities.GetCacheFilePath(_request, assetsFile); // Tool restores are unique since the output path is not known until after restore if (_request.LockFilePath == null && _request.ProjectStyle == ProjectStyle.DotnetCliTool) { _request.LockFilePath = assetsFilePath; } if (contextForProject.IsMsBuildBased) { msbuildOutputFiles = BuildAssetsUtils.GetMSBuildOutputFiles( _request.Project, assetsFile, graphs, localRepositories, _request, assetsFilePath, _success, _logger); } // If the request is for a lower lock file version, downgrade it appropriately DowngradeLockFileIfNeeded(assetsFile); // Revert to the original case if needed await FixCaseForLegacyReaders(graphs, assetsFile, token); // Write the logs into the assets file var logs = _logger.Errors .Select(l => AssetsLogMessage.Create(l)) .ToList(); _success &= !logs.Any(l => l.Level == LogLevel.Error); assetsFile.LogMessages = logs; if (cacheFile != null) { cacheFile.Success = _success; } var errorCodes = ConcatAsString(new HashSet <NuGetLogCode>(logs.Where(l => l.Level == LogLevel.Error).Select(l => l.Code))); var warningCodes = ConcatAsString(new HashSet <NuGetLogCode>(logs.Where(l => l.Level == LogLevel.Warning).Select(l => l.Code))); if (!string.IsNullOrEmpty(errorCodes)) { telemetry.TelemetryEvent[ErrorCodes] = errorCodes; } if (!string.IsNullOrEmpty(warningCodes)) { telemetry.TelemetryEvent[WarningCodes] = warningCodes; } telemetry.TelemetryEvent[RestoreSuccess] = _success; } restoreTime.Stop(); // Create result return(new RestoreResult( _success, graphs, checkResults, msbuildOutputFiles, assetsFile, _request.ExistingLockFile, assetsFilePath, cacheFile, cacheFilePath, _request.ProjectStyle, restoreTime.Elapsed)); } }