Esempio n. 1
0
        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;
        }
Esempio n. 2
0
        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);
                }
            }
        }
Esempio n. 4
0
        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));
        }
Esempio n. 5
0
        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));
            }
        }