예제 #1
0
        private IReadOnlyList <RestoreSummaryRequest> GetRequestsFromItems(RestoreArgs restoreContext, DependencyGraphSpec dgFile)
        {
            if (restoreContext == null)
            {
                throw new ArgumentNullException(nameof(restoreContext));
            }

            if (dgFile == null)
            {
                throw new ArgumentNullException(nameof(dgFile));
            }

            // Write the dg file to disk of the NUGET_PERSIST_DG is set.
            MSBuildRestoreUtility.PersistDGFileIfDebugging(dgFile, restoreContext.Log);

            // Validate the dg file input, this throws if errors are found.
            SpecValidationUtility.ValidateDependencySpec(dgFile);

            // Create requests
            var requests     = new List <RestoreSummaryRequest>();
            var toolRequests = new List <RestoreSummaryRequest>();

            foreach (var projectNameToRestore in dgFile.Restore)
            {
                var closure = dgFile.GetClosure(projectNameToRestore);

                var projectDependencyGraphSpec = dgFile.WithProjectClosure(projectNameToRestore);

                var externalClosure = new HashSet <ExternalProjectReference>(closure.Select(GetExternalProject));

                var rootProject = externalClosure.Single(p =>
                                                         StringComparer.Ordinal.Equals(projectNameToRestore, p.UniqueName));

                var request = Create(projectNameToRestore, rootProject, externalClosure, restoreContext, projectDgSpec: projectDependencyGraphSpec);

                if (request.Request.ProjectStyle == ProjectStyle.DotnetCliTool)
                {
                    // Store tool requests to be filtered later
                    toolRequests.Add(request);
                }
                else
                {
                    requests.Add(request);
                }
            }

            // Filter out duplicate tool restore requests
            requests.AddRange(ToolRestoreUtility.GetSubSetRequests(toolRequests));

            return(requests);
        }
예제 #2
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.
                        await MSBuildRestoreUtility.ReplayWarningsAndErrorsAsync(_request.ExistingLockFile, _logger);

                        restoreTime.Stop();

                        return new NoOpRestoreResult(
                            _success,
                            _request.ExistingLockFile,
                            _request.ExistingLockFile,
                            _request.ExistingLockFile.Path,
                            cacheFile,
                            _request.Project.RestoreMetadata.CacheFilePath,
                            _request.ProjectStyle,
                            restoreTime.Elapsed);
                    }
                }
            }

            // 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);
        }
예제 #3
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));
            }
        }