Esempio n. 1
0
 async Task DeletePackages(IEnumerable<PackageIdentity> packages, NuGetFramework projectFramework, ILogger logger, CancellationToken token)
 {
     foreach (var package in packages)
     {
         var installPath = PathResolver.GetInstalledPath(package);
         var localPackage = LocalRepository.GetLocalPackage(package);
         if (localPackage != null)
         {
             await DeletePackage(localPackage, projectFramework, installPath, logger, token);
         }
     }
 }
Esempio n. 2
0
        private async Task<PackageReaderBase> ExtractPackage(
            SourcePackageDependencyInfo packageInfo,
            NuGetFramework projectFramework,
            SourceCacheContext cacheContext,
            PackageExtractionContext packageExtractionContext,
            ILogger logger,
            CancellationToken token)
        {
            logger.LogInformation($"Installing package '{packageInfo.Id} {packageInfo.Version}'.");
            var downloadResource = await packageInfo.Source.GetResourceAsync<DownloadResource>(token);
            var downloadResult = await downloadResource.GetDownloadResourceResultAsync(
                packageInfo,
                new PackageDownloadContext(cacheContext),
                SettingsUtility.GetGlobalPackagesFolder(Settings),
                logger, token);

            var installPath = PathResolver.GetInstallPath(packageInfo);
            foreach (var plugin in PackageManagerPlugins)
            {
                var accepted = await plugin.OnPackageInstallingAsync(packageInfo, projectFramework, downloadResult.PackageReader, installPath);
                if (!accepted) return downloadResult.PackageReader;
            }

            await PackageExtractor.ExtractPackageAsync(
                downloadResult.PackageSource,
                downloadResult.PackageStream,
                PathResolver,
                packageExtractionContext,
                token);

            installPath = PathResolver.GetInstalledPath(packageInfo);
            foreach (var plugin in PackageManagerPlugins)
            {
                await plugin.OnPackageInstalledAsync(packageInfo, projectFramework, downloadResult.PackageReader, installPath);
            }
            return downloadResult.PackageReader;
        }
Esempio n. 3
0
        public async Task<PackageReaderBase> InstallPackageAsync(PackageIdentity package, NuGetFramework projectFramework, bool ignoreDependencies, CancellationToken token)
        {
            using (var cacheContext = new SourceCacheContext())
            {
                var logger = Logger;
                var installedPath = PathResolver.GetInstalledPath(package);
                if (installedPath != null)
                {
                    return new PackageFolderReader(installedPath);
                }

                var repositories = SourceRepositoryProvider.GetRepositories();
                var dependencyInfoResource = await LocalRepository.GetResourceAsync<DependencyInfoResource>(token);
                var installedPackages = (await GetInstalledPackagesAsync(token)).Select(info => info.Identity);
                var localPackages = await GetDependencyInfoAsync(dependencyInfoResource, installedPackages, projectFramework);
                var sourcePackages = localPackages.ToDictionary(dependencyInfo => dependencyInfo, PackageIdentityComparer.Default);
                var packageVersion = new VersionRange(package.Version, new FloatRange(NuGetVersionFloatBehavior.None));
                await GetPackageDependencies(package.Id, packageVersion, projectFramework, cacheContext, repositories, sourcePackages, logger, ignoreDependencies, token);

                var resolverContext = new PackageResolverContext(
                    dependencyBehavior: ignoreDependencies ? DependencyBehavior.Ignore : DependencyBehavior,
                    targetIds: new[] { package.Id },
                    requiredPackageIds: Enumerable.Empty<string>(),
                    packagesConfig: Enumerable.Empty<PackageReference>(),
                    preferredVersions: new[] { package },
                    availablePackages: sourcePackages.Values,
                    packageSources: repositories.Select(repository => repository.PackageSource),
                    log: NullLogger.Instance);

                var resolver = new PackageResolver();
                var installOperations = resolver.Resolve(resolverContext, token);
                var packagesToRemove = new List<PackageIdentity>();
                var licensePackages = new List<IPackageSearchMetadata>();
                var findLocalPackageResource = await LocalRepository.GetResourceAsync<FindPackageByIdResource>(token);
                foreach (var identity in installOperations)
                {
                    installedPath = PathResolver.GetInstalledPath(identity);
                    if (installedPath == null)
                    {
                        var packageInfo = sourcePackages[identity];
                        var packageMetadataResource = await packageInfo.Source.GetResourceAsync<PackageMetadataResource>(token);
                        var packageMetadata = await packageMetadataResource.GetMetadataAsync(identity, cacheContext, NullLogger.Instance, token);
                        if (packageMetadata.RequireLicenseAcceptance) licensePackages.Add(packageMetadata);
                        try
                        {
                            var existingPackages = await findLocalPackageResource.GetAllVersionsAsync(identity.Id, cacheContext, NullLogger.Instance, token);
                            packagesToRemove.AddRange(existingPackages.Select(version => new PackageIdentity(identity.Id, version)));
                        }
                        catch (NuGetProtocolException)
                        {
                            // Ignore exception if packages folder does not exist
                            continue;
                        }
                    }
                }

                if (licensePackages.Count > 0 && !AcceptLicenseAgreement(licensePackages))
                {
                    token.ThrowIfCancellationRequested();
                    var pluralSuffix = licensePackages.Count == 1 ? "s" : "";
                    var message = $"Unable to install package '{package}' because '{string.Join(", ", licensePackages.Select(x => x.Identity))}' require{pluralSuffix} license acceptance.";
                    throw new InvalidOperationException(message);
                }

                // Get dependencies from removed packages while they are still installed
                if (packagesToRemove.Count > 0)
                {
                    localPackages = await GetDependencyInfoAsync(dependencyInfoResource, packagesToRemove, projectFramework);
                    await DeletePackages(packagesToRemove, projectFramework, logger, token);
                }

                var targetPackage = default(PackageReaderBase);
                var packageExtractionContext = new PackageExtractionContext(
                    PackageSaveMode,
                    XmlDocFileSaveMode.None,
                    ClientPolicyContext.GetClientPolicy(Settings, logger),
                    NullLogger.Instance);
                foreach (var identity in installOperations)
                {
                    PackageReaderBase packageReader;
                    installedPath = PathResolver.GetInstalledPath(identity);
                    if (installedPath == null)
                    {
                        var packageInfo = sourcePackages[identity];
                        packageReader = await ExtractPackage(packageInfo, projectFramework, cacheContext, packageExtractionContext, logger, token);
                    }
                    else
                    {
                        packageReader = new PackageFolderReader(installedPath);
                    }

                    if (PackageIdentityComparer.Default.Equals(package, identity))
                    {
                        targetPackage = packageReader;
                    }
                }

                if (packagesToRemove.Count > 0)
                {
                    IDictionary<PackageIdentity, HashSet<PackageIdentity>> dependentPackages, packageDependencies;
                    installedPackages = (await GetInstalledPackagesAsync(token)).Select(info => info.Identity);
                    localPackages = localPackages.Union(await GetDependencyInfoAsync(dependencyInfoResource, installedPackages, projectFramework));
                    GetPackageDependents(installedPackages, localPackages, out dependentPackages, out packageDependencies);
                    var uninstallOperations = GetPackagesToUninstall(packagesToRemove, packageDependencies, removeDependencies: true);
                    uninstallOperations = KeepActiveDependencies(uninstallOperations, packagesToRemove, dependentPackages, forceRemoveTargets: true);
                    await DeletePackages(uninstallOperations, projectFramework, logger, token);
                }

                return targetPackage;
            }
        }