public SolutionRestoreRequest(
     bool forceRestore,
     RestoreOperationSource restoreSource)
 {
     ForceRestore  = forceRestore;
     RestoreSource = restoreSource;
 }
        private void EmitRestoreTelemetryEvent(IEnumerable <NuGetProject> projects,
                                               bool forceRestore,
                                               RestoreOperationSource source,
                                               DateTimeOffset startTime,
                                               double duration,
                                               PackageSourceTelemetry.Totals protocolDiagnosticTotals,
                                               IntervalTracker intervalTimingTracker)
        {
            var sortedProjects = projects.OrderBy(
                project => project.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName));
            var projectIds = sortedProjects.Select(
                project => project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId)).ToArray();

            var restoreTelemetryEvent = new RestoreTelemetryEvent(
                _nuGetProjectContext.OperationId.ToString(),
                projectIds,
                forceRestore,
                source,
                startTime,
                _status,
                packageCount: _packageCount,
                noOpProjectsCount: _noOpProjectsCount,
                upToDateProjectsCount: _upToDateProjectCount,
                DateTimeOffset.Now,
                duration,
                isSolutionLoadRestore: _isSolutionLoadRestore,
                intervalTimingTracker);

            TelemetryActivity.EmitTelemetryEvent(restoreTelemetryEvent);

            var sources     = _sourceRepositoryProvider.PackageSourceProvider.LoadPackageSources().ToList();
            var sourceEvent = SourceTelemetry.GetRestoreSourceSummaryEvent(_nuGetProjectContext.OperationId, sources, protocolDiagnosticTotals);

            TelemetryActivity.EmitTelemetryEvent(sourceEvent);
        }
        public RestoreTelemetryEvent(
            string operationId,
            string[] projectIds,
            bool forceRestore,
            RestoreOperationSource source,
            DateTimeOffset startTime,
            NuGetOperationStatus status,
            int packageCount,
            int noOpProjectsCount,
            int upToDateProjectsCount,
            DateTimeOffset endTime,
            double duration,
            bool isSolutionLoadRestore,
            IntervalTracker intervalTimingTracker) : base(RestoreActionEventName, operationId, projectIds, startTime, status, packageCount, endTime, duration)
        {
            base[nameof(OperationSource)]       = source;
            base[nameof(NoOpProjectsCount)]     = noOpProjectsCount;
            base[nameof(UpToDateProjectCount)]  = upToDateProjectsCount;
            base[nameof(ForceRestore)]          = forceRestore;
            base[nameof(IsSolutionLoadRestore)] = isSolutionLoadRestore;

            foreach (var(intervalName, intervalDuration) in intervalTimingTracker.GetIntervals())
            {
                base[intervalName] = intervalDuration;
            }
        }
Esempio n. 4
0
        private void EmitRestoreTelemetryEvent(IEnumerable <NuGetProject> projects,
                                               RestoreOperationSource source,
                                               DateTimeOffset startTime,
                                               double duration)
        {
            var sortedProjects = projects.OrderBy(
                project => project.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName));
            var projectIds = sortedProjects.Select(
                project => project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId)).ToArray();

            var restoreTelemetryEvent = new RestoreTelemetryEvent(
                _nuGetProjectContext.OperationId.ToString(),
                projectIds,
                source,
                startTime,
                _status,
                _packageCount,
                _noOpProjectsCount,
                DateTimeOffset.Now,
                duration);

            TelemetryActivity.EmitTelemetryEvent(restoreTelemetryEvent);

            var sources     = _sourceRepositoryProvider.PackageSourceProvider.LoadPackageSources().ToList();
            var sourceEvent = SourceTelemetry.GetRestoreSourceSummaryEvent(_nuGetProjectContext.OperationId, sources);

            TelemetryActivity.EmitTelemetryEvent(sourceEvent);
        }
        public void RestoreTelemetryService_EmitRestoreEvent_OperationSucceed(RestoreOperationSource source, NuGetOperationStatus status)
        {
            // Arrange
            var            telemetrySession   = new Mock <ITelemetrySession>();
            TelemetryEvent lastTelemetryEvent = null;

            telemetrySession
            .Setup(x => x.PostEvent(It.IsAny <TelemetryEvent>()))
            .Callback <TelemetryEvent>(x => lastTelemetryEvent = x);

            string operationId = Guid.NewGuid().ToString();

            var stausMessage         = status == NuGetOperationStatus.Failed ? "Operation Failed" : string.Empty;
            var restoreTelemetryData = new RestoreTelemetryEvent(
                operationId: operationId,
                projectIds: new[] { Guid.NewGuid().ToString() },
                source: source,
                startTime: DateTimeOffset.Now.AddSeconds(-3),
                status: status,
                packageCount: 2,
                endTime: DateTimeOffset.Now,
                duration: 2.10);
            var service = new RestoreTelemetryService(telemetrySession.Object);

            // Act
            service.EmitRestoreEvent(restoreTelemetryData);

            // Assert
            VerifyTelemetryEventData(restoreTelemetryData, lastTelemetryEvent);
        }
 public SolutionRestoreRequest(
     bool forceRestore,
     RestoreOperationSource restoreSource,
     ExplicitRestoreReason explicitRestoreReason)
 {
     ForceRestore          = forceRestore;
     RestoreSource         = restoreSource;
     ExplicitRestoreReason = explicitRestoreReason;
 }
Esempio n. 7
0
        public async Task StartAsync(
            RestoreOperationSource operationSource,
            Lazy <ErrorListTableDataSource> errorListDataSource,
            JoinableTaskFactory jtf,
            CancellationTokenSource cts)
        {
            Assumes.Present(errorListDataSource);
            Assumes.Present(jtf);
            Assumes.Present(cts);

            _operationSource     = operationSource;
            _errorListDataSource = errorListDataSource;

            _jtc         = jtf.Context.CreateCollection();
            _taskFactory = jtf.Context.CreateFactory(_jtc);

            _externalCts = cts;
            _externalCts.Token.Register(() => _cancelled = true);

#if VS14
            _progressFactory = t => WaitDialogProgress.StartAsync(_serviceProvider, _taskFactory, t);
#else
            _progressFactory = t => StatusBarProgress.StartAsync(_serviceProvider, _taskFactory, t);
#endif

            await _taskFactory.RunAsync(async() =>
            {
                await _taskFactory.SwitchToMainThreadAsync();

                OutputVerbosity = GetMSBuildOutputVerbositySetting();

                switch (_operationSource)
                {
                case RestoreOperationSource.Implicit:     // background auto-restore
                    _outputConsole = _outputConsoleProvider.CreatePackageManagerConsole();
                    break;

                case RestoreOperationSource.OnBuild:
                    _outputConsole = _outputConsoleProvider.CreateBuildOutputConsole();
                    _outputConsole.Activate();
                    break;

                case RestoreOperationSource.Explicit:
                    _outputConsole = _outputConsoleProvider.CreatePackageManagerConsole();
                    _outputConsole.Activate();
                    _outputConsole.Clear();
                    break;
                }
            });

            if (_errorListDataSource.IsValueCreated)
            {
                // Clear old entries
                _errorListDataSource.Value.ClearNuGetEntries();
            }
        }
Esempio n. 8
0
        public RestoreTelemetryEvent(
            string operationId,
            string[] projectIds,
            bool forceRestore,
            RestoreOperationSource source,
            DateTimeOffset startTime,
            NuGetOperationStatus status,
            int packageCount,
            int noOpProjectsCount,
            int upToDateProjectsCount,
            int unknownProjectsCount,
            int projectJsonProjectsCount,
            int packageReferenceProjectsCount,
            int legacyPackageReferenceProjectsCount,
            int cpsPackageReferenceProjectsCount,
            int dotnetCliToolProjectsCount,
            int packagesConfigProjectsCount,
            DateTimeOffset endTime,
            double duration,
            IDictionary <string, object> additionalTrackingData,
            IntervalTracker intervalTimingTracker,
            bool isPackageSourceMappingEnabled,
            int httpFeedsCount,
            int localFeedsCount,
            bool hasNuGetOrg,
            bool hasVSOfflineFeed
            ) : base(RestoreActionEventName, operationId, projectIds, startTime, status, packageCount, endTime, duration)
        {
            base[nameof(OperationSource)]                     = source;
            base[nameof(NoOpProjectsCount)]                   = noOpProjectsCount;
            base[nameof(UpToDateProjectCount)]                = upToDateProjectsCount;
            base[nameof(UnknownProjectsCount)]                = unknownProjectsCount;
            base[nameof(ProjectJsonProjectsCount)]            = projectJsonProjectsCount;
            base[nameof(PackageReferenceProjectsCount)]       = packageReferenceProjectsCount;
            base[nameof(LegacyPackageReferenceProjectsCount)] = legacyPackageReferenceProjectsCount;
            base[nameof(CpsPackageReferenceProjectsCount)]    = cpsPackageReferenceProjectsCount;
            base[nameof(DotnetCliToolProjectsCount)]          = dotnetCliToolProjectsCount;
            base[nameof(PackagesConfigProjectsCount)]         = packagesConfigProjectsCount;
            base[nameof(ForceRestore)] = forceRestore;
            base[PackageSourceMappingIsMappingEnabled] = isPackageSourceMappingEnabled;
            base[NumHTTPFeeds]      = httpFeedsCount;
            base[NumLocalFeeds]     = localFeedsCount;
            base[NuGetOrg]          = hasNuGetOrg;
            base[VsOfflinePackages] = hasVSOfflineFeed;

            foreach (KeyValuePair <string, object> data in additionalTrackingData)
            {
                base[data.Key] = data.Value;
            }

            foreach (var(intervalName, intervalDuration) in intervalTimingTracker.GetIntervals())
            {
                base[intervalName] = intervalDuration;
            }
        }
Esempio n. 9
0
 public RestoreTelemetryEvent(
     string operationId,
     string[] projectIds,
     RestoreOperationSource source,
     DateTimeOffset startTime,
     NuGetOperationStatus status,
     int packageCount,
     DateTimeOffset endTime,
     double duration) : base(operationId, projectIds, startTime, status, packageCount, endTime, duration)
 {
     Source = source;
 }
Esempio n. 10
0
 public RestoreTelemetryEvent(
     string[] projectIds,
     RestoreOperationSource source,
     DateTimeOffset startTime,
     NuGetOperationStatus status,
     int packageCount,
     int noOpProjectsCount,
     DateTimeOffset endTime,
     double duration) : base(RestoreActionEventName, projectIds, startTime, status, packageCount, endTime, duration)
 {
     base[nameof(OperationSource)]     = source;
     base[(nameof(NoOpProjectsCount))] = noOpProjectsCount;
 }
Esempio n. 11
0
        public async Task StartAsync(
            RestoreOperationSource operationSource,
            Lazy <INuGetErrorList> errorList,
            JoinableTaskFactory jtf,
            CancellationTokenSource cts)
        {
            Assumes.Present(errorList);
            Assumes.Present(jtf);
            Assumes.Present(cts);

            _operationSource = operationSource;
            _errorList       = errorList;

            _jtc         = jtf.Context.CreateCollection();
            _taskFactory = jtf.Context.CreateFactory(_jtc);

            _externalCts = cts;
            _externalCts.Token.Register(() => _cancelled = true);

            _progressFactory = t => StatusBarProgress.StartAsync(_asyncServiceProvider, _taskFactory, t);

            await _taskFactory.RunAsync(async() =>
            {
                OutputVerbosity = await GetMSBuildOutputVerbositySettingAsync();

                switch (_operationSource)
                {
                case RestoreOperationSource.Implicit:     // background auto-restore
                    _outputConsole = await _outputConsoleProvider.Value.CreatePackageManagerConsoleAsync();
                    break;

                case RestoreOperationSource.OnBuild:
                    _outputConsole = await _outputConsoleProvider.Value.CreateBuildOutputConsoleAsync();
                    await _outputConsole.ActivateAsync();
                    break;

                case RestoreOperationSource.Explicit:
                    _outputConsole = await _outputConsoleProvider.Value.CreatePackageManagerConsoleAsync();
                    await _outputConsole.ActivateAsync();
                    await _outputConsole.ClearAsync();
                    break;
                }
            });

            if (_errorList.IsValueCreated)
            {
                // Clear old entries
                _errorList.Value.ClearNuGetEntries();
            }
        }
Esempio n. 12
0
        private void EmitRestoreTelemetryEvent(IEnumerable <NuGetProject> projects,
                                               bool forceRestore,
                                               RestoreOperationSource source,
                                               DateTimeOffset startTime,
                                               double duration,
                                               PackageSourceTelemetry.Totals protocolDiagnosticTotals,
                                               IntervalTracker intervalTimingTracker)
        {
            var sortedProjects = projects.OrderBy(
                project => project.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName));
            var projectIds = sortedProjects.Select(
                project => project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId)).ToArray();
            var projectDictionary = sortedProjects
                                    .GroupBy(x => x.ProjectStyle)
                                    .ToDictionary(x => x.Key, y => y.Count());

            var  packageSourceMapping          = PackageSourceMapping.GetPackageSourceMapping(_settings);
            bool isPackageSourceMappingEnabled = packageSourceMapping?.IsEnabled ?? false;

            var restoreTelemetryEvent = new RestoreTelemetryEvent(
                _nuGetProjectContext.OperationId.ToString(),
                projectIds,
                forceRestore,
                source,
                startTime,
                _status,
                packageCount: _packageCount,
                noOpProjectsCount: _noOpProjectsCount,
                upToDateProjectsCount: _upToDateProjectCount,
                unknownProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.Unknown, 0), // appears in DependencyGraphRestoreUtility
                projectJsonProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.ProjectJson, 0),
                packageReferenceProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.PackageReference, 0),
                legacyPackageReferenceProjectsCount: sortedProjects.Where(x => x.ProjectStyle == ProjectStyle.PackageReference && x is LegacyPackageReferenceProject).Count(),
                cpsPackageReferenceProjectsCount: sortedProjects.Where(x => x.ProjectStyle == ProjectStyle.PackageReference && x is CpsPackageReferenceProject).Count(),
                dotnetCliToolProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.DotnetCliTool, 0), // appears in DependencyGraphRestoreUtility
                packagesConfigProjectsCount: projectDictionary.GetValueOrDefault(ProjectStyle.PackagesConfig, 0),
                DateTimeOffset.Now,
                duration,
                _trackingData,
                intervalTimingTracker,
                isPackageSourceMappingEnabled);

            TelemetryActivity.EmitTelemetryEvent(restoreTelemetryEvent);

            var sources     = _sourceRepositoryProvider.PackageSourceProvider.LoadPackageSources().ToList();
            var sourceEvent = SourceTelemetry.GetRestoreSourceSummaryEvent(_nuGetProjectContext.OperationId, sources, protocolDiagnosticTotals);

            TelemetryActivity.EmitTelemetryEvent(sourceEvent);
        }
Esempio n. 13
0
        public RestoreTelemetryEvent(
            string operationId,
            string[] projectIds,
            bool forceRestore,
            RestoreOperationSource source,
            DateTimeOffset startTime,
            NuGetOperationStatus status,
            int packageCount,
            int noOpProjectsCount,
            int upToDateProjectsCount,
            int unknownProjectsCount,
            int projectJsonProjectsCount,
            int packageReferenceProjectsCount,
            int legacyPackageReferenceProjectsCount,
            int cpsPackageReferenceProjectsCount,
            int dotnetCliToolProjectsCount,
            int packagesConfigProjectsCount,
            DateTimeOffset endTime,
            double duration,
            bool isSolutionLoadRestore,
            IntervalTracker intervalTimingTracker) : base(RestoreActionEventName, operationId, projectIds, startTime, status, packageCount, endTime, duration)
        {
            base[nameof(OperationSource)]                     = source;
            base[nameof(NoOpProjectsCount)]                   = noOpProjectsCount;
            base[nameof(UpToDateProjectCount)]                = upToDateProjectsCount;
            base[nameof(UnknownProjectsCount)]                = unknownProjectsCount;
            base[nameof(ProjectJsonProjectsCount)]            = projectJsonProjectsCount;
            base[nameof(PackageReferenceProjectsCount)]       = packageReferenceProjectsCount;
            base[nameof(LegacyPackageReferenceProjectsCount)] = legacyPackageReferenceProjectsCount;
            base[nameof(CpsPackageReferenceProjectsCount)]    = cpsPackageReferenceProjectsCount;
            base[nameof(DotnetCliToolProjectsCount)]          = dotnetCliToolProjectsCount;
            base[nameof(PackagesConfigProjectsCount)]         = packagesConfigProjectsCount;
            base[nameof(ForceRestore)]          = forceRestore;
            base[nameof(IsSolutionLoadRestore)] = isSolutionLoadRestore;

            foreach (var(intervalName, intervalDuration) in intervalTimingTracker.GetIntervals())
            {
                base[intervalName] = intervalDuration;
            }
        }
        private void EmitRestoreTelemetryEvent(IEnumerable <NuGetProject> projects,
                                               RestoreOperationSource source,
                                               DateTimeOffset startTime,
                                               double duration)
        {
            var sortedProjects = projects.OrderBy(
                project => project.GetMetadata <string>(NuGetProjectMetadataKeys.UniqueName));
            var projectIds = sortedProjects.Select(
                project => project.GetMetadata <string>(NuGetProjectMetadataKeys.ProjectId)).ToArray();

            var restoreTelemetryEvent = new RestoreTelemetryEvent(
                Guid.NewGuid().ToString(),
                projectIds,
                source,
                startTime,
                _status,
                _packageCount,
                _noOpProjectsCount,
                DateTimeOffset.Now,
                duration);

            RestoreTelemetryService.Instance.EmitRestoreEvent(restoreTelemetryEvent);
        }
        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 RestoreAsync(bool forceRestore, RestoreOperationSource restoreSource, CancellationToken token)
        {
            var startTime = DateTimeOffset.Now;

            _status = NuGetOperationStatus.NoOp;

            // start timer for telemetry event
            TelemetryUtility.StartorResumeTimer();

            var projects = Enumerable.Empty <NuGetProject>();

            _packageRestoreManager.PackageRestoredEvent      += PackageRestoreManager_PackageRestored;
            _packageRestoreManager.PackageRestoreFailedEvent += PackageRestoreManager_PackageRestoreFailedEvent;

            try
            {
                var solutionDirectory   = _solutionManager.SolutionDirectory;
                var isSolutionAvailable = await _solutionManager.IsSolutionAvailableAsync();

                if (solutionDirectory == null)
                {
                    await _logger.DoAsync((l, _) =>
                    {
                        _status = NuGetOperationStatus.Failed;
                        l.ShowError(Resources.SolutionIsNotSaved);
                        l.WriteLine(VerbosityLevel.Minimal, Resources.SolutionIsNotSaved);
                    });

                    return;
                }

                // Get the projects from the SolutionManager
                // Note that projects that are not supported by NuGet, will not show up in this list
                projects = await _solutionManager.GetNuGetProjectsAsync();

                // Check if there are any projects that are not INuGetIntegratedProject, that is,
                // projects with packages.config. OR
                // any of the deferred project is type of packages.config, If so, perform package restore on them
                if (projects.Any(project => !(project is INuGetIntegratedProject)))
                {
                    await RestorePackagesOrCheckForMissingPackagesAsync(
                        solutionDirectory,
                        isSolutionAvailable,
                        restoreSource,
                        token);
                }

                var dependencyGraphProjects = projects
                                              .OfType <IDependencyGraphProject>()
                                              .ToList();

                await RestorePackageSpecProjectsAsync(
                    dependencyGraphProjects,
                    forceRestore,
                    isSolutionAvailable,
                    restoreSource,
                    token);

#if !VS14
                // TODO: To limit risk, we only publish the event when there is a cross-platform PackageReference
                // project in the solution. Extending this behavior to all solutions is tracked here:
                // NuGet/Home#4478
                if (projects.OfType <NetCorePackageReferenceProject>().Any())
                {
                    _restoreEventsPublisher.OnSolutionRestoreCompleted(
                        new SolutionRestoredEventArgs(_status, solutionDirectory));
                }
#endif
            }
            finally
            {
                _packageRestoreManager.PackageRestoredEvent      -= PackageRestoreManager_PackageRestored;
                _packageRestoreManager.PackageRestoreFailedEvent -= PackageRestoreManager_PackageRestoreFailedEvent;

                TelemetryUtility.StopTimer();
                var duration = TelemetryUtility.GetTimerElapsedTime();

                // Do not log any restore message if user disabled restore.
                if (_packageRestoreConsent.IsGranted)
                {
                    await _logger.WriteSummaryAsync(_status, duration);
                }
                else
                {
                    _logger.LogDebug(Resources.PackageRefNotRestoredBecauseOfNoConsent);
                }
                // Emit telemetry event for restore operation
                EmitRestoreTelemetryEvent(
                    projects,
                    restoreSource,
                    startTime,
                    duration.TotalSeconds);
            }
        }
Esempio n. 17
0
        private async Task RestoreAsync(bool forceRestore, RestoreOperationSource restoreSource, CancellationToken token)
        {
            var startTime = DateTimeOffset.Now;

            _status = NuGetOperationStatus.NoOp;

            // start timer for telemetry event
            TelemetryUtility.StartorResumeTimer();

            var projects = Enumerable.Empty <NuGetProject>();

            _packageRestoreManager.PackageRestoredEvent      += PackageRestoreManager_PackageRestored;
            _packageRestoreManager.PackageRestoreFailedEvent += PackageRestoreManager_PackageRestoreFailedEvent;

            try
            {
                var solutionDirectory   = _solutionManager.SolutionDirectory;
                var isSolutionAvailable = _solutionManager.IsSolutionAvailable;

                if (solutionDirectory == null)
                {
                    await _logger.DoAsync((l, _) =>
                    {
                        _status = NuGetOperationStatus.Failed;
                        l.ShowError(Resources.SolutionIsNotSaved);
                        l.WriteLine(VerbosityLevel.Minimal, Resources.SolutionIsNotSaved);
                    });

                    return;
                }

                // Check if solution has deferred projects
                var deferredProjectsData = new DeferredProjectRestoreData(new Dictionary <PackageReference, List <string> >(), new List <PackageSpec>());
                if (await _solutionManager.SolutionHasDeferredProjectsAsync())
                {
                    var deferredProjectsPath = await _solutionManager.GetDeferredProjectsFilePathAsync();

                    deferredProjectsData = await DeferredProjectRestoreUtility.GetDeferredProjectsData(_deferredWorkspaceService, deferredProjectsPath, token);
                }

                // Get the projects from the SolutionManager
                // Note that projects that are not supported by NuGet, will not show up in this list
                projects = _solutionManager.GetNuGetProjects();

                // Check if there are any projects that are not INuGetIntegratedProject, that is,
                // projects with packages.config. OR
                // any of the deferred project is type of packages.config, If so, perform package restore on them
                if (projects.Any(project => !(project is INuGetIntegratedProject)) ||
                    deferredProjectsData.PackageReferenceDict.Count > 0)
                {
                    await RestorePackagesOrCheckForMissingPackagesAsync(
                        solutionDirectory,
                        isSolutionAvailable,
                        deferredProjectsData.PackageReferenceDict,
                        token);
                }

                var dependencyGraphProjects = projects
                                              .OfType <IDependencyGraphProject>()
                                              .ToList();

                await RestorePackageSpecProjectsAsync(
                    dependencyGraphProjects,
                    forceRestore,
                    isSolutionAvailable,
                    deferredProjectsData.PackageSpecs,
                    token);

                // TODO: To limit risk, we only publish the event when there is a cross-platform PackageReference
                // project in the solution. Extending this behavior to all solutions is tracked here:
                // https://github.com/NuGet/Home/issues/4478
#if !VS14
                if (projects.OfType <CpsPackageReferenceProject>().Any() &&
                    !string.IsNullOrEmpty(_dependencyGraphProjectCacheHash))
                {
                    // A no-op restore is considered successful. A cancellation is considered unsuccessful.
                    var args = new SolutionRestoredEventArgs(
                        isSuccess: _status == NuGetOperationStatus.Succeeded || _status == NuGetOperationStatus.NoOp,
                        solutionSpecHash: _dependencyGraphProjectCacheHash);
                    _restoreEventsPublisher.OnSolutionRestoreCompleted(args);
                }
#endif
            }
            finally
            {
                _packageRestoreManager.PackageRestoredEvent      -= PackageRestoreManager_PackageRestored;
                _packageRestoreManager.PackageRestoreFailedEvent -= PackageRestoreManager_PackageRestoreFailedEvent;

                TelemetryUtility.StopTimer();

                var duration = TelemetryUtility.GetTimerElapsedTime();
                await _logger.WriteSummaryAsync(_status, duration);

                // Emit telemetry event for restore operation
                EmitRestoreTelemetryEvent(
                    projects,
                    restoreSource,
                    startTime,
                    _status,
                    _packageCount,
                    duration.TotalSeconds);
            }
        }
Esempio n. 18
0
        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);
            }
        }
Esempio n. 19
0
        private async Task RestoreAsync(bool forceRestore, RestoreOperationSource restoreSource, CancellationToken token)
        {
            var startTime = DateTimeOffset.Now;

            _status = NuGetOperationStatus.NoOp;

            // start timer for telemetry event
            var stopWatch       = Stopwatch.StartNew();
            var intervalTracker = new IntervalTracker(RestoreTelemetryEvent.RestoreActionEventName);
            var projects        = Enumerable.Empty <NuGetProject>();

            _packageRestoreManager.PackageRestoredEvent      += PackageRestoreManager_PackageRestored;
            _packageRestoreManager.PackageRestoreFailedEvent += PackageRestoreManager_PackageRestoreFailedEvent;

            var sources = _sourceRepositoryProvider.GetRepositories();

            using (var packageSourceTelemetry = new PackageSourceTelemetry(sources, _nuGetProjectContext.OperationId, PackageSourceTelemetry.TelemetryAction.Restore))
            {
                try
                {
                    token.ThrowIfCancellationRequested();

                    string solutionDirectory;
                    bool   isSolutionAvailable;

                    using (intervalTracker.Start(RestoreTelemetryEvent.RestoreOperationChecks))
                    {
                        solutionDirectory   = _solutionManager.SolutionDirectory;
                        isSolutionAvailable = await _solutionManager.IsSolutionAvailableAsync();

                        // Get the projects from the SolutionManager
                        // Note that projects that are not supported by NuGet, will not show up in this list
                        projects = (await _solutionManager.GetNuGetProjectsAsync()).ToList();

                        if (projects.Any() && solutionDirectory == null)
                        {
                            _status = NuGetOperationStatus.Failed;
                            await _logger.ShowErrorAsync(Resources.SolutionIsNotSaved);

                            await _logger.WriteLineAsync(VerbosityLevel.Minimal, Resources.SolutionIsNotSaved);

                            return;
                        }
                    }

                    using (intervalTracker.Start(RestoreTelemetryEvent.PackagesConfigRestore))
                    {
                        // Check if there are any projects that are not INuGetIntegratedProject, that is,
                        // projects with packages.config. OR
                        // any of the deferred project is type of packages.config, If so, perform package restore on them
                        if (projects.Any(project => !(project is INuGetIntegratedProject)))
                        {
                            await RestorePackagesOrCheckForMissingPackagesAsync(
                                projects,
                                solutionDirectory,
                                isSolutionAvailable,
                                restoreSource,
                                token);
                        }
                    }

                    var dependencyGraphProjects = projects
                                                  .OfType <IDependencyGraphProject>()
                                                  .ToList();

                    await RestorePackageSpecProjectsAsync(
                        dependencyGraphProjects,
                        forceRestore,
                        isSolutionAvailable,
                        restoreSource,
                        intervalTracker,
                        token);

                    // TODO: To limit risk, we only publish the event when there is a cross-platform PackageReference
                    // project in the solution. Extending this behavior to all solutions is tracked here:
                    // NuGet/Home#4478
                    if (projects.OfType <CpsPackageReferenceProject>().Any())
                    {
                        _restoreEventsPublisher.OnSolutionRestoreCompleted(
                            new SolutionRestoredEventArgs(_status, solutionDirectory));
                    }
                }
                catch (OperationCanceledException)
                {
                    _status = NuGetOperationStatus.Cancelled;
                    throw;
                }
                catch
                {
                    _status = NuGetOperationStatus.Failed;
                    throw;
                }
                finally
                {
                    _packageRestoreManager.PackageRestoredEvent      -= PackageRestoreManager_PackageRestored;
                    _packageRestoreManager.PackageRestoreFailedEvent -= PackageRestoreManager_PackageRestoreFailedEvent;

                    await packageSourceTelemetry.SendTelemetryAsync();

                    stopWatch.Stop();
                    var duration = stopWatch.Elapsed;

                    // Do not log any restore message if user disabled restore.
                    if (_packageRestoreConsent.IsGranted)
                    {
                        await _logger.WriteSummaryAsync(_status, duration);
                    }
                    else
                    {
                        _logger.LogDebug(Resources.PackageRefNotRestoredBecauseOfNoConsent);
                    }

                    var protocolDiagnosticsTotals = packageSourceTelemetry.GetTotals();
                    // Emit telemetry event for restore operation
                    EmitRestoreTelemetryEvent(
                        projects,
                        forceRestore,
                        restoreSource,
                        startTime,
                        duration.TotalSeconds,
                        protocolDiagnosticsTotals,
                        intervalTracker);
                }
            }
        }
Esempio n. 20
0
        public void RestoreTelemetryService_EmitRestoreEvent_OperationSucceed(bool forceRestore, RestoreOperationSource source, NuGetOperationStatus status)
        {
            // Arrange
            var            telemetrySession   = new Mock <ITelemetrySession>();
            TelemetryEvent lastTelemetryEvent = null;

            telemetrySession
            .Setup(x => x.PostEvent(It.IsAny <TelemetryEvent>()))
            .Callback <TelemetryEvent>(x => lastTelemetryEvent = x);

            var noopProjectsCount = 0;

            if (status == NuGetOperationStatus.NoOp)
            {
                noopProjectsCount = 1;
            }

            var operationId = Guid.NewGuid().ToString();

            var restoreTelemetryData = new RestoreTelemetryEvent(
                operationId,
                projectIds: new[] { Guid.NewGuid().ToString() },
                forceRestore: forceRestore,
                source: source,
                startTime: DateTimeOffset.Now.AddSeconds(-3),
                status: status,
                packageCount: 2,
                noOpProjectsCount: noopProjectsCount,
                upToDateProjectsCount: 5,
                unknownProjectsCount: 0,
                projectJsonProjectsCount: 0,
                packageReferenceProjectsCount: 0,
                legacyPackageReferenceProjectsCount: 0,
                cpsPackageReferenceProjectsCount: 0,
                dotnetCliToolProjectsCount: 0,
                packagesConfigProjectsCount: 1,
                endTime: DateTimeOffset.Now,
                duration: 2.10,
                additionalTrackingData: new Dictionary <string, object>()
            {
                { nameof(RestoreTelemetryEvent.IsSolutionLoadRestore), true }
            },
                new IntervalTracker("Activity"),
                isPackageSourceMappingEnabled: false);
            var service = new NuGetVSTelemetryService(telemetrySession.Object);

            // Act
            service.EmitTelemetryEvent(restoreTelemetryData);

            // Assert
            VerifyTelemetryEventData(operationId, restoreTelemetryData, lastTelemetryEvent);
        }
        private async Task RestorePackagesOrCheckForMissingPackagesAsync(
            string solutionDirectory,
            bool isSolutionAvailable,
            RestoreOperationSource restoreSource,
            CancellationToken token)
        {
            if (string.IsNullOrEmpty(solutionDirectory))
            {
                // If the solution is closed, SolutionDirectory will be unavailable. Just return. Do nothing
                return;
            }

            var packages = (await _packageRestoreManager.GetPackagesInSolutionAsync(
                                solutionDirectory, token)).ToList();

            if (_packageRestoreConsent.IsGranted)
            {
                _currentCount = 0;

                if (packages.Count == 0)
                {
                    if (!isSolutionAvailable &&
                        await CheckPackagesConfigAsync())
                    {
                        await _logger.DoAsync((l, _) =>
                        {
                            l.ShowError(Resources.SolutionIsNotSaved);
                            l.WriteLine(VerbosityLevel.Quiet, Resources.SolutionIsNotSaved);
                        });
                    }

                    // Restore is not applicable, since, there is no project with installed packages
                    return;
                }

                _packageCount += packages.Count;
                var missingPackagesList = packages.Where(p => p.IsMissing).ToList();
                _missingPackagesCount = missingPackagesList.Count;
                if (_missingPackagesCount > 0)
                {
                    // Only show the wait dialog, when there are some packages to restore
                    await _logger.RunWithProgressAsync(
                        async (l, _, t) =>
                    {
                        // Display the restore opt out message if it has not been shown yet
                        await l.WriteHeaderAsync();

                        await RestoreMissingPackagesInSolutionAsync(solutionDirectory, packages, t);
                    },
                        token);

                    // Mark that work is being done during this restore
                    _status = NuGetOperationStatus.Succeeded;
                }
            }
            else if (restoreSource == RestoreOperationSource.Explicit)
            {
                // When the user consent is not granted, missing packages may not be restored.
                // So, we just check for them, and report them as warning(s) on the error list window
                await _logger.RunWithProgressAsync(
                    (_, __, ___) => CheckForMissingPackagesAsync(packages),
                    token);
            }

            await _packageRestoreManager.RaisePackagesMissingEventForSolutionAsync(
                solutionDirectory,
                token);
        }
        public void RestoreTelemetryService_EmitRestoreEvent_OperationSucceed(bool forceRestore, RestoreOperationSource source, NuGetOperationStatus status)
        {
            // Arrange
            var            telemetrySession   = new Mock <ITelemetrySession>();
            TelemetryEvent lastTelemetryEvent = null;

            telemetrySession
            .Setup(x => x.PostEvent(It.IsAny <TelemetryEvent>()))
            .Callback <TelemetryEvent>(x => lastTelemetryEvent = x);

            var noopProjectsCount = 0;

            if (status == NuGetOperationStatus.NoOp)
            {
                noopProjectsCount = 1;
            }

            var stausMessage = status == NuGetOperationStatus.Failed ? "Operation Failed" : string.Empty;

            var operationId = Guid.NewGuid().ToString();

            var restoreTelemetryData = new RestoreTelemetryEvent(
                operationId,
                projectIds: new[] { Guid.NewGuid().ToString() },
                forceRestore: forceRestore,
                source: source,
                startTime: DateTimeOffset.Now.AddSeconds(-3),
                status: status,
                packageCount: 2,
                noOpProjectsCount: noopProjectsCount,
                upToDateProjectsCount: 0,
                endTime: DateTimeOffset.Now,
                duration: 2.10,
                new IntervalTracker("Activity"));
            var service = new NuGetVSTelemetryService(telemetrySession.Object);

            // Act
            service.EmitTelemetryEvent(restoreTelemetryData);

            // Assert
            VerifyTelemetryEventData(operationId, restoreTelemetryData, lastTelemetryEvent);
        }
Esempio n. 23
0
 public SolutionRestoreRequest(
     bool forceRestore,
     RestoreOperationSource restoreSource)
     : this(forceRestore, restoreSource, ExplicitRestoreReason.None)
 {
 }