Example #1
0
        public static NuGetVersion GetNuGetPackageVersion(this ICakeContext context, FilePath file)
        {
            var f   = file.MakeAbsolute(context.Environment).FullPath;
            var par = new NuGet.Packaging.PackageArchiveReader(System.IO.File.OpenRead(f));
            var id  = par.GetIdentity();

            return(id.Version);
        }
Example #2
0
        public static bool IsNuGetPublished(this ICakeContext context, FilePath file, string nugetSource = DefaultNuGetSource)
        {
            var f   = file.MakeAbsolute(context.Environment).FullPath;
            var par = new NuGet.Packaging.PackageArchiveReader(System.IO.File.OpenRead(f));
            var id  = par.GetIdentity();

            return(IsNuGetPublished(context, id.Id, id.Version, nugetSource));
        }
Example #3
0
        /// <summary>
        /// Uses a copy function to install a package to a global packages directory.
        /// </summary>
        /// <param name="copyToAsync">
        /// A function which should copy the package to the provided destination stream.
        /// </param>
        /// <param name="packageExtractionContext">
        /// The version folder path context, which encapsulates all of the parameters to observe
        /// while installing the package.
        /// </param>
        /// <param name="token">The cancellation token.</param>
        /// <returns>
        /// True if the package was installed. False if the package already exists and therefore
        /// resulted in no copy operation.
        /// </returns>
        public static async Task <bool> InstallFromSourceAsync(
            string source,
            PackageIdentity packageIdentity,
            Func <Stream, Task> copyToAsync,
            VersionFolderPathResolver versionFolderPathResolver,
            PackageExtractionContext packageExtractionContext,
            CancellationToken token,
            Guid parentId = default(Guid))
        {
            if (copyToAsync == null)
            {
                throw new ArgumentNullException(nameof(copyToAsync));
            }

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

            var logger       = packageExtractionContext.Logger;
            var extractionId = Guid.NewGuid();

            using (var telemetry = TelemetryActivity.CreateTelemetryActivityWithNewOperationId(parentId))
            {
                var targetPath   = versionFolderPathResolver.GetInstallPath(packageIdentity.Id, packageIdentity.Version);
                var targetNuspec = versionFolderPathResolver.GetManifestFilePath(packageIdentity.Id, packageIdentity.Version);
                var targetNupkg  = versionFolderPathResolver.GetPackageFilePath(packageIdentity.Id, packageIdentity.Version);
                var hashPath     = versionFolderPathResolver.GetHashPath(packageIdentity.Id, packageIdentity.Version);

                logger.LogVerbose(
                    $"Acquiring lock for the installation of {packageIdentity.Id} {packageIdentity.Version}");

                // Acquire the lock on a nukpg before we extract it to prevent the race condition when multiple
                // processes are extracting to the same destination simultaneously
                return(await ConcurrencyUtilities.ExecuteWithFileLockedAsync(targetNupkg,
                                                                             action : async cancellationToken =>
                {
                    // If this is the first process trying to install the target nupkg, go ahead
                    // After this process successfully installs the package, all other processes
                    // waiting on this lock don't need to install it again.
                    if (!File.Exists(hashPath))
                    {
                        logger.LogVerbose(
                            $"Acquired lock for the installation of {packageIdentity.Id} {packageIdentity.Version}");

                        logger.LogMinimal(string.Format(
                                              CultureInfo.CurrentCulture,
                                              Strings.Log_InstallingPackage,
                                              packageIdentity.Id,
                                              packageIdentity.Version));

                        cancellationToken.ThrowIfCancellationRequested();

                        // We do not stop the package extraction after this point
                        // based on CancellationToken, but things can still be stopped if the process is killed.
                        if (Directory.Exists(targetPath))
                        {
                            // If we had a broken restore, clean out the files first
                            var info = new DirectoryInfo(targetPath);

                            foreach (var file in info.GetFiles())
                            {
                                file.Delete();
                            }

                            foreach (var dir in info.GetDirectories())
                            {
                                dir.Delete(true);
                            }
                        }
                        else
                        {
                            Directory.CreateDirectory(targetPath);
                        }

                        var targetTempNupkg = Path.Combine(targetPath, Path.GetRandomFileName());
                        var tempHashPath = Path.Combine(targetPath, Path.GetRandomFileName());
                        var packageSaveMode = packageExtractionContext.PackageSaveMode;

                        try
                        {
                            // Extract the nupkg
                            using (var nupkgStream = new FileStream(
                                       targetTempNupkg,
                                       FileMode.Create,
                                       FileAccess.ReadWrite,
                                       FileShare.ReadWrite | FileShare.Delete,
                                       bufferSize: 4096,
                                       useAsync: true))
                            {
                                await copyToAsync(nupkgStream);
                                nupkgStream.Seek(0, SeekOrigin.Begin);

                                using (var packageReader = new PackageArchiveReader(nupkgStream))
                                {
                                    if (packageSaveMode.HasFlag(PackageSaveMode.Nuspec) || packageSaveMode.HasFlag(PackageSaveMode.Files))
                                    {
                                        telemetry.StartIntervalMeasure();

                                        await VerifyPackageSignatureAsync(
                                            source,
                                            telemetry.OperationId,
                                            packageIdentity,
                                            packageExtractionContext,
                                            packageReader,
                                            token);

                                        telemetry.EndIntervalMeasure(PackagingConstants.PackageVerifyDurationName);
                                    }

                                    var nuspecFile = packageReader.GetNuspecFile();
                                    if ((packageSaveMode & PackageSaveMode.Nuspec) == PackageSaveMode.Nuspec)
                                    {
                                        packageReader.ExtractFile(nuspecFile, targetNuspec, logger);
                                    }

                                    if ((packageSaveMode & PackageSaveMode.Files) == PackageSaveMode.Files)
                                    {
                                        var nupkgFileName = Path.GetFileName(targetNupkg);
                                        var nuspecFileName = Path.GetFileName(targetNuspec);
                                        var hashFileName = Path.GetFileName(hashPath);
                                        var packageFiles = packageReader.GetFiles()
                                                           .Where(file => ShouldInclude(file, hashFileName));
                                        var packageFileExtractor = new PackageFileExtractor(
                                            packageFiles,
                                            packageExtractionContext.XmlDocFileSaveMode);
                                        packageReader.CopyFiles(
                                            targetPath,
                                            packageFiles,
                                            packageFileExtractor.ExtractPackageFile,
                                            logger,
                                            token);
                                    }

                                    string packageHash;
                                    nupkgStream.Position = 0;
                                    packageHash = Convert.ToBase64String(new CryptoHashProvider("SHA512").CalculateHash(nupkgStream));

                                    File.WriteAllText(tempHashPath, packageHash);
                                }
                            }
                        }
                        catch (SignatureException)
                        {
                            try
                            {
                                if (File.Exists(targetTempNupkg))
                                {
                                    File.Delete(targetTempNupkg);
                                }

                                if (Directory.Exists(targetPath))
                                {
                                    Directory.Delete(targetPath);
                                }
                            }
                            catch (IOException ex)
                            {
                                logger.LogWarning(string.Format(
                                                      CultureInfo.CurrentCulture,
                                                      Strings.ErrorUnableToDeleteFile,
                                                      targetTempNupkg,
                                                      ex.Message));
                            }

                            telemetry.TelemetryEvent = new PackageExtractionTelemetryEvent(
                                packageExtractionContext.PackageSaveMode,
                                NuGetOperationStatus.Failed,
                                ExtractionSource.DownloadResource,
                                packageIdentity);
                            throw;
                        }

                        // Now rename the tmp file
                        if ((packageExtractionContext.PackageSaveMode & PackageSaveMode.Nupkg) ==
                            PackageSaveMode.Nupkg)
                        {
                            File.Move(targetTempNupkg, targetNupkg);
                        }
                        else
                        {
                            try
                            {
                                File.Delete(targetTempNupkg);
                            }
                            catch (IOException ex)
                            {
                                logger.LogWarning(string.Format(
                                                      CultureInfo.CurrentCulture,
                                                      Strings.ErrorUnableToDeleteFile,
                                                      targetTempNupkg,
                                                      ex.Message));
                            }
                        }

                        // Note: PackageRepository relies on the hash file being written out as the
                        // final operation as part of a package install to assume a package was fully installed.
                        // Rename the tmp hash file
                        File.Move(tempHashPath, hashPath);

                        logger.LogVerbose($"Completed installation of {packageIdentity.Id} {packageIdentity.Version}");

                        telemetry.TelemetryEvent = new PackageExtractionTelemetryEvent(
                            packageExtractionContext.PackageSaveMode,
                            NuGetOperationStatus.Succeeded,
                            ExtractionSource.DownloadResource,
                            packageIdentity);
                        return true;
                    }
                    else
                    {
                        logger.LogVerbose("Lock not required - Package already installed "
                                          + $"{packageIdentity.Id} {packageIdentity.Version}");

                        telemetry.TelemetryEvent = new PackageExtractionTelemetryEvent(
                            packageExtractionContext.PackageSaveMode,
                            NuGetOperationStatus.NoOp,
                            ExtractionSource.DownloadResource,
                            packageIdentity);
                        return false;
                    }
                },
                                                                             token : token));
            }
        }
Example #4
0
        public static async Task <IEnumerable <string> > ExtractPackageAsync(
            string source,
            Stream packageStream,
            PackagePathResolver packagePathResolver,
            PackageExtractionContext packageExtractionContext,
            CancellationToken token,
            Guid parentId = default(Guid))
        {
            if (packageStream == null)
            {
                throw new ArgumentNullException(nameof(packageStream));
            }

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

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

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

            var packageSaveMode    = packageExtractionContext.PackageSaveMode;
            var filesAdded         = new List <string>();
            var nupkgStartPosition = packageStream.Position;

            using (var telemetry = TelemetryActivity.CreateTelemetryActivityWithNewOperationId(parentId))
            {
                using (var packageReader = new PackageArchiveReader(packageStream, leaveStreamOpen: true))
                {
                    var packageIdentityFromNuspec = await packageReader.GetIdentityAsync(CancellationToken.None);

                    var installPath          = packagePathResolver.GetInstallPath(packageIdentityFromNuspec);
                    var packageDirectoryInfo = Directory.CreateDirectory(installPath);
                    var packageDirectory     = packageDirectoryInfo.FullName;

                    try
                    {
                        telemetry.StartIntervalMeasure();

                        await VerifyPackageSignatureAsync(
                            source,
                            telemetry.OperationId,
                            packageIdentityFromNuspec,
                            packageExtractionContext,
                            packageReader,
                            token);

                        telemetry.EndIntervalMeasure(PackagingConstants.PackageVerifyDurationName);
                    }
                    catch (SignatureException)
                    {
                        telemetry.TelemetryEvent = new PackageExtractionTelemetryEvent(
                            packageExtractionContext.PackageSaveMode,
                            NuGetOperationStatus.Failed,
                            ExtractionSource.NuGetFolderProject,
                            packageIdentityFromNuspec);
                        throw;
                    }

                    var packageFiles = await packageReader.GetPackageFilesAsync(packageSaveMode, token);

                    if ((packageSaveMode & PackageSaveMode.Nuspec) == PackageSaveMode.Nuspec)
                    {
                        var sourceNuspecFile = packageFiles.Single(p => PackageHelper.IsManifest(p));

                        var targetNuspecPath = Path.Combine(
                            packageDirectory,
                            packagePathResolver.GetManifestFileName(packageIdentityFromNuspec));

                        // Extract the .nuspec file with a well known file name.
                        filesAdded.Add(packageReader.ExtractFile(
                                           sourceNuspecFile,
                                           targetNuspecPath,
                                           packageExtractionContext.Logger));

                        packageFiles = packageFiles.Except(new[] { sourceNuspecFile });
                    }

                    var packageFileExtractor = new PackageFileExtractor(packageFiles, packageExtractionContext.XmlDocFileSaveMode);

                    filesAdded.AddRange(await packageReader.CopyFilesAsync(
                                            packageDirectory,
                                            packageFiles,
                                            packageFileExtractor.ExtractPackageFile,
                                            packageExtractionContext.Logger,
                                            token));

                    if ((packageSaveMode & PackageSaveMode.Nupkg) == PackageSaveMode.Nupkg)
                    {
                        // During package extraction, nupkg is the last file to be created
                        // Since all the packages are already created, the package stream is likely positioned at its end
                        // Reset it to the nupkgStartPosition
                        packageStream.Seek(nupkgStartPosition, SeekOrigin.Begin);

                        var nupkgFilePath = Path.Combine(
                            packageDirectory,
                            packagePathResolver.GetPackageFileName(packageIdentityFromNuspec));

                        filesAdded.Add(packageStream.CopyToFile(nupkgFilePath));
                    }

                    // Now, copy satellite files unless requested to not copy them
                    if (packageExtractionContext.CopySatelliteFiles)
                    {
                        filesAdded.AddRange(await CopySatelliteFilesAsync(
                                                packageReader,
                                                packagePathResolver,
                                                packageSaveMode,
                                                packageExtractionContext,
                                                token));
                    }
                    telemetry.TelemetryEvent = new PackageExtractionTelemetryEvent(
                        packageExtractionContext.PackageSaveMode,
                        NuGetOperationStatus.Succeeded,
                        ExtractionSource.NuGetFolderProject,
                        packageIdentityFromNuspec);
                }

                return(filesAdded);
            }
        }
        public static IEnumerable <string> ExtractPackage(
            Stream packageStream,
            PackagePathResolver packagePathResolver,
            PackageExtractionContext packageExtractionContext,
            CancellationToken token)
        {
            if (packageStream == null)
            {
                throw new ArgumentNullException(nameof(packageStream));
            }

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

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

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

            var packageSaveMode = packageExtractionContext.PackageSaveMode;

            var filesAdded = new List <string>();

            var nupkgStartPosition = packageStream.Position;

            using (var packageReader = new PackageArchiveReader(packageStream, leaveStreamOpen: true))
            {
                var packageIdentityFromNuspec = packageReader.GetIdentity();

                var packageDirectoryInfo = Directory.CreateDirectory(packagePathResolver.GetInstallPath(packageIdentityFromNuspec));
                var packageDirectory     = packageDirectoryInfo.FullName;

                var packageFiles         = packageReader.GetPackageFiles(packageSaveMode);
                var packageFileExtractor = new PackageFileExtractor(packageFiles, packageExtractionContext.XmlDocFileSaveMode);

                filesAdded.AddRange(packageReader.CopyFiles(
                                        packageDirectory,
                                        packageFiles,
                                        packageFileExtractor.ExtractPackageFile,
                                        packageExtractionContext.Logger,
                                        token));

                var nupkgFilePath = Path.Combine(packageDirectory, packagePathResolver.GetPackageFileName(packageIdentityFromNuspec));
                if (packageSaveMode.HasFlag(PackageSaveMode.Nupkg))
                {
                    // During package extraction, nupkg is the last file to be created
                    // Since all the packages are already created, the package stream is likely positioned at its end
                    // Reset it to the nupkgStartPosition
                    packageStream.Seek(nupkgStartPosition, SeekOrigin.Begin);
                    filesAdded.Add(packageStream.CopyToFile(nupkgFilePath));
                }

                // Now, copy satellite files unless requested to not copy them
                if (packageExtractionContext.CopySatelliteFiles)
                {
                    filesAdded.AddRange(CopySatelliteFiles(
                                            packageReader,
                                            packagePathResolver,
                                            packageSaveMode,
                                            packageExtractionContext,
                                            token));
                }
            }

            return(filesAdded);
        }
        public static async Task InstallFromSourceAsync(
            Func <Stream, Task> copyToAsync,
            VersionFolderPathContext versionFolderPathContext,
            CancellationToken token)
        {
            if (copyToAsync == null)
            {
                throw new ArgumentNullException(nameof(copyToAsync));
            }

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

            var packagePathResolver = new VersionFolderPathResolver(
                versionFolderPathContext.PackagesDirectory, versionFolderPathContext.NormalizeFileNames);

            var packageIdentity = versionFolderPathContext.Package;
            var logger          = versionFolderPathContext.Logger;

            var targetPath   = packagePathResolver.GetInstallPath(packageIdentity.Id, packageIdentity.Version);
            var targetNuspec = packagePathResolver.GetManifestFilePath(packageIdentity.Id, packageIdentity.Version);
            var targetNupkg  = packagePathResolver.GetPackageFilePath(packageIdentity.Id, packageIdentity.Version);
            var hashPath     = packagePathResolver.GetHashPath(packageIdentity.Id, packageIdentity.Version);

            logger.LogVerbose(
                $"Acquiring lock for the installation of {packageIdentity.Id} {packageIdentity.Version}");

            // Acquire the lock on a nukpg before we extract it to prevent the race condition when multiple
            // processes are extracting to the same destination simultaneously
            await ConcurrencyUtilities.ExecuteWithFileLockedAsync(targetNupkg,
                                                                  action : async cancellationToken =>
            {
                // If this is the first process trying to install the target nupkg, go ahead
                // After this process successfully installs the package, all other processes
                // waiting on this lock don't need to install it again.
                if (!File.Exists(hashPath))
                {
                    logger.LogVerbose(
                        $"Acquired lock for the installation of {packageIdentity.Id} {packageIdentity.Version}");

                    logger.LogMinimal(string.Format(
                                          CultureInfo.CurrentCulture,
                                          Strings.Log_InstallingPackage,
                                          packageIdentity.Id,
                                          packageIdentity.Version));

                    cancellationToken.ThrowIfCancellationRequested();

                    // We do not stop the package extraction after this point
                    // based on CancellationToken, but things can still be stopped if the process is killed.
                    if (Directory.Exists(targetPath))
                    {
                        // If we had a broken restore, clean out the files first
                        var info = new DirectoryInfo(targetPath);

                        foreach (var file in info.GetFiles())
                        {
                            file.Delete();
                        }

                        foreach (var dir in info.GetDirectories())
                        {
                            dir.Delete(true);
                        }
                    }
                    else
                    {
                        Directory.CreateDirectory(targetPath);
                    }

                    var targetTempNupkg = Path.Combine(targetPath, Path.GetRandomFileName());
                    var tempHashPath    = Path.Combine(targetPath, Path.GetRandomFileName());
                    var packageSaveMode = versionFolderPathContext.PackageSaveMode;

                    // Extract the nupkg
                    using (var nupkgStream = new FileStream(
                               targetTempNupkg,
                               FileMode.Create,
                               FileAccess.ReadWrite,
                               FileShare.ReadWrite | FileShare.Delete,
                               bufferSize: 4096,
                               useAsync: true))
                    {
                        await copyToAsync(nupkgStream);
                        nupkgStream.Seek(0, SeekOrigin.Begin);

                        using (var packageReader = new PackageArchiveReader(nupkgStream))
                        {
                            var nuspecFile = packageReader.GetNuspecFile();
                            if ((packageSaveMode & PackageSaveMode.Nuspec) == PackageSaveMode.Nuspec)
                            {
                                packageReader.ExtractFile(nuspecFile, targetNuspec, logger);
                                if (versionFolderPathContext.FixNuspecIdCasing)
                                {
                                    // DNU REFACTORING TODO: delete the hacky FixNuSpecIdCasing()
                                    // and uncomment logic below after we
                                    // have implementation of NuSpecFormatter.Read()
                                    // Fixup the casing of the nuspec on disk to match what we expect
                                    nuspecFile = Directory.EnumerateFiles(targetPath, "*" + PackagingCoreConstants.NuspecExtension).Single();
                                    FixNuSpecIdCasing(nuspecFile, targetNuspec, packageIdentity.Id);
                                }
                            }

                            if ((packageSaveMode & PackageSaveMode.Files) == PackageSaveMode.Files)
                            {
                                var nupkgFileName = Path.GetFileName(targetNupkg);
                                var hashFileName  = Path.GetFileName(hashPath);
                                var packageFiles  = packageReader.GetFiles()
                                                    .Where(file => ShouldInclude(file, nupkgFileName, nuspecFile, hashFileName));
                                var packageFileExtractor = new PackageFileExtractor(
                                    packageFiles,
                                    versionFolderPathContext.XmlDocFileSaveMode);
                                packageReader.CopyFiles(
                                    targetPath,
                                    packageFiles,
                                    packageFileExtractor.ExtractPackageFile,
                                    logger,
                                    token);
                            }

                            string packageHash;
                            nupkgStream.Position = 0;
                            packageHash          = Convert.ToBase64String(new CryptoHashProvider("SHA512").CalculateHash(nupkgStream));

                            File.WriteAllText(tempHashPath, packageHash);
                        }
                    }

                    // Now rename the tmp file
                    if ((versionFolderPathContext.PackageSaveMode & PackageSaveMode.Nupkg) ==
                        PackageSaveMode.Nupkg)
                    {
                        File.Move(targetTempNupkg, targetNupkg);
                    }
                    else
                    {
                        try
                        {
                            File.Delete(targetTempNupkg);
                        }
                        catch (IOException ex)
                        {
                            logger.LogWarning(string.Format(
                                                  CultureInfo.CurrentCulture,
                                                  Strings.ErrorUnableToDeleteFile,
                                                  targetTempNupkg,
                                                  ex.Message));
                        }
                    }

                    // Note: PackageRepository relies on the hash file being written out as the
                    // final operation as part of a package install to assume a package was fully installed.
                    // Rename the tmp hash file
                    File.Move(tempHashPath, hashPath);

                    logger.LogVerbose($"Completed installation of {packageIdentity.Id} {packageIdentity.Version}");
                }
                else
                {
                    logger.LogVerbose("Lock not required - Package already installed "
                                      + $"{packageIdentity.Id} {packageIdentity.Version}");
                }

                return(0);
            },
                                                                  token : token);
        }
        public List <DllInfo> GetInstallPackagesDllPath(PackageWrapper packageWrapper, ref FolderNuGetProject project)
        {
            List <DllInfo> dllinfo = new List <DllInfo>();

            var packageIdentity = packageWrapper.rootPackageIdentity;
            var packageFilePath = project.GetInstalledPackageFilePath(packageIdentity);

            if (!string.IsNullOrWhiteSpace(packageFilePath))
            {
                _logger.LogInformation(packageFilePath);


                var archiveReader  = new NuGet.Packaging.PackageArchiveReader(packageFilePath, null, null);
                var nugetFramwork  = NuGetFramework.ParseFrameworkName(NugetHelper.Instance.GetTargetFramwork(), new DefaultFrameworkNameProvider());
                var referenceGroup = NugetHelper.Instance.GetMostCompatibleGroup(nugetFramwork, archiveReader.GetReferenceItems());
                if (referenceGroup != null)
                {
                    foreach (var group in referenceGroup.Items)
                    {
                        var    installedPackagedFolder = project.GetInstalledPath(packageIdentity);
                        string installedDllPath        = string.Empty;
                        if (NugetHelper.Instance.GetNugetSettings().RunningOnwindows)
                        {
                            installedDllPath = Path.Combine(installedPackagedFolder, group.Replace("/", "\\"));
                        }
                        else
                        {
                            installedDllPath = Path.Combine(installedPackagedFolder, group);
                        }


                        var installedDllFolder = Path.GetDirectoryName(installedDllPath);
                        var dllName            = Path.GetFileName(installedDllPath);
                        var extension          = Path.GetExtension(installedDllPath).ToLower();
                        var processor          = group.GetProcessor();

                        _logger.LogInformation($"dll Path: {installedDllPath}");

                        //check if file path exist , then only add
                        if (File.Exists(installedDllPath) && extension == ".dll")
                        {
                            dllinfo.Add(
                                new DllInfo()
                            {
                                name        = dllName,
                                path        = installedDllPath,
                                framework   = referenceGroup.TargetFramework.DotNetFrameworkName,
                                processor   = processor,
                                rootPackage = packageIdentity.Id
                            }
                                );
                        }

                        //also , try to cross refer this with expected folder name to avoid version mismatch
                    }
                }
            }


            return(dllinfo);
        }