| File: Utility\GlobalPackagesFolderUtility.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Protocol\NuGet.Protocol.csproj (NuGet.Protocol) |
// Copyright (c) .NET Foundation. All rights reserved. // Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information. using System; using System.IO; using System.Threading; using System.Threading.Tasks; using NuGet.Common; using NuGet.Packaging; using NuGet.Packaging.Core; using NuGet.Packaging.PackageExtraction; using NuGet.Packaging.Signing; using NuGet.Protocol.Core.Types; namespace NuGet.Protocol { public static class GlobalPackagesFolderUtility { private const int BufferSize = 8192; public static DownloadResourceResult? GetPackage(PackageIdentity packageIdentity, string globalPackagesFolder) { if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } if (globalPackagesFolder == null) { throw new ArgumentNullException(nameof(globalPackagesFolder)); } var defaultPackagePathResolver = new VersionFolderPathResolver(globalPackagesFolder); var nupkgMetadataPath = defaultPackagePathResolver.GetNupkgMetadataPath(packageIdentity.Id, packageIdentity.Version); var hashPath = defaultPackagePathResolver.GetHashPath(packageIdentity.Id, packageIdentity.Version); var installPath = defaultPackagePathResolver.GetInstallPath( packageIdentity.Id, packageIdentity.Version); var nupkgPath = defaultPackagePathResolver.GetPackageFilePath( packageIdentity.Id, packageIdentity.Version); if (File.Exists(nupkgMetadataPath)) { return CreateDownloadResourceResult(nupkgPath, installPath); } else if (File.Exists(hashPath)) { LocalFolderUtility.GenerateNupkgMetadataFile(nupkgPath, installPath, hashPath, nupkgMetadataPath); return CreateDownloadResourceResult(nupkgPath, installPath); } return null; } private static DownloadResourceResult CreateDownloadResourceResult(string nupkgPath, string installPath) { Stream? stream = null; PackageReaderBase? packageReader = null; try { stream = File.Open(nupkgPath, FileMode.Open, FileAccess.Read, FileShare.Read); packageReader = new PackageFolderReader(installPath); return new DownloadResourceResult(stream, packageReader, source: null) { SignatureVerified = true }; } catch { if (stream != null) { stream.Dispose(); } if (packageReader != null) { packageReader.Dispose(); } throw; } } public static async Task<DownloadResourceResult> AddPackageAsync( string source, PackageIdentity packageIdentity, Stream packageStream, string globalPackagesFolder, Guid parentId, ClientPolicyContext? clientPolicyContext, ILogger logger, CancellationToken token) { if (packageIdentity == null) { throw new ArgumentNullException(nameof(packageIdentity)); } if (packageStream == null) { throw new ArgumentNullException(nameof(packageStream)); } if (globalPackagesFolder == null) { throw new ArgumentNullException(nameof(globalPackagesFolder)); } // The following call adds it to the global packages folder. // Addition is performed using ConcurrentUtils, such that, // multiple processes may add at the same time var extractionContext = new PackageExtractionContext( PackageSaveMode.Defaultv3, PackageExtractionBehavior.XmlDocFileSaveMode, clientPolicyContext, logger); var versionFolderPathResolver = new VersionFolderPathResolver(globalPackagesFolder); await PackageExtractor.InstallFromSourceAsync( source, packageIdentity, stream => packageStream.CopyToAsync(stream, BufferSize, token), versionFolderPathResolver, extractionContext, token, parentId); // It is hard for to enforce this via the compiler, but at this point we are guaranteed to have the package. // If there were installation failured, PackageExtractor.InstallFromSourceAsync would have thrown. var package = GetPackage(packageIdentity, globalPackagesFolder)!; return package; } } }