public async Task ResolverGather_Basic2()
        {
            ResolutionContext context = new ResolutionContext(Resolver.DependencyBehavior.Lowest, true);

            PackageIdentity target = new PackageIdentity("a", new NuGetVersion(1, 0, 0));
            IEnumerable<PackageIdentity> targets = new PackageIdentity[] { target };

            NuGetFramework framework = NuGetFramework.Parse("net451");

            List<PackageDependencyInfo> packagesA = new List<PackageDependencyInfo>()
            {
                new PackageDependencyInfo("a", new NuGetVersion(1, 0, 0), new PackageDependency[] { new PackageDependency("b", new VersionRange(new NuGetVersion(1, 0, 0))) }),
                new PackageDependencyInfo("c", new NuGetVersion(1, 0, 0), new PackageDependency[] { new PackageDependency("d", new VersionRange(new NuGetVersion(1, 0, 0))) }),
                new PackageDependencyInfo("e", new NuGetVersion(1, 0, 0), new PackageDependency[] { }),
                new PackageDependencyInfo("d", new NuGetVersion(1, 0, 0), new PackageDependency[] { new PackageDependency("e", new VersionRange(new NuGetVersion(1, 0, 0))) }),
                new PackageDependencyInfo("notpartofthis", new NuGetVersion(1, 0, 0), new PackageDependency[] { })
            };

            List<PackageDependencyInfo> packagesB = new List<PackageDependencyInfo>()
            {
                new PackageDependencyInfo("b", new NuGetVersion(1, 0, 0), new PackageDependency[] { new PackageDependency("c", new VersionRange(new NuGetVersion(1, 0, 0))) }),
                new PackageDependencyInfo("notpartofthis2", new NuGetVersion(1, 0, 0), new PackageDependency[] { })
            };

            List<Lazy<INuGetResourceProvider>> providersA = new List<Lazy<INuGetResourceProvider>>();
            providersA.Add(new Lazy<INuGetResourceProvider>(() => new TestDependencyInfoProvider(packagesA)));

            List<Lazy<INuGetResourceProvider>> providersB = new List<Lazy<INuGetResourceProvider>>();
            providersB.Add(new Lazy<INuGetResourceProvider>(() => new TestDependencyInfoProvider(packagesB)));

            List<SourceRepository> repos = new List<SourceRepository>();
            repos.Add(new SourceRepository(new PackageSource("http://a"), providersA));
            repos.Add(new SourceRepository(new PackageSource("http://b"), providersB));

            var results = await ResolverGather.GatherPackageDependencyInfo(context, targets, Enumerable.Empty<PackageIdentity>(),
                framework, repos, repos, CancellationToken.None);

            var check = results.OrderBy(e => e.Id).ToList();

            Assert.Equal(5, check.Count);
            Assert.Equal("a", check[0].Id);
            Assert.Equal("b", check[1].Id);
            Assert.Equal("c", check[2].Id);
            Assert.Equal("d", check[3].Id);
            Assert.Equal("e", check[4].Id);
        }
        public async Task TestPackageRestoredEvent()
        {
            // Arrange
            var testSolutionManager = new TestSolutionManager();
            var projectA = testSolutionManager.AddNewMSBuildProject();
            var projectB = testSolutionManager.AddNewMSBuildProject();

            var packageIdentity = Packages[0];
            var testNuGetProjectContext = new TestNuGetProjectContext();
            var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateV3OnlySourceRepositoryProvider();
            var testSettings = NullSettings.Instance;
            var resolutionContext = new ResolutionContext();
            var token = CancellationToken.None;

            var nuGetPackageManager = new NuGetPackageManager(sourceRepositoryProvider, testSettings, testSolutionManager);

            await nuGetPackageManager.InstallPackageAsync(projectA, packageIdentity,
                resolutionContext, new TestNuGetProjectContext(), sourceRepositoryProvider.GetRepositories().First(), null, token);
            await nuGetPackageManager.InstallPackageAsync(projectB, packageIdentity,
                resolutionContext, new TestNuGetProjectContext(), sourceRepositoryProvider.GetRepositories().First(), null, token);

            var packageRestoreManager = new PackageRestoreManager(sourceRepositoryProvider, testSettings, testSolutionManager);
            var restoredPackages = new List<PackageIdentity>();
            packageRestoreManager.PackageRestoredEvent += delegate(object sender, PackageRestoredEventArgs args)
            {
                if(args.Restored)
                {
                    restoredPackages.Add(args.Package);
                }
            };


            Assert.True(nuGetPackageManager.PackageExistsInPackagesFolder(packageIdentity));

            // Delete packages folder
            Directory.Delete(Path.Combine(testSolutionManager.SolutionDirectory, "packages"), recursive: true);

            Assert.False(nuGetPackageManager.PackageExistsInPackagesFolder((packageIdentity)));

            // Act
            await packageRestoreManager.RestoreMissingPackagesInSolutionAsync(CancellationToken.None);

            Assert.Equal(1, restoredPackages.Count);
            Assert.True(nuGetPackageManager.PackageExistsInPackagesFolder((packageIdentity)));
        }
 public static async Task<HashSet<SourceDependencyInfo>> GatherPackageDependencyInfo(ResolutionContext context,
     IEnumerable<PackageIdentity> primaryTargets,
     IEnumerable<PackageIdentity> allTargets,
     NuGetFramework targetFramework,
     IEnumerable<SourceRepository> primarySources,
     IEnumerable<SourceRepository> allSources,
     CancellationToken token)
 {
     return await GatherPackageDependencyInfo(context,
         null,
         null,
         primaryTargets,
         allTargets,
         targetFramework,
         primarySources,
         allSources,
         token);
 }
        public async Task TestPacManUninstallPackageOnMultipleProjects()
        {
            // Arrange
            var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateV3OnlySourceRepositoryProvider();
            var testSolutionManager = new TestSolutionManager();
            var testSettings = new NullSettings();
            var token = CancellationToken.None;
            var resolutionContext = new ResolutionContext();
            var testNuGetProjectContext = new TestNuGetProjectContext();
            var nuGetPackageManager = new NuGetPackageManager(sourceRepositoryProvider, testSettings, testSolutionManager);
            var packagesFolderPath = PackagesFolderPathUtility.GetPackagesFolderPath(testSolutionManager, testSettings);
            var packagePathResolver = new PackagePathResolver(packagesFolderPath);

            var projectA = testSolutionManager.AddNewMSBuildProject();
            var projectB = testSolutionManager.AddNewMSBuildProject();
            var packageIdentity = NoDependencyLibPackages[0];

            // Act
            await nuGetPackageManager.InstallPackageAsync(projectA, packageIdentity,
                resolutionContext, testNuGetProjectContext, sourceRepositoryProvider.GetRepositories().First(), null, token);
            await nuGetPackageManager.InstallPackageAsync(projectB, packageIdentity,
                resolutionContext, testNuGetProjectContext, sourceRepositoryProvider.GetRepositories().First(), null, token);

            // Assert
            var projectAInstalled = (await projectA.GetInstalledPackagesAsync(token)).ToList();
            var projectBInstalled = (await projectB.GetInstalledPackagesAsync(token)).ToList();
            Assert.Equal(1, projectAInstalled.Count);
            Assert.Equal(1, projectBInstalled.Count);

            // Main Act
            var uninstallationContext = new UninstallationContext();
            await nuGetPackageManager.UninstallPackageAsync(projectA, packageIdentity.Id,
                uninstallationContext, testNuGetProjectContext, token);

            // Assert
            projectAInstalled = (await projectA.GetInstalledPackagesAsync(token)).ToList();
            projectBInstalled = (await projectB.GetInstalledPackagesAsync(token)).ToList();
            Assert.Equal(0, projectAInstalled.Count);
            Assert.Equal(1, projectBInstalled.Count);
            Assert.True(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageIdentity)));

            // Clean-up
            TestFilesystemUtility.DeleteRandomTestFolders(testSolutionManager.SolutionDirectory);
        }
        private static async Task ProcessMissingPackageIdentities(HashSet<SourceDependencyInfo> combinedResults,
            IEnumerable<PackageIdentity> targets,
            Dictionary<SourceRepository, HashSet<string>> sourceToPackageIdsChecked,
            List<Tuple<SourceRepository, DepedencyInfoResource>> dependencyResources,
            NuGetFramework targetFramework,
            ResolutionContext context,
            bool ignoreExceptions,
            CancellationToken token)
        {
            // results need to be kept in order
            var results = new Queue<Tuple<SourceRepository, Task<IEnumerable<PackageDependencyInfo>>>>();

            // search against the target package
            foreach (Tuple<SourceRepository, DepedencyInfoResource> resourceTuple in dependencyResources)
            {
                token.ThrowIfCancellationRequested();

                // foundIds - all ids that have been checked on this source
                HashSet<string> foundIds;
                if (!sourceToPackageIdsChecked.TryGetValue(resourceTuple.Item1, out foundIds))
                {
                    foundIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
                    sourceToPackageIdsChecked.Add(resourceTuple.Item1, foundIds);
                }

                IEnumerable<PackageIdentity> missingTargets = targets.Except((IEnumerable<PackageIdentity>)combinedResults, PackageIdentity.Comparer);

                if(missingTargets.Any())
                {
                    // add the target id incase it isn't found at all, this records that we tried already
                    foundIds.UnionWith(missingTargets.Select(e => e.Id));

                    // get package info from the source for the missing targets alone
                    // search on another thread, we'll retrieve the results later
                    var task = Task.Run(async () => await resourceTuple.Item2.ResolvePackages(missingTargets, targetFramework, context.IncludePrerelease, token));

                    var data = new Tuple<SourceRepository, Task<IEnumerable<PackageDependencyInfo>>>(resourceTuple.Item1, task);

                    results.Enqueue(data);
                }
            }

            // retrieve package results from the gather tasks
            // order is important here. packages from the first repository beat packages from later repositories
            while (results.Count > 0)
            {
                var data = results.Dequeue();
                var source = data.Item1;

                var task = data.Item2;

                try
                {
                    var packages = await task;

                    ProcessResults(combinedResults, source, sourceToPackageIdsChecked[source], packages, context.IncludePrerelease);
                }
                catch (Exception ex)
                {
                    // swallow exceptions for secondary repositories
                    if (!ignoreExceptions)
                    {
                        throw;
                    }
                }
            }
        }
        public async Task<IEnumerable<NuGetProjectAction>> PreviewInstallPackageAsync(NuGetProject nuGetProject, PackageIdentity packageIdentity,
            ResolutionContext resolutionContext, INuGetProjectContext nuGetProjectContext,
            IEnumerable<SourceRepository> primarySources, IEnumerable<SourceRepository> secondarySources,
            CancellationToken token)
        {
            if(nuGetProject == null)
            {
                throw new ArgumentNullException("nuGetProject");
            }

            if (packageIdentity == null)
            {
                throw new ArgumentNullException("packageIdentity");
            }

            if(resolutionContext == null)
            {
                throw new ArgumentNullException("resolutionContext");
            }

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

            if (primarySources == null)
            {
                throw new ArgumentNullException("primarySources");
            }

            if (secondarySources == null)
            {
                secondarySources = SourceRepositoryProvider.GetRepositories().Where(e => e.PackageSource.IsEnabled);
            }

            if(!primarySources.Any())
            {
                throw new ArgumentException("primarySources");
            }

            if(packageIdentity.Version == null)
            {
                throw new ArgumentNullException("packageIdentity.Version");
            }

            // TODO: BUGBUG: HACK: Multiple primary repositories is mainly intended for nuget.exe at the moment
            // The following special case for ProjectK is not correct, if they used nuget.exe
            // and multiple repositories in the -Source switch
            if (nuGetProject is ProjectManagement.Projects.ProjectKNuGetProjectBase)
            {
                var action = NuGetProjectAction.CreateInstallProjectAction(packageIdentity, primarySources.First());
                return new NuGetProjectAction[] { action };
            }

            var projectInstalledPackageReferences = await nuGetProject.GetInstalledPackagesAsync(token);
            var oldListOfInstalledPackages = projectInstalledPackageReferences.Select(p => p.PackageIdentity);
            if(oldListOfInstalledPackages.Any(p => p.Equals(packageIdentity)))
            {
                string projectName;
                nuGetProject.TryGetMetadata<string>(NuGetProjectMetadataKeys.Name, out projectName);
                throw new InvalidOperationException(String.Format(NuGet.ProjectManagement.Strings.PackageAlreadyExistsInProject, packageIdentity, projectName ?? String.Empty));
            }

            List<NuGetProjectAction> nuGetProjectActions = new List<NuGetProjectAction>();
            // TODO: these sources should be ordered
            // TODO: search in only the active source but allow dependencies to come from other sources?

            var effectiveSources = GetEffectiveSources(primarySources, secondarySources);
            
            if (resolutionContext.DependencyBehavior != DependencyBehavior.Ignore)
            {
                try
                {
                    bool downgradeAllowed = false;
                    var packageTargetsForResolver = new HashSet<PackageIdentity>(oldListOfInstalledPackages, PackageIdentity.Comparer);
                    // Note: resolver needs all the installed packages as targets too. And, metadata should be gathered for the installed packages as well
                    var installedPackageWithSameId = packageTargetsForResolver.Where(p => p.Id.Equals(packageIdentity.Id, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                    if(installedPackageWithSameId != null)
                    {
                        packageTargetsForResolver.Remove(installedPackageWithSameId);
                        if(installedPackageWithSameId.Version > packageIdentity.Version)
                        {
                            // Looks like the installed package is of higher version than one being installed. So, we take it that downgrade is allowed
                            downgradeAllowed = true;
                        }
                    }
                    packageTargetsForResolver.Add(packageIdentity);

                    // Step-1 : Get metadata resources using gatherer
                    var targetFramework = nuGetProject.GetMetadata<NuGetFramework>(NuGetProjectMetadataKeys.TargetFramework);
                    nuGetProjectContext.Log(MessageLevel.Info, Strings.AttemptingToGatherDependencyInfo, packageIdentity, targetFramework);

                    var primaryPackages = new List<PackageIdentity>() { packageIdentity };

                    // If any targets are prerelease we should gather with prerelease on and filter afterwards
                    bool includePrereleaseInGather = resolutionContext.IncludePrerelease || (packageTargetsForResolver.Any(p => (p.HasVersion && p.Version.IsPrerelease)));
                    ResolutionContext contextForGather = new ResolutionContext(resolutionContext.DependencyBehavior, includePrereleaseInGather, resolutionContext.IncludeUnlisted);

                    var availablePackageDependencyInfoWithSourceSet = await ResolverGather.GatherPackageDependencyInfo(contextForGather,
                        primaryPackages,
                        packageTargetsForResolver,
                        targetFramework,
                        primarySources,
                        effectiveSources,
                        token);

                    if (!availablePackageDependencyInfoWithSourceSet.Any())
                    {
                        throw new InvalidOperationException(String.Format(Strings.UnableToGatherDependencyInfo, packageIdentity));
                    }

                    // Prune the results down to only what we would allow to be installed

                    // Keep only the target package we are trying to install for that Id
                    IEnumerable<SourceDependencyInfo> prunedAvailablePackages = PrunePackageTree.RemoveAllVersionsForIdExcept(availablePackageDependencyInfoWithSourceSet, packageIdentity);

                    if (!resolutionContext.IncludePrerelease)
                    {
                        prunedAvailablePackages = PrunePackageTree.PrunePreleaseForStableTargets(prunedAvailablePackages, packageTargetsForResolver);
                    }

                    // Remove versions that do not satisfy 'allowedVersions' attribute in packages.config, if any
                    prunedAvailablePackages = PrunePackageTree.PruneDisallowedVersions(prunedAvailablePackages, projectInstalledPackageReferences);

                    // TODO: prune down level packages?

                    // Step-2 : Call IPackageResolver.Resolve to get new list of installed packages
                    // TODO: Consider using IPackageResolver once it is extensible
                    var packageResolver = new PackageResolver(resolutionContext.DependencyBehavior);
                    nuGetProjectContext.Log(MessageLevel.Info, Strings.AttemptingToResolveDependencies, packageIdentity, resolutionContext.DependencyBehavior);

                    // Note: resolver prefers installed package versions if the satisfy the dependency version constraints
                    // So, since we want an exact version of a package, create a new list of installed packages where the packageIdentity being installed
                    // is present after removing the one with the same id
                    var preferredPackageReferences = new List<PackageReference>(projectInstalledPackageReferences.Where(pr =>
                        !pr.PackageIdentity.Id.Equals(packageIdentity.Id, StringComparison.OrdinalIgnoreCase)));
                    preferredPackageReferences.Add(new PackageReference(packageIdentity, targetFramework));

                    IEnumerable<PackageIdentity> newListOfInstalledPackages = packageResolver.Resolve(packageTargetsForResolver,
                        prunedAvailablePackages,
                        preferredPackageReferences,
                        token);
                    if (newListOfInstalledPackages == null)
                    {
                        throw new InvalidOperationException(String.Format(Strings.UnableToResolveDependencyInfo, packageIdentity, resolutionContext.DependencyBehavior));
                    }

                    // Step-3 : Get the list of nuGetProjectActions to perform, install/uninstall on the nugetproject
                    // based on newPackages obtained in Step-2 and project.GetInstalledPackages                    

                    nuGetProjectContext.Log(MessageLevel.Info, Strings.ResolvingActionsToInstallPackage, packageIdentity);
                    var newPackagesToUninstall = new List<PackageIdentity>();
                    foreach(var oldInstalledPackage in oldListOfInstalledPackages)
                    {
                        var newPackageWithSameId = newListOfInstalledPackages
                            .Where(np => oldInstalledPackage.Id.Equals(np.Id, StringComparison.OrdinalIgnoreCase) &&
                            !oldInstalledPackage.Version.Equals(np.Version)).FirstOrDefault();

                        if(newPackageWithSameId != null)
                        {
                            if(!downgradeAllowed && oldInstalledPackage.Version > newPackageWithSameId.Version)
                            {
                                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Strings.NewerVersionAlreadyReferenced, newPackageWithSameId.Id));
                            }
                            newPackagesToUninstall.Add(oldInstalledPackage);
                        }
                    }
                    var newPackagesToInstall = newListOfInstalledPackages.Where(p => !oldListOfInstalledPackages.Contains(p));

                    foreach (PackageIdentity newPackageToUninstall in newPackagesToUninstall)
                    {
                        nuGetProjectActions.Add(NuGetProjectAction.CreateUninstallProjectAction(newPackageToUninstall));
                    }

                    var comparer = PackageIdentity.Comparer;

                    foreach (PackageIdentity newPackageToInstall in newPackagesToInstall)
                    {
                        // find the package match based on identity
                        SourceDependencyInfo sourceDepInfo = prunedAvailablePackages.Where(p => comparer.Equals(p, newPackageToInstall)).SingleOrDefault();

                        if (sourceDepInfo == null)
                        {
                            // this really should never happen
                            throw new InvalidOperationException(String.Format(Strings.PackageNotFound, packageIdentity));
                        }

                        nuGetProjectActions.Add(NuGetProjectAction.CreateInstallProjectAction(newPackageToInstall, sourceDepInfo.Source));
                    }
                }
                catch (InvalidOperationException)
                {
                    throw;
                }
                catch (AggregateException aggregateEx)
                {
                    throw new InvalidOperationException(aggregateEx.Message, aggregateEx);
                }
                catch (Exception ex)
                {
                    if (String.IsNullOrEmpty(ex.Message))
                    {
                        throw new InvalidOperationException(String.Format(Strings.PackageCouldNotBeInstalled, packageIdentity), ex);
                    }
                    else
                    {
                        throw new InvalidOperationException(ex.Message, ex);
                    }
                }
            }
            else
            {
                var sourceRepository = await GetSourceRepository(packageIdentity, effectiveSources);
                nuGetProjectActions.Add(NuGetProjectAction.CreateInstallProjectAction(packageIdentity, sourceRepository));
            }

            nuGetProjectContext.Log(MessageLevel.Info, Strings.ResolvedActionsToInstallPackage, packageIdentity);
            return nuGetProjectActions;
        }
        public async Task<IEnumerable<NuGetProjectAction>> PreviewReinstallPackagesAsync(IEnumerable<PackageIdentity> packagesToInstall, NuGetProject nuGetProject,
            ResolutionContext resolutionContext, INuGetProjectContext nuGetProjectContext,
            SourceRepository primarySourceRepository, IEnumerable<SourceRepository> secondarySources,
            CancellationToken token)
        {
            if(packagesToInstall == null)
            {
                throw new ArgumentNullException("packagesToInstall");
            }

            if (nuGetProject == null)
            {
                throw new ArgumentNullException("nuGetProject");
            }

            if (resolutionContext == null)
            {
                throw new ArgumentNullException("resolutionContext");
            }

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

            if(packagesToInstall.Any(p => p.Version == null))
            {
                throw new ArgumentException("packagesToInstall");
            }

            if (primarySourceRepository == null)
            {
                throw new ArgumentNullException("primarySourceRepository");
            }
            var primarySources = new List<SourceRepository>() { primarySourceRepository };

            if (secondarySources == null)
            {
                secondarySources = SourceRepositoryProvider.GetRepositories().Where(e => e.PackageSource.IsEnabled);
            }

            var projectInstalledPackageReferences = await nuGetProject.GetInstalledPackagesAsync(token);
            var oldListOfInstalledPackages = projectInstalledPackageReferences.Select(p => p.PackageIdentity);

            // Note: resolver needs all the installed packages as targets too. And, metadata should be gathered for the installed packages as well
            var packageTargetsForResolver = new HashSet<PackageIdentity>(oldListOfInstalledPackages, PackageIdentity.Comparer);
            foreach(var packageToInstall in packagesToInstall)
            {
                packageTargetsForResolver.Add(packageToInstall);
            }

            List<NuGetProjectAction> nuGetProjectActions = new List<NuGetProjectAction>();
            // TODO: these sources should be ordered
            // TODO: search in only the active source but allow dependencies to come from other sources?

            var effectiveSources = GetEffectiveSources(primarySources, secondarySources);

            try
            {
                // If any targets are prerelease we should gather with prerelease on and filter afterwards
                bool includePrereleaseInGather = resolutionContext.IncludePrerelease || (packageTargetsForResolver.Any(p => (p.HasVersion && p.Version.IsPrerelease)));
                ResolutionContext contextForGather = new ResolutionContext(resolutionContext.DependencyBehavior, includePrereleaseInGather, resolutionContext.IncludeUnlisted);

                // Step-1 : Get metadata resources using gatherer
                var targetFramework = nuGetProject.GetMetadata<NuGetFramework>(NuGetProjectMetadataKeys.TargetFramework);
                nuGetProjectContext.Log(MessageLevel.Info, Strings.AttemptingToGatherDependencyInfoForMultiplePackages, targetFramework);
                var availablePackageDependencyInfoWithSourceSet = await ResolverGather.GatherPackageDependencyInfo(contextForGather,
                    packagesToInstall,
                    packageTargetsForResolver,
                    targetFramework,
                    primarySources,
                    effectiveSources,
                    token);

                if (!availablePackageDependencyInfoWithSourceSet.Any())
                {
                    throw new InvalidOperationException(Strings.UnableToGatherDependencyInfoForMultiplePackages);
                }

                // Prune the results down to only what we would allow to be installed
                IEnumerable<SourceDependencyInfo> prunedAvailablePackages = availablePackageDependencyInfoWithSourceSet;

                // Keep only the target package we are trying to install for that Id
                foreach (var packageIdentity in packagesToInstall)
                {
                    prunedAvailablePackages = PrunePackageTree.RemoveAllVersionsForIdExcept(prunedAvailablePackages, packageIdentity);
                }

                if (!resolutionContext.IncludePrerelease)
                {
                    prunedAvailablePackages = PrunePackageTree.PrunePreleaseForStableTargets(prunedAvailablePackages, packageTargetsForResolver);
                }

                // TODO: prune down level packages?

                // Remove versions that do not satisfy 'allowedVersions' attribute in packages.config, if any
                prunedAvailablePackages = PrunePackageTree.PruneDisallowedVersions(prunedAvailablePackages, projectInstalledPackageReferences);

                // Step-2 : Call IPackageResolver.Resolve to get new list of installed packages                
                // TODO: Consider using IPackageResolver once it is extensible
                var packageResolver = new PackageResolver(resolutionContext.DependencyBehavior);
                nuGetProjectContext.Log(MessageLevel.Info, Strings.AttemptingToResolveDependenciesForMultiplePackages);

                IEnumerable<PackageIdentity> newListOfInstalledPackages = packageResolver.Resolve(packageTargetsForResolver,
                    prunedAvailablePackages,
                    projectInstalledPackageReferences,
                    token);
                if (newListOfInstalledPackages == null)
                {
                    throw new InvalidOperationException(Strings.UnableToResolveDependencyInfoForMultiplePackages);
                }

                var packagesInDependencyOrder = (await GetInstalledPackagesInDependencyOrder(nuGetProject,
                    nuGetProjectContext, token)).Reverse();

                foreach(var package in packagesInDependencyOrder)
                {
                    nuGetProjectActions.Add(NuGetProjectAction.CreateUninstallProjectAction(package));
                }

                var comparer = PackageIdentity.Comparer;
                foreach (PackageIdentity newPackageToInstall in newListOfInstalledPackages)
                {
                    // find the package match based on identity
                    SourceDependencyInfo sourceDepInfo = availablePackageDependencyInfoWithSourceSet.Where(p => comparer.Equals(p, newPackageToInstall)).SingleOrDefault();

                    if (sourceDepInfo == null)
                    {
                        // this really should never happen
                        throw new InvalidOperationException(String.Format(Strings.PackageNotFound, newPackageToInstall));
                    }

                    nuGetProjectActions.Add(NuGetProjectAction.CreateInstallProjectAction(newPackageToInstall, sourceDepInfo.Source));
                }
            }
            catch(InvalidOperationException)
            {
                throw;
            }
            catch (AggregateException aggregateEx)
            {
                throw new InvalidOperationException(aggregateEx.Message, aggregateEx);
            }
            catch (Exception ex)
            {
                if(String.IsNullOrEmpty(ex.Message))
                {
                    throw new InvalidOperationException(Strings.PackagesCouldNotBeInstalled, ex);
                }
                else
                {
                    throw new InvalidOperationException(ex.Message, ex);
                }                
            }
            return nuGetProjectActions;
        }
        /// <summary>
        /// Installs given <param name="packageIdentity"></param> to NuGetProject <param name="nuGetProject"></param>
        /// <param name="resolutionContext"></param> and <param name="nuGetProjectContext"></param> are used in the process
        /// </summary>
        public async Task InstallPackageAsync(NuGetProject nuGetProject, PackageIdentity packageIdentity, ResolutionContext resolutionContext,
            INuGetProjectContext nuGetProjectContext, IEnumerable<SourceRepository> primarySources,
            IEnumerable<SourceRepository> secondarySources, CancellationToken token)
        {
            // Step-1 : Call PreviewInstallPackageAsync to get all the nuGetProjectActions
            var nuGetProjectActions = await PreviewInstallPackageAsync(nuGetProject, packageIdentity, resolutionContext,
                nuGetProjectContext, primarySources, secondarySources, token);

            SetDirectInstall(packageIdentity, nuGetProjectContext);

            // Step-2 : Execute all the nuGetProjectActions
            await ExecuteNuGetProjectActionsAsync(nuGetProject, nuGetProjectActions, nuGetProjectContext, token);

            ClearDirectInstall(nuGetProjectContext);
        }
		public Task<IEnumerable<NuGetProjectAction>> PreviewInstallPackageAsync (
			NuGetProject nuGetProject,
			PackageIdentity packageIdentity,
			ResolutionContext resolutionContext,
			INuGetProjectContext nuGetProjectContext,
			IEnumerable<SourceRepository> primarySources,
			IEnumerable<SourceRepository> secondarySources,
			CancellationToken token)
		{
			PreviewInstallProject = nuGetProject;
			PreviewInstallPackageIdentity = packageIdentity;
			PreviewInstallResolutionContext = resolutionContext;
			PreviewInstallPrimarySources = primarySources.ToList ();
			PreviewInstallSecondarySources = secondarySources;
			PreviewInstallCancellationToken = token;

			BeforePreviewInstallPackageAsyncAction ();

			IEnumerable<NuGetProjectAction> actions = InstallActions.ToArray ();
			return Task.FromResult (actions);
		}
		public Task<NuGetVersion> GetLatestVersionAsync (
			string packageId,
			NuGetProject project,
			ResolutionContext resolutionContext,
			IEnumerable<SourceRepository> sources,
			ILogger log,
			CancellationToken token)
		{
			return NuGetPackageManager.GetLatestVersionAsync (
				packageId,
				project,
				resolutionContext,
				sources,
				log,
				token
			);
		}
		public Task<IEnumerable<NuGetProjectAction>> PreviewInstallPackageAsync (
			NuGetProject nuGetProject,
			PackageIdentity packageIdentity,
			ResolutionContext resolutionContext,
			INuGetProjectContext nuGetProjectContext,
			IEnumerable<SourceRepository> primarySources,
			IEnumerable<SourceRepository> secondarySources,
			CancellationToken token)
		{
			return packageManager.PreviewInstallPackageAsync (
				nuGetProject,
				packageIdentity,
				resolutionContext,
				nuGetProjectContext,
				primarySources,
				secondarySources,
				token
			);
		}
        /// <summary>
        /// Core install method. All installs from the VS API and template wizard end up here.
        /// </summary>
        internal async Task InstallInternal(Project project, List<PackageIdentity> packages, ISourceRepositoryProvider repoProvider, VSAPIProjectContext projectContext, bool ignoreDependencies, CancellationToken token)
        {
            // store expanded node state
            IDictionary<string, ISet<VsHierarchyItem>> expandedNodes = VsHierarchyHelper.GetAllExpandedNodes(_solutionManager);

            try
            {
                DependencyBehavior depBehavior = ignoreDependencies ? DependencyBehavior.Ignore : DependencyBehavior.Lowest;

                bool includePrerelease = false;

                ResolutionContext resolution = new ResolutionContext(depBehavior, includePrerelease, false);

                NuGetPackageManager packageManager = new NuGetPackageManager(repoProvider, _settings, _solutionManager);

                // find the project
                NuGetProject nuGetProject = PackageManagementHelpers.GetProject(_solutionManager, project, projectContext);

                // install the package
                foreach (PackageIdentity package in packages)
                {
                    if (package.Version == null)
                    {
                        if (!_packageServices.IsPackageInstalled(project, package.Id))
                        {
                            await packageManager.InstallPackageAsync(nuGetProject, package.Id, resolution, projectContext, repoProvider.GetRepositories(), Enumerable.Empty<SourceRepository>(), token);
                        }
                    }
                    else
                    {
                        if (!_packageServices.IsPackageInstalledEx(project, package.Id, package.Version.ToString()))
                        {
                            await packageManager.InstallPackageAsync(nuGetProject, package, resolution, projectContext, repoProvider.GetRepositories(), Enumerable.Empty<SourceRepository>(), token);
                        }
                    }
                }
            }
            finally
            {
                // collapse nodes
                VsHierarchyHelper.CollapseAllNodes(_solutionManager, expandedNodes);
            }
        }
Пример #13
0
 public async Task Install(IReadOnlyList<SourceRepository> remoteRepositories, NuGetPackageManager packageManager)
 {
     if (_versionMatch == null)
     {
         return;
     }
     IReadOnlyList<SourceRepository> sourceRepositories = GetSourceRepositories(remoteRepositories);
     Trace.Verbose($"Installing package {_packageId} {_versionMatch.Version}");
     ResolutionContext resolutionContext = new ResolutionContext(
         DependencyBehavior.Lowest, _allowPrereleaseVersions, _allowUnlisted, VersionConstraints.None);
     INuGetProjectContext projectContext = new NuGetProjectContext();
     await packageManager.InstallPackageAsync(packageManager.PackagesFolderNuGetProject,
         new PackageIdentity(_packageId, _versionMatch), resolutionContext, projectContext, sourceRepositories,
         Array.Empty<SourceRepository>(), CancellationToken.None);
     Trace.Verbose($"Installed package {_packageId} {_versionMatch.Version}");
 }
        public async Task TestPacManInstallPackageWhichUsesExistingDependency()
        {
            // Arrange
            var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateV3OnlySourceRepositoryProvider();
            var testSolutionManager = new TestSolutionManager();
            var testSettings = new NullSettings();
            var token = CancellationToken.None;
            var resolutionContext = new ResolutionContext();
            var testNuGetProjectContext = new TestNuGetProjectContext();
            var nuGetPackageManager = new NuGetPackageManager(sourceRepositoryProvider, testSettings, testSolutionManager);
            var packagesFolderPath = PackagesFolderPathUtility.GetPackagesFolderPath(testSolutionManager, testSettings);
            var packagePathResolver = new PackagePathResolver(packagesFolderPath);

            var projectA = testSolutionManager.AddNewMSBuildProject();
            var packageIdentity0 = PackageWithDependents[0];
            var packageIdentity1 = PackageWithDependents[1];
            var packageIdentity2 = PackageWithDependents[2];
            var packageIdentity3 = PackageWithDependents[3];

            // Act
            await nuGetPackageManager.InstallPackageAsync(projectA, packageIdentity3,
                resolutionContext, testNuGetProjectContext, sourceRepositoryProvider.GetRepositories().First(), null, token);

            // Assert
            var projectAInstalled = (await projectA.GetInstalledPackagesAsync(token)).ToList();
            Assert.Equal(2, projectAInstalled.Count);
            Assert.Equal(packageIdentity1, projectAInstalled[0].PackageIdentity);
            Assert.Equal(packageIdentity3, projectAInstalled[1].PackageIdentity);
            Assert.True(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageIdentity1)));
            Assert.True(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageIdentity3)));

            // Main Act
            await nuGetPackageManager.InstallPackageAsync(projectA, packageIdentity2,
                resolutionContext, testNuGetProjectContext, sourceRepositoryProvider.GetRepositories().First(), null, token);

            // Assert
            projectAInstalled = (await projectA.GetInstalledPackagesAsync(token)).ToList();
            Assert.Equal(3, projectAInstalled.Count);
            Assert.Equal(packageIdentity1, projectAInstalled[0].PackageIdentity);
            Assert.Equal(packageIdentity2, projectAInstalled[2].PackageIdentity);
            Assert.Equal(packageIdentity3, projectAInstalled[1].PackageIdentity);
            Assert.False(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageIdentity0)));
            Assert.True(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageIdentity1)));
            Assert.True(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageIdentity2)));
            Assert.True(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageIdentity3)));

            // Clean-up
            TestFilesystemUtility.DeleteRandomTestFolders(testSolutionManager.SolutionDirectory);
        }
        public async Task TestPacManInstallLowerSpecificVersionOfDependencyPackage()
        {
            // Arrange
            var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateV3OnlySourceRepositoryProvider();
            var testSolutionManager = new TestSolutionManager();
            var testSettings = new NullSettings();
            var token = CancellationToken.None;
            var resolutionContext = new ResolutionContext(DependencyBehavior.Highest);
            var testNuGetProjectContext = new TestNuGetProjectContext();
            var nuGetPackageManager = new NuGetPackageManager(sourceRepositoryProvider, testSettings, testSolutionManager);
            var packagesFolderPath = PackagesFolderPathUtility.GetPackagesFolderPath(testSolutionManager, testSettings);
            var packagePathResolver = new PackagePathResolver(packagesFolderPath);

            var projectA = testSolutionManager.AddNewMSBuildProject();
            var packageIdentity0 = PackageWithDependents[0];
            var dependentPackage = PackageWithDependents[2];

            var latestVersion = await NuGetPackageManager.GetLatestVersionAsync(packageIdentity0.Id, resolutionContext,
                sourceRepositoryProvider.GetRepositories().First(), token);

            var packageLatest = new PackageIdentity(packageIdentity0.Id, latestVersion);

            // Act
            await nuGetPackageManager.InstallPackageAsync(projectA, dependentPackage,
                resolutionContext, testNuGetProjectContext, sourceRepositoryProvider.GetRepositories().First(), null, token);

            // Assert
            var projectAInstalled = (await projectA.GetInstalledPackagesAsync(token)).ToList();
            Assert.Equal(2, projectAInstalled.Count);
            Assert.Equal(packageLatest, projectAInstalled[0].PackageIdentity);
            Assert.True(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageLatest)));
            Assert.Equal(dependentPackage, projectAInstalled[1].PackageIdentity);
            Assert.True(File.Exists(packagePathResolver.GetInstalledPackageFilePath(dependentPackage)));
            Assert.False(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageIdentity0)));

            // Main Act
            await nuGetPackageManager.InstallPackageAsync(projectA, packageIdentity0,
                resolutionContext, testNuGetProjectContext, sourceRepositoryProvider.GetRepositories().First(), null, token);

            // Assert
            projectAInstalled = (await projectA.GetInstalledPackagesAsync(token)).ToList();
            Assert.Equal(2, projectAInstalled.Count);
            Assert.Equal(packageIdentity0, projectAInstalled[0].PackageIdentity);
            Assert.Equal(dependentPackage, projectAInstalled[1].PackageIdentity);
            Assert.True(File.Exists(packagePathResolver.GetInstalledPackageFilePath(dependentPackage)));
            Assert.False(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageLatest)));
            Assert.True(File.Exists(packagePathResolver.GetInstalledPackageFilePath(packageIdentity0)));

            // Clean-up
            TestFilesystemUtility.DeleteRandomTestFolders(testSolutionManager.SolutionDirectory);
        }
        private static async Task<NuGetVersion> GetLatestVersionAsync(string packageId, ResolutionContext resolutionContext,
            IEnumerable<SourceRepository> sources, CancellationToken token)
        {
            List<Task<NuGetVersion>> tasks = new List<Task<NuGetVersion>>();

            foreach (var source in sources)
            {
                tasks.Add(Task.Run(async () => await GetLatestVersionCoreAsync(packageId, resolutionContext, source, token)));
            }

            var versions = await Task.WhenAll(tasks);
            return versions.Where(v => v != null).Max();
        }
        private static async Task<NuGetVersion> GetLatestVersionCoreAsync(string packageId, ResolutionContext resolutionContext, SourceRepository source, CancellationToken token)
        {
            NuGetVersion latestVersion = null;

            var metadataResource = await source.GetResourceAsync<MetadataResource>();

            if (metadataResource != null)
            {
                latestVersion = await metadataResource.GetLatestVersion(packageId,
                    resolutionContext.IncludePrerelease, resolutionContext.IncludeUnlisted, token);
            }

            return latestVersion;
        }
		public Task<IEnumerable<NuGetProjectAction>> PreviewUpdatePackagesAsync (
			string packageId,
			NuGetProject nuGetProject,
			ResolutionContext resolutionContext,
			INuGetProjectContext nuGetProjectContext,
			IEnumerable<SourceRepository> primarySources,
			IEnumerable<SourceRepository> secondarySources,
			CancellationToken token)
		{
			PreviewUpdateProject = nuGetProject;
			PreviewUpdatePackageId = packageId;
			PreviewUpdateResolutionContext = resolutionContext;
			PreviewUpdatePrimarySources = primarySources.ToList ();
			PreviewUpdateSecondarySources = secondarySources;
			PreviewUpdateCancellationToken = token;

			IEnumerable<NuGetProjectAction> actions = UpdateActions.ToArray ();
			return Task.FromResult (actions);
		}
        /// <summary>
        /// Gives the preview as a list of NuGetProjectActions that will be performed to install <param name="packageId"></param> into <param name="nuGetProject"></param>
        /// <param name="resolutionContext"></param> and <param name="nuGetProjectContext"></param> are used in the process
        /// </summary>
        public async Task<IEnumerable<NuGetProjectAction>> PreviewInstallPackageAsync(NuGetProject nuGetProject, string packageId,
            ResolutionContext resolutionContext, INuGetProjectContext nuGetProjectContext,
            SourceRepository primarySourceRepository, IEnumerable<SourceRepository> secondarySources, CancellationToken token)
        {
            if (nuGetProject == null)
            {
                throw new ArgumentNullException("nuGetProject");
            }

            if (packageId == null)
            {
                throw new ArgumentNullException("packageId");
            }

            if (resolutionContext == null)
            {
                throw new ArgumentNullException("resolutionContext");
            }

            if (nuGetProjectContext == null)
            {
                throw new ArgumentNullException("nuGetProjectContext");
            }
            // Step-1 : Get latest version for packageId
            var latestVersion = await GetLatestVersionAsync(packageId, resolutionContext, primarySourceRepository, token);

            if (latestVersion == null)
            {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Strings.UnknownPackage, packageId));
            }

            var projectInstalledPackageReferences = await nuGetProject.GetInstalledPackagesAsync(token);
            var installedPackageReference = projectInstalledPackageReferences.Where(pr => StringComparer.OrdinalIgnoreCase.Equals(pr.PackageIdentity.Id, packageId)).FirstOrDefault();
            if(installedPackageReference != null && installedPackageReference.PackageIdentity.Version > latestVersion)
            {
                throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, Strings.NewerVersionAlreadyReferenced, packageId));
            }

            // Step-2 : Call InstallPackage(project, packageIdentity)
            return await PreviewInstallPackageAsync(nuGetProject, new PackageIdentity(packageId, latestVersion), resolutionContext,
                nuGetProjectContext, primarySourceRepository, secondarySources, token);
        }
		public Task<IEnumerable<NuGetProjectAction>> PreviewUpdatePackagesAsync (
			NuGetProject nuGetProject,
			ResolutionContext resolutionContext,
			INuGetProjectContext nuGetProjectContext,
			IEnumerable<SourceRepository> primarySources,
			IEnumerable<SourceRepository> secondarySources,
			CancellationToken token)
		{
			return PreviewUpdatePackagesAsync (
				null,
				nuGetProject,
				resolutionContext,
				nuGetProjectContext,
				primarySources,
				secondarySources,
				token
			);
		}
        /// <summary>
        /// Gives the preview as a list of NuGetProjectActions that will be performed to install <param name="packageIdentity"></param> into <param name="nuGetProject"></param>
        /// <param name="resolutionContext"></param> and <param name="nuGetProjectContext"></param> are used in the process
        /// </summary>
        public async Task<IEnumerable<NuGetProjectAction>> PreviewInstallPackageAsync(NuGetProject nuGetProject, PackageIdentity packageIdentity,
            ResolutionContext resolutionContext, INuGetProjectContext nuGetProjectContext,
            SourceRepository primarySourceRepository, IEnumerable<SourceRepository> secondarySources, CancellationToken token)
        {
            if (nuGetProject is ProjectManagement.Projects.ProjectKNuGetProjectBase)
            {
                var action = NuGetProjectAction.CreateInstallProjectAction(packageIdentity, primarySourceRepository);
                return new NuGetProjectAction[] { action };
            }

            var primarySources = new List<SourceRepository>() { primarySourceRepository };
            return await PreviewInstallPackageAsync(nuGetProject, packageIdentity, resolutionContext,
                nuGetProjectContext, primarySources, secondarySources, token);
        }
		public Task<NuGetVersion> GetLatestVersionAsync (
			string packageId,
			NuGetProject project,
			ResolutionContext resolutionContext,
			IEnumerable<SourceRepository> sources,
			ILogger log,
			CancellationToken token)
		{
			GetLatestVersionPackageId = packageId;
			GetLatestVersionProject = project;
			GetLatestVersionResolutionContext = resolutionContext;
			GetLatestVersionSources = sources.ToList ();
			GetLatestVersionLogger = log;
			GetLatestVersionCancellationToken = token;

			return Task.FromResult (LatestVersion);
		}
 /// <summary>
 /// Installs the latest version of the given <param name="packageId"></param> to NuGetProject <param name="nuGetProject"></param>
 /// <param name="resolutionContext"></param> and <param name="nuGetProjectContext"></param> are used in the process
 /// </summary>
 public async Task InstallPackageAsync(NuGetProject nuGetProject, string packageId, ResolutionContext resolutionContext,
     INuGetProjectContext nuGetProjectContext, SourceRepository primarySourceRepository,
     IEnumerable<SourceRepository> secondarySources, CancellationToken token)
 {
     await InstallPackageAsync(nuGetProject, packageId, resolutionContext, nuGetProjectContext,
         new List<SourceRepository>() { primarySourceRepository }, secondarySources, token);
 }
Пример #24
0
        public async Task<NuGetInstallResult> InstallPackage(
            string packageId,
            NuGetVersion version,
            bool prerelease)
        {
            var installPath = Path.Combine(Path.GetTempPath(), "testnuget");

            var projectContext = new EmptyNuGetProjectContext
            {
                PackageExtractionContext = new PackageExtractionContext()
            };

            var references = new List<string>();
            var frameworkReferences = new List<string>();
            var projectSystem = new DelegateNuGetProjectSystem(projectContext, (reference, isFrameworkReference) =>
            {
                if (isFrameworkReference) frameworkReferences.Add(reference);
                else references.Add(reference);
            });

            var project = new MSBuildNuGetProject(projectSystem, installPath, installPath);
            OverrideProject(project);

            var packageManager = new NuGetPackageManager(_sourceRepositoryProvider, _settings, installPath);

            var primaryRepositories = _packageSources.Select(_sourceRepositoryProvider.CreateRepository).ToArray();

            var resolutionContext = new ResolutionContext(
                DependencyBehavior.Lowest,
                includePrelease: prerelease,
                includeUnlisted: true,
                versionConstraints: VersionConstraints.None);

            if (version == null)
            {
                // Find the latest version using NuGetPackageManager
                version = await NuGetPackageManager.GetLatestVersionAsync(
                    packageId,
                    project,
                    resolutionContext,
                    primaryRepositories,
                    NullLogger.Instance,
                    CancellationToken.None).ConfigureAwait(false);

                if (version == null)
                {
                    throw new Exception("Unable to find package");
                }
            }

            var packageIdentity = new PackageIdentity(packageId, version);

            await packageManager.InstallPackageAsync(
                project,
                packageIdentity,
                resolutionContext,
                projectContext,
                primaryRepositories,
                Enumerable.Empty<SourceRepository>(),
                CancellationToken.None).ConfigureAwait(false);

            return new NuGetInstallResult(references.AsReadOnly(), frameworkReferences.AsReadOnly());
        }
        /// <summary>
        /// ***NOTE: Parameters combinedResults, sourceToPackageIdsChecked may get updated before the return of this call
        /// </summary>
        private static async Task<bool> ProcessMissingPackageIds(HashSet<SourceDependencyInfo> combinedResults,
            HashSet<string> allDiscoveredIds,
            Dictionary<SourceRepository, HashSet<string>> sourceToPackageIdsChecked,
            List<Tuple<SourceRepository, DepedencyInfoResource>> dependencyResources,
            NuGetFramework targetFramework,
            ResolutionContext context,
            bool ignoreExceptions,
            CancellationToken token)
        {
            bool complete = true;

            // results need to be kept in order
            var results = new Queue<Tuple<SourceRepository, Task<IEnumerable<PackageDependencyInfo>>>>();

            // resolve further on each source
            foreach (SourceRepository source in sourceToPackageIdsChecked.Keys)
            {
                // reuse the existing resource
                // TODO: Try using the SourceRepositoryComparer and see if this works fine
                var resolverResTuple = dependencyResources.Where(e => e.Item1 == source).FirstOrDefault();
                if(resolverResTuple == null)
                    continue;

                DepedencyInfoResource resolverRes = resolverResTuple.Item2;

                // check each source for packages discovered on other sources if we have no checked here already
                foreach (string missingId in allDiscoveredIds.Except(sourceToPackageIdsChecked[source], StringComparer.OrdinalIgnoreCase).ToArray())
                {
                    token.ThrowIfCancellationRequested();

                    // an id was missing - we will have to loop again on all sources incase this finds new ids
                    complete = false;

                    // mark that we searched for this id here
                    sourceToPackageIdsChecked[source].Add(missingId);

                    // search on another thread, we'll retrieve the results later
                    var task = Task.Run(async () => await resolverRes.ResolvePackages(missingId, targetFramework, context.IncludePrerelease, token));

                    var data = new Tuple<SourceRepository, Task<IEnumerable<PackageDependencyInfo>>>(source, task);

                    results.Enqueue(data);
                }
            }

            // retrieve package results from the gather tasks
            // order is important here. packages from the first repository beat packages from later repositories
            while (results.Count > 0)
            {
                var data = results.Dequeue();
                var source = data.Item1;

                var task = data.Item2;

                try
                {
                    var packages = await task;

                    ProcessResults(combinedResults, source, sourceToPackageIdsChecked[source], packages, context.IncludePrerelease);
                }
                catch (Exception ex)
                {
                    // swallow exceptions for secondary repositories
                    if (!ignoreExceptions)
                    {
                        throw;
                    }
                }
            }

            return complete;
        }
        /// <summary>
        /// Устанавливает пакет.
        /// </summary>
        /// <param name="packageId">ID пакета.</param>
        /// <param name="packageVersion">Версия пакета.</param>
        /// <param name="allowPrerelease">Разрешена ли установка предварительного релиза.</param>
        /// <returns>Содержимое установленного пакета.</returns>
        public async Task<PackageContent> InstallPackage(string packageId, string packageVersion = null, bool allowPrerelease = false)
        {
            NuGetVersion packageNuGetVersion = null;

            if (!string.IsNullOrWhiteSpace(packageVersion))
            {
                packageNuGetVersion = NuGetVersion.Parse(packageVersion);
            }

            // Конфигурационный файл NuGet.config по умолчанию
            var settings = new NuGet.Configuration.Settings(_packagesPath, "NuGet.config");

            // Фабрика источников пактов на основе конфигурационного файла
            var packageSourceProvider = new PackageSourceProvider(settings);

            // Добавление в фабрику источников пакетов дополнительных источников
            packageSourceProvider.SavePackageSources(_packageSources.Select(i => new PackageSource(i)));

            // Фабрика хранилищ пакетов на основе фабрики источников пакетов
            var packageRepositoryProvider = new CachingSourceProvider(packageSourceProvider);

            // Получение всех хранилищ пакетов на основе указанных источников
            var packageRepositories = packageRepositoryProvider.GetRepositories().ToList();

            // Определение возможности установки prerelease-версии пакетов
            allowPrerelease = allowPrerelease || (packageNuGetVersion != null && packageNuGetVersion.IsPrerelease);

            // Создание правил разрешения зависимостей при установке пакета
            var resolutionContext = new ResolutionContext(
                dependencyBehavior: DependencyBehavior.Lowest,
                includePrelease: allowPrerelease,
                includeUnlisted: true,
                versionConstraints: VersionConstraints.None);

            // Если версия пакета не указана, поиск последней версии
            if (packageNuGetVersion == null)
            {
                packageNuGetVersion = await NuGetPackageManager.GetLatestVersionAsync(
                    packageId,
                    NuGetFramework.AnyFramework,
                    resolutionContext,
                    packageRepositories,
                    _logger,
                    CancellationToken.None);

                if (packageNuGetVersion == null)
                {
                    throw new InvalidOperationException(string.Format(Properties.Resources.PackageNotFound, packageId));
                }
            }

            // Уникальный идентификатор версии пакета для установки
            var packageIdentity = new PackageIdentity(packageId, packageNuGetVersion);

            // Каталог для установки пакетов (каталог packages)
            NuGetProject folderProject = new InfinniFolderNuGetProject(_packagesPath);
            
            // Менеджер для управления пакетами
            var packageManager = new NuGetPackageManager(packageRepositoryProvider, settings, _packagesPath);

            // Правила установки пакетов
            var projectContext = new NuGetLoggerProjectContext(_logger)
            {
                PackageExtractionContext = new PackageExtractionContext
                {
                    PackageSaveMode = PackageSaveMode.Defaultv3
                }
            };

            // Определение порядка действий при установке пакета
            var installActions = (await packageManager.PreviewInstallPackageAsync(
                folderProject,
                packageIdentity,
                resolutionContext,
                projectContext,
                packageRepositories,
                Enumerable.Empty<SourceRepository>(),
                CancellationToken.None)).ToList();

            // Применение действий по установке пакета
            await packageManager.ExecuteNuGetProjectActionsAsync(
                folderProject,
                installActions,
                projectContext,
                CancellationToken.None);

            return GetPackageContent(packageIdentity, installActions.Select(i => i.PackageIdentity).ToList());
        }
        private static async Task<HashSet<SourceDependencyInfo>> GatherPackageDependencyInfo(ResolutionContext context,
            IEnumerable<string> primaryTargetIds,
            IEnumerable<string> allTargetIds,
            IEnumerable<PackageIdentity> primaryTargets,
            IEnumerable<PackageIdentity> allTargets,
            NuGetFramework targetFramework,
            IEnumerable<SourceRepository> primarySources,
            IEnumerable<SourceRepository> allSources,
            CancellationToken token)
        {
            // get a distinct set of packages from all repos
            var combinedResults = new HashSet<SourceDependencyInfo>(PackageIdentity.Comparer);

            // get the dependency info resources for each repo
            // primary and all may share the same resources
            var depResources = new Dictionary<SourceRepository, Task<DepedencyInfoResource>>();
            foreach (var source in allSources.Concat(primarySources))
            {
                if (!depResources.ContainsKey(source))
                {
                    depResources.Add(source, source.GetResourceAsync<DepedencyInfoResource>(token));
                }
            }

            // a resource may be null, if it is exclude this source from the gather
            var primaryDependencyResources = new List<Tuple<SourceRepository, DepedencyInfoResource>>();

            foreach (var source in primarySources)
            {
                var resource = await depResources[source];

                if (source != null)
                {
                    primaryDependencyResources.Add(new Tuple<SourceRepository, DepedencyInfoResource>(source, resource));
                }
            }

            var allDependencyResources = new List<Tuple<SourceRepository, DepedencyInfoResource>>();

            foreach (var source in allSources)
            {
                var resource = await depResources[source];

                if (source != null)
                {
                    allDependencyResources.Add(new Tuple<SourceRepository, DepedencyInfoResource>(source, resource));
                }
            }

            // track which sources have been searched for each package id
            Dictionary<SourceRepository, HashSet<string>> sourceToPackageIdsChecked = new Dictionary<SourceRepository, HashSet<string>>();

            UpdateSourceToPackageIdsChecked(sourceToPackageIdsChecked, primaryDependencyResources);
            UpdateSourceToPackageIdsChecked(sourceToPackageIdsChecked, allDependencyResources);
            
            if (primaryTargetIds != null && allTargetIds != null)
            {
                // First, check for primary targets alone against primary source repositories alone
                var primaryIdsAsAllDiscoveredIds = new HashSet<string>(primaryTargetIds);
                await ProcessMissingPackageIds(combinedResults, primaryIdsAsAllDiscoveredIds, sourceToPackageIdsChecked,
                    primaryDependencyResources, targetFramework, context, false, token);

                string missingPrimaryPackageId = primaryTargetIds.Where(p => !combinedResults.Any(c => c.Id.Equals(p, StringComparison.OrdinalIgnoreCase))).FirstOrDefault();
                if (!String.IsNullOrEmpty(missingPrimaryPackageId))
                {
                    throw new InvalidOperationException(String.Format(Strings.PackageNotFound, missingPrimaryPackageId));
                }

                var allIdsAsAllDiscoveredIds = new HashSet<string>(allTargetIds);
                await ProcessMissingPackageIds(combinedResults, allIdsAsAllDiscoveredIds, sourceToPackageIdsChecked,
                    primaryDependencyResources, targetFramework, context, false, token);
            }
            else
            {
                Debug.Assert(primaryTargets != null && allTargets != null);

                // First, check for primary targets alone against primary source repositories alone
                await ProcessMissingPackageIdentities(combinedResults, primaryTargets, sourceToPackageIdsChecked,
                    primaryDependencyResources, targetFramework, context, false, token);

                PackageIdentity missingPrimaryPackageIdentity = primaryTargets.Where(p => !combinedResults.Any(c => c.Equals(p))).FirstOrDefault();
                if (missingPrimaryPackageIdentity != null)
                {
                    throw new InvalidOperationException(String.Format(Strings.PackageNotFound, missingPrimaryPackageIdentity));
                }

                await ProcessMissingPackageIdentities(combinedResults, allTargets, sourceToPackageIdsChecked,
                    allDependencyResources, targetFramework, context, true, token);
            }

            // loop until we finish a full iteration with no new ids discovered
            bool complete = false;

            while (!complete)
            {
                HashSet<string> allDiscoveredIds = new HashSet<string>(sourceToPackageIdsChecked.SelectMany(e => e.Value), StringComparer.OrdinalIgnoreCase);
                complete = await ProcessMissingPackageIds(combinedResults, allDiscoveredIds, sourceToPackageIdsChecked, allDependencyResources, targetFramework, context, true, token);
            }

            return combinedResults;
        }
        /// <summary>
        /// Installs the latest version of the given <param name="packageId"></param> to NuGetProject <param name="nuGetProject"></param>
        /// <param name="resolutionContext"></param> and <param name="nuGetProjectContext"></param> are used in the process
        /// </summary>
        public async Task InstallPackageAsync(NuGetProject nuGetProject, string packageId, ResolutionContext resolutionContext,
            INuGetProjectContext nuGetProjectContext, IEnumerable<SourceRepository> primarySources,
            IEnumerable<SourceRepository> secondarySources, CancellationToken token)
        {
            // Step-1 : Get latest version for packageId
            var latestVersion = await GetLatestVersionAsync(packageId, resolutionContext, primarySources, token);

            if (latestVersion == null)
            {
                throw new InvalidOperationException(String.Format(Strings.NoLatestVersionFound, packageId));
            }

            // Step-2 : Call InstallPackageAsync(project, packageIdentity)
            await InstallPackageAsync(nuGetProject, new PackageIdentity(packageId, latestVersion), resolutionContext,
                nuGetProjectContext, primarySources, secondarySources, token);
        }
 public static async Task<NuGetVersion> GetLatestVersionAsync(string packageId, ResolutionContext resolutionContext, SourceRepository primarySourceRepository, CancellationToken token)
 {
     return await GetLatestVersionAsync(packageId, resolutionContext, new List<SourceRepository> { primarySourceRepository }, token);
 }
        public async Task TestPacManPreviewUninstallDependencyPackage()
        {
            // Arrange
            var sourceRepositoryProvider = TestSourceRepositoryUtility.CreateV3OnlySourceRepositoryProvider();
            var testSolutionManager = new TestSolutionManager();
            var testSettings = new NullSettings();
            var token = CancellationToken.None;
            var resolutionContext = new ResolutionContext();
            var testNuGetProjectContext = new TestNuGetProjectContext();
            var packagesFolderPath = PackagesFolderPathUtility.GetPackagesFolderPath(testSolutionManager, testSettings);
            var nuGetPackageManager = new NuGetPackageManager(sourceRepositoryProvider, testSettings, testSolutionManager);

            var randomPackagesConfigFolderPath = TestFilesystemUtility.CreateRandomTestFolder();
            var randomPackagesConfigPath = Path.Combine(randomPackagesConfigFolderPath, "packages.config");

            var projectTargetFramework = NuGetFramework.Parse("net45");
            var msBuildNuGetProjectSystem = new TestMSBuildNuGetProjectSystem(projectTargetFramework, new TestNuGetProjectContext());
            var msBuildNuGetProject = new MSBuildNuGetProject(msBuildNuGetProjectSystem, packagesFolderPath, randomPackagesConfigPath);
            var packageIdentity = PackageWithDependents[2];

            // Pre-Assert
            // Check that the packages.config file does not exist
            Assert.False(File.Exists(randomPackagesConfigPath));
            // Check that there are no packages returned by PackagesConfigProject
            var packagesInPackagesConfig = (await msBuildNuGetProject.PackagesConfigNuGetProject.GetInstalledPackagesAsync(token)).ToList();
            Assert.Equal(0, packagesInPackagesConfig.Count);
            Assert.Equal(0, msBuildNuGetProjectSystem.References.Count);

            // Act
            await nuGetPackageManager.InstallPackageAsync(msBuildNuGetProject, packageIdentity,
                resolutionContext, testNuGetProjectContext, sourceRepositoryProvider.GetRepositories().First(), null, token);

            // Assert
            // Check that the packages.config file exists after the installation
            Assert.True(File.Exists(randomPackagesConfigPath));
            // Check the number of packages and packages returned by PackagesConfigProject after the installation
            packagesInPackagesConfig = (await msBuildNuGetProject.PackagesConfigNuGetProject.GetInstalledPackagesAsync(token)).ToList();
            Assert.Equal(2, packagesInPackagesConfig.Count);
            Assert.Equal(packageIdentity, packagesInPackagesConfig[1].PackageIdentity);
            Assert.Equal(projectTargetFramework, packagesInPackagesConfig[1].TargetFramework);
            Assert.Equal(PackageWithDependents[0], packagesInPackagesConfig[0].PackageIdentity);
            Assert.Equal(projectTargetFramework, packagesInPackagesConfig[0].TargetFramework);

            // Main Act
            Exception exception = null;
            try
            {
                var uninstallationContext = new UninstallationContext();
                var packageActions = await nuGetPackageManager.PreviewUninstallPackageAsync(msBuildNuGetProject, "jQuery",
                        uninstallationContext, testNuGetProjectContext, token);
            }
            catch (InvalidOperationException ex)
            {
                exception = ex;
            }
            catch (AggregateException ex)
            {
                exception = ExceptionUtility.Unwrap(ex);
            }

            Assert.NotNull(exception);
            Assert.True(exception is InvalidOperationException);
            Assert.Equal("Unable to uninstall 'jQuery.1.4.4' because 'jQuery.Validation.1.13.1' depends on it.",
                exception.Message);

            // Clean-up
            TestFilesystemUtility.DeleteRandomTestFolders(testSolutionManager.SolutionDirectory, randomPackagesConfigFolderPath);
        }