public virtual Task <PackageRestoreResult> RestoreMissingPackagesAsync(string solutionDirectory,
                                                                               IEnumerable <PackageRestoreData> packages,
                                                                               INuGetProjectContext nuGetProjectContext,
                                                                               PackageDownloadContext downloadContext,
                                                                               CancellationToken token)
        {
            if (packages == null)
            {
                throw new ArgumentNullException(nameof(packages));
            }

            var nuGetPackageManager = GetNuGetPackageManager(solutionDirectory);

            var packageRestoreContext = new PackageRestoreContext(
                nuGetPackageManager,
                packages,
                token,
                PackageRestoredEvent,
                PackageRestoreFailedEvent,
                sourceRepositories: null,
                maxNumberOfParallelTasks: PackageManagementConstants.DefaultMaxDegreeOfParallelism,
                logger: NullLogger.Instance);

            return(RestoreMissingPackagesAsync(packageRestoreContext, nuGetProjectContext, downloadContext));
        }
Exemple #2
0
        public virtual Task <PackageRestoreResult> RestoreMissingPackagesAsync(string solutionDirectory,
                                                                               IEnumerable <PackageRestoreData> packages,
                                                                               INuGetProjectContext nuGetProjectContext,
                                                                               PackageDownloadContext downloadContext,
                                                                               ILogger logger,
                                                                               CancellationToken token)
        {
            if (packages == null)
            {
                throw new ArgumentNullException(nameof(packages));
            }

            var nuGetPackageManager = GetNuGetPackageManager(solutionDirectory);

            var packageRestoreContext = new PackageRestoreContext(
                nuGetPackageManager,
                packages,
                token,
                PackageRestoredEvent,
                PackageRestoreFailedEvent,
                sourceRepositories: null,
                maxNumberOfParallelTasks: PackageManagementConstants.DefaultMaxDegreeOfParallelism,
                logger: logger);

            if (nuGetProjectContext.PackageExtractionContext == null)
            {
                nuGetProjectContext.PackageExtractionContext = new PackageExtractionContext(
                    PackageSaveMode.Defaultv2,
                    PackageExtractionBehavior.XmlDocFileSaveMode,
                    ClientPolicyContext.GetClientPolicy(Settings, packageRestoreContext.Logger),
                    packageRestoreContext.Logger);
            }

            return(RestoreMissingPackagesAsync(packageRestoreContext, nuGetProjectContext, downloadContext));
        }
Exemple #3
0
        private static async Task <AttemptedPackage> RestorePackageAsync(
            PackageReference packageReference,
            PackageRestoreContext packageRestoreContext,
            INuGetProjectContext nuGetProjectContext,
            PackageDownloadContext downloadContext)
        {
            Exception exception = null;
            var       restored  = false;

            try
            {
                restored = await packageRestoreContext.PackageManager.RestorePackageAsync(
                    packageReference.PackageIdentity,
                    nuGetProjectContext,
                    downloadContext,
                    packageRestoreContext.SourceRepositories,
                    packageRestoreContext.Token);
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            packageRestoreContext.PackageRestoredEvent?.Invoke(null, new PackageRestoredEventArgs(packageReference.PackageIdentity, restored));

            // PackageReferences cannot be null here
            if (exception != null)
            {
                if (!string.IsNullOrEmpty(exception.Message))
                {
                    nuGetProjectContext.Log(MessageLevel.Warning, exception.Message);
                }

                if (packageRestoreContext.PackageRestoreFailedEvent != null)
                {
                    var packageReferenceComparer = new PackageReferenceComparer();

                    var packageRestoreData = packageRestoreContext.Packages
                                             .Where(p => packageReferenceComparer.Equals(p.PackageReference, packageReference))
                                             .SingleOrDefault();

                    if (packageRestoreData != null)
                    {
                        Debug.Assert(packageRestoreData.ProjectNames != null);
                        packageRestoreContext.PackageRestoreFailedEvent(
                            null,
                            new PackageRestoreFailedEventArgs(packageReference,
                                                              exception,
                                                              packageRestoreData.ProjectNames));
                    }
                }
            }

            return(new AttemptedPackage
            {
                Restored = restored,
                Package = packageReference
            });
        }
Exemple #4
0
        /// <summary>
        /// The static method which takes in all the possible parameters
        /// </summary>
        /// <returns>Returns true if at least one of the packages needed to be restored and got restored</returns>
        /// <remarks>
        /// Best use case is 'nuget.exe restore .sln' where there is no project loaded and there is no SolutionManager.
        /// The references are obtained by parsing of solution file and by using PackagesConfigReader. In this case,
        /// you don't construct an object of PackageRestoreManager,
        /// but just the NuGetPackageManager using constructor that does not need the SolutionManager, and, optionally
        /// register to events and/or specify the source repositories
        /// </remarks>
        public static async Task <PackageRestoreResult> RestoreMissingPackagesAsync(
            PackageRestoreContext packageRestoreContext,
            INuGetProjectContext nuGetProjectContext,
            PackageDownloadContext downloadContext)
        {
            if (packageRestoreContext == null)
            {
                throw new ArgumentNullException(nameof(packageRestoreContext));
            }

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

            ActivityCorrelationId.StartNew();

            var missingPackages = packageRestoreContext.Packages.Where(p => p.IsMissing).ToList();

            if (!missingPackages.Any())
            {
                return(new PackageRestoreResult(true, Enumerable.Empty <PackageIdentity>()));
            }

            // It is possible that the dictionary passed in may not have used the PackageReferenceComparer.
            // So, just to be sure, create a hashset with the keys from the dictionary using the PackageReferenceComparer
            // Now, we are guaranteed to not restore the same package more than once
            var hashSetOfMissingPackageReferences = new HashSet <PackageReference>(missingPackages.Select(p => p.PackageReference), new PackageReferenceComparer());

            nuGetProjectContext.PackageExtractionContext.CopySatelliteFiles = false;

            packageRestoreContext.Token.ThrowIfCancellationRequested();

            foreach (SourceRepository enabledSource in packageRestoreContext.SourceRepositories)
            {
                PackageSource source = enabledSource.PackageSource;
                if (source.IsHttp && !source.IsHttps)
                {
                    packageRestoreContext.Logger.Log(LogLevel.Warning, string.Format(CultureInfo.CurrentCulture, Strings.Warning_HttpServerUsage, "restore", source.Source));
                }
            }

            var attemptedPackages = await ThrottledPackageRestoreAsync(
                hashSetOfMissingPackageReferences,
                packageRestoreContext,
                nuGetProjectContext,
                downloadContext);

            packageRestoreContext.Token.ThrowIfCancellationRequested();

            await ThrottledCopySatelliteFilesAsync(
                hashSetOfMissingPackageReferences,
                packageRestoreContext,
                nuGetProjectContext);

            return(new PackageRestoreResult(
                       attemptedPackages.All(p => p.Restored),
                       attemptedPackages.Select(p => p.Package.PackageIdentity).ToList()));
        }
        /// <summary>
        /// The static method which takes in all the possible parameters
        /// </summary>
        /// <returns>Returns true if at least one of the packages needed to be restored and got restored</returns>
        /// <remarks>
        /// Best use case is 'nuget.exe restore .sln' where there is no project loaded and there is no SolutionManager.
        /// The references are obtained by parsing of solution file and by using PackagesConfigReader. In this case,
        /// you don't construct an object of PackageRestoreManager,
        /// but just the NuGetPackageManager using constructor that does not need the SolutionManager, and, optionally
        /// register to events and/or specify the source repositories
        /// </remarks>
        public static async Task <PackageRestoreResult> RestoreMissingPackagesAsync(
            PackageRestoreContext packageRestoreContext,
            INuGetProjectContext nuGetProjectContext,
            PackageDownloadContext downloadContext)
        {
            if (packageRestoreContext == null)
            {
                throw new ArgumentNullException(nameof(packageRestoreContext));
            }

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

            ActivityCorrelationId.StartNew();

            var missingPackages = packageRestoreContext.Packages.Where(p => p.IsMissing).ToList();

            if (!missingPackages.Any())
            {
                return(new PackageRestoreResult(true, Enumerable.Empty <PackageIdentity>()));
            }

            // It is possible that the dictionary passed in may not have used the PackageReferenceComparer.
            // So, just to be sure, create a hashset with the keys from the dictionary using the PackageReferenceComparer
            // Now, we are guaranteed to not restore the same package more than once
            var hashSetOfMissingPackageReferences = new HashSet <PackageReference>(missingPackages.Select(p => p.PackageReference), new PackageReferenceComparer());

            // Before starting to restore package, set the nuGetProjectContext such that satellite files are not copied yet
            // Satellite files will be copied as a post operation. This helps restore packages in parallel
            // and not have to determine if the package is a satellite package beforehand
            if (nuGetProjectContext.PackageExtractionContext == null)
            {
                nuGetProjectContext.PackageExtractionContext = new PackageExtractionContext(new LoggerAdapter(nuGetProjectContext));
            }

            nuGetProjectContext.PackageExtractionContext.CopySatelliteFiles = false;

            packageRestoreContext.Token.ThrowIfCancellationRequested();

            var attemptedPackages = await ThrottledPackageRestoreAsync(
                hashSetOfMissingPackageReferences,
                packageRestoreContext,
                nuGetProjectContext,
                downloadContext);

            packageRestoreContext.Token.ThrowIfCancellationRequested();

            await ThrottledCopySatelliteFilesAsync(
                hashSetOfMissingPackageReferences,
                packageRestoreContext,
                nuGetProjectContext);

            return(new PackageRestoreResult(
                       attemptedPackages.All(p => p.Restored),
                       attemptedPackages.Select(p => p.Package.PackageIdentity).ToList()));
        }
 /// <summary>
 /// This is the runner which dequeues package references from <paramref name="packageReferencesQueue" />, and
 /// performs copying of satellite files
 /// Note that this method should only Dequeue from the concurrent queue and not Enqueue
 /// </summary>
 private static async Task CopySatelliteFilesRunnerAsync(ConcurrentQueue <Packaging.PackageReference> packageReferencesQueue,
                                                         PackageRestoreContext packageRestoreContext,
                                                         INuGetProjectContext nuGetProjectContext)
 {
     Packaging.PackageReference currentPackageReference = null;
     while (packageReferencesQueue.TryDequeue(out currentPackageReference))
     {
         var result = await packageRestoreContext.PackageManager.CopySatelliteFilesAsync(currentPackageReference.PackageIdentity, nuGetProjectContext, packageRestoreContext.Token);
     }
 }
        /// <summary>
        /// ThrottledCopySatelliteFilesAsync method throttles the number of tasks created to perform copy satellite
        /// files in parallel
        /// The maximum number of parallel tasks that may be created can be specified via
        /// <paramref name="packageRestoreContext" />
        /// The method creates a ConcurrentQueue of passed in <paramref name="packageReferences" />. And, creates a
        /// fixed number of tasks
        /// that dequeue from the ConcurrentQueue and perform copying of satellite files. So, this method should
        /// pre-populate the queue and must not enqueued to by other methods
        /// </summary>
        private static Task ThrottledCopySatelliteFilesAsync(HashSet <PackageReference> packageReferences,
                                                             PackageRestoreContext packageRestoreContext,
                                                             INuGetProjectContext nuGetProjectContext)
        {
            var packageReferencesQueue = new ConcurrentQueue <PackageReference>(packageReferences);
            var tasks = new List <Task>();

            for (var i = 0; i < Math.Min(packageRestoreContext.MaxNumberOfParallelTasks, packageReferences.Count); i++)
            {
                tasks.Add(Task.Run(() => CopySatelliteFilesRunnerAsync(packageReferencesQueue, packageRestoreContext, nuGetProjectContext)));
            }

            return(Task.WhenAll(tasks));
        }
        public Task <PackageRestoreResult> RestoreMissingPackagesAsync(NuGetPackageManager nuGetPackageManager,
                                                                       IEnumerable <PackageRestoreData> packages,
                                                                       INuGetProjectContext nuGetProjectContext,
                                                                       CancellationToken token)
        {
            var packageRestoreContext = new PackageRestoreContext(nuGetPackageManager,
                                                                  packages,
                                                                  token,
                                                                  PackageRestoredEvent,
                                                                  PackageRestoreFailedEvent,
                                                                  sourceRepositories: null,
                                                                  maxNumberOfParallelTasks: PackageManagementConstants.DefaultMaxDegreeOfParallelism);

            return(RestoreMissingPackagesAsync(packageRestoreContext, nuGetProjectContext));
        }
        /// <summary>
        /// This is the runner which dequeues package references from <paramref name="packageReferencesQueue" />, and
        /// performs package restore
        /// Note that this method should only Dequeue from the concurrent queue and not Enqueue
        /// </summary>
        private static async Task <bool> PackageRestoreRunnerAsync(ConcurrentQueue <Packaging.PackageReference> packageReferencesQueue,
                                                                   PackageRestoreContext packageRestoreContext,
                                                                   INuGetProjectContext nuGetProjectContext)
        {
            Packaging.PackageReference currentPackageReference = null;
            var restoreResult = true;

            while (packageReferencesQueue.TryDequeue(out currentPackageReference))
            {
                var result = await RestorePackageAsync(currentPackageReference, packageRestoreContext, nuGetProjectContext);

                restoreResult &= result;
            }

            return(restoreResult);
        }
        private static async Task <bool> RestorePackageAsync(Packaging.PackageReference packageReference,
                                                             PackageRestoreContext packageRestoreContext,
                                                             INuGetProjectContext nuGetProjectContext)
        {
            Exception exception = null;
            var       restored  = false;

            try
            {
                restored = await packageRestoreContext.PackageManager.RestorePackageAsync(packageReference.PackageIdentity, nuGetProjectContext,
                                                                                          packageRestoreContext.SourceRepositories, packageRestoreContext.Token);
            }
            catch (Exception ex)
            {
                exception = ex;
            }

            if (packageRestoreContext.PackageRestoredEvent != null)
            {
                packageRestoreContext.PackageRestoredEvent(null, new PackageRestoredEventArgs(packageReference.PackageIdentity, restored));
            }

            // PackageReferences cannot be null here
            if (exception != null)
            {
                nuGetProjectContext.Log(ProjectManagement.MessageLevel.Warning, exception.Message);
                if (packageRestoreContext.PackageRestoreFailedEvent != null)
                {
                    var packageReferenceComparer = new PackageReferenceComparer();

                    var packageRestoreData = packageRestoreContext.Packages
                                             .Where(p => packageReferenceComparer.Equals(p.PackageReference, packageReference))
                                             .SingleOrDefault();

                    if (packageRestoreData != null)
                    {
                        Debug.Assert(packageRestoreData.ProjectNames != null);
                        packageRestoreContext.PackageRestoreFailedEvent(null, new PackageRestoreFailedEventArgs(packageReference,
                                                                                                                exception,
                                                                                                                packageRestoreData.ProjectNames));
                    }
                }
            }

            return(restored);
        }
Exemple #11
0
        /// <summary>
        /// ThrottledPackageRestoreAsync method throttles the number of tasks created to perform package restore in
        /// parallel
        /// The maximum number of parallel tasks that may be created can be specified via
        /// <paramref name="packageRestoreContext" />
        /// The method creates a ConcurrentQueue of passed in <paramref name="packageReferences" />. And, creates a
        /// fixed number of tasks
        /// that dequeue from the ConcurrentQueue and perform package restore. So, this method should pre-populate the
        /// queue and must not enqueued to by other methods
        /// </summary>
        private static async Task <IEnumerable <AttemptedPackage> > ThrottledPackageRestoreAsync(
            HashSet <PackageReference> packageReferences,
            PackageRestoreContext packageRestoreContext,
            INuGetProjectContext nuGetProjectContext,
            PackageDownloadContext downloadContext)
        {
            var packageReferencesQueue = new ConcurrentQueue <PackageReference>(packageReferences);
            var tasks = new List <Task <List <AttemptedPackage> > >();

            for (var i = 0; i < Math.Min(packageRestoreContext.MaxNumberOfParallelTasks, packageReferences.Count); i++)
            {
                tasks.Add(Task.Run(() => PackageRestoreRunnerAsync(
                                       packageReferencesQueue,
                                       packageRestoreContext,
                                       nuGetProjectContext,
                                       downloadContext)));
            }

            return((await Task.WhenAll(tasks)).SelectMany(package => package));
        }
        /// <summary>
        /// This is the runner which dequeues package references from <paramref name="packageReferencesQueue" />, and
        /// performs package restore
        /// Note that this method should only Dequeue from the concurrent queue and not Enqueue
        /// </summary>
        private static async Task <List <AttemptedPackage> > PackageRestoreRunnerAsync(
            ConcurrentQueue <PackageReference> packageReferencesQueue,
            PackageRestoreContext packageRestoreContext,
            INuGetProjectContext nuGetProjectContext,
            PackageDownloadContext downloadContext)
        {
            PackageReference currentPackageReference = null;

            var attemptedPackages = new List <AttemptedPackage>();

            while (packageReferencesQueue.TryDequeue(out currentPackageReference))
            {
                var attemptedPackage = await RestorePackageAsync(
                    currentPackageReference,
                    packageRestoreContext,
                    nuGetProjectContext,
                    downloadContext);

                attemptedPackages.Add(attemptedPackage);
            }

            return(attemptedPackages);
        }
        public virtual Task <PackageRestoreResult> RestoreMissingPackagesAsync(string solutionDirectory,
                                                                               IEnumerable <PackageRestoreData> packages,
                                                                               INuGetProjectContext nuGetProjectContext,
                                                                               PackageDownloadContext downloadContext,
                                                                               CancellationToken token)
        {
            if (packages == null)
            {
                throw new ArgumentNullException(nameof(packages));
            }

            var nuGetPackageManager = GetNuGetPackageManager(solutionDirectory);

            var packageRestoreContext = new PackageRestoreContext(
                nuGetPackageManager,
                packages,
                token,
                PackageRestoredEvent,
                PackageRestoreFailedEvent,
                sourceRepositories: null,
                maxNumberOfParallelTasks: PackageManagementConstants.DefaultMaxDegreeOfParallelism,
                logger: NullLogger.Instance);

            if (nuGetProjectContext.PackageExtractionContext == null)
            {
                var signedPackageVerifier = new PackageSignatureVerifier(SignatureVerificationProviderFactory.GetSignatureVerificationProviders());

                nuGetProjectContext.PackageExtractionContext = new PackageExtractionContext(
                    PackageSaveMode.Defaultv2,
                    PackageExtractionBehavior.XmlDocFileSaveMode,
                    packageRestoreContext.Logger,
                    signedPackageVerifier,
                    SignedPackageVerifierSettings.GetDefault());
            }

            return(RestoreMissingPackagesAsync(packageRestoreContext, nuGetProjectContext, downloadContext));
        }