| File: FallbackPackagePathResolver.cs | Web Access |
| Project: src\nuget-client\src\NuGet.Core\NuGet.Packaging\NuGet.Packaging.csproj (NuGet.Packaging) |
// 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.Collections.Generic; using System.Globalization; using System.IO; using System.Linq; using NuGet.Common; using NuGet.Packaging.Core; using NuGet.Versioning; namespace NuGet.Packaging { public class FallbackPackagePathResolver { private readonly List<VersionFolderPathResolver> _pathResolvers; /// <summary> /// Creates a package folder path resolver that scans multiple folders to find a package. /// </summary> /// <param name="pathContext">NuGet paths loaded from NuGet.Config settings.</param> public FallbackPackagePathResolver(INuGetPathContext pathContext) : this(pathContext.UserPackageFolder, pathContext.FallbackPackageFolders) { } public FallbackPackagePathResolver(string userPackageFolder, IEnumerable<string> fallbackPackageFolders) { if (fallbackPackageFolders == null) { throw new ArgumentNullException(nameof(fallbackPackageFolders)); } if (userPackageFolder == null) { throw new ArgumentNullException(nameof(userPackageFolder)); } var packageFolders = new List<string>(); // The user's packages folder may not exist, this is expected if the fallback // folders contain all packages. if (Directory.Exists(userPackageFolder)) { packageFolders.Add(userPackageFolder); } // All fallback folders must exist foreach (var path in fallbackPackageFolders) { if (!Directory.Exists(path)) { var message = string.Format( CultureInfo.CurrentCulture, Strings.FallbackFolderNotFound, path); throw new PackagingException(message); } packageFolders.Add(path); } // Create path resolvers for each source. _pathResolvers = PathUtility.GetUniquePathsBasedOnOS(packageFolders) .Select(path => new VersionFolderPathResolver(path)) .ToList(); } /// <summary> /// Returns the root directory of an installed package. /// </summary> /// <param name="packageId">Package id.</param> /// <param name="version">Package version.</param> /// <returns>Returns the path if the package exists in any of the folders. Null if the package does not exist.</returns> public string? GetPackageDirectory(string packageId, string version) { return GetPackageDirectory(packageId, NuGetVersion.Parse(version)); } /// <summary> /// Returns the root directory of an installed package. /// </summary> /// <param name="packageId">Package id.</param> /// <param name="version">Package version.</param> /// <returns>Returns the path if the package exists in any of the folders. Null if the package does not exist.</returns> public string? GetPackageDirectory(string packageId, NuGetVersion version) { // Find the package var info = GetPackageInfo(packageId, version); // Find the folder using the resolver for the folder where it was found. return info?.PathResolver.GetInstallPath(packageId, version); } /// <summary> /// Returns the package info along with a path resolver specific to the folder where the package exists. /// </summary> /// <param name="packageId">Package id.</param> /// <param name="version">Package version.</param> /// <returns>Returns the package info if the package exists in any of the folders. Null if the package does not exist.</returns> public FallbackPackagePathInfo? GetPackageInfo(string packageId, NuGetVersion version) { if (string.IsNullOrEmpty(packageId)) { throw new ArgumentException( string.Format( CultureInfo.CurrentCulture, Strings.StringCannotBeNullOrEmpty, nameof(packageId))); } if (version == null) { throw new ArgumentNullException(nameof(version)); } // Check each folder for the package. foreach (var resolver in _pathResolvers) { var hashPath = resolver.GetHashPath(packageId, version); if (File.Exists(hashPath)) { // If the hash exists we can use this path return new FallbackPackagePathInfo(packageId, version, resolver); } // Perf: As hashPath is commonly found and the GetNupkgMetadataPath call is relatively // expensive, only request nupkgMetadataFilePath if hashPath isn't found var nupkgMetadataFilePath = resolver.GetNupkgMetadataPath(packageId, version); if (File.Exists(nupkgMetadataFilePath)) { // If the hash exists we can use this path return new FallbackPackagePathInfo(packageId, version, resolver); } } // Not found return null; } } }