コード例 #1
0
 private bool ShouldNoOpDueToRestore(SolutionRestoredEventArgs latestRestore)
 {
     return(latestRestore != null &&
            _currentRestore != null &&
            latestRestore.SolutionSpecHash == _currentRestore.SolutionSpecHash &&
            latestRestore.IsSuccess == _currentRestore.IsSuccess);
 }
コード例 #2
0
 private bool ShouldNoOpDueToRestore(SolutionRestoredEventArgs latestRestore)
 {
     return
         (_currentRestore != null &&
          latestRestore != null &&
          (
              latestRestore.RestoreStatus == NuGetOperationStatus.NoOp ||
              object.ReferenceEquals(_currentRestore, latestRestore)
          ));
 }
コード例 #3
0
        private async Task ExecuteInitScriptsAsync()
        {
            // Fix for Bug 1426 Disallow ExecuteInitScripts from being executed concurrently by multiple threads.
            using (await _initScriptsLock.EnterAsync())
            {
                if (!await _solutionManager.Value.IsSolutionOpenAsync())
                {
                    return;
                }

                Debug.Assert(_settings != null);
                if (_settings == null)
                {
                    return;
                }

                var latestRestore           = _latestRestore;
                var latestSolutionDirectory = await _solutionManager.Value.GetSolutionDirectoryAsync();

                if (ShouldNoOpDueToRestore(latestRestore) &&
                    ShouldNoOpDueToSolutionDirectory(latestSolutionDirectory))
                {
                    _currentRestore           = latestRestore;
                    _currentSolutionDirectory = latestSolutionDirectory;

                    return;
                }
                // We may be enumerating packages from disk here. Always do it from a background thread.
                await TaskScheduler.Default;

                var packageManager = new NuGetPackageManager(
                    _sourceRepositoryProvider,
                    _settings.Value,
                    _solutionManager.Value,
                    _deleteOnRestartManager.Value,
                    _restoreProgressReporter.Value);

                var enumerator        = new InstalledPackageEnumerator(_solutionManager.Value, _settings.Value);
                var installedPackages = await enumerator.EnumeratePackagesAsync(packageManager, CancellationToken.None);

                foreach (var installedPackage in installedPackages)
                {
                    await ExecuteInitPs1Async(installedPackage.InstallPath, installedPackage.Identity);
                }

                // We are done executing scripts, so record the restore and solution directory that we executed for.
                // This aids the no-op logic above.
                _currentRestore           = latestRestore;
                _currentSolutionDirectory = latestSolutionDirectory;
            }
        }
コード例 #4
0
 public void OnSolutionRestoreCompleted(SolutionRestoredEventArgs args)
 {
     Task.Run(() =>
     {
         try
         {
             SolutionRestoreCompleted?.Invoke(args);
         }
         catch (Exception ex)
         {
             _logger.Value.LogError(ex.ToString());
         }
     });
 }
コード例 #5
0
 private void RestoreEvents_SolutionRestoreCompleted(SolutionRestoredEventArgs args)
 {
     _latestRestore = args;
 }
コード例 #6
0
        private async Task ExecuteInitScriptsAsync()
        {
            // Fix for Bug 1426 Disallow ExecuteInitScripts from being executed concurrently by multiple threads.
            using (await _initScriptsLock.EnterAsync())
            {
                if (!_solutionManager.IsSolutionOpen)
                {
                    return;
                }

                Debug.Assert(_settings != null);
                if (_settings == null)
                {
                    return;
                }

                var latestRestore           = _latestRestore;
                var latestSolutionDirectory = _solutionManager.SolutionDirectory;
                if (ShouldNoOpDueToRestore(latestRestore) &&
                    ShouldNoOpDueToSolutionDirectory(latestSolutionDirectory))
                {
                    _currentRestore           = latestRestore;
                    _currentSolutionDirectory = latestSolutionDirectory;

                    return;
                }

                // invoke init.ps1 files in the order of package dependency.
                // if A -> B, we invoke B's init.ps1 before A's.

                var projects       = _solutionManager.GetNuGetProjects().ToList();
                var packageManager = new NuGetPackageManager(
                    _sourceRepositoryProvider,
                    _settings,
                    _solutionManager,
                    _deleteOnRestartManager);

                var packagesByFramework  = new Dictionary <NuGetFramework, HashSet <PackageIdentity> >();
                var sortedGlobalPackages = new List <PackageIdentity>();

                // Sort projects by type
                foreach (var project in projects)
                {
                    // Skip project K projects.
                    if (project is ProjectKNuGetProjectBase)
                    {
                        continue;
                    }

                    var buildIntegratedProject = project as BuildIntegratedNuGetProject;

                    if (buildIntegratedProject != null)
                    {
                        var packages = await BuildIntegratedProjectUtility
                                       .GetOrderedProjectPackageDependencies(buildIntegratedProject);

                        sortedGlobalPackages.AddRange(packages);
                    }
                    else
                    {
                        // Read packages.config
                        var installedRefs = await project.GetInstalledPackagesAsync(CancellationToken.None);

                        if (installedRefs?.Any() == true)
                        {
                            // Index packages.config references by target framework since this affects dependencies
                            NuGetFramework targetFramework;
                            if (!project.TryGetMetadata(NuGetProjectMetadataKeys.TargetFramework, out targetFramework))
                            {
                                targetFramework = NuGetFramework.AnyFramework;
                            }

                            HashSet <PackageIdentity> fwPackages;
                            if (!packagesByFramework.TryGetValue(targetFramework, out fwPackages))
                            {
                                fwPackages = new HashSet <PackageIdentity>();
                                packagesByFramework.Add(targetFramework, fwPackages);
                            }

                            fwPackages.UnionWith(installedRefs.Select(reference => reference.PackageIdentity));
                        }
                    }
                }

                // Each id/version should only be executed once
                var finishedPackages = new HashSet <PackageIdentity>();

                // Packages.config projects
                if (packagesByFramework.Count > 0)
                {
                    await ExecuteInitPs1ForPackagesConfig(
                        packageManager,
                        packagesByFramework,
                        finishedPackages);
                }

                // build integrated projects
                if (sortedGlobalPackages.Count > 0)
                {
                    await ExecuteInitPs1ForBuildIntegratedAsync(
                        sortedGlobalPackages,
                        finishedPackages);
                }

                // We are done executing scripts, so record the restore and solution directory that we executed for.
                // This aids the no-op logic above.
                _currentRestore           = latestRestore;
                _currentSolutionDirectory = latestSolutionDirectory;
            }
        }
コード例 #7
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;
                }

                // 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)))
                {
                    await RestorePackagesOrCheckForMissingPackagesAsync(
                        solutionDirectory,
                        isSolutionAvailable,
                        token);
                }

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

                await RestorePackageSpecProjectsAsync(
                    dependencyGraphProjects,
                    forceRestore,
                    isSolutionAvailable,
                    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 !VS14
                if (projects.OfType <NetCorePackageReferenceProject>().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);
            }
        }
コード例 #8
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;

                // 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);
            }
        }