示例#1
0
 public void Constructor_StreamPackageReaderBaseSource_InitializesProperties()
 {
     using (var packageReader = new TestPackageReader())
         using (var result = new DownloadResourceResult(Stream.Null, packageReader, source: "a"))
         {
             Assert.Same(packageReader, result.PackageReader);
             Assert.Equal("a", result.PackageSource);
             Assert.Same(Stream.Null, result.PackageStream);
             Assert.Equal(DownloadResourceResultStatus.Available, result.Status);
         }
 }
示例#2
0
        public void Dispose_IsIdempotent()
        {
            using (var stream = new TestStream())
                using (var result = new DownloadResourceResult(stream, source: null))
                {
                    result.Dispose();
                    result.Dispose();

                    Assert.Equal(1, stream.DisposeCallCount);
                }
        }
示例#3
0
        public static string GetResourceRoot(this DownloadResourceResult downloadResourceResult)
        {
            Argument.IsNotNull(() => downloadResourceResult);

            var fileStream = downloadResourceResult.PackageStream as FileStream;

            if (fileStream is not null)
            {
                return(fileStream.Name);
            }
            else
            {
                return(downloadResourceResult.PackageSource ?? string.Empty);
            }
        }
示例#4
0
 private IEnumerable <INugetPackageAssembly> NugetPackageAssemblies(DownloadResourceResult result)
 {
     return(result.PackageReader.GetLibItems().SelectMany(group => group.Items
                                                          .Where(s => AllFiles || Path.GetExtension(s) == ".dll")
                                                          .Select(s => {
         var identity = result.PackageReader.NuspecReader.GetIdentity();
         return new{
             Package = identity.Id,
             Version = identity.Version.Version.ToString(),
             DotNetFramework = group.TargetFramework.GetDotNetFrameworkName(DefaultFrameworkNameProvider.Instance),
             File = $@"{s.Replace(@"/", @"\")}"
         }
         .ActLike <INugetPackageAssembly>();
     })));
 }
            public void VerifySuccess(NuGetProject nugetProject)
            {
                // Arrange
                var result = new DownloadResourceResult(Stream.Null, PackageReader.Object);

                // Act & Assert
                Target.EnsurePackageCompatibility(
                    nugetProject,
                    PackageIdentityA,
                    result);

                PackageReader.Verify(x => x.GetMinClientVersion(), Times.Never);
                PackageReader.Verify(x => x.GetPackageTypes(), Times.Never);
                NuspecReader.Verify(x => x.GetMinClientVersion(), Times.Once);
                NuspecReader.Verify(x => x.GetPackageTypes(), Times.Once);
            }
示例#6
0
        private async Task ConsumeItemAsync(PackageIdentity package)
        {
            Console.WriteLine($"Processing {package}");

            DownloadResourceResult result = await PackageDownloader.GetDownloadResourceResultAsync(this.Sources, package, this.DownloadCache, this.DownloadDirectory, DebugLogger.Instance, CancellationToken.None);

            foreach (PackageDependencyGroup dependencyGroup in await result.PackageReader.GetPackageDependenciesAsync(CancellationToken.None))
            {
                foreach (PackageDependency dependency in dependencyGroup.Packages)
                {
                    PackageIdentity dependencyPackage = new PackageIdentity(dependency.Id, dependency.VersionRange.MaxVersion ?? dependency.VersionRange.MinVersion);

                    this.TryQueue(dependencyPackage);
                }
            }
        }
        /// <summary>
        /// A safe wait for the download task. Exceptions are caught and stored.
        /// </summary>
        public async Task EnsureResultAsync()
        {
            // This is a noop if this has been called before, or if the result is in the packages folder.
            if (!InPackagesFolder && _result == null)
            {
                try
                {
                    _result = await _downloadTask;
                }
                catch (Exception ex)
                {
                    _exception = ExceptionDispatchInfo.Capture(ex);
                }

                IsComplete = true;
            }
        }
        public async Task GetDownloadResourceResultAsync_SupportsDownloadResultWithoutPackageStream()
        {
            using (var test = new PackageDownloaderTest())
                using (var stream = new MemoryStream())
                    using (var zipArchive = new ZipArchive(stream, ZipArchiveMode.Create))
                        using (var packageReader = new PackageArchiveReader(zipArchive))
                        {
                            var resourceProvider = new Mock <INuGetResourceProvider>();
                            var resource         = new Mock <DownloadResource>();
                            var expectedResult   = new DownloadResourceResult(
                                packageReader,
                                test.SourceRepository.PackageSource.Source);

                            resource.Setup(x => x.GetDownloadResourceResultAsync(
                                               It.IsNotNull <PackageIdentity>(),
                                               It.IsNotNull <PackageDownloadContext>(),
                                               It.IsAny <string>(),
                                               It.IsNotNull <ILogger>(),
                                               It.IsAny <CancellationToken>()))
                            .ReturnsAsync(expectedResult);

                            resourceProvider.SetupGet(x => x.Name)
                            .Returns(nameof(DownloadResource) + "Provider");
                            resourceProvider.SetupGet(x => x.ResourceType)
                            .Returns(typeof(DownloadResource));
                            resourceProvider.Setup(x => x.TryCreate(
                                                       It.IsNotNull <SourceRepository>(),
                                                       It.IsAny <CancellationToken>()))
                            .ReturnsAsync(new Tuple <bool, INuGetResource>(true, resource.Object));

                            var sourceRepository = new SourceRepository(
                                test.SourceRepository.PackageSource,
                                new[] { resourceProvider.Object });

                            var actualResult = await PackageDownloader.GetDownloadResourceResultAsync(
                                sourceRepository,
                                test.PackageIdentity,
                                test.Context,
                                globalPackagesFolder : "",
                                logger : NullLogger.Instance,
                                token : CancellationToken.None);

                            Assert.Equal(DownloadResourceResultStatus.AvailableWithoutStream, actualResult.Status);
                            Assert.Same(expectedResult, actualResult);
                        }
        }
示例#9
0
            public async Task VerifySuccessAsync(NuGetProject nugetProject)
            {
                // Arrange
                var result = new DownloadResourceResult(Stream.Null, PackageReader.Object, string.Empty);

                // Act & Assert
                await Target.EnsurePackageCompatibilityAsync(
                    nugetProject,
                    PackageIdentityA,
                    result,
                    CancellationToken.None);

                PackageReader.Verify(x => x.GetMinClientVersion(), Times.Never);
                PackageReader.Verify(x => x.GetPackageTypes(), Times.Never);
                NuspecReader.Verify(x => x.GetMinClientVersion(), Times.Once);
                NuspecReader.Verify(x => x.GetPackageTypes(), Times.Once);
            }
        public override async Task <bool> InstallPackageAsync(
            PackageIdentity packageIdentity,
            DownloadResourceResult downloadResourceResult,
            INuGetProjectContext nuGetProjectContext,
            CancellationToken token)
        {
            if (downloadResourceResult == null)
            {
                throw new ArgumentNullException(nameof(downloadResourceResult));
            }

            var packageStream = downloadResourceResult.PackageStream;

            if (!packageStream.CanSeek)
            {
                throw new ArgumentException(ProjectManagement.Strings.PackageStreamShouldBeSeekable);
            }

            nuGetProjectContext.Log(ProjectManagement.MessageLevel.Info, Strings.InstallingPackage, packageIdentity);

            packageStream.Seek(0, SeekOrigin.Begin);
            var packageSupportedFrameworks = GetSupportedFrameworks(packageStream);
            var projectFrameworks          = _project.GetSupportedFrameworksAsync(token)
                                             .Result
                                             .Select(f => NuGetFramework.Parse(f.FullName));

            var args = new Dictionary <string, object>();

            args["Frameworks"] = projectFrameworks.Where(
                projectFramework =>
                IsCompatible(projectFramework, packageSupportedFrameworks)).ToArray();
            await _project.InstallPackageAsync(
                new NuGetPackageMoniker
            {
                Id      = packageIdentity.Id,
                Version = packageIdentity.Version.ToNormalizedString()
            },
                args,
                logger : null,
                progress : null,
                cancellationToken : token);

            return(true);
        }
        public override async Task <bool> InstallPackageAsync(
            PackageIdentity packageIdentity,
            DownloadResourceResult downloadResourceResult,
            INuGetProjectContext nuGetProjectContext,
            CancellationToken token)
        {
            return(await Runtime.RunInMainThread(async() => {
                // Check if this NuGet package is already installed and should be removed.
                ProjectPackageReference existingPackageReference = project.FindPackageReference(packageIdentity);
                if (existingPackageReference != null)
                {
                    if (ShouldRemoveExistingPackageReference(existingPackageReference, packageIdentity))
                    {
                        project.PackageReferences.Remove(existingPackageReference);
                    }
                    else
                    {
                        nuGetProjectContext.Log(
                            MessageLevel.Info,
                            GettextCatalog.GetString("Package '{0}' already installed.", packageIdentity));
                        return true;
                    }
                }

                bool developmentDependency = false;
                if (IsNuGetBuildPackagingPackage(packageIdentity))
                {
                    await GlobalPackagesExtractor.Extract(project.ParentSolution, packageIdentity, downloadResourceResult, token);

                    developmentDependency = true;
                    GenerateNuGetBuildPackagingTargets(packageIdentity);
                }

                var packageReference = ProjectPackageReference.Create(packageIdentity);
                if (developmentDependency)
                {
                    packageReference.Metadata.SetValue("PrivateAssets", "All");
                }
                project.PackageReferences.Add(packageReference);
                await SaveProject();
                return true;
            }));
        }
示例#12
0
        /// <summary>
        /// Asynchronously validates the compatibility of a single downloaded package.
        /// </summary>
        /// <param name="nuGetProject">The NuGet project. The type of the NuGet project determines the sorts or
        /// validations that are done.</param>
        /// <param name="packageIdentity">The identity of that package contained in the download result.</param>
        /// <param name="resourceResult">The downloaded package.</param>
        /// <param name="cancellationToken">A cancellation token.</param>.
        /// <returns>A task that represents the asynchronous operation.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="nuGetProject" />
        /// is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="packageIdentity" />
        /// is <c>null</c>.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="resourceResult" />
        /// is <c>null</c>.</exception>
        /// <exception cref="OperationCanceledException">Thrown if <paramref name="cancellationToken" />
        /// is cancelled.</exception>
        public async Task EnsurePackageCompatibilityAsync(
            NuGetProject nuGetProject,
            PackageIdentity packageIdentity,
            DownloadResourceResult resourceResult,
            CancellationToken cancellationToken)
        {
            if (nuGetProject == null)
            {
                throw new ArgumentNullException(nameof(nuGetProject));
            }

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

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

            cancellationToken.ThrowIfCancellationRequested();

            NuspecReader nuspecReader;

            if (resourceResult.PackageReader != null)
            {
                nuspecReader = await resourceResult.PackageReader.GetNuspecReaderAsync(cancellationToken);
            }
            else
            {
                using (var packageReader = new PackageArchiveReader(resourceResult.PackageStream, leaveStreamOpen: true))
                {
                    nuspecReader = packageReader.NuspecReader;
                }
            }

            EnsurePackageCompatibility(
                nuGetProject,
                packageIdentity,
                nuspecReader);
        }
            public void VerifyFailure(
                NuGetProject nugetProject,
                string expected)
            {
                // Arrange
                var result = new DownloadResourceResult(Stream.Null, PackageReader.Object);

                // Act & Assert
                var ex = Assert.Throws <PackagingException>(() =>
                                                            Target.EnsurePackageCompatibility(
                                                                nugetProject,
                                                                PackageIdentityA,
                                                                result));

                Assert.Equal(expected, ex.Message);
                PackageReader.Verify(x => x.GetMinClientVersion(), Times.Never);
                PackageReader.Verify(x => x.GetPackageTypes(), Times.Never);
                NuspecReader.Verify(x => x.GetMinClientVersion(), Times.Once);
                NuspecReader.Verify(x => x.GetPackageTypes(), Times.Once);
            }
        // This gets called for every package install, including dependencies, and is our only chance to handle dependency PackageIdentity instances
        // If the package is already installed, returns false.
        public override Task <bool> InstallPackageAsync(
            PackageIdentity packageIdentity,
            DownloadResourceResult downloadResourceResult,
            INuGetProjectContext nuGetProjectContext,
            CancellationToken token)
        {
            LogTo.Information(
                $"Installing plugin or dependency {packageIdentity.Id} {(packageIdentity.HasVersion ? packageIdentity.Version.ToNormalizedString() : string.Empty)}");

            if (packageIdentity.Id != Plugin.Identity.Id)
            {
                var dependency = Plugin.AddDependency(packageIdentity);

                foreach (var contentDir in dependency.GetContentDirectoryPath(this, _currentFramework))
                {
                    contentDir.CopyTo(_pluginHomeDirPath);
                }
            }

            return(base.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token));
        }
示例#15
0
            public async Task VerifyFailureAsync(
                NuGetProject nugetProject,
                string expected)
            {
                // Arrange
                var result = new DownloadResourceResult(Stream.Null, PackageReader.Object, string.Empty);

                // Act & Assert
                var ex = await Assert.ThrowsAsync <PackagingException>(() =>
                                                                       Target.EnsurePackageCompatibilityAsync(
                                                                           nugetProject,
                                                                           PackageIdentityA,
                                                                           result,
                                                                           CancellationToken.None));

                Assert.Equal(expected, ex.Message);
                PackageReader.Verify(x => x.GetMinClientVersion(), Times.Never);
                PackageReader.Verify(x => x.GetPackageTypes(), Times.Never);
                NuspecReader.Verify(x => x.GetMinClientVersion(), Times.Once);
                NuspecReader.Verify(x => x.GetPackageTypes(), Times.Once);
            }
        public static async Task Extract(
            Solution solution,
            PackageIdentity packageIdentity,
            DownloadResourceResult downloadResult,
            INuGetProjectContext context,
            CancellationToken token)
        {
            string globalPackagesFolder = await GetPackagesDirectory(solution);

            var defaultPackagePathResolver = new VersionFolderPathResolver(globalPackagesFolder);

            string hashPath = defaultPackagePathResolver.GetHashPath(packageIdentity.Id, packageIdentity.Version);

            if (File.Exists(hashPath))
            {
                return;
            }

            var logger              = new LoggerAdapter(context);
            var solutionManager     = new MonoDevelopSolutionManager(solution);
            var clientPolicyContext = ClientPolicyContext.GetClientPolicy(solutionManager.Settings, logger);

            var packageExtractionContext = new PackageExtractionContext(
                PackageSaveMode.Defaultv3,
                PackageExtractionBehavior.XmlDocFileSaveMode,
                clientPolicyContext,
                logger);

            downloadResult.PackageStream.Position = 0;
            await PackageExtractor.InstallFromSourceAsync(
                downloadResult.PackageSource,
                packageIdentity,
                stream => downloadResult.PackageStream.CopyToAsync(stream, BufferSize, token),
                defaultPackagePathResolver,
                packageExtractionContext,
                token);
        }
        public void EnsurePackageCompatibility(
            NuGetProject nuGetProject,
            PackageIdentity packageIdentity,
            DownloadResourceResult resourceResult)
        {
            NuspecReader nuspecReader;

            if (resourceResult.PackageReader != null)
            {
                nuspecReader = resourceResult.PackageReader.NuspecReader;
            }
            else
            {
                using (var packageReader = new PackageArchiveReader(resourceResult.PackageStream, leaveStreamOpen: true))
                {
                    nuspecReader = packageReader.NuspecReader;
                }
            }

            EnsurePackageCompatibility(
                nuGetProject,
                packageIdentity,
                nuspecReader);
        }
        public override Task <bool> InstallPackageAsync(
            PackageIdentity packageIdentity,
            DownloadResourceResult downloadResourceResult,
            INuGetProjectContext nuGetProjectContext,
            CancellationToken token)
        {
            if (InstallationContext == null)
            {
                throw new NullReferenceException(
                          "InstallationContext must be set before package install");
            }
            if (packageIdentity == null)
            {
                throw new ArgumentNullException(nameof(packageIdentity));
            }
            if (downloadResourceResult == null)
            {
                throw new ArgumentNullException(nameof(downloadResourceResult));
            }
            if (nuGetProjectContext == null)
            {
                throw new ArgumentNullException(nameof(nuGetProjectContext));
            }

            var packageReader = downloadResourceResult.PackageReader ?? new PackageArchiveReader(
                downloadResourceResult.PackageStream,
                leaveStreamOpen: true);
            var packageAssemblyReferences = GetRelativePackageAssemblyReferences(packageReader);

            InstallationContext.AddInstalledPackage(new InteractivePackage(
                                                        packageIdentity,
                                                        isExplicit: false, // This gets determined by InteractivePackageManager
                                                        assemblyReferences: RelativeToAbsolute(packageAssemblyReferences, packageIdentity)));

            return(Task.FromResult(true));
        }
示例#19
0
        /// <summary>
        /// This method ensures that the packages.config file is created and all the installed packages are added to it.
        /// </summary>
        /// <param name="packageToInstall">The nuget package to install with all its dependencies</param>
        /// <param name="packageReader">The <see cref="PackageReaderBase"/> to use in reading the package.</param>
        /// <param name="downloadResult">The <see cref="DownloadResourceResult"/> for the package.</param>
        /// <param name="nuGetFramework">The <see cref="NuGetFramework"/></param>
        /// <returns>The <see cref="NuspecReader"/> for reading the package's nuspec files.</returns>
        private async Task <NuspecReader> UpdatePackagesConfigFile(
            SourcePackageDependencyInfo packageToInstall,
            PackageReaderBase packageReader,
            DownloadResourceResult downloadResult,
            NuGetFramework nuGetFramework)
        {
            NuspecReader nuspecReader = await packageReader.GetNuspecReaderAsync(CancellationToken.None).ConfigureAwait(false);

            Dictionary <string, object> metadata = new Dictionary <string, object>()
            {
                { "Name", packageToInstall.Id },
                { "TargetFrameWork", nuGetFramework }
            };

            IDictionary <string, object> metadataObject = new ExpandoObject()  as IDictionary <string, object>;

            foreach (KeyValuePair <string, object> kvp in metadata)
            {
                metadataObject.Add(kvp.Key, kvp.Value);
            }

            Dictionary <string, object> meta = new Dictionary <string, object>
            {
                { "Name", metadataObject.ToList().FirstOrDefault().Value },
                { "TargetFramework", metadataObject.ToList().LastOrDefault().Value }
            };

            PackagesConfigNuGetProject packagesConfigNuGetProject = new PackagesConfigNuGetProject(this.project.DirectoryPath, meta);
            await packagesConfigNuGetProject.InstallPackageAsync(
                packageToInstall,
                downloadResult,
                new EmptyNuGetProjectContext(),
                CancellationToken.None);

            return(nuspecReader);
        }
示例#20
0
 public override Task <bool> InstallPackageAsync(PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult, INuGetProjectContext nuGetProjectContext, CancellationToken token)
 {
     throw new NotImplementedException();
 }
示例#21
0
        public override Task <bool> InstallPackageAsync(PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult,
                                                        INuGetProjectContext nuGetProjectContext, CancellationToken token)
        {
            _installedPackages.Add(packageIdentity);

            if (_fileSystem.Exist(new DirectoryPath(_pathResolver.GetInstallPath(packageIdentity))))
            {
                _log.Debug("Package {0} has already been installed.", packageIdentity.ToString());
                return(Task.FromResult(true));
            }
            return(base.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token));
        }
示例#22
0
        private List <PSResourceInfo> InstallPackage(
            IEnumerable <PSResourceInfo> pkgsToInstall, // those found to be required to be installed (includes Dependency packages as well)
            string repoUrl,
            PSCredential credential,
            bool isLocalRepo)
        {
            List <PSResourceInfo> pkgsSuccessfullyInstalled = new List <PSResourceInfo>();
            int totalPkgs = pkgsToInstall.Count();

            // Counters for tracking current package out of total
            int totalInstalledPkgCount = 0;

            foreach (PSResourceInfo pkg in pkgsToInstall)
            {
                totalInstalledPkgCount++;
                var tempInstallPath = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
                try
                {
                    // Create a temp directory to install to
                    var dir = Directory.CreateDirectory(tempInstallPath);  // should check it gets created properly
                                                                           // To delete file attributes from the existing ones get the current file attributes first and use AND (&) operator
                                                                           // with a mask (bitwise complement of desired attributes combination).
                                                                           // TODO: check the attributes and if it's read only then set it
                                                                           // attribute may be inherited from the parent
                                                                           // TODO:  are there Linux accommodations we need to consider here?
                    dir.Attributes &= ~FileAttributes.ReadOnly;

                    _cmdletPassedIn.WriteVerbose(string.Format("Begin installing package: '{0}'", pkg.Name));

                    if (!_quiet)
                    {
                        int    activityId        = 0;
                        int    percentComplete   = ((totalInstalledPkgCount * 100) / totalPkgs);
                        string activity          = string.Format("Installing {0}...", pkg.Name);
                        string statusDescription = string.Format("{0}% Complete", percentComplete);
                        _cmdletPassedIn.WriteProgress(
                            new ProgressRecord(activityId, activity, statusDescription));
                    }

                    // Create PackageIdentity in order to download
                    string createFullVersion = pkg.Version.ToString();
                    if (pkg.IsPrerelease)
                    {
                        createFullVersion = pkg.Version.ToString() + "-" + pkg.PrereleaseLabel;
                    }

                    if (!NuGetVersion.TryParse(createFullVersion, out NuGetVersion pkgVersion))
                    {
                        var message = String.Format("{0} package could not be installed with error: could not parse package '{0}' version '{1} into a NuGetVersion",
                                                    pkg.Name,
                                                    pkg.Version.ToString());
                        var ex = new ArgumentException(message);
                        var packageIdentityVersionParseError = new ErrorRecord(ex, "psdataFileNotExistError", ErrorCategory.ReadError, null);
                        _cmdletPassedIn.WriteError(packageIdentityVersionParseError);
                        _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase));
                        continue;
                    }

                    var pkgIdentity  = new PackageIdentity(pkg.Name, pkgVersion);
                    var cacheContext = new SourceCacheContext();

                    if (isLocalRepo)
                    {
                        /* Download from a local repository -- this is slightly different process than from a server */
                        var localResource = new FindLocalPackagesResourceV2(repoUrl);
                        var resource      = new LocalDownloadResource(repoUrl, localResource);

                        // Actually downloading the .nupkg from a local repo
                        var result = resource.GetDownloadResourceResultAsync(
                            identity: pkgIdentity,
                            downloadContext: new PackageDownloadContext(cacheContext),
                            globalPackagesFolder: tempInstallPath,
                            logger: NullLogger.Instance,
                            token: _cancellationToken).GetAwaiter().GetResult();

                        // Create the package extraction context
                        PackageExtractionContext packageExtractionContext = new PackageExtractionContext(
                            packageSaveMode: PackageSaveMode.Nupkg,
                            xmlDocFileSaveMode: PackageExtractionBehavior.XmlDocFileSaveMode,
                            clientPolicyContext: null,
                            logger: NullLogger.Instance);

                        // Extracting from .nupkg and placing files into tempInstallPath
                        result.PackageReader.CopyFiles(
                            destination: tempInstallPath,
                            packageFiles: result.PackageReader.GetFiles(),
                            extractFile: new PackageFileExtractor(
                                result.PackageReader.GetFiles(),
                                packageExtractionContext.XmlDocFileSaveMode).ExtractPackageFile,
                            logger: NullLogger.Instance,
                            token: _cancellationToken);
                        result.Dispose();
                    }
                    else
                    {
                        /* Download from a non-local repository */
                        // Set up NuGet API resource for download
                        PackageSource source = new PackageSource(repoUrl);
                        if (credential != null)
                        {
                            string password = new NetworkCredential(string.Empty, credential.Password).Password;
                            source.Credentials = PackageSourceCredential.FromUserInput(repoUrl, credential.UserName, password, true, null);
                        }
                        var provider = FactoryExtensionsV3.GetCoreV3(NuGet.Protocol.Core.Types.Repository.Provider);
                        SourceRepository repository = new SourceRepository(source, provider);

                        /* Download from a non-local repository -- ie server */
                        var downloadResource          = repository.GetResourceAsync <DownloadResource>().GetAwaiter().GetResult();
                        DownloadResourceResult result = null;
                        try
                        {
                            result = downloadResource.GetDownloadResourceResultAsync(
                                identity: pkgIdentity,
                                downloadContext: new PackageDownloadContext(cacheContext),
                                globalPackagesFolder: tempInstallPath,
                                logger: NullLogger.Instance,
                                token: _cancellationToken).GetAwaiter().GetResult();
                        }
                        catch (Exception e)
                        {
                            _cmdletPassedIn.WriteVerbose(string.Format("Error attempting download: '{0}'", e.Message));
                        }
                        finally
                        {
                            // Need to close the .nupkg
                            if (result != null)
                            {
                                result.Dispose();
                            }
                        }
                    }

                    _cmdletPassedIn.WriteVerbose(string.Format("Successfully able to download package from source to: '{0}'", tempInstallPath));

                    // pkgIdentity.Version.Version gets the version without metadata or release labels.
                    string newVersion = pkgIdentity.Version.ToNormalizedString();
                    string normalizedVersionNoPrereleaseLabel = newVersion;
                    if (pkgIdentity.Version.IsPrerelease)
                    {
                        // eg: 2.0.2
                        normalizedVersionNoPrereleaseLabel = pkgIdentity.Version.ToNormalizedString().Substring(0, pkgIdentity.Version.ToNormalizedString().IndexOf('-'));
                    }

                    string tempDirNameVersion        = isLocalRepo ? tempInstallPath : Path.Combine(tempInstallPath, pkgIdentity.Id.ToLower(), newVersion);
                    var    version4digitNoPrerelease = pkgIdentity.Version.Version.ToString();
                    string moduleManifestVersion     = string.Empty;
                    var    scriptPath = Path.Combine(tempDirNameVersion, pkg.Name + ".ps1");
                    var    modulePath = Path.Combine(tempDirNameVersion, pkg.Name + ".psd1");
                    // Check if the package is a module or a script
                    var isModule = File.Exists(modulePath);

                    string installPath;
                    if (_savePkg)
                    {
                        // For save the installation path is what is passed in via -Path
                        installPath = _pathsToInstallPkg.FirstOrDefault();

                        // If saving as nupkg simply copy the nupkg and move onto next iteration of loop
                        // asNupkg functionality only applies to Save-PSResource
                        if (_asNupkg)
                        {
                            var nupkgFile = pkgIdentity.ToString().ToLower() + ".nupkg";
                            File.Copy(Path.Combine(tempDirNameVersion, nupkgFile), Path.Combine(installPath, nupkgFile));

                            _cmdletPassedIn.WriteVerbose(string.Format("'{0}' moved into file path '{1}'", nupkgFile, installPath));
                            pkgsSuccessfullyInstalled.Add(pkg);

                            continue;
                        }
                    }
                    else
                    {
                        // PSModules:
                        /// ./Modules
                        /// ./Scripts
                        /// _pathsToInstallPkg is sorted by desirability, Find will pick the pick the first Script or Modules path found in the list
                        installPath = isModule ? _pathsToInstallPkg.Find(path => path.EndsWith("Modules", StringComparison.InvariantCultureIgnoreCase))
                                : _pathsToInstallPkg.Find(path => path.EndsWith("Scripts", StringComparison.InvariantCultureIgnoreCase));
                    }

                    if (isModule)
                    {
                        var moduleManifest = Path.Combine(tempDirNameVersion, pkgIdentity.Id + ".psd1");
                        if (!File.Exists(moduleManifest))
                        {
                            var message = String.Format("{0} package could not be installed with error: Module manifest file: {1} does not exist. This is not a valid PowerShell module.", pkgIdentity.Id, moduleManifest);

                            var ex = new ArgumentException(message);
                            var psdataFileDoesNotExistError = new ErrorRecord(ex, "psdataFileNotExistError", ErrorCategory.ReadError, null);
                            _cmdletPassedIn.WriteError(psdataFileDoesNotExistError);
                            _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase));
                            continue;
                        }

                        if (!Utils.TryParseModuleManifest(moduleManifest, _cmdletPassedIn, out Hashtable parsedMetadataHashtable))
                        {
                            // Ran into errors parsing the module manifest file which was found in Utils.ParseModuleManifest() and written.
                            continue;
                        }

                        moduleManifestVersion = parsedMetadataHashtable["ModuleVersion"] as string;

                        // Accept License verification
                        if (!_savePkg && !CallAcceptLicense(pkg, moduleManifest, tempInstallPath, newVersion))
                        {
                            continue;
                        }

                        // If NoClobber is specified, ensure command clobbering does not happen
                        if (_noClobber && !DetectClobber(pkg.Name, parsedMetadataHashtable))
                        {
                            continue;
                        }
                    }

                    // Delete the extra nupkg related files that are not needed and not part of the module/script
                    DeleteExtraneousFiles(pkgIdentity, tempDirNameVersion);

                    if (_includeXML)
                    {
                        CreateMetadataXMLFile(tempDirNameVersion, installPath, pkg, isModule);
                    }

                    MoveFilesIntoInstallPath(
                        pkg,
                        isModule,
                        isLocalRepo,
                        tempDirNameVersion,
                        tempInstallPath,
                        installPath,
                        newVersion,
                        moduleManifestVersion,
                        scriptPath);

                    _cmdletPassedIn.WriteVerbose(String.Format("Successfully installed package '{0}' to location '{1}'", pkg.Name, installPath));
                    pkgsSuccessfullyInstalled.Add(pkg);
                }
                catch (Exception e)
                {
                    _cmdletPassedIn.WriteError(
                        new ErrorRecord(
                            new PSInvalidOperationException(
                                message: $"Unable to successfully install package '{pkg.Name}': '{e.Message}'",
                                innerException: e),
                            "InstallPackageFailed",
                            ErrorCategory.InvalidOperation,
                            _cmdletPassedIn));
                    _pkgNamesToInstall.RemoveAll(x => x.Equals(pkg.Name, StringComparison.InvariantCultureIgnoreCase));
                }
                finally
                {
                    // Delete the temp directory and all its contents
                    _cmdletPassedIn.WriteVerbose(string.Format("Attempting to delete '{0}'", tempInstallPath));

                    if (Directory.Exists(tempInstallPath))
                    {
                        if (!TryDeleteDirectory(tempInstallPath, out ErrorRecord errorMsg))
                        {
                            _cmdletPassedIn.WriteError(errorMsg);
                        }
                        else
                        {
                            _cmdletPassedIn.WriteVerbose(String.Format("Successfully deleted '{0}'", tempInstallPath));
                        }
                    }
                }
            }

            return(pkgsSuccessfullyInstalled);
        }
示例#23
0
 /// <summary>
 /// This installs a package into the NuGetProject using the <see cref="Stream"/> passed in
 /// <param name="downloadResourceResult"></param>
 /// should be seekable
 /// </summary>
 /// <returns>
 /// Returns false if the package was already present in the NuGetProject. On successful installation,
 /// returns true
 /// </returns>
 public abstract Task <bool> InstallPackageAsync(
     PackageIdentity packageIdentity,
     DownloadResourceResult downloadResourceResult,
     INuGetProjectContext nuGetProjectContext,
     CancellationToken token);
示例#24
0
 // This gets called for every package install, including dependencies, and is our only chance to handle dependency PackageIdentity instances
 public override Task <bool> InstallPackageAsync(PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult,
                                                 INuGetProjectContext nuGetProjectContext, CancellationToken token)
 {
     _packageIdentities.Add(packageIdentity);
     return(base.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token));
 }
示例#25
0
        public override Task <bool> InstallPackageAsync(
            PackageIdentity packageIdentity,
            DownloadResourceResult downloadResourceResult,
            INuGetProjectContext nuGetProjectContext,
            CancellationToken token)
        {
            if (packageIdentity == null)
            {
                throw new ArgumentNullException(nameof(packageIdentity));
            }

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

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

            if (!downloadResourceResult.PackageStream.CanSeek)
            {
                throw new ArgumentException(Strings.PackageStreamShouldBeSeekable);
            }
            var packageFile = PackagePathResolver.GetInstallPath(packageIdentity);

            return(ConcurrencyUtilities.ExecuteWithFileLockedAsync(packageFile,
                                                                   action: cancellationToken =>
            {
                // 1. Set a default package extraction context, if necessary.
                PackageExtractionContext packageExtractionContext = nuGetProjectContext.PackageExtractionContext;
                if (packageExtractionContext == null)
                {
                    packageExtractionContext = new PackageExtractionContext(new LoggerAdapter(nuGetProjectContext));
                }

                // 2. Check if the Package already exists at root, if so, return false
                if (PackageExists(packageIdentity, packageExtractionContext.PackageSaveMode))
                {
                    nuGetProjectContext.Log(MessageLevel.Info, Strings.PackageAlreadyExistsInFolder, packageIdentity, Root);
                    return Task.FromResult(false);
                }

                nuGetProjectContext.Log(MessageLevel.Info, Strings.AddingPackageToFolder, packageIdentity, Path.GetFullPath(Root));

                // 3. Call PackageExtractor to extract the package into the root directory of this FileSystemNuGetProject
                downloadResourceResult.PackageStream.Seek(0, SeekOrigin.Begin);
                var addedPackageFilesList = new List <string>();

                if (downloadResourceResult.PackageReader != null)
                {
                    addedPackageFilesList.AddRange(
                        PackageExtractor.ExtractPackage(
                            downloadResourceResult.PackageReader,
                            downloadResourceResult.PackageStream,
                            PackagePathResolver,
                            packageExtractionContext,
                            cancellationToken));
                }
                else
                {
                    addedPackageFilesList.AddRange(
                        PackageExtractor.ExtractPackage(
                            downloadResourceResult.PackageStream,
                            PackagePathResolver,
                            packageExtractionContext,
                            cancellationToken));
                }

                var packageSaveMode = GetPackageSaveMode(nuGetProjectContext);
                if (packageSaveMode.HasFlag(PackageSaveMode.Nupkg))
                {
                    var packageFilePath = GetInstalledPackageFilePath(packageIdentity);
                    if (File.Exists(packageFilePath))
                    {
                        addedPackageFilesList.Add(packageFilePath);
                    }
                }

                // Pend all the package files including the nupkg file
                FileSystemUtility.PendAddFiles(addedPackageFilesList, Root, nuGetProjectContext);

                nuGetProjectContext.Log(MessageLevel.Info, Strings.AddedPackageToFolder, packageIdentity, Path.GetFullPath(Root));
                return Task.FromResult(true);
            },
                                                                   token: token));
        }
示例#26
0
        /// <summary>
        /// Asynchronously returns a <see cref="DownloadResourceResult" /> for a given package identity
        /// and source repository.
        /// </summary>
        /// <param name="sourceRepository">A source repository.</param>
        /// <param name="packageIdentity">A package identity.</param>
        /// <param name="downloadContext">A package download context.</param>
        /// <param name="globalPackagesFolder">A global packages folder path.</param>
        /// <param name="logger">A logger.</param>
        /// <param name="token">A cancellation token.</param>
        /// <returns>A task that represents the asynchronous operation.
        /// The task result (<see cref="Task{TResult}.Result" />) returns a <see cref="DownloadResourceResult" />
        /// instance.</returns>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="sourceRepository" />
        /// is either <c>null</c> or empty.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="packageIdentity" />
        /// is either <c>null</c> or empty.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="downloadContext" />
        /// is either <c>null</c> or empty.</exception>
        /// <exception cref="ArgumentNullException">Thrown if <paramref name="logger" />
        /// is either <c>null</c> or empty.</exception>
        /// <exception cref="OperationCanceledException">Thrown if <paramref name="token" />
        /// is cancelled.</exception>
        public static async Task <DownloadResourceResult> GetDownloadResourceResultAsync(
            SourceRepository sourceRepository,
            PackageIdentity packageIdentity,
            PackageDownloadContext downloadContext,
            string globalPackagesFolder,
            ILogger logger,
            CancellationToken token)
        {
            if (sourceRepository == null)
            {
                throw new ArgumentNullException(nameof(sourceRepository));
            }

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

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

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

            var downloadResource = await sourceRepository.GetResourceAsync <DownloadResource>(token);

            if (downloadResource == null)
            {
                throw new InvalidOperationException(
                          string.Format(
                              CultureInfo.CurrentCulture,
                              Strings.DownloadResourceNotFound,
                              sourceRepository.PackageSource.Source));
            }

            token.ThrowIfCancellationRequested();

            DownloadResourceResult result;

            try
            {
                result = await downloadResource.GetDownloadResourceResultAsync(
                    packageIdentity,
                    downloadContext,
                    globalPackagesFolder,
                    logger,
                    token);
            }
            catch (OperationCanceledException)
            {
                result = new DownloadResourceResult(DownloadResourceResultStatus.Cancelled);
            }

            if (result == null)
            {
                throw new FatalProtocolException(string.Format(
                                                     CultureInfo.CurrentCulture,
                                                     Strings.DownloadStreamNotAvailable,
                                                     packageIdentity,
                                                     sourceRepository.PackageSource.Source));
            }

            if (result.Status == DownloadResourceResultStatus.Cancelled)
            {
                throw new RetriableProtocolException(string.Format(
                                                         CultureInfo.CurrentCulture,
                                                         Strings.PackageCancelledFromSource,
                                                         packageIdentity,
                                                         sourceRepository.PackageSource.Source));
            }

            if (result.Status == DownloadResourceResultStatus.NotFound)
            {
                throw new FatalProtocolException(string.Format(
                                                     CultureInfo.CurrentCulture,
                                                     Strings.PackageNotFoundOnSource,
                                                     packageIdentity,
                                                     sourceRepository.PackageSource.Source));
            }

            if (result.PackageReader == null)
            {
                result.PackageStream.Seek(0, SeekOrigin.Begin);
                var packageReader = new PackageArchiveReader(result.PackageStream);
                result.PackageStream.Seek(0, SeekOrigin.Begin);
                result = new DownloadResourceResult(result.PackageStream, packageReader, sourceRepository.PackageSource.Source)
                {
                    SignatureVerified = result.SignatureVerified
                };
            }
            else if (result.Status != DownloadResourceResultStatus.AvailableWithoutStream)
            {
                // bind the source
                result = new DownloadResourceResult(result.PackageStream, result.PackageReader, sourceRepository.PackageSource.Source)
                {
                    SignatureVerified = result.SignatureVerified
                };
            }

            return(result);
        }
示例#27
0
 internal static bool SuccessSafe(this DownloadResourceResult downloadResourceResult)
 {
     return(downloadResourceResult != null && downloadResourceResult.Status == DownloadResourceResultStatus.Available);
 }
示例#28
0
 // This gets called for every package install, including dependencies, and is our only chance to handle dependency PackageIdentity instances
 public override Task <bool> InstallPackageAsync(PackageIdentity packageIdentity, DownloadResourceResult downloadResourceResult,
                                                 INuGetProjectContext nuGetProjectContext, CancellationToken token)
 {
     _installedPackages.AddPackage(packageIdentity, _currentFramework);
     Trace.Verbose($"Installing package or dependency {packageIdentity.Id} {(packageIdentity.HasVersion ? packageIdentity.Version.ToNormalizedString() : string.Empty)}");
     return(base.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token));
 }
示例#29
0
        public static async Task <DownloadResourceResult> GetDownloadResultAsync(
            HttpSource client,
            PackageIdentity identity,
            Uri uri,
            PackageDownloadContext downloadContext,
            string globalPackagesFolder,
            ILogger logger,
            CancellationToken token)
        {
            // Observe the NoCache argument.
            var directDownload = downloadContext.DirectDownload;
            DownloadResourceResult packageFromGlobalPackages = null;

            try
            {
                packageFromGlobalPackages = GlobalPackagesFolderUtility.GetPackage(
                    identity,
                    globalPackagesFolder);

                if (packageFromGlobalPackages != null)
                {
                    if (!downloadContext.SourceCacheContext.NoCache)
                    {
                        return(packageFromGlobalPackages);
                    }
                    else
                    {
                        // The package already exists in the global packages folder but the caller has requested NoCache,
                        // which means the package in the global packages folder should not be used. In this particular
                        // case, NoCache needs to imply DirectDownload.
                        directDownload = true;
                        packageFromGlobalPackages.Dispose();
                    }
                }
            }
            catch
            {
                packageFromGlobalPackages?.Dispose();
            }

            // Get the package from the source.
            for (var retry = 0; retry < 3; retry++)
            {
                try
                {
                    return(await client.ProcessStreamAsync(
                               new HttpSourceRequest(uri, logger)
                    {
                        IgnoreNotFounds = true,
                        MaxTries = 1
                    },
                               async packageStream =>
                    {
                        if (packageStream == null)
                        {
                            return new DownloadResourceResult(DownloadResourceResultStatus.NotFound);
                        }

                        if (directDownload)
                        {
                            return await DirectDownloadAsync(
                                client.PackageSource,
                                identity,
                                packageStream,
                                downloadContext,
                                token);
                        }
                        else
                        {
                            return await GlobalPackagesFolderUtility.AddPackageAsync(
                                client.PackageSource,
                                identity,
                                packageStream,
                                globalPackagesFolder,
                                downloadContext.ParentId,
                                downloadContext.ClientPolicyContext,
                                logger,
                                token);
                        }
                    },
                               downloadContext.SourceCacheContext,
                               logger,
                               token));
                }
                catch (OperationCanceledException)
                {
                    return(new DownloadResourceResult(DownloadResourceResultStatus.Cancelled));
                }
                catch (SignatureException)
                {
                    throw;
                }
                catch (Exception ex) when(retry < 2)
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_ErrorDownloading, identity, uri)
                                  + Environment.NewLine
                                  + ExceptionUtilities.DisplayMessage(ex);

                    logger.LogWarning(message);
                }
                catch (Exception ex)
                {
                    var message = string.Format(CultureInfo.CurrentCulture, Strings.Log_ErrorDownloading, identity, uri);

                    throw new FatalProtocolException(message, ex);
                }
            }

            throw new InvalidOperationException("Reached an unexpected point in the code");
        }
示例#30
0
        public override async Task <bool> InstallPackageAsync(
            PackageIdentity packageIdentity,
            DownloadResourceResult downloadResourceResult,
            INuGetProjectContext nuGetProjectContext,
            CancellationToken token)
        {
            if (packageIdentity == null)
            {
                throw new ArgumentNullException(nameof(packageIdentity));
            }

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

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

            if (downloadResourceResult.Status != DownloadResourceResultStatus.AvailableWithoutStream &&
                !downloadResourceResult.PackageStream.CanSeek)
            {
                throw new ArgumentException(Strings.PackageStreamShouldBeSeekable);
            }

            // Step-1: Check if the package already exists after setting the nuGetProjectContext
            ProjectSystem.NuGetProjectContext = nuGetProjectContext;

            var packageReference = (await GetInstalledPackagesAsync(token))
                                   .FirstOrDefault(p => p.PackageIdentity.Equals(packageIdentity));

            if (packageReference != null)
            {
                nuGetProjectContext.Log(MessageLevel.Warning, Strings.PackageAlreadyExistsInProject,
                                        packageIdentity, ProjectSystem.ProjectName);
                return(false);
            }

            // Step-2: Create PackageArchiveReader using the PackageStream and obtain the various item groups
            if (downloadResourceResult.Status != DownloadResourceResultStatus.AvailableWithoutStream)
            {
                downloadResourceResult.PackageStream.Seek(0, SeekOrigin.Begin);
            }

            // These casts enforce use of -Async(...) methods.
            var packageReader = downloadResourceResult.PackageReader
                                ?? new PackageArchiveReader(downloadResourceResult.PackageStream, leaveStreamOpen: true);
            IAsyncPackageContentReader packageContentReader = packageReader;
            IAsyncPackageCoreReader    packageCoreReader    = packageReader;

            var libItemGroups = await packageContentReader.GetLibItemsAsync(token);

            var referenceItemGroups = await packageContentReader.GetReferenceItemsAsync(token);

            var frameworkReferenceGroups = await packageContentReader.GetFrameworkItemsAsync(token);

            var contentFileGroups = await packageContentReader.GetContentItemsAsync(token);

            var buildFileGroups = await packageContentReader.GetBuildItemsAsync(token);

            var toolItemGroups = await packageContentReader.GetToolItemsAsync(token);

            // Step-3: Get the most compatible items groups for all items groups
            var hasCompatibleProjectLevelContent = false;

            var compatibleLibItemsGroup =
                MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, libItemGroups);
            var compatibleReferenceItemsGroup =
                MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, referenceItemGroups);
            var compatibleFrameworkReferencesGroup =
                MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, frameworkReferenceGroups);
            var compatibleContentFilesGroup =
                MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, contentFileGroups);
            var compatibleBuildFilesGroup =
                MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, buildFileGroups);
            var compatibleToolItemsGroup =
                MSBuildNuGetProjectSystemUtility.GetMostCompatibleGroup(ProjectSystem.TargetFramework, toolItemGroups);

            compatibleLibItemsGroup
                = MSBuildNuGetProjectSystemUtility.Normalize(compatibleLibItemsGroup);
            compatibleReferenceItemsGroup
                = MSBuildNuGetProjectSystemUtility.Normalize(compatibleReferenceItemsGroup);
            compatibleFrameworkReferencesGroup
                = MSBuildNuGetProjectSystemUtility.Normalize(compatibleFrameworkReferencesGroup);
            compatibleContentFilesGroup
                = MSBuildNuGetProjectSystemUtility.Normalize(compatibleContentFilesGroup);
            compatibleBuildFilesGroup
                = MSBuildNuGetProjectSystemUtility.Normalize(compatibleBuildFilesGroup);
            compatibleToolItemsGroup
                = MSBuildNuGetProjectSystemUtility.Normalize(compatibleToolItemsGroup);

            hasCompatibleProjectLevelContent = MSBuildNuGetProjectSystemUtility.IsValid(compatibleLibItemsGroup) ||
                                               MSBuildNuGetProjectSystemUtility.IsValid(compatibleFrameworkReferencesGroup) ||
                                               MSBuildNuGetProjectSystemUtility.IsValid(compatibleContentFilesGroup) ||
                                               MSBuildNuGetProjectSystemUtility.IsValid(compatibleBuildFilesGroup);

            // Check if package has any content for project
            var hasProjectLevelContent = libItemGroups.Any() || frameworkReferenceGroups.Any() ||
                                         contentFileGroups.Any() || buildFileGroups.Any();
            var onlyHasCompatibleTools = false;
            var onlyHasDependencies    = false;

            if (!hasProjectLevelContent)
            {
                // Since it does not have project-level content, check if it has dependencies or compatible tools
                // Note that we are not checking if it has compatible project level content, but, just that it has project level content
                // If the package has project-level content, but nothing compatible, we still need to throw
                // If a package does not have any project-level content, it can be a
                // Legacy solution level packages which only has compatible tools group
                onlyHasCompatibleTools = MSBuildNuGetProjectSystemUtility.IsValid(compatibleToolItemsGroup) && compatibleToolItemsGroup.Items.Any();
                if (!onlyHasCompatibleTools)
                {
                    // If it does not have compatible tool items either, check if it at least has dependencies
                    onlyHasDependencies = (await packageContentReader.GetPackageDependenciesAsync(token)).Any();
                }
            }
            else
            {
                var shortFramework = ProjectSystem.TargetFramework.GetShortFolderName();
                nuGetProjectContext.Log(MessageLevel.Debug, Strings.Debug_TargetFrameworkInfoPrefix, packageIdentity,
                                        GetMetadata <string>(NuGetProjectMetadataKeys.Name), shortFramework);
            }

            // Step-4: Check if there are any compatible items in the package or that this is not a package with only tools group. If not, throw
            if (!hasCompatibleProjectLevelContent &&
                !onlyHasCompatibleTools &&
                !onlyHasDependencies)
            {
                throw new InvalidOperationException(
                          string.Format(CultureInfo.CurrentCulture,
                                        Strings.UnableToFindCompatibleItems, packageIdentity.Id + " " + packageIdentity.Version.ToNormalizedString(), ProjectSystem.TargetFramework));
            }

            if (hasCompatibleProjectLevelContent)
            {
                var shortFramework = ProjectSystem.TargetFramework.GetShortFolderName();
                nuGetProjectContext.Log(MessageLevel.Debug, Strings.Debug_TargetFrameworkInfoPrefix, packageIdentity,
                                        GetMetadata <string>(NuGetProjectMetadataKeys.Name), shortFramework);
            }
            else if (onlyHasCompatibleTools)
            {
                nuGetProjectContext.Log(MessageLevel.Info, Strings.AddingPackageWithOnlyToolsGroup, packageIdentity,
                                        GetMetadata <string>(NuGetProjectMetadataKeys.Name));
            }
            else if (onlyHasDependencies)
            {
                nuGetProjectContext.Log(MessageLevel.Info, Strings.AddingPackageWithOnlyDependencies, packageIdentity,
                                        GetMetadata <string>(NuGetProjectMetadataKeys.Name));
            }

            // Step-5: Raise PackageInstalling event
            // At this point, GetInstalledPath is pointless since the package is, likely, not already installed. It will be empty
            // Using PackagePathResolver.GetInstallPath would be wrong, since, package version from the nuspec is always used
            var packageEventArgs = new PackageEventArgs(FolderNuGetProject, packageIdentity, installPath: string.Empty);

            if (PackageInstalling != null)
            {
                PackageInstalling(this, packageEventArgs);
            }
            PackageEventsProvider.Instance.NotifyInstalling(packageEventArgs);

            // Step-6: Install package to FolderNuGetProject
            await FolderNuGetProject.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token);

            // Step-7: Raise PackageInstalled event
            // Call GetInstalledPath to get the package installed path
            var packageInstallPath = FolderNuGetProject.GetInstalledPath(packageIdentity);

            packageEventArgs = new PackageEventArgs(FolderNuGetProject, packageIdentity, packageInstallPath);
            if (PackageInstalled != null)
            {
                PackageInstalled(this, packageEventArgs);
            }
            PackageEventsProvider.Instance.NotifyInstalled(packageEventArgs);

            // Step-8: MSBuildNuGetProjectSystem operations
            // Step-8.1: Add references to project
            if (!IsSkipAssemblyReferences(nuGetProjectContext) &&
                MSBuildNuGetProjectSystemUtility.IsValid(compatibleReferenceItemsGroup))
            {
                foreach (var referenceItem in compatibleReferenceItemsGroup.Items)
                {
                    if (IsAssemblyReference(referenceItem))
                    {
                        var referenceItemFullPath = Path.Combine(packageInstallPath, referenceItem);
                        var referenceName         = Path.GetFileName(referenceItem);

                        if (await ProjectSystem.ReferenceExistsAsync(referenceName))
                        {
                            await ProjectSystem.RemoveReferenceAsync(referenceName);
                        }

                        await ProjectSystem.AddReferenceAsync(referenceItemFullPath);
                    }
                }
            }

            // Step-8.2: Add Frameworkreferences to project
            if (!IsSkipAssemblyReferences(nuGetProjectContext) &&
                MSBuildNuGetProjectSystemUtility.IsValid(compatibleFrameworkReferencesGroup))
            {
                foreach (var frameworkReference in compatibleFrameworkReferencesGroup.Items)
                {
                    if (!await ProjectSystem.ReferenceExistsAsync(frameworkReference))
                    {
                        await ProjectSystem.AddFrameworkReferenceAsync(frameworkReference, packageIdentity.Id);
                    }
                }
            }

            // Step-8.3: Add Content Files
            if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleContentFilesGroup))
            {
                await MSBuildNuGetProjectSystemUtility.AddFilesAsync(
                    ProjectSystem,
                    packageCoreReader,
                    compatibleContentFilesGroup,
                    FileTransformers,
                    token);
            }

            // Step-8.4: Add Build imports
            if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleBuildFilesGroup))
            {
                foreach (var buildImportFile in compatibleBuildFilesGroup.Items)
                {
                    var fullImportFilePath = Path.Combine(packageInstallPath, buildImportFile);
                    ProjectSystem.AddImport(fullImportFilePath,
                                            fullImportFilePath.EndsWith(".props", StringComparison.OrdinalIgnoreCase) ? ImportLocation.Top : ImportLocation.Bottom);
                }
            }

            // Step-9: Install package to PackagesConfigNuGetProject
            await PackagesConfigNuGetProject.InstallPackageAsync(packageIdentity, downloadResourceResult, nuGetProjectContext, token);

            // Step-10: Add packages.config to MSBuildNuGetProject
            ProjectSystem.AddExistingFile(Path.GetFileName(PackagesConfigNuGetProject.FullPath));

            // Step 11: Raise PackageReferenceAdded event
            PackageReferenceAdded?.Invoke(this, packageEventArgs);
            PackageEventsProvider.Instance.NotifyReferenceAdded(packageEventArgs);

            // Step-12: Execute powershell script - install.ps1
            var anyFrameworkToolsGroup = toolItemGroups.FirstOrDefault(g => g.TargetFramework.Equals(NuGetFramework.AnyFramework));

            if (anyFrameworkToolsGroup != null)
            {
                var initPS1RelativePath = anyFrameworkToolsGroup.Items.Where(p =>
                                                                             p.StartsWith(PowerShellScripts.InitPS1RelativePath, StringComparison.OrdinalIgnoreCase)).FirstOrDefault();
                if (!string.IsNullOrEmpty(initPS1RelativePath))
                {
                    initPS1RelativePath = PathUtility.ReplaceAltDirSeparatorWithDirSeparator(
                        initPS1RelativePath);
                    await ProjectServices.ScriptService.ExecutePackageScriptAsync(
                        packageIdentity,
                        packageInstallPath,
                        initPS1RelativePath,
                        nuGetProjectContext,
                        throwOnFailure : true,
                        token : token);
                }
            }

            if (MSBuildNuGetProjectSystemUtility.IsValid(compatibleToolItemsGroup))
            {
                var installPS1RelativePath = compatibleToolItemsGroup.Items.FirstOrDefault(
                    p => p.EndsWith(Path.DirectorySeparatorChar + PowerShellScripts.Install, StringComparison.OrdinalIgnoreCase));
                if (!string.IsNullOrEmpty(installPS1RelativePath))
                {
                    await ProjectServices.ScriptService.ExecutePackageScriptAsync(
                        packageIdentity,
                        packageInstallPath,
                        installPS1RelativePath,
                        nuGetProjectContext,
                        throwOnFailure : true,
                        token : token);
                }
            }
            return(true);
        }