From e04c530d340d1f0f6a753565737284bc41d23fde Mon Sep 17 00:00:00 2001 From: Annie Li Date: Thu, 25 May 2023 19:18:47 -0700 Subject: [PATCH 01/47] able to download a package via nuget api --- .../ToolPackage/ToolPackageDownloader.cs | 81 +++++++++++++++++++ .../ToolInstallGlobalOrToolPathCommand.cs | 15 ++++ 2 files changed, 96 insertions(+) create mode 100644 src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs new file mode 100644 index 000000000000..82d2fae7b593 --- /dev/null +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -0,0 +1,81 @@ +// Copyright (c) .NET Foundation and contributors. All rights reserved. +// Licensed under the MIT license. See LICENSE file in the project root for full license information. +// + +using System; +using System.Collections.Generic; +using System.IO; +using System.Threading.Tasks; +using Microsoft.DotNet.Cli.NuGetPackageDownloader; +using Microsoft.DotNet.ToolPackage; +using Microsoft.DotNet.Tools; +using Microsoft.Extensions.EnvironmentAbstractions; +using NuGet.Packaging; +using NuGet.Versioning; + + +namespace Microsoft.DotNet.Cli.ToolPackage +{ + internal class ToolPackageDownloader + { + private readonly INuGetPackageDownloader _nugetPackageDownloader; + protected readonly DirectoryPath _tempPackagesDir; + + public ToolPackageDownloader( + INuGetPackageDownloader nugetPackageDownloader = null, + string tempDirPath = null + ) + { + _tempPackagesDir = new DirectoryPath(tempDirPath ?? PathUtilities.CreateTempSubdirectory()); + _nugetPackageDownloader = nugetPackageDownloader ?? + new NuGetPackageDownloader.NuGetPackageDownloader(_tempPackagesDir); + } + + public async Task InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, + VersionRange versionRange = null, + string targetFramework = null, + string verbosity = null) + { + var tempDirsToDelete = new List(); + var tempFilesToDelete = new List(); + + var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId); + tempFilesToDelete.Add(packagePath); + + // Look fo nuget package on disk and read the version + await using FileStream packageStream = File.OpenRead(packagePath); + PackageArchiveReader reader = new PackageArchiveReader(packageStream); + var version = new NuspecReader(reader.GetNuspec()).GetVersion(); + + var tempExtractionDir = Path.GetDirectoryName(packagePath); + var tempToolExtractionDir = Path.Combine(tempExtractionDir, packageId.ToString(), version.ToString(), "tools"); + + tempDirsToDelete.Add(tempExtractionDir); + + var filesInPackage = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(tempToolExtractionDir)); + + if (Directory.Exists(packagePath)) + { + throw new ToolPackageException( + string.Format( + CommonLocalizableStrings.ToolPackageConflictPackageId, + packageId, + version.ToNormalizedString())); + } + + return new ToolPackageInstance(id: packageId, + version: version, + packageDirectory: new DirectoryPath(tempExtractionDir), + assetsJsonParentDirectory: new DirectoryPath(tempExtractionDir)); + //cleanup + /*foreach (var dir in tempDirsToDelete) + { + if (Directory.Exists(dir)) + { + Directory.Delete(dir, true); + } + }*/ + + } + } +} diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 9d08af45df0d..25c0793abe15 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -10,6 +10,7 @@ using System.Transactions; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.NuGetPackageDownloader; +using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ShellShim; using Microsoft.DotNet.ToolPackage; @@ -96,6 +97,7 @@ public override int Execute() Path.GetFullPath(_configFilePath))); } + Console.WriteLine("1"); VersionRange versionRange = _parseResult.GetVersionRange(); DirectoryPath? toolPath = null; @@ -104,6 +106,7 @@ public override int Execute() toolPath = new DirectoryPath(_toolPath); } + //same class for IToolpackagestore, storequery and installer (IToolPackageStore toolPackageStore, IToolPackageStoreQuery toolPackageStoreQuery, IToolPackageInstaller toolPackageInstaller) = _createToolPackageStoresAndInstaller(toolPath, _forwardRestoreArguments); @@ -122,7 +125,18 @@ public override int Execute() try { + ToolPackageStoreAndQuery downloaderStore = ToolPackageFactory.CreateConcreteToolPackageStore(toolPath); + var toolPackageDownloader = new ToolPackageDownloader(); + var res = toolPackageDownloader.InstallPackageAsync( + new PackageLocation(nugetConfig: configFile, additionalFeeds: _source), + packageId: _packageId, + versionRange: versionRange, + targetFramework: _framework, verbosity: _verbosity + ).GetAwaiter().GetResult(); + + // Original Code Below IToolPackage package = null; + // transaction scope: if something fails in the middle undo the process using (var scope = new TransactionScope( TransactionScopeOption.Required, TimeSpan.Zero)) @@ -150,6 +164,7 @@ public override int Execute() string appHostSourceDirectory = _shellShimTemplateFinder.ResolveAppHostSourceDirectoryAsync(_architectureOption, framework, RuntimeInformation.ProcessArchitecture).Result; IShellShimRepository shellShimRepository = _createShellShimRepository(appHostSourceDirectory, toolPath); + // actual executable that runs foreach (var command in package.Commands) { shellShimRepository.CreateShim(command.Executable, command.Name, package.PackagedShims); From 6556b540351a80531d5413e3d3ed4086373bc939 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Thu, 15 Jun 2023 07:55:24 -0700 Subject: [PATCH 02/47] commit before switch branch --- .../ToolPackage/ToolPackageDownloader.cs | 161 +++++++++++++++++- .../dotnet/ToolPackage/ToolPackageFactory.cs | 2 +- .../ToolPackage/ToolPackageInstaller.cs | 5 +- .../ToolInstallGlobalOrToolPathCommand.cs | 50 +++++- 4 files changed, 203 insertions(+), 15 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 82d2fae7b593..ccacc89a2560 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -5,13 +5,26 @@ using System; using System.Collections.Generic; using System.IO; +using System.Runtime.InteropServices; using System.Threading.Tasks; +using Microsoft.Build.Evaluation; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Tools; using Microsoft.Extensions.EnvironmentAbstractions; +using NuGet.Client; +using NuGet.Common; +using NuGet.ContentModel; +using NuGet.Frameworks; +using NuGet.LibraryModel; using NuGet.Packaging; +using NuGet.Packaging.Core; +using NuGet.ProjectModel; +using NuGet.Repositories; +using NuGet.RuntimeModel; using NuGet.Versioning; +using static Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext; +using static System.Formats.Asn1.AsnWriter; namespace Microsoft.DotNet.Cli.ToolPackage @@ -20,15 +33,79 @@ internal class ToolPackageDownloader { private readonly INuGetPackageDownloader _nugetPackageDownloader; protected readonly DirectoryPath _tempPackagesDir; + protected readonly DirectoryPath _storePackagesDir; public ToolPackageDownloader( INuGetPackageDownloader nugetPackageDownloader = null, - string tempDirPath = null - ) + string tempDirPath = null + ) { _tempPackagesDir = new DirectoryPath(tempDirPath ?? PathUtilities.CreateTempSubdirectory()); + + _storePackagesDir = new DirectoryPath ("C:\\Users\\liannie\\.dotnet\\tools\\.store"); _nugetPackageDownloader = nugetPackageDownloader ?? - new NuGetPackageDownloader.NuGetPackageDownloader(_tempPackagesDir); + new NuGetPackageDownloader.NuGetPackageDownloader(_storePackagesDir); + } + + private static void AddToolsAssets( + ManagedCodeConventions managedCodeConventions, + LockFileTargetLibrary lockFileLib, + ContentItemCollection contentItems, + IReadOnlyList orderedCriteria) + { + var toolsGroup = GetLockFileItems( + orderedCriteria, + contentItems, + managedCodeConventions.Patterns.ToolsAssemblies); + + lockFileLib.ToolsAssemblies.AddRange(toolsGroup); + } + + private static IEnumerable GetLockFileItems( + IReadOnlyList criteria, + ContentItemCollection items, + params PatternSet[] patterns) + { + return GetLockFileItems(criteria, items, additionalAction: null, patterns); + } + + private static IEnumerable GetLockFileItems( + IReadOnlyList criteria, + ContentItemCollection items, + Action additionalAction, + params PatternSet[] patterns) + { + // Loop through each criteria taking the first one that matches one or more items. + foreach (var managedCriteria in criteria) + { + var group = items.FindBestItemGroup( + managedCriteria, + patterns); + + if (group != null) + { + foreach (var item in group.Items) + { + var newItem = new LockFileItem(item.Path); + object locale; + if (item.Properties.TryGetValue("locale", out locale)) + { + newItem.Properties["locale"] = (string)locale; + } + object related; + if (item.Properties.TryGetValue("related", out related)) + { + newItem.Properties["related"] = (string)related; + } + additionalAction?.Invoke(newItem); + yield return newItem; + } + // Take only the first group that has items + break; + } + } + + yield break; } public async Task InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, @@ -39,21 +116,37 @@ public async Task InstallPackageAsync(PackageLocation packageLocat var tempDirsToDelete = new List(); var tempFilesToDelete = new List(); - var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId); + //var versionFromVersionRange = versionRange?.ToString("N", new VersionRangeFormatter()) ?? "*"; + Console.WriteLine(versionRange); + //Console.WriteLine(versionFromVersionRange); + var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); + var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId, null, packageSourceLocation); tempFilesToDelete.Add(packagePath); + var tempExtractionDir = Path.GetDirectoryName(packagePath); + + // Look fo nuget package on disk and read the version await using FileStream packageStream = File.OpenRead(packagePath); PackageArchiveReader reader = new PackageArchiveReader(packageStream); var version = new NuspecReader(reader.GetNuspec()).GetVersion(); - var tempExtractionDir = Path.GetDirectoryName(packagePath); + + var tempToolExtractionDir = Path.Combine(tempExtractionDir, packageId.ToString(), version.ToString(), "tools"); + var nupkgDir = Path.Combine(tempExtractionDir, packageId.ToString(), version.ToString()); tempDirsToDelete.Add(tempExtractionDir); var filesInPackage = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(tempToolExtractionDir)); - + + var packageHash = Convert.ToBase64String(new CryptoHashProvider("SHA512").CalculateHash(reader.GetNuspec())); + var hashPath = new VersionFolderPathResolver(tempExtractionDir).GetHashPath(packageId.ToString(), version); + File.WriteAllText(hashPath, packageHash); + + //Copy nupkg file to hash file folder + File.Copy(packagePath, Path.Combine(nupkgDir, Path.GetFileName(packagePath))); + if (Directory.Exists(packagePath)) { throw new ToolPackageException( @@ -63,6 +156,60 @@ public async Task InstallPackageAsync(PackageLocation packageLocat version.ToNormalizedString())); } + // create asset files + + // To get runtimeGraph: + var runtimeJsonPath = "C:\\Program Files\\dotnet\\sdk\\7.0.200\\RuntimeIdentifierGraph.json"; + var runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonPath); + + // Create ManagedCodeConventions: + var conventions = new ManagedCodeConventions(runtimeGraph); + + // Create LockFileTargetLibrary + var lockFileLib = new LockFileTargetLibrary() + { + Name = packageId.ToString(), + Version = version, + Type = LibraryType.Package, + PackageType = new List() { PackageType.DotnetTool } + }; + + // Create NuGetv3LocalRepository + NuGetv3LocalRepository localRepository = new(tempExtractionDir); + Console.WriteLine(tempExtractionDir); + var package = localRepository.FindPackage(packageId.ToString(), version); + + var collection = new ContentItemCollection(); + collection.Load(package.Files); + + // Create criteria + var managedCriteria = new List(1); + + var currentTargetFramework = NuGetFramework.Parse("net8.0"); + + // Not supporting FallbackFramework for tools + var standardCriteria = conventions.Criteria.ForFrameworkAndRuntime( + //NuGetFramework.Parse(targetFramework), + currentTargetFramework, + RuntimeInformation.RuntimeIdentifier); + managedCriteria.Add(standardCriteria); + + // To be implemented + if (lockFileLib.PackageType.Contains(PackageType.DotnetTool)) + { + AddToolsAssets(conventions, lockFileLib, collection, managedCriteria); + } + + var lockFile = new LockFile(); + var lockFileTarget = new LockFileTarget() + { + TargetFramework = currentTargetFramework, + RuntimeIdentifier = RuntimeInformation.RuntimeIdentifier + }; + lockFileTarget.Libraries.Add(lockFileLib); + lockFile.Targets.Add(lockFileTarget); + new LockFileFormat().Write(Path.Combine(tempExtractionDir, "project.assets.json"), lockFile); + return new ToolPackageInstance(id: packageId, version: version, packageDirectory: new DirectoryPath(tempExtractionDir), @@ -75,7 +222,7 @@ public async Task InstallPackageAsync(PackageLocation packageLocat Directory.Delete(dir, true); } }*/ - + } } } diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs b/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs index 4a6d2640a5e4..4fe99f321418 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs @@ -60,7 +60,7 @@ private static DirectoryPath GetPackageLocation() return new DirectoryPath(CliFolderPathCalculator.ToolsPackagePath); } - private static ToolPackageStoreAndQuery CreateConcreteToolPackageStore( + public static ToolPackageStoreAndQuery CreateConcreteToolPackageStore( DirectoryPath? nonGlobalLocation = null) { var toolPackageStore = diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index e049949cb237..a7aaf8891d39 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -49,6 +49,7 @@ public IToolPackage InstallPackage( { try { + // create a temp project with a package reference to the tool and download it var stageDirectory = _store.GetRandomStagingDirectory(); Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; @@ -76,6 +77,7 @@ public IToolPackage InstallPackage( var version = _store.GetStagedPackageVersion(stageDirectory, packageId); var packageDirectory = _store.GetPackageDirectory(packageId, version); + if (Directory.Exists(packageDirectory.Value)) { throw new ToolPackageException( @@ -88,7 +90,8 @@ public IToolPackage InstallPackage( Directory.CreateDirectory(packageRootDirectory.Value); FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(stageDirectory.Value, packageDirectory.Value)); rollbackDirectory = packageDirectory.Value; - + Console.WriteLine("In toolPackageInstaller the package directory value is: "); + Console.WriteLine(packageDirectory.Value); return new ToolPackageInstance(id: packageId, version: version, packageDirectory: packageDirectory, diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 25c0793abe15..0ebc6ba10759 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -97,8 +97,9 @@ public override int Execute() Path.GetFullPath(_configFilePath))); } - Console.WriteLine("1"); VersionRange versionRange = _parseResult.GetVersionRange(); + Console.WriteLine("The versionRange at execute is: "); + Console.WriteLine(versionRange); DirectoryPath? toolPath = null; if (!string.IsNullOrEmpty(_toolPath)) @@ -125,17 +126,53 @@ public override int Execute() try { - ToolPackageStoreAndQuery downloaderStore = ToolPackageFactory.CreateConcreteToolPackageStore(toolPath); - var toolPackageDownloader = new ToolPackageDownloader(); - var res = toolPackageDownloader.InstallPackageAsync( + //ToolPackageStoreAndQuery downloaderStore = ToolPackageFactory.CreateConcreteToolPackageStore(toolPath); + IToolPackage package = null; + // transaction scope: if something fails in the middle undo the process + using (var scope = new TransactionScope( + TransactionScopeOption.Required, + TimeSpan.Zero)) + { + var toolPackageDownloader = new ToolPackageDownloader(); + package = toolPackageDownloader.InstallPackageAsync( new PackageLocation(nugetConfig: configFile, additionalFeeds: _source), packageId: _packageId, versionRange: versionRange, targetFramework: _framework, verbosity: _verbosity ).GetAwaiter().GetResult(); + NuGetFramework framework; + if (string.IsNullOrEmpty(_framework) && package.Frameworks.Count() > 0) + { + framework = package.Frameworks + .Where(f => f.Version < (new NuGetVersion(Product.Version)).Version) + .MaxBy(f => f.Version); + } + else + { + framework = string.IsNullOrEmpty(_framework) ? + null : + NuGetFramework.Parse(_framework); + } + + string appHostSourceDirectory = _shellShimTemplateFinder.ResolveAppHostSourceDirectoryAsync(_architectureOption, framework, RuntimeInformation.ProcessArchitecture).Result; + IShellShimRepository shellShimRepository = _createShellShimRepository(appHostSourceDirectory, toolPath); + + Console.WriteLine(package.Commands); + + // actual executable that runs + foreach (var command in package.Commands) + { + shellShimRepository.CreateShim(command.Executable, command.Name, package.PackagedShims); + } + + scope.Complete(); + } + + + // Original Code Below - IToolPackage package = null; + /*IToolPackage package = null; // transaction scope: if something fails in the middle undo the process using (var scope = new TransactionScope( TransactionScopeOption.Required, @@ -171,7 +208,8 @@ public override int Execute() } scope.Complete(); - } + }*/ + foreach (string w in package.Warnings) { From 983897d7543c4fe5175c5fc33361b36e05062198 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Tue, 27 Jun 2023 15:57:03 -0700 Subject: [PATCH 03/47] tool package downloader using nuget API for installing global tools --- .../ToolPackage/ToolPackageDownloader.cs | 94 ++++++++----------- 1 file changed, 38 insertions(+), 56 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index ccacc89a2560..0b2f71680853 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -7,8 +7,8 @@ using System.IO; using System.Runtime.InteropServices; using System.Threading.Tasks; -using Microsoft.Build.Evaluation; using Microsoft.DotNet.Cli.NuGetPackageDownloader; +using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Tools; using Microsoft.Extensions.EnvironmentAbstractions; @@ -23,8 +23,6 @@ using NuGet.Repositories; using NuGet.RuntimeModel; using NuGet.Versioning; -using static Microsoft.ApplicationInsights.MetricDimensionNames.TelemetryContext; -using static System.Formats.Asn1.AsnWriter; namespace Microsoft.DotNet.Cli.ToolPackage @@ -33,18 +31,19 @@ internal class ToolPackageDownloader { private readonly INuGetPackageDownloader _nugetPackageDownloader; protected readonly DirectoryPath _tempPackagesDir; - protected readonly DirectoryPath _storePackagesDir; + protected readonly DirectoryPath _tempStageDir; + private readonly IToolPackageStore _toolPackageStore; public ToolPackageDownloader( + IToolPackageStore store, INuGetPackageDownloader nugetPackageDownloader = null, - string tempDirPath = null - ) - { + string tempDirPath = null + ){ + _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); _tempPackagesDir = new DirectoryPath(tempDirPath ?? PathUtilities.CreateTempSubdirectory()); - - _storePackagesDir = new DirectoryPath ("C:\\Users\\liannie\\.dotnet\\tools\\.store"); + _tempStageDir = _toolPackageStore.GetRandomStagingDirectory(); _nugetPackageDownloader = nugetPackageDownloader ?? - new NuGetPackageDownloader.NuGetPackageDownloader(_storePackagesDir); + new NuGetPackageDownloader.NuGetPackageDownloader(_tempStageDir); } private static void AddToolsAssets( @@ -111,41 +110,34 @@ private static IEnumerable GetLockFileItems( public async Task InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, VersionRange versionRange = null, string targetFramework = null, - string verbosity = null) + string verbosity = null + ) { - var tempDirsToDelete = new List(); - var tempFilesToDelete = new List(); - - //var versionFromVersionRange = versionRange?.ToString("N", new VersionRangeFormatter()) ?? "*"; - Console.WriteLine(versionRange); - //Console.WriteLine(versionFromVersionRange); var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId, null, packageSourceLocation); - tempFilesToDelete.Add(packagePath); var tempExtractionDir = Path.GetDirectoryName(packagePath); - + Directory.CreateDirectory(_tempStageDir.Value); - // Look fo nuget package on disk and read the version - await using FileStream packageStream = File.OpenRead(packagePath); - PackageArchiveReader reader = new PackageArchiveReader(packageStream); - var version = new NuspecReader(reader.GetNuspec()).GetVersion(); + // Look fo nuget package on disk and read the version + NuGetVersion version; - + using (FileStream packageStream = File.OpenRead(packagePath)) + { + PackageArchiveReader reader = new PackageArchiveReader(packageStream); + version = new NuspecReader(reader.GetNuspec()).GetVersion(); + + var packageHash = Convert.ToBase64String(new CryptoHashProvider("SHA512").CalculateHash(reader.GetNuspec())); + var hashPath = new VersionFolderPathResolver(_tempStageDir.Value).GetHashPath(packageId.ToString(), version); + + Directory.CreateDirectory(Path.GetDirectoryName(hashPath)); + File.WriteAllText(hashPath, packageHash); + } - var tempToolExtractionDir = Path.Combine(tempExtractionDir, packageId.ToString(), version.ToString(), "tools"); + var packageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + var tempToolExtractionDir = Path.Combine(tempExtractionDir, packageId.ToString(), version.ToString()); var nupkgDir = Path.Combine(tempExtractionDir, packageId.ToString(), version.ToString()); - - tempDirsToDelete.Add(tempExtractionDir); - - var filesInPackage = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(tempToolExtractionDir)); - - var packageHash = Convert.ToBase64String(new CryptoHashProvider("SHA512").CalculateHash(reader.GetNuspec())); - var hashPath = new VersionFolderPathResolver(tempExtractionDir).GetHashPath(packageId.ToString(), version); - File.WriteAllText(hashPath, packageHash); - - //Copy nupkg file to hash file folder - File.Copy(packagePath, Path.Combine(nupkgDir, Path.GetFileName(packagePath))); + var filesInPackage = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(tempExtractionDir)); if (Directory.Exists(packagePath)) { @@ -156,8 +148,6 @@ public async Task InstallPackageAsync(PackageLocation packageLocat version.ToNormalizedString())); } - // create asset files - // To get runtimeGraph: var runtimeJsonPath = "C:\\Program Files\\dotnet\\sdk\\7.0.200\\RuntimeIdentifierGraph.json"; var runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonPath); @@ -175,8 +165,7 @@ public async Task InstallPackageAsync(PackageLocation packageLocat }; // Create NuGetv3LocalRepository - NuGetv3LocalRepository localRepository = new(tempExtractionDir); - Console.WriteLine(tempExtractionDir); + NuGetv3LocalRepository localRepository = new(_tempStageDir.Value); var package = localRepository.FindPackage(packageId.ToString(), version); var collection = new ContentItemCollection(); @@ -184,17 +173,14 @@ public async Task InstallPackageAsync(PackageLocation packageLocat // Create criteria var managedCriteria = new List(1); - var currentTargetFramework = NuGetFramework.Parse("net8.0"); - // Not supporting FallbackFramework for tools var standardCriteria = conventions.Criteria.ForFrameworkAndRuntime( - //NuGetFramework.Parse(targetFramework), currentTargetFramework, RuntimeInformation.RuntimeIdentifier); managedCriteria.Add(standardCriteria); - // To be implemented + // Create asset file if (lockFileLib.PackageType.Contains(PackageType.DotnetTool)) { AddToolsAssets(conventions, lockFileLib, collection, managedCriteria); @@ -208,21 +194,17 @@ public async Task InstallPackageAsync(PackageLocation packageLocat }; lockFileTarget.Libraries.Add(lockFileLib); lockFile.Targets.Add(lockFileTarget); - new LockFileFormat().Write(Path.Combine(tempExtractionDir, "project.assets.json"), lockFile); + new LockFileFormat().Write(Path.Combine(_tempStageDir.Value, "project.assets.json"), lockFile); + + var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); + Directory.CreateDirectory(packageRootDirectory.Value); + + FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_tempStageDir.Value, packageDirectory.Value)); return new ToolPackageInstance(id: packageId, version: version, - packageDirectory: new DirectoryPath(tempExtractionDir), - assetsJsonParentDirectory: new DirectoryPath(tempExtractionDir)); - //cleanup - /*foreach (var dir in tempDirsToDelete) - { - if (Directory.Exists(dir)) - { - Directory.Delete(dir, true); - } - }*/ - + packageDirectory: packageDirectory, + assetsJsonParentDirectory: packageDirectory); } } } From 8c66b875912f2a91f9705eced8f63a1924a87c3a Mon Sep 17 00:00:00 2001 From: Annie Li Date: Thu, 29 Jun 2023 16:44:58 -0700 Subject: [PATCH 04/47] update the global install method entry point --- .../ToolInstallGlobalOrToolPathCommand.cs | 46 +------------------ 1 file changed, 1 insertion(+), 45 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 0ebc6ba10759..390cf9903ac6 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -107,7 +107,6 @@ public override int Execute() toolPath = new DirectoryPath(_toolPath); } - //same class for IToolpackagestore, storequery and installer (IToolPackageStore toolPackageStore, IToolPackageStoreQuery toolPackageStoreQuery, IToolPackageInstaller toolPackageInstaller) = _createToolPackageStoresAndInstaller(toolPath, _forwardRestoreArguments); @@ -126,14 +125,13 @@ public override int Execute() try { - //ToolPackageStoreAndQuery downloaderStore = ToolPackageFactory.CreateConcreteToolPackageStore(toolPath); IToolPackage package = null; // transaction scope: if something fails in the middle undo the process using (var scope = new TransactionScope( TransactionScopeOption.Required, TimeSpan.Zero)) { - var toolPackageDownloader = new ToolPackageDownloader(); + var toolPackageDownloader = new ToolPackageDownloader(toolPackageStore); package = toolPackageDownloader.InstallPackageAsync( new PackageLocation(nugetConfig: configFile, additionalFeeds: _source), packageId: _packageId, @@ -169,48 +167,6 @@ public override int Execute() scope.Complete(); } - - - // Original Code Below - /*IToolPackage package = null; - // transaction scope: if something fails in the middle undo the process - using (var scope = new TransactionScope( - TransactionScopeOption.Required, - TimeSpan.Zero)) - { - package = toolPackageInstaller.InstallPackage( - new PackageLocation(nugetConfig: configFile, additionalFeeds: _source), - packageId: _packageId, - versionRange: versionRange, - targetFramework: _framework, verbosity: _verbosity); - - NuGetFramework framework; - if (string.IsNullOrEmpty(_framework) && package.Frameworks.Count() > 0) - { - framework = package.Frameworks - .Where(f => f.Version < (new NuGetVersion(Product.Version)).Version) - .MaxBy(f => f.Version); - } - else - { - framework = string.IsNullOrEmpty(_framework) ? - null : - NuGetFramework.Parse(_framework); - } - - string appHostSourceDirectory = _shellShimTemplateFinder.ResolveAppHostSourceDirectoryAsync(_architectureOption, framework, RuntimeInformation.ProcessArchitecture).Result; - IShellShimRepository shellShimRepository = _createShellShimRepository(appHostSourceDirectory, toolPath); - - // actual executable that runs - foreach (var command in package.Commands) - { - shellShimRepository.CreateShim(command.Executable, command.Name, package.PackagedShims); - } - - scope.Complete(); - }*/ - - foreach (string w in package.Warnings) { _reporter.WriteLine(w.Yellow()); From f322c75c94cc556d0ff3f0a1edf07308d039c627 Mon Sep 17 00:00:00 2001 From: Annie Li Date: Thu, 29 Jun 2023 16:47:07 -0700 Subject: [PATCH 05/47] update the global install method entry point --- .../dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 390cf9903ac6..c8bd102cbd04 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -98,8 +98,6 @@ public override int Execute() } VersionRange versionRange = _parseResult.GetVersionRange(); - Console.WriteLine("The versionRange at execute is: "); - Console.WriteLine(versionRange); DirectoryPath? toolPath = null; if (!string.IsNullOrEmpty(_toolPath)) From 496c8540f71f08ea0e9271d7e147e5f2278a635d Mon Sep 17 00:00:00 2001 From: Annie Li Date: Mon, 10 Jul 2023 15:27:59 -0700 Subject: [PATCH 06/47] add nuget api to tool update global command --- .../update/ToolUpdateGlobalOrToolPathCommand.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs index 4400876ddb84..adfdd2af108f 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs @@ -4,7 +4,6 @@ using System; using System.Collections.Generic; using System.CommandLine; -using System.CommandLine.Parsing; using System.IO; using System.Linq; using System.Transactions; @@ -12,11 +11,11 @@ using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ShellShim; using Microsoft.DotNet.ToolPackage; -using Microsoft.DotNet.Tools.Tool.Common; using Microsoft.DotNet.Tools.Tool.Install; using Microsoft.DotNet.Tools.Tool.Uninstall; using Microsoft.Extensions.EnvironmentAbstractions; using NuGet.Versioning; +using Microsoft.DotNet.Cli.ToolPackage; namespace Microsoft.DotNet.Tools.Tool.Update { @@ -110,12 +109,13 @@ public override int Execute() RunWithHandlingInstallError(() => { - IToolPackage newInstalledPackage = toolPackageInstaller.InstallPackage( - new PackageLocation(nugetConfig: GetConfigFile(), additionalFeeds: _additionalFeeds), + var toolPackageDownloader = new ToolPackageDownloader(toolPackageStore); + IToolPackage newInstalledPackage = toolPackageDownloader.InstallPackageAsync( + new PackageLocation(nugetConfig: GetConfigFile(), additionalFeeds: _additionalFeeds), packageId: _packageId, - targetFramework: _framework, versionRange: versionRange, - verbosity: _verbosity); + targetFramework: _framework, verbosity: _verbosity + ).GetAwaiter().GetResult(); EnsureVersionIsHigher(oldPackageNullable, newInstalledPackage); From 587fe7b822a1c254af76a6b5001f88de571d7320 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Fri, 28 Jul 2023 17:26:10 -0700 Subject: [PATCH 07/47] remove unused comment --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 0b2f71680853..cc64e1ad14a9 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -74,7 +74,6 @@ private static IEnumerable GetLockFileItems( Action additionalAction, params PatternSet[] patterns) { - // Loop through each criteria taking the first one that matches one or more items. foreach (var managedCriteria in criteria) { var group = items.FindBestItemGroup( From 4be01a55da6362091833d66b84dadcb1162a138f Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 1 Aug 2023 17:22:27 -0700 Subject: [PATCH 08/47] combine global and local tool nuget install & update --- .../ToolPackage/IToolPackageDownloader.cs | 19 +++ .../ToolPackage/ToolPackageDownloader.cs | 116 +++++++++++------- .../dotnet-tool/install/ToolInstallCommand.cs | 2 - .../ToolInstallGlobalOrToolPathCommand.cs | 6 +- .../install/ToolInstallLocalInstaller.cs | 34 +++-- .../ToolUpdateGlobalOrToolPathCommand.cs | 6 +- 6 files changed, 116 insertions(+), 67 deletions(-) create mode 100644 src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs diff --git a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs new file mode 100644 index 000000000000..213bf9ba9b0f --- /dev/null +++ b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs @@ -0,0 +1,19 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Threading.Tasks; +using Microsoft.DotNet.ToolPackage; +using NuGet.Versioning; + +namespace Microsoft.DotNet.Cli.ToolPackage +{ + internal interface IToolPackageDownloader + { + IToolPackage InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, + VersionRange versionRange = null, + string targetFramework = null, + string verbosity = null, + bool isGlobalTool = false + ); + } +} diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index cc64e1ad14a9..2b3deaae4163 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -1,6 +1,5 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -// using System; using System.Collections.Generic; @@ -29,21 +28,60 @@ namespace Microsoft.DotNet.Cli.ToolPackage { internal class ToolPackageDownloader { - private readonly INuGetPackageDownloader _nugetPackageDownloader; - protected readonly DirectoryPath _tempPackagesDir; - protected readonly DirectoryPath _tempStageDir; + private INuGetPackageDownloader _nugetPackageDownloader; private readonly IToolPackageStore _toolPackageStore; + protected DirectoryPath _toolDownloadDir; + protected DirectoryPath _toolReturnPackageDirectory; + protected DirectoryPath _toolReturnJsonParentDirectory; + + protected readonly DirectoryPath _globalToolStageDir; + protected readonly DirectoryPath _localToolDownloadDir; + protected readonly DirectoryPath _localToolAssetDir; + + public ToolPackageDownloader( - IToolPackageStore store, - INuGetPackageDownloader nugetPackageDownloader = null, - string tempDirPath = null - ){ - _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); - _tempPackagesDir = new DirectoryPath(tempDirPath ?? PathUtilities.CreateTempSubdirectory()); - _tempStageDir = _toolPackageStore.GetRandomStagingDirectory(); - _nugetPackageDownloader = nugetPackageDownloader ?? - new NuGetPackageDownloader.NuGetPackageDownloader(_tempStageDir); + IToolPackageStore store + ) + { + _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); ; + _globalToolStageDir = _toolPackageStore.GetRandomStagingDirectory(); + _localToolDownloadDir = new DirectoryPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package")); + _localToolAssetDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); + } + + public IToolPackage InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, + VersionRange versionRange = null, + string targetFramework = null, + string verbosity = null, + bool isGlobalTool = false + ) + { + _toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; + var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; + _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir); + + NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, _toolDownloadDir.Value).GetAwaiter().GetResult(); + CreateAssetFiles(packageId, version, _toolDownloadDir, assetFileDirectory); + + if (isGlobalTool) + { + _toolReturnPackageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + _toolReturnJsonParentDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); + Directory.CreateDirectory(packageRootDirectory.Value); + FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, _toolReturnPackageDirectory.Value)); + } + else + { + _toolReturnPackageDirectory = _toolDownloadDir; + _toolReturnJsonParentDirectory = _localToolAssetDir; + } + + return new ToolPackageInstance(id: packageId, + version: version, + packageDirectory: _toolReturnPackageDirectory, + assetsJsonParentDirectory: _toolReturnJsonParentDirectory); } private static void AddToolsAssets( @@ -74,6 +112,7 @@ private static IEnumerable GetLockFileItems( Action additionalAction, params PatternSet[] patterns) { + // Loop through each criteria taking the first one that matches one or more items. foreach (var managedCriteria in criteria) { var group = items.FindBestItemGroup( @@ -106,37 +145,34 @@ private static IEnumerable GetLockFileItems( yield break; } - public async Task InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, - VersionRange versionRange = null, - string targetFramework = null, - string verbosity = null + private static async Task DownloadAndExtractPackage( + PackageLocation packageLocation, + PackageId packageId, + INuGetPackageDownloader _nugetPackageDownloader, + string hashPathLocation ) - { + { var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId, null, packageSourceLocation); - var tempExtractionDir = Path.GetDirectoryName(packagePath); - Directory.CreateDirectory(_tempStageDir.Value); - - // Look fo nuget package on disk and read the version + // look for package on disk and read the version NuGetVersion version; using (FileStream packageStream = File.OpenRead(packagePath)) { PackageArchiveReader reader = new PackageArchiveReader(packageStream); version = new NuspecReader(reader.GetNuspec()).GetVersion(); - + var packageHash = Convert.ToBase64String(new CryptoHashProvider("SHA512").CalculateHash(reader.GetNuspec())); - var hashPath = new VersionFolderPathResolver(_tempStageDir.Value).GetHashPath(packageId.ToString(), version); + var hashPath = new VersionFolderPathResolver(hashPathLocation).GetHashPath(packageId.ToString(), version); Directory.CreateDirectory(Path.GetDirectoryName(hashPath)); File.WriteAllText(hashPath, packageHash); } - var packageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); - var tempToolExtractionDir = Path.Combine(tempExtractionDir, packageId.ToString(), version.ToString()); - var nupkgDir = Path.Combine(tempExtractionDir, packageId.ToString(), version.ToString()); - var filesInPackage = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(tempExtractionDir)); + // Extract the package + var nupkgDir = Path.Combine(hashPathLocation, packageId.ToString(), version.ToString()); + var filesInPackage = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(nupkgDir)); if (Directory.Exists(packagePath)) { @@ -146,7 +182,15 @@ public async Task InstallPackageAsync(PackageLocation packageLocat packageId, version.ToNormalizedString())); } + return version; + } + private static void CreateAssetFiles( + PackageId packageId, + NuGetVersion version, + DirectoryPath nugetLocalRepository, + DirectoryPath assetFileDirectory) + { // To get runtimeGraph: var runtimeJsonPath = "C:\\Program Files\\dotnet\\sdk\\7.0.200\\RuntimeIdentifierGraph.json"; var runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonPath); @@ -156,7 +200,7 @@ public async Task InstallPackageAsync(PackageLocation packageLocat // Create LockFileTargetLibrary var lockFileLib = new LockFileTargetLibrary() - { + { Name = packageId.ToString(), Version = version, Type = LibraryType.Package, @@ -164,7 +208,7 @@ public async Task InstallPackageAsync(PackageLocation packageLocat }; // Create NuGetv3LocalRepository - NuGetv3LocalRepository localRepository = new(_tempStageDir.Value); + NuGetv3LocalRepository localRepository = new(nugetLocalRepository.Value); var package = localRepository.FindPackage(packageId.ToString(), version); var collection = new ContentItemCollection(); @@ -193,17 +237,7 @@ public async Task InstallPackageAsync(PackageLocation packageLocat }; lockFileTarget.Libraries.Add(lockFileLib); lockFile.Targets.Add(lockFileTarget); - new LockFileFormat().Write(Path.Combine(_tempStageDir.Value, "project.assets.json"), lockFile); - - var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); - Directory.CreateDirectory(packageRootDirectory.Value); - - FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_tempStageDir.Value, packageDirectory.Value)); - - return new ToolPackageInstance(id: packageId, - version: version, - packageDirectory: packageDirectory, - assetsJsonParentDirectory: packageDirectory); + new LockFileFormat().Write(Path.Combine(assetFileDirectory.Value, "project.assets.json"), lockFile); } } } diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommand.cs index c495d8bcd3e1..1aa443ed942e 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallCommand.cs @@ -2,8 +2,6 @@ // The .NET Foundation licenses this file to you under the MIT license. using System.CommandLine; -using System.CommandLine.Parsing; -using System.Linq; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools.Tool.Common; diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index c8bd102cbd04..97626a59554b 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -134,8 +134,10 @@ public override int Execute() new PackageLocation(nugetConfig: configFile, additionalFeeds: _source), packageId: _packageId, versionRange: versionRange, - targetFramework: _framework, verbosity: _verbosity - ).GetAwaiter().GetResult(); + targetFramework: _framework, + verbosity: _verbosity, + isGlobalTool: true + ); NuGetFramework framework; if (string.IsNullOrEmpty(_framework) && package.Frameworks.Count() > 0) diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs index 730f3c5156c7..94d9862f579f 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs @@ -3,9 +3,9 @@ using System; using System.CommandLine; -using System.CommandLine.Parsing; using System.IO; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; using Microsoft.Extensions.EnvironmentAbstractions; @@ -18,7 +18,7 @@ internal class ToolInstallLocalInstaller private readonly ParseResult _parseResult; public string TargetFrameworkToInstall { get; private set; } - private readonly IToolPackageInstaller _toolPackageInstaller; + private readonly IToolPackageStore _toolPackageStore; private readonly PackageId _packageId; private readonly string _packageVersion; private readonly string _configFilePath; @@ -36,20 +36,15 @@ public ToolInstallLocalInstaller( _sources = parseResult.GetValue(ToolInstallCommandParser.AddSourceOption); _verbosity = Enum.GetName(parseResult.GetValue(ToolInstallCommandParser.VerbosityOption)); - if (toolPackageInstaller == null) - { - (IToolPackageStore, - IToolPackageStoreQuery, - IToolPackageInstaller installer) toolPackageStoresAndInstaller - = ToolPackageFactory.CreateToolPackageStoresAndInstaller( - additionalRestoreArguments: parseResult.OptionValuesToBeForwarded(ToolInstallCommandParser.GetCommand())); - _toolPackageInstaller = toolPackageStoresAndInstaller.installer; - } - else - { - _toolPackageInstaller = toolPackageInstaller; - } - + + (IToolPackageStore store, + IToolPackageStoreQuery, + IToolPackageInstaller installer) toolPackageStoresAndInstaller + = ToolPackageFactory.CreateToolPackageStoresAndInstaller( + additionalRestoreArguments: parseResult.OptionValuesToBeForwarded(ToolInstallCommandParser.GetCommand())); + _toolPackageStore = toolPackageStoresAndInstaller.store; + + TargetFrameworkToInstall = BundledTargetFramework.GetTargetFrameworkMoniker(); } @@ -73,13 +68,12 @@ public IToolPackage Install(FilePath manifestFile) try { - IToolPackage toolDownloadedPackage = - _toolPackageInstaller.InstallPackageToExternalManagedLocation( + var toolPackageDownloader = new ToolPackageDownloader(_toolPackageStore); + IToolPackage toolDownloadedPackage = toolPackageDownloader.InstallPackageAsync( new PackageLocation( nugetConfig: configFile, additionalFeeds: _sources, - // Fix https://github.com/dotnet/sdk/issues/23135 - rootConfigDirectory: manifestFile.GetDirectoryPath().GetParentPath()), + rootConfigDirectory: manifestFile.GetDirectoryPath()), _packageId, versionRange, TargetFrameworkToInstall, diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs index adfdd2af108f..196e4d267c21 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs @@ -114,8 +114,10 @@ public override int Execute() new PackageLocation(nugetConfig: GetConfigFile(), additionalFeeds: _additionalFeeds), packageId: _packageId, versionRange: versionRange, - targetFramework: _framework, verbosity: _verbosity - ).GetAwaiter().GetResult(); + targetFramework: _framework, + verbosity: _verbosity, + isGlobalTool: true + ); EnsureVersionIsHigher(oldPackageNullable, newInstalledPackage); From 498ceeec40ddde1b06191c946dcde8af70c90ac1 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 1 Aug 2023 17:28:30 -0700 Subject: [PATCH 09/47] clear out comments --- src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs | 4 +--- .../dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs | 3 --- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index a7aaf8891d39..7cb9f616679a 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -49,7 +49,6 @@ public IToolPackage InstallPackage( { try { - // create a temp project with a package reference to the tool and download it var stageDirectory = _store.GetRandomStagingDirectory(); Directory.CreateDirectory(stageDirectory.Value); rollbackDirectory = stageDirectory.Value; @@ -90,8 +89,7 @@ public IToolPackage InstallPackage( Directory.CreateDirectory(packageRootDirectory.Value); FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(stageDirectory.Value, packageDirectory.Value)); rollbackDirectory = packageDirectory.Value; - Console.WriteLine("In toolPackageInstaller the package directory value is: "); - Console.WriteLine(packageDirectory.Value); + return new ToolPackageInstance(id: packageId, version: version, packageDirectory: packageDirectory, diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 97626a59554b..e4af664d6553 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -124,7 +124,6 @@ public override int Execute() try { IToolPackage package = null; - // transaction scope: if something fails in the middle undo the process using (var scope = new TransactionScope( TransactionScopeOption.Required, TimeSpan.Zero)) @@ -156,8 +155,6 @@ public override int Execute() string appHostSourceDirectory = _shellShimTemplateFinder.ResolveAppHostSourceDirectoryAsync(_architectureOption, framework, RuntimeInformation.ProcessArchitecture).Result; IShellShimRepository shellShimRepository = _createShellShimRepository(appHostSourceDirectory, toolPath); - Console.WriteLine(package.Commands); - // actual executable that runs foreach (var command in package.Commands) { From c5331162b9ed49fc96c41c680d8d5f7227dbd7ef Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 2 Aug 2023 14:03:36 -0700 Subject: [PATCH 10/47] resolve the path of runtimeIdentifierGraph.json in ToolPackageDownloader --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 2b3deaae4163..eed45ac189b5 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.IO; +using System.Reflection; using System.Runtime.InteropServices; using System.Threading.Tasks; using Microsoft.DotNet.Cli.NuGetPackageDownloader; @@ -192,7 +193,7 @@ private static void CreateAssetFiles( DirectoryPath assetFileDirectory) { // To get runtimeGraph: - var runtimeJsonPath = "C:\\Program Files\\dotnet\\sdk\\7.0.200\\RuntimeIdentifierGraph.json"; + var runtimeJsonPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "runtimeIdentifierGraph.json"); var runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonPath); // Create ManagedCodeConventions: From 9621b31326aa11c863f7cf0ee7959f8f3082cf02 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:28:24 -0700 Subject: [PATCH 11/47] adding class interface for ToolPackageDownloader class --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index eed45ac189b5..a7da09be7a45 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -27,7 +27,7 @@ namespace Microsoft.DotNet.Cli.ToolPackage { - internal class ToolPackageDownloader + internal class ToolPackageDownloader:IToolPackageDownloader { private INuGetPackageDownloader _nugetPackageDownloader; private readonly IToolPackageStore _toolPackageStore; From 01320fa19b1d3efbd93447cfbbcf9498435ebffd Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 2 Aug 2023 15:30:00 -0700 Subject: [PATCH 12/47] changing createToolPackageStoresAndDownlaoder to return a downloader --- src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs b/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs index 4fe99f321418..91bd59bc7691 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs @@ -3,6 +3,7 @@ using System.Collections.Generic; using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Configurer; using Microsoft.DotNet.Tools.Tool.Install; using Microsoft.Extensions.EnvironmentAbstractions; @@ -22,6 +23,15 @@ public static (IToolPackageStore, IToolPackageStoreQuery, IToolPackageInstaller) return (toolPackageStore, toolPackageStore, toolPackageInstaller); } + public static (IToolPackageStore, IToolPackageStoreQuery, IToolPackageDownloader) CreateToolPackageStoresAndDownloader( + DirectoryPath? nonGlobalLocation = null, IEnumerable additionalRestoreArguments = null) + { + ToolPackageStoreAndQuery toolPackageStore = CreateConcreteToolPackageStore(nonGlobalLocation); + var toolPackageDownloader = new ToolPackageDownloader(toolPackageStore); + + return (toolPackageStore, toolPackageStore, toolPackageDownloader); + } + public static (IToolPackageStore, IToolPackageStoreQuery, IToolPackageUninstaller) CreateToolPackageStoresAndUninstaller( DirectoryPath? nonGlobalLocation = null) { From 6893a23a6a7ed873386e14affa2c9e70745366ac Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 9 Aug 2023 23:18:55 -0700 Subject: [PATCH 13/47] Writing a mock for ToolPackageDownloader; Updated ToolInstallGlobalOrToolPathCommandTests.cs to use the ToolPackageDownloaderMock; --- .../ToolPackage/ToolPackageDownloader.cs | 73 +-- .../ToolPackageDownloaderMock.cs | 423 ++++++++++++++++++ ...ToolInstallGlobalOrToolPathCommandTests.cs | 108 +++-- 3 files changed, 521 insertions(+), 83 deletions(-) create mode 100644 src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index a7da09be7a45..5ba8b78557d4 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -1,12 +1,7 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. -using System; -using System.Collections.Generic; -using System.IO; using System.Reflection; -using System.Runtime.InteropServices; -using System.Threading.Tasks; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; @@ -58,31 +53,53 @@ public IToolPackage InstallPackageAsync(PackageLocation packageLocation, Package bool isGlobalTool = false ) { - _toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; - var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; - _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir); + var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); + string rollbackDirectory = null; + + return TransactionalAction.Run( + action: () => + { + _toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; + var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; + _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir); + rollbackDirectory = _toolDownloadDir.Value; - NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, _toolDownloadDir.Value).GetAwaiter().GetResult(); - CreateAssetFiles(packageId, version, _toolDownloadDir, assetFileDirectory); + NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, _toolDownloadDir.Value).GetAwaiter().GetResult(); + CreateAssetFiles(packageId, version, _toolDownloadDir, assetFileDirectory); - if (isGlobalTool) - { - _toolReturnPackageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); - _toolReturnJsonParentDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); - var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); - Directory.CreateDirectory(packageRootDirectory.Value); - FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, _toolReturnPackageDirectory.Value)); - } - else - { - _toolReturnPackageDirectory = _toolDownloadDir; - _toolReturnJsonParentDirectory = _localToolAssetDir; - } + if (isGlobalTool) + { + _toolReturnPackageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + _toolReturnJsonParentDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); + Directory.CreateDirectory(packageRootDirectory.Value); + FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, _toolReturnPackageDirectory.Value)); + rollbackDirectory = _toolReturnPackageDirectory.Value; + } + else + { + _toolReturnPackageDirectory = _toolDownloadDir; + _toolReturnJsonParentDirectory = _localToolAssetDir; + } - return new ToolPackageInstance(id: packageId, - version: version, - packageDirectory: _toolReturnPackageDirectory, - assetsJsonParentDirectory: _toolReturnJsonParentDirectory); + return new ToolPackageInstance(id: packageId, + version: version, + packageDirectory: _toolReturnPackageDirectory, + assetsJsonParentDirectory: _toolReturnJsonParentDirectory); + }, + rollback: () => + { + if (rollbackDirectory != null && Directory.Exists(rollbackDirectory)) + { + Directory.Delete(rollbackDirectory, true); + } + // Delete the root if it is empty + if (Directory.Exists(packageRootDirectory.Value) && + !Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any()) + { + Directory.Delete(packageRootDirectory.Value, false); + } + }); } private static void AddToolsAssets( @@ -193,7 +210,7 @@ private static void CreateAssetFiles( DirectoryPath assetFileDirectory) { // To get runtimeGraph: - var runtimeJsonPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "runtimeIdentifierGraph.json"); + var runtimeJsonPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "RuntimeIdentifierGraph.json"); var runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonPath); // Create ManagedCodeConventions: diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs new file mode 100644 index 000000000000..1b556929217d --- /dev/null +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -0,0 +1,423 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +using System.Reflection; +using System.Text.Json; +using Microsoft.Build.Evaluation; +using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.NuGetPackageDownloader; +using Microsoft.DotNet.Cli.ToolPackage; +using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.ToolPackage; +using Microsoft.Extensions.EnvironmentAbstractions; +using NuGet.Client; +using NuGet.Common; +using NuGet.ContentModel; +using NuGet.Frameworks; +using NuGet.LibraryModel; +using NuGet.Packaging; +using NuGet.Packaging.Core; +using NuGet.ProjectModel; +using NuGet.Repositories; +using NuGet.RuntimeModel; +using NuGet.Versioning; +using LocalizableStrings = Microsoft.DotNet.Tools.Tool.Install.LocalizableStrings; + +namespace Microsoft.DotNet.Tools.Tests.ComponentMocks +{ + internal class ToolPackageDownloaderMock : IToolPackageDownloader + { + private readonly IToolPackageStore _toolPackageStore; + + protected DirectoryPath _toolDownloadDir; + protected DirectoryPath _toolReturnPackageDirectory; + protected DirectoryPath _toolReturnJsonParentDirectory; + + protected readonly DirectoryPath _globalToolStageDir; + protected readonly DirectoryPath _localToolDownloadDir; + protected readonly DirectoryPath _localToolAssetDir; + + public const string FakeEntrypointName = "SimulatorEntryPoint.dll"; + public const string DefaultToolCommandName = "SimulatorCommand"; + public const string DefaultPackageName = "global.tool.console.demo"; + public const string DefaultPackageVersion = "1.0.4"; + public const string FakeCommandSettingsFileName = "FakeDotnetToolSettings.json"; + + + private const string ProjectFileName = "TempProject.csproj"; + private readonly IFileSystem _fileSystem; + private readonly IReporter _reporter; + private readonly List _feeds; + + private readonly Dictionary> _warningsMap; + private readonly Dictionary> _packagedShimsMap; + private readonly Dictionary> _frameworksMap; + private readonly Action _downloadCallback; + + public ToolPackageDownloaderMock( + IToolPackageStore store, + IFileSystem fileSystem, + IReporter reporter = null, + List feeds = null, + Action downloadCallback = null, + Dictionary> warningsMap = null, + Dictionary> packagedShimsMap = null, + Dictionary> frameworksMap = null + ) + { + _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); ; + _globalToolStageDir = _toolPackageStore.GetRandomStagingDirectory(); + _localToolDownloadDir = new DirectoryPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package")); + _localToolAssetDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); + + _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); + _reporter = reporter; + + _warningsMap = warningsMap ?? new Dictionary>(); + _packagedShimsMap = packagedShimsMap ?? new Dictionary>(); + _frameworksMap = frameworksMap ?? new Dictionary>(); + _downloadCallback = downloadCallback; + + if (feeds == null) + { + _feeds = new List(); + _feeds.Add(new MockFeed + { + Type = MockFeedType.FeedFromGlobalNugetConfig, + Packages = new List + { + new MockFeedPackage + { + PackageId = DefaultPackageName, + Version = DefaultPackageVersion, + ToolCommandName = DefaultToolCommandName, + } + } + }); + } + else + { + _feeds = feeds; + } + } + + + + public IToolPackage InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, + VersionRange versionRange = null, + string targetFramework = null, + string verbosity = null, + bool isGlobalTool = false + ) + { + string rollbackDirectory = null; + var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); + + return TransactionalAction.Run( + action: () => + { + var versionString = versionRange?.OriginalString ?? "*"; + versionRange = VersionRange.Parse(versionString); + _toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; + var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; + rollbackDirectory = _toolDownloadDir.Value; + // _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir); + + // NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, _toolDownloadDir.Value).GetAwaiter().GetResult(); + + if (string.IsNullOrEmpty(packageId.ToString())) + { + throw new ToolPackageException(LocalizableStrings.ToolInstallationRestoreFailed); + } + + var feedPackage = GetPackage( + packageId.ToString(), + versionRange, + packageLocation.NugetConfig, + packageLocation.RootConfigDirectory); + + var packageVersion = feedPackage.Version; + targetFramework = string.IsNullOrEmpty(targetFramework) ? "targetFramework" : targetFramework; + + var fakeExecutableSubDirectory = Path.Combine( + packageId.ToString().ToLowerInvariant(), + packageVersion.ToLowerInvariant(), + "tools", + targetFramework, + Constants.AnyRid); + var fakeExecutablePath = Path.Combine(fakeExecutableSubDirectory, FakeEntrypointName); + + _fileSystem.Directory.CreateDirectory(Path.Combine(_toolDownloadDir.Value, fakeExecutableSubDirectory)); + _fileSystem.File.CreateEmptyFile(Path.Combine(_toolDownloadDir.Value, fakeExecutablePath)); + _fileSystem.File.WriteAllText( + _toolDownloadDir.WithFile("project.assets.json").Value, + fakeExecutablePath); + _fileSystem.File.WriteAllText( + _toolDownloadDir.WithFile(FakeCommandSettingsFileName).Value, + JsonSerializer.Serialize(new { Name = feedPackage.ToolCommandName })); + + if (_downloadCallback != null) + { + _downloadCallback(); + } + + var version = _toolPackageStore.GetStagedPackageVersion(_toolDownloadDir, packageId); + var packageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + if (_fileSystem.Directory.Exists(packageDirectory.Value)) + { + throw new ToolPackageException( + string.Format( + CommonLocalizableStrings.ToolPackageConflictPackageId, + packageId, + version.ToNormalizedString())); + } + + + + // CreateAssetFiles(packageId, version, _toolDownloadDir, assetFileDirectory); + + if (isGlobalTool) + { + _toolReturnPackageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + _toolReturnJsonParentDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); + // Directory.CreateDirectory(packageRootDirectory.Value); + // FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, _toolReturnPackageDirectory.Value)); + _fileSystem.Directory.CreateDirectory(packageRootDirectory.Value); + _fileSystem.Directory.Move(_toolDownloadDir.Value, packageDirectory.Value); + rollbackDirectory = packageDirectory.Value; + } + else + { + _toolReturnPackageDirectory = _toolDownloadDir; + _toolReturnJsonParentDirectory = _localToolAssetDir; + } + + IEnumerable warnings = null; + _warningsMap.TryGetValue(packageId, out warnings); + + IReadOnlyList packedShims = null; + _packagedShimsMap.TryGetValue(packageId, out packedShims); + + IEnumerable frameworks = null; + _frameworksMap.TryGetValue(packageId, out frameworks); + + return new ToolPackageMock(_fileSystem, id: packageId, + version: version, + packageDirectory: packageDirectory, + warnings: warnings, packagedShims: packedShims, frameworks: frameworks); + }, + rollback: () => + { + if (rollbackDirectory != null && _fileSystem.Directory.Exists(rollbackDirectory)) + { + _fileSystem.Directory.Delete(rollbackDirectory, true); + } + if (_fileSystem.Directory.Exists(packageRootDirectory.Value) && + !_fileSystem.Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any()) + { + _fileSystem.Directory.Delete(packageRootDirectory.Value, false); + } + + }); + } + + private static void AddToolsAssets( + ManagedCodeConventions managedCodeConventions, + LockFileTargetLibrary lockFileLib, + ContentItemCollection contentItems, + IReadOnlyList orderedCriteria) + { + var toolsGroup = GetLockFileItems( + orderedCriteria, + contentItems, + managedCodeConventions.Patterns.ToolsAssemblies); + + lockFileLib.ToolsAssemblies.AddRange(toolsGroup); + } + + private static IEnumerable GetLockFileItems( + IReadOnlyList criteria, + ContentItemCollection items, + params PatternSet[] patterns) + { + return GetLockFileItems(criteria, items, additionalAction: null, patterns); + } + + private static IEnumerable GetLockFileItems( + IReadOnlyList criteria, + ContentItemCollection items, + Action additionalAction, + params PatternSet[] patterns) + { + // Loop through each criteria taking the first one that matches one or more items. + foreach (var managedCriteria in criteria) + { + var group = items.FindBestItemGroup( + managedCriteria, + patterns); + + if (group != null) + { + foreach (var item in group.Items) + { + var newItem = new LockFileItem(item.Path); + object locale; + if (item.Properties.TryGetValue("locale", out locale)) + { + newItem.Properties["locale"] = (string)locale; + } + object related; + if (item.Properties.TryGetValue("related", out related)) + { + newItem.Properties["related"] = (string)related; + } + additionalAction?.Invoke(newItem); + yield return newItem; + } + // Take only the first group that has items + break; + } + } + + yield break; + } + + private static void CreateAssetFiles( + PackageId packageId, + NuGetVersion version, + DirectoryPath nugetLocalRepository, + DirectoryPath assetFileDirectory) + { + // To get runtimeGraph: + var runtimeJsonPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "runtimeIdentifierGraph.json"); + var runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonPath); + + // Create ManagedCodeConventions: + var conventions = new ManagedCodeConventions(runtimeGraph); + + // Create LockFileTargetLibrary + var lockFileLib = new LockFileTargetLibrary() + { + Name = packageId.ToString(), + Version = version, + Type = LibraryType.Package, + PackageType = new List() { PackageType.DotnetTool } + }; + + // Create NuGetv3LocalRepository + NuGetv3LocalRepository localRepository = new(nugetLocalRepository.Value); + var package = localRepository.FindPackage(packageId.ToString(), version); + + var collection = new ContentItemCollection(); + collection.Load(package.Files); + + // Create criteria + var managedCriteria = new List(1); + var currentTargetFramework = NuGetFramework.Parse("net8.0"); + + var standardCriteria = conventions.Criteria.ForFrameworkAndRuntime( + currentTargetFramework, + RuntimeInformation.RuntimeIdentifier); + managedCriteria.Add(standardCriteria); + + // Create asset file + if (lockFileLib.PackageType.Contains(PackageType.DotnetTool)) + { + AddToolsAssets(conventions, lockFileLib, collection, managedCriteria); + } + + var lockFile = new LockFile(); + var lockFileTarget = new LockFileTarget() + { + TargetFramework = currentTargetFramework, + RuntimeIdentifier = RuntimeInformation.RuntimeIdentifier + }; + lockFileTarget.Libraries.Add(lockFileLib); + lockFile.Targets.Add(lockFileTarget); + new LockFileFormat().Write(Path.Combine(assetFileDirectory.Value, "project.assets.json"), lockFile); + } + + public MockFeedPackage GetPackage( + string packageId, + VersionRange versionRange, + FilePath? nugetConfig = null, + DirectoryPath? rootConfigDirectory = null) + { + var allPackages = _feeds + .Where(feed => + { + if (nugetConfig == null) + { + return SimulateNugetSearchNugetConfigAndMatch( + rootConfigDirectory, + feed); + } + else + { + return ExcludeOtherFeeds(nugetConfig.Value, feed); + } + }) + .SelectMany(f => f.Packages) + .Where(f => f.PackageId == packageId) + .ToList(); + + var bestVersion = versionRange.FindBestMatch(allPackages.Select(p => NuGetVersion.Parse(p.Version))); + + var package = allPackages.FirstOrDefault(p => NuGetVersion.Parse(p.Version).Equals(bestVersion)); + + if (package == null) + { + _reporter?.WriteLine($"Error: failed to restore package {packageId}."); + throw new ToolPackageException(LocalizableStrings.ToolInstallationRestoreFailed); + } + + return package; + } + + /// + /// Simulate NuGet search nuget config from parent directories. + /// Assume all nuget.config has Clear + /// And then filter against mock feed + /// + private bool SimulateNugetSearchNugetConfigAndMatch( + DirectoryPath? rootConfigDirectory, + MockFeed feed) + { + if (rootConfigDirectory != null) + { + var probedNugetConfig = EnumerateDefaultAllPossibleNuGetConfig(rootConfigDirectory.Value) + .FirstOrDefault(possibleNugetConfig => + _fileSystem.File.Exists(possibleNugetConfig.Value)); + + if (!Equals(probedNugetConfig, default(FilePath))) + { + return (feed.Type == MockFeedType.FeedFromLookUpNugetConfig) || + (feed.Type == MockFeedType.ImplicitAdditionalFeed) || + (feed.Type == MockFeedType.FeedFromLookUpNugetConfig + && feed.Uri == probedNugetConfig.Value); + } + } + + return feed.Type != MockFeedType.ExplicitNugetConfig + && feed.Type != MockFeedType.FeedFromLookUpNugetConfig; + } + + private static IEnumerable EnumerateDefaultAllPossibleNuGetConfig(DirectoryPath probStart) + { + DirectoryPath? currentSearchDirectory = probStart; + while (currentSearchDirectory.HasValue) + { + var tryNugetConfig = currentSearchDirectory.Value.WithFile("nuget.config"); + yield return tryNugetConfig; + currentSearchDirectory = currentSearchDirectory.Value.GetParentPathNullable(); + } + } + + private static bool ExcludeOtherFeeds(FilePath nugetConfig, MockFeed f) + { + return f.Type == MockFeedType.ImplicitAdditionalFeed + || (f.Type == MockFeedType.ExplicitNugetConfig && f.Uri == nugetConfig.Value); + } + } +} diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs index 4b76e710beb4..ad259c251d7b 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolInstallGlobalOrToolPathCommandTests.cs @@ -24,6 +24,7 @@ using Parser = Microsoft.DotNet.Cli.Parser; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.NET.TestFramework; +using Microsoft.DotNet.Cli.ToolPackage; namespace Microsoft.DotNet.Tests.Commands.Tool { @@ -33,7 +34,7 @@ public class ToolInstallGlobalOrToolPathCommandTests private readonly IToolPackageStore _toolPackageStore; private readonly IToolPackageStoreQuery _toolPackageStoreQuery; private readonly CreateShellShimRepository _createShellShimRepository; - private readonly CreateToolPackageStoresAndInstaller _createToolPackageStoreAndInstaller; + private readonly CreateToolPackageStoresAndDownloader _createToolPackageStoresAndDownloader; private readonly EnvironmentPathInstructionMock _environmentPathInstructionMock; private readonly ParseResult _parseResult; private readonly BufferedReporter _reporter; @@ -48,7 +49,7 @@ public ToolInstallGlobalOrToolPathCommandTests() { _reporter = new BufferedReporter(); _fileSystem = new FileSystemMockBuilder().UseCurrentSystemTemporaryDirectory().Build(); - _temporaryDirectory = _fileSystem.Directory.CreateTemporaryDirectory().DirectoryPath; + _temporaryDirectory = _fileSystem.Directory.CreateTemporaryDirectory().DirectoryPath; _pathToPlaceShim = Path.Combine(_temporaryDirectory, "pathToPlace"); _fileSystem.Directory.CreateDirectory(_pathToPlaceShim); _pathToPlacePackages = _pathToPlaceShim + "Packages"; @@ -64,7 +65,8 @@ public ToolInstallGlobalOrToolPathCommandTests() filePermissionSetter: new NoOpFilePermissionSetter()); _environmentPathInstructionMock = new EnvironmentPathInstructionMock(_reporter, _pathToPlaceShim); - _createToolPackageStoreAndInstaller = (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, CreateToolPackageInstaller()); + _createToolPackageStoresAndDownloader = (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, CreateToolPackageDownloader()); + _parseResult = Parser.Instance.Parse($"dotnet tool install -g {PackageId}"); } @@ -74,7 +76,7 @@ public void WhenRunWithPackageIdItShouldCreateValidShim() { var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( _parseResult, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -94,7 +96,7 @@ public void WhenRunFromToolInstallRedirectCommandWithPackageIdItShouldCreateVali { var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( _parseResult, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -114,7 +116,7 @@ public void WhenRunWithPackageIdWithSourceItShouldCreateValidShim() const string sourcePath = "http://mysource.com"; ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --add-source {sourcePath}"); - var toolToolPackageInstaller = CreateToolPackageInstaller( + var toolToolPackageDownloader = CreateToolPackageDownloader( feeds: new List { new MockFeed { @@ -134,7 +136,7 @@ public void WhenRunWithPackageIdWithSourceItShouldCreateValidShim() var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, - (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolToolPackageInstaller), + (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolToolPackageDownloader), _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -155,7 +157,7 @@ public void WhenRunWithPackageIdItShouldShowPathInstruction() { var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( _parseResult, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -174,17 +176,14 @@ public void WhenRunWithPackageIdPackageFormatIsNotFullySupportedItShouldShowPath [new PackageId(PackageId)] = new List() { Warning } }; - var toolPackageInstaller = new ToolPackageInstallerMock( - fileSystem: _fileSystem, + var toolPackageDownloader = new ToolPackageDownloaderMock( + fileSystem: _fileSystem, store: _toolPackageStore, - projectRestorer: new ProjectRestorerMock( - fileSystem: _fileSystem, - reporter: _reporter), warningsMap: injectedWarnings); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( _parseResult, - (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolPackageInstaller), + (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolPackageDownloader), _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -200,13 +199,13 @@ public void GivenFailedPackageInstallWhenRunWithPackageIdItShouldFail() { const string ErrorMessage = "Simulated error"; - var toolPackageInstaller = - CreateToolPackageInstaller( - installCallback: () => throw new ToolPackageException(ErrorMessage)); + var toolPackageDownloader = + CreateToolPackageDownloader( + downloadCallback: () => throw new ToolPackageException(ErrorMessage)); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( _parseResult, - (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolPackageInstaller), + (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolPackageDownloader), _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -229,7 +228,7 @@ public void GivenCreateShimItShouldHaveNoBrokenFolderOnDisk() var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( _parseResult, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -247,13 +246,13 @@ public void GivenCreateShimItShouldHaveNoBrokenFolderOnDisk() [Fact] public void GivenInCorrectToolConfigurationWhenRunWithPackageIdItShouldFail() { - var toolPackageInstaller = - CreateToolPackageInstaller( - installCallback: () => throw new ToolConfigurationException("Simulated error")); + var toolPackageDownloader = + CreateToolPackageDownloader( + downloadCallback: () => throw new ToolConfigurationException("Simulated error")); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( _parseResult, - (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolPackageInstaller), + (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolPackageDownloader), _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -274,7 +273,7 @@ public void WhenRunWithPackageIdItShouldShowSuccessMessage() { var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( _parseResult, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, new EnvironmentPathInstructionMock(_reporter, _pathToPlaceShim, true), _reporter); @@ -299,7 +298,7 @@ public void WhenRunWithInvalidVersionItShouldThrow() var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, new EnvironmentPathInstructionMock(_reporter, _pathToPlaceShim, true), _reporter); @@ -320,7 +319,7 @@ public void WhenRunWithExactVersionItShouldSucceed() var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, new EnvironmentPathInstructionMock(_reporter, _pathToPlaceShim, true), _reporter); @@ -344,7 +343,7 @@ public void WhenRunWithValidVersionRangeItShouldSucceed() var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, new EnvironmentPathInstructionMock(_reporter, _pathToPlaceShim, true), _reporter); @@ -364,13 +363,13 @@ public void WhenRunWithValidVersionRangeItShouldSucceed() [Fact] public void WhenRunWithPrereleaseItShouldSucceed() { - IToolPackageInstaller toolToolPackageInstaller = GetToolToolPackageInstallerWithPreviewInFeed(); + IToolPackageDownloader toolToolPackageDownloader = GetToolToolPackageDownloaderWithPreviewInFeed(); ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --prerelease"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, - (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolToolPackageInstaller), + (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolToolPackageDownloader), _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -390,13 +389,13 @@ public void WhenRunWithPrereleaseItShouldSucceed() [Fact] public void WhenRunWithPrereleaseAndPackageVersionItShouldThrow() { - IToolPackageInstaller toolToolPackageInstaller = GetToolToolPackageInstallerWithPreviewInFeed(); + IToolPackageDownloader toolToolPackageDownloader = GetToolToolPackageDownloaderWithPreviewInFeed(); ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version 2.0 --prerelease"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, - (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolToolPackageInstaller), + (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, toolToolPackageDownloader), _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -405,9 +404,9 @@ public void WhenRunWithPrereleaseAndPackageVersionItShouldThrow() a.Should().Throw(); } - private IToolPackageInstaller GetToolToolPackageInstallerWithPreviewInFeed() + private IToolPackageDownloader GetToolToolPackageDownloaderWithPreviewInFeed() { - var toolToolPackageInstaller = CreateToolPackageInstaller( + var toolToolPackageDownloader = CreateToolPackageDownloader( feeds: new List { new MockFeed @@ -430,7 +429,7 @@ private IToolPackageInstaller GetToolToolPackageInstallerWithPreviewInFeed() } } }); - return toolToolPackageInstaller; + return toolToolPackageDownloader; } [Fact] @@ -440,7 +439,7 @@ public void WhenRunWithoutAMatchingRangeItShouldFail() var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, new EnvironmentPathInstructionMock(_reporter, _pathToPlaceShim, true), _reporter); @@ -455,14 +454,14 @@ public void WhenRunWithoutAMatchingRangeItShouldFail() _fileSystem.Directory.Exists(Path.Combine(_pathToPlacePackages, PackageId)).Should().BeFalse(); } - [Fact] + [Fact] public void WhenRunWithValidVersionWildcardItShouldSucceed() { ParseResult result = Parser.Instance.Parse($"dotnet tool install -g {PackageId} --version 1.0.*"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, new EnvironmentPathInstructionMock(_reporter, _pathToPlaceShim, true), _reporter); @@ -486,7 +485,7 @@ public void WhenRunWithPackageIdAndBinPathItShouldNoteHaveEnvironmentPathInstruc var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( result, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, new EnvironmentPathInstructionMock(_reporter, _pathToPlaceShim), _reporter); @@ -500,7 +499,7 @@ public void WhenRunWithPackageIdAndBinPathItShouldNoteHaveEnvironmentPathInstruc public void AndPackagedShimIsProvidedWhenRunWithPackageIdItCreateShimUsingPackagedShim() { var extension = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ? ".exe" : string.Empty; - var prepackagedShimPath = Path.Combine (_temporaryDirectory, ToolCommandName + extension); + var prepackagedShimPath = Path.Combine(_temporaryDirectory, ToolCommandName + extension); var tokenToIdentifyPackagedShim = "packagedShim"; _fileSystem.File.WriteAllText(prepackagedShimPath, tokenToIdentifyPackagedShim); @@ -508,18 +507,16 @@ public void AndPackagedShimIsProvidedWhenRunWithPackageIdItCreateShimUsingPackag var packagedShimsMap = new Dictionary> { - [new PackageId(PackageId)] = new[] {new FilePath(prepackagedShimPath)} + [new PackageId(PackageId)] = new[] { new FilePath(prepackagedShimPath) } }; var installCommand = new ToolInstallGlobalOrToolPathCommand( result, - (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, new ToolPackageInstallerMock( + (location, forwardArguments) => (_toolPackageStore, _toolPackageStoreQuery, new ToolPackageDownloaderMock( fileSystem: _fileSystem, store: _toolPackageStore, packagedShimsMap: packagedShimsMap, - projectRestorer: new ProjectRestorerMock( - fileSystem: _fileSystem, - reporter: _reporter))), + reporter: _reporter)), _createShellShimRepository, new EnvironmentPathInstructionMock(_reporter, _pathToPlaceShim), _reporter); @@ -529,6 +526,7 @@ [new PackageId(PackageId)] = new[] {new FilePath(prepackagedShimPath)} _fileSystem.File.ReadAllText(ExpectedCommandPath()).Should().Be(tokenToIdentifyPackagedShim); } + [Fact] public void WhenRunWithArchOptionItErrorsOnInvalidRids() { @@ -536,7 +534,7 @@ public void WhenRunWithArchOptionItErrorsOnInvalidRids() var parseResult = Parser.Instance.Parse($"dotnet tool install -g {PackageId} -a invalid"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( parseResult, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, _environmentPathInstructionMock, _reporter); @@ -552,7 +550,7 @@ public void WhenRunWithArchOptionItDownloadsAppHostTemplate() var parseResult = Parser.Instance.Parse($"dotnet tool install -g {PackageId} -a arm64"); var toolInstallGlobalOrToolPathCommand = new ToolInstallGlobalOrToolPathCommand( parseResult, - _createToolPackageStoreAndInstaller, + _createToolPackageStoresAndDownloader, _createShellShimRepository, _environmentPathInstructionMock, _reporter, @@ -564,18 +562,15 @@ public void WhenRunWithArchOptionItDownloadsAppHostTemplate() nugetPackageDownloader.DownloadCallParams.First().Item1.Should().Be(new PackageId("microsoft.netcore.app.host.win-arm64")); } - private IToolPackageInstaller CreateToolPackageInstaller( + private IToolPackageDownloader CreateToolPackageDownloader( List feeds = null, - Action installCallback = null) + Action downloadCallback = null) { - return new ToolPackageInstallerMock( - fileSystem: _fileSystem, + return new ToolPackageDownloaderMock(fileSystem: _fileSystem, store: _toolPackageStore, - projectRestorer: new ProjectRestorerMock( - fileSystem: _fileSystem, - reporter: _reporter, - feeds: feeds), - installCallback: installCallback); + reporter: _reporter, + feeds: feeds, + downloadCallback: downloadCallback); } private string ExpectedCommandPath() @@ -598,3 +593,6 @@ public void SetPermission(string path, string chmodArgument) } } } + + + From 047b35d2b76dd4d7ee1b0221b8769429e2c2a362 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 9 Aug 2023 23:54:05 -0700 Subject: [PATCH 14/47] Updated ToolUpdateGlobalOrToolPathCommandTests.cs to use ToolPackageDownloaderMock; Updated ToolUpdateGlobalOrToolPathCommand to use ToolPackageDownloaderMock --- .../dotnet/ToolPackage/ToolPackageFactory.cs | 16 ++++ .../ToolInstallGlobalOrToolPathCommand.cs | 17 ++-- .../ToolUpdateGlobalOrToolPathCommand.cs | 17 ++-- .../ToolUpdateGlobalOrToolPathCommandTests.cs | 93 ++++++++----------- 4 files changed, 74 insertions(+), 69 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs b/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs index 91bd59bc7691..73f6789f1dd5 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs @@ -59,6 +59,22 @@ public static (IToolPackageStore, return (toolPackageStore, toolPackageStore, toolPackageInstaller, toolPackageUninstaller); } + public static (IToolPackageStore, + IToolPackageStoreQuery, + IToolPackageDownloader, + IToolPackageUninstaller) + CreateToolPackageStoresAndDownloaderAndUninstaller( + DirectoryPath? nonGlobalLocation = null, IEnumerable additionalRestoreArguments = null) + { + ToolPackageStoreAndQuery toolPackageStore = CreateConcreteToolPackageStore(nonGlobalLocation); + var toolPackageDownloader = new ToolPackageDownloader(toolPackageStore); + var toolPackageUninstaller = new ToolPackageUninstaller( + toolPackageStore); + + return (toolPackageStore, toolPackageStore, toolPackageDownloader, toolPackageUninstaller); + } + + public static IToolPackageStoreQuery CreateToolPackageStoreQuery( DirectoryPath? nonGlobalLocation = null) { diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index e4af664d6553..72d20bd2b182 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -15,6 +15,7 @@ using Microsoft.DotNet.ShellShim; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Tools.Tool.Common; +using Microsoft.DotNet.Tools.Tool.Uninstall; using Microsoft.Extensions.EnvironmentAbstractions; using NuGet.Common; using NuGet.Frameworks; @@ -23,7 +24,8 @@ namespace Microsoft.DotNet.Tools.Tool.Install { internal delegate IShellShimRepository CreateShellShimRepository(string appHostSourceDirectory, DirectoryPath? nonGlobalLocation = null); - internal delegate (IToolPackageStore, IToolPackageStoreQuery, IToolPackageInstaller) CreateToolPackageStoresAndInstaller( + + internal delegate (IToolPackageStore, IToolPackageStoreQuery, IToolPackageDownloader) CreateToolPackageStoresAndDownloader( DirectoryPath? nonGlobalLocation = null, IEnumerable forwardRestoreArguments = null); @@ -33,7 +35,7 @@ internal class ToolInstallGlobalOrToolPathCommand : CommandBase private readonly IReporter _reporter; private readonly IReporter _errorReporter; private CreateShellShimRepository _createShellShimRepository; - private CreateToolPackageStoresAndInstaller _createToolPackageStoresAndInstaller; + private CreateToolPackageStoresAndDownloader _createToolPackageStoresAndDownloader; private readonly ShellShimTemplateFinder _shellShimTemplateFinder; private readonly PackageId _packageId; @@ -49,7 +51,7 @@ internal class ToolInstallGlobalOrToolPathCommand : CommandBase public ToolInstallGlobalOrToolPathCommand( ParseResult parseResult, - CreateToolPackageStoresAndInstaller createToolPackageStoreAndInstaller = null, + CreateToolPackageStoresAndDownloader createToolPackageStoreAndDownloader = null, CreateShellShimRepository createShellShimRepository = null, IEnvironmentPathInstruction environmentPathInstruction = null, IReporter reporter = null, @@ -66,7 +68,8 @@ public ToolInstallGlobalOrToolPathCommand( _toolPath = parseResult.GetValue(ToolAppliedOption.ToolPathOption); _architectureOption = parseResult.GetValue(ToolInstallCommandParser.ArchitectureOption); - _createToolPackageStoresAndInstaller = createToolPackageStoreAndInstaller ?? ToolPackageFactory.CreateToolPackageStoresAndInstaller; + _createToolPackageStoresAndDownloader = createToolPackageStoreAndDownloader ?? ToolPackageFactory.CreateToolPackageStoresAndDownloader; + _forwardRestoreArguments = parseResult.OptionValuesToBeForwarded(ToolInstallCommandParser.GetCommand()); _environmentPathInstruction = environmentPathInstruction @@ -105,8 +108,8 @@ public override int Execute() toolPath = new DirectoryPath(_toolPath); } - (IToolPackageStore toolPackageStore, IToolPackageStoreQuery toolPackageStoreQuery, IToolPackageInstaller toolPackageInstaller) = - _createToolPackageStoresAndInstaller(toolPath, _forwardRestoreArguments); + (IToolPackageStore toolPackageStore, IToolPackageStoreQuery toolPackageStoreQuery, IToolPackageDownloader toolPackageDownloader) = + _createToolPackageStoresAndDownloader(toolPath, _forwardRestoreArguments); // Prevent installation if any version of the package is installed if (toolPackageStoreQuery.EnumeratePackageVersions(_packageId).FirstOrDefault() != null) @@ -128,7 +131,6 @@ public override int Execute() TransactionScopeOption.Required, TimeSpan.Zero)) { - var toolPackageDownloader = new ToolPackageDownloader(toolPackageStore); package = toolPackageDownloader.InstallPackageAsync( new PackageLocation(nugetConfig: configFile, additionalFeeds: _source), packageId: _packageId, @@ -155,7 +157,6 @@ public override int Execute() string appHostSourceDirectory = _shellShimTemplateFinder.ResolveAppHostSourceDirectoryAsync(_architectureOption, framework, RuntimeInformation.ProcessArchitecture).Result; IShellShimRepository shellShimRepository = _createShellShimRepository(appHostSourceDirectory, toolPath); - // actual executable that runs foreach (var command in package.Commands) { shellShimRepository.CreateShim(command.Executable, command.Name, package.PackagedShims); diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs index 196e4d267c21..b7adbbf0e5e0 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs @@ -21,16 +21,16 @@ namespace Microsoft.DotNet.Tools.Tool.Update { internal delegate IShellShimRepository CreateShellShimRepository(string appHostSourceDirectory, DirectoryPath? nonGlobalLocation = null); - internal delegate (IToolPackageStore, IToolPackageStoreQuery, IToolPackageInstaller, IToolPackageUninstaller) CreateToolPackageStoresAndInstallerAndUninstaller( + internal delegate (IToolPackageStore, IToolPackageStoreQuery, IToolPackageDownloader, IToolPackageUninstaller) CreateToolPackageStoresAndDownloaderAndUninstaller( DirectoryPath? nonGlobalLocation = null, - IEnumerable additionalRestoreArguments = null); + IEnumerable additionalRestoreArguments = null); internal class ToolUpdateGlobalOrToolPathCommand : CommandBase { private readonly IReporter _reporter; private readonly IReporter _errorReporter; private readonly CreateShellShimRepository _createShellShimRepository; - private readonly CreateToolPackageStoresAndInstallerAndUninstaller _createToolPackageStoreInstallerUninstaller; + private readonly CreateToolPackageStoresAndDownloaderAndUninstaller _createToolPackageStoreDownloaderUninstaller; private readonly PackageId _packageId; private readonly string _configFilePath; @@ -43,7 +43,7 @@ internal class ToolUpdateGlobalOrToolPathCommand : CommandBase private readonly string _packageVersion; public ToolUpdateGlobalOrToolPathCommand(ParseResult parseResult, - CreateToolPackageStoresAndInstallerAndUninstaller createToolPackageStoreInstallerUninstaller = null, + CreateToolPackageStoresAndDownloaderAndUninstaller createToolPackageStoreDownloaderUninstaller = null, CreateShellShimRepository createShellShimRepository = null, IReporter reporter = null) : base(parseResult) @@ -58,8 +58,8 @@ public ToolUpdateGlobalOrToolPathCommand(ParseResult parseResult, _toolPath = parseResult.GetValue(ToolUpdateCommandParser.ToolPathOption); _forwardRestoreArguments = parseResult.OptionValuesToBeForwarded(ToolUpdateCommandParser.GetCommand()); - _createToolPackageStoreInstallerUninstaller = createToolPackageStoreInstallerUninstaller ?? - ToolPackageFactory.CreateToolPackageStoresAndInstallerAndUninstaller; + _createToolPackageStoreDownloaderUninstaller = createToolPackageStoreDownloaderUninstaller ?? + ToolPackageFactory.CreateToolPackageStoresAndDownloaderAndUninstaller; _createShellShimRepository = createShellShimRepository ?? ShellShimRepositoryFactory.CreateShellShimRepository; @@ -82,8 +82,8 @@ public override int Execute() (IToolPackageStore toolPackageStore, IToolPackageStoreQuery toolPackageStoreQuery, - IToolPackageInstaller toolPackageInstaller, - IToolPackageUninstaller toolPackageUninstaller) = _createToolPackageStoreInstallerUninstaller(toolPath, _forwardRestoreArguments); + IToolPackageDownloader toolPackageDownloader, + IToolPackageUninstaller toolPackageUninstaller) = _createToolPackageStoreDownloaderUninstaller(toolPath, _forwardRestoreArguments); var appHostSourceDirectory = ShellShimTemplateFinder.GetDefaultAppHostSourceDirectory(); IShellShimRepository shellShimRepository = _createShellShimRepository(appHostSourceDirectory, toolPath); @@ -109,7 +109,6 @@ public override int Execute() RunWithHandlingInstallError(() => { - var toolPackageDownloader = new ToolPackageDownloader(toolPackageStore); IToolPackage newInstalledPackage = toolPackageDownloader.InstallPackageAsync( new PackageLocation(nugetConfig: GetConfigFile(), additionalFeeds: _additionalFeeds), packageId: _packageId, diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolUpdateGlobalOrToolPathCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolUpdateGlobalOrToolPathCommandTests.cs index 11c04019b3a7..177e3fc9cbb6 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolUpdateGlobalOrToolPathCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolUpdateGlobalOrToolPathCommandTests.cs @@ -124,14 +124,12 @@ public void GivenAnExistedLowerversionInstallationWhenCallFromRedirectorItCanUpd var toolUpdateGlobalOrToolPathCommand = new ToolUpdateGlobalOrToolPathCommand( result, - (location, forwardArguments) => (_store, _store, new ToolPackageInstallerMock( - _fileSystem, - _store, - new ProjectRestorerMock( - _fileSystem, - _reporter, - _mockFeeds - )), + (location, forwardArguments) => (_store, _store, new ToolPackageDownloaderMock( + store: _store, + fileSystem: _fileSystem, + reporter: _reporter, + feeds: _mockFeeds + ), new ToolPackageUninstallerMock(_fileSystem, _store)), (_, _) => GetMockedShellShimRepository(), _reporter); @@ -222,7 +220,7 @@ public void GivenAnExistedSameVersionInstallationWhenCallItCanPrintSuccessMessag var command = CreateUpdateCommand($"-g {_packageId}"); command.Execute(); - + _reporter.Lines.First().Should().Contain(string.Format( LocalizableStrings.UpdateSucceededStableVersionNoChange, _packageId, HigherPackageVersion)); @@ -250,18 +248,16 @@ public void GivenAnExistedLowerversionWhenReinstallThrowsIthasTheFirstLineIndica _reporter.Lines.Clear(); ParseResult result = Parser.Instance.Parse("dotnet tool update " + $"-g {_packageId}"); + var command = new ToolUpdateGlobalOrToolPathCommand( result, (location, forwardArguments) => (_store, _store, - new ToolPackageInstallerMock( - _fileSystem, - _store, - new ProjectRestorerMock( - _fileSystem, - _reporter, - _mockFeeds - ), - installCallback: () => throw new ToolConfigurationException("Simulated error")), + new ToolPackageDownloaderMock( + store: _store, + fileSystem: _fileSystem, + reporter: _reporter, + feeds: _mockFeeds, + downloadCallback: () => throw new ToolConfigurationException("Simulated error")), new ToolPackageUninstallerMock(_fileSystem, _store)), (_, _) => GetMockedShellShimRepository(), _reporter); @@ -279,18 +275,16 @@ public void GivenAnExistedLowerversionWhenReinstallThrowsItRollsBack() _reporter.Lines.Clear(); ParseResult result = Parser.Instance.Parse("dotnet tool update " + $"-g {_packageId}"); + var command = new ToolUpdateGlobalOrToolPathCommand( result, (location, forwardArguments) => (_store, _store, - new ToolPackageInstallerMock( - _fileSystem, - _store, - new ProjectRestorerMock( - _fileSystem, - _reporter, - _mockFeeds - ), - installCallback: () => throw new ToolConfigurationException("Simulated error")), + new ToolPackageDownloaderMock( + store: _store, + fileSystem: _fileSystem, + reporter: _reporter, + feeds: _mockFeeds, + downloadCallback: () => throw new ToolConfigurationException("Simulated error")), new ToolPackageUninstallerMock(_fileSystem, _store)), (_, _) => GetMockedShellShimRepository(), _reporter); @@ -314,21 +308,19 @@ public void GivenPackagedShimIsProvidedWhenRunWithPackageIdItCreatesShimUsingPac var packagedShimsMap = new Dictionary> { - [_packageId] = new[] {new FilePath(prepackagedShimPath)} + [_packageId] = new[] { new FilePath(prepackagedShimPath) } }; string options = $"-g {_packageId}"; ParseResult result = Parser.Instance.Parse("dotnet tool update " + options); + var command = new ToolUpdateGlobalOrToolPathCommand( result, - (_, _) => (_store, _store, new ToolPackageInstallerMock( - _fileSystem, - _store, - new ProjectRestorerMock( - _fileSystem, - _reporter, - _mockFeeds - ), + (_, _) => (_store, _store, new ToolPackageDownloaderMock( + store:_store, + fileSystem: _fileSystem, + reporter: _reporter, + feeds: _mockFeeds, packagedShimsMap: packagedShimsMap), new ToolPackageUninstallerMock(_fileSystem, _store)), (_, _) => GetMockedShellShimRepository(), @@ -353,14 +345,12 @@ private ToolInstallGlobalOrToolPathCommand CreateInstallCommand(string options) return new ToolInstallGlobalOrToolPathCommand( result, - (location, forwardArguments) => (_store, _store, new ToolPackageInstallerMock( - _fileSystem, - _store, - new ProjectRestorerMock( - _fileSystem, - _reporter, - _mockFeeds - ))), + (location, forwardArguments) => (_store, _store, new ToolPackageDownloaderMock( + store: _store, + fileSystem: _fileSystem, + _reporter, + _mockFeeds + )), (_, _) => GetMockedShellShimRepository(), _environmentPathInstructionMock, _reporter); @@ -372,14 +362,12 @@ private ToolUpdateGlobalOrToolPathCommand CreateUpdateCommand(string options) return new ToolUpdateGlobalOrToolPathCommand( result, - (location, forwardArguments) => (_store, _store, new ToolPackageInstallerMock( - _fileSystem, - _store, - new ProjectRestorerMock( - _fileSystem, - _reporter, - _mockFeeds - )), + (location, forwardArguments) => (_store, _store, new ToolPackageDownloaderMock( + store: _store, + fileSystem: _fileSystem, + _reporter, + _mockFeeds + ), new ToolPackageUninstallerMock(_fileSystem, _store)), (_, _) => GetMockedShellShimRepository(), _reporter); @@ -396,3 +384,4 @@ private ShellShimRepository GetMockedShellShimRepository() } } } + From ce166b3541f0b9c4f57a27080230632831e5b66f Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 10 Aug 2023 00:00:56 -0700 Subject: [PATCH 15/47] Updated ToolUninstallGlobalOrToolPathCommandTests.cs to use toolPackageDownloaderMock --- ...olUninstallGlobalOrToolPathCommandTests.cs | 29 ++++++++++--------- 1 file changed, 15 insertions(+), 14 deletions(-) diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolUninstallGlobalOrToolPathCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolUninstallGlobalOrToolPathCommandTests.cs index 5e2655e0482c..1ac105e6e3fd 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolUninstallGlobalOrToolPathCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolUninstallGlobalOrToolPathCommandTests.cs @@ -102,7 +102,7 @@ public void GivenAPackageItUninstalls() _fileSystem.Directory.Exists(packageDirectory.Value).Should().BeFalse(); _fileSystem.File.Exists(shimPath).Should().BeFalse(); } - + [Fact] public void GivenAPackageWhenCallFromUninstallRedirectCommandItUninstalls() { @@ -130,7 +130,7 @@ public void GivenAPackageWhenCallFromUninstallRedirectCommandItUninstalls() _reporter.Lines.Clear(); - + ParseResult result = Parser.Instance.Parse("dotnet tool uninstall " + $"-g {PackageId}"); (IToolPackageStore, IToolPackageStoreQuery, IToolPackageUninstaller) CreateToolPackageStoreAndUninstaller( @@ -152,14 +152,14 @@ public void GivenAPackageWhenCallFromUninstallRedirectCommandItUninstalls() fileSystem: _fileSystem, appHostShellShimMaker: new AppHostShellShimMakerMock(_fileSystem)), _reporter); - - var uninstallCommand + + var uninstallCommand = new ToolUninstallCommand( - result, - toolUninstallGlobalOrToolPathCommand: toolUninstallGlobalOrToolPathCommand) ; + result, + toolUninstallGlobalOrToolPathCommand: toolUninstallGlobalOrToolPathCommand); uninstallCommand.Execute().Should().Be(0); - + _reporter .Lines .Single() @@ -237,16 +237,16 @@ private ToolInstallGlobalOrToolPathCommand CreateInstallCommand(string options) ParseResult result = Parser.Instance.Parse("dotnet tool install " + options); var store = new ToolPackageStoreMock(new DirectoryPath(_toolsDirectory), _fileSystem); - var packageInstallerMock = new ToolPackageInstallerMock( - _fileSystem, - store, - new ProjectRestorerMock( - _fileSystem, - _reporter)); + + var packageDownloaderMock = new ToolPackageDownloaderMock( + store: store, + fileSystem: _fileSystem, + _reporter + ); return new ToolInstallGlobalOrToolPathCommand( result, - (location, forwardArguments) => (store, store, packageInstallerMock), + (location, forwardArguments) => (store, store, packageDownloaderMock), (_, _) => new ShellShimRepository( new DirectoryPath(_shimsDirectory), string.Empty, @@ -282,3 +282,4 @@ private ToolUninstallGlobalOrToolPathCommand CreateUninstallCommand(string optio } } } + From d3b4fecda888cf580294a93a3a0dc2be3e2a2788 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 10 Aug 2023 11:03:24 -0700 Subject: [PATCH 16/47] Update the tests in ToolInstallLocalCommandTests, ToolUpdateLocalCommandTests, ToolRestoreCommandTests, and ToolRestoreCommandWithMultipleNugetConfigTests to use the ToolPackageDownloaderMock; Update ToolInstallLocalCommand, ToolRestoreCommand, ToolUpdateLocalCommand, and ToolInstallLocalInstaller to use ToolPackageDownloader --- .../ToolPackage/ToolPackageDownloader.cs | 6 ++ .../install/ToolInstallLocalCommand.cs | 5 +- .../install/ToolInstallLocalInstaller.cs | 14 ++-- .../dotnet-tool/restore/ToolRestoreCommand.cs | 17 ++-- .../update/ToolUpdateLocalCommand.cs | 23 +++--- .../ToolPackageDownloaderMock.cs | 5 ++ .../ToolInstallLocalCommandTests.cs | 75 +++++++++--------- .../CommandTests/ToolRestoreCommandTests.cs | 79 ++++++++++--------- ...toreCommandWithMultipleNugetConfigTests.cs | 65 ++++++++------- .../ToolUpdateLocalCommandTests.cs | 30 +++---- 10 files changed, 167 insertions(+), 152 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 5ba8b78557d4..7b154d469a0c 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -1,7 +1,13 @@ // Copyright (c) .NET Foundation and contributors. All rights reserved. // Licensed under the MIT license. See LICENSE file in the project root for full license information. +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; +using System.Threading.Tasks; using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs index 73b217b9b0ba..0a12153e1b6e 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalCommand.cs @@ -6,6 +6,7 @@ using System.IO; using System.Linq; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolManifest; using Microsoft.DotNet.ToolPackage; @@ -29,7 +30,7 @@ internal class ToolInstallLocalCommand : CommandBase public ToolInstallLocalCommand( ParseResult parseResult, - IToolPackageInstaller toolPackageInstaller = null, + IToolPackageDownloader toolPackageDownloader = null, IToolManifestFinder toolManifestFinder = null, IToolManifestEditor toolManifestEditor = null, ILocalToolsResolverCache localToolsResolverCache = null, @@ -47,7 +48,7 @@ public ToolInstallLocalCommand( new ToolManifestFinder(new DirectoryPath(Directory.GetCurrentDirectory())); _toolManifestEditor = toolManifestEditor ?? new ToolManifestEditor(); _localToolsResolverCache = localToolsResolverCache ?? new LocalToolsResolverCache(); - _toolLocalPackageInstaller = new ToolInstallLocalInstaller(parseResult, toolPackageInstaller); + _toolLocalPackageInstaller = new ToolInstallLocalInstaller(parseResult, toolPackageDownloader); } public override int Execute() diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs index 94d9862f579f..1614f91ad9c0 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs @@ -19,6 +19,7 @@ internal class ToolInstallLocalInstaller public string TargetFrameworkToInstall { get; private set; } private readonly IToolPackageStore _toolPackageStore; + private readonly IToolPackageDownloader _toolPackageDownloader; private readonly PackageId _packageId; private readonly string _packageVersion; private readonly string _configFilePath; @@ -27,7 +28,7 @@ internal class ToolInstallLocalInstaller public ToolInstallLocalInstaller( ParseResult parseResult, - IToolPackageInstaller toolPackageInstaller = null) + IToolPackageDownloader toolPackageDownloader = null) { _parseResult = parseResult; _packageId = new PackageId(parseResult.GetValue(ToolInstallCommandParser.PackageIdArgument)); @@ -36,13 +37,13 @@ public ToolInstallLocalInstaller( _sources = parseResult.GetValue(ToolInstallCommandParser.AddSourceOption); _verbosity = Enum.GetName(parseResult.GetValue(ToolInstallCommandParser.VerbosityOption)); - (IToolPackageStore store, IToolPackageStoreQuery, - IToolPackageInstaller installer) toolPackageStoresAndInstaller - = ToolPackageFactory.CreateToolPackageStoresAndInstaller( + IToolPackageDownloader installer) toolPackageStoresAndDownloader + = ToolPackageFactory.CreateToolPackageStoresAndDownloader( additionalRestoreArguments: parseResult.OptionValuesToBeForwarded(ToolInstallCommandParser.GetCommand())); - _toolPackageStore = toolPackageStoresAndInstaller.store; + _toolPackageStore = toolPackageStoresAndDownloader.store; + _toolPackageDownloader = toolPackageDownloader?? toolPackageStoresAndDownloader.installer; TargetFrameworkToInstall = BundledTargetFramework.GetTargetFrameworkMoniker(); @@ -68,8 +69,7 @@ public IToolPackage Install(FilePath manifestFile) try { - var toolPackageDownloader = new ToolPackageDownloader(_toolPackageStore); - IToolPackage toolDownloadedPackage = toolPackageDownloader.InstallPackageAsync( + IToolPackage toolDownloadedPackage = _toolPackageDownloader.InstallPackageAsync( new PackageLocation( nugetConfig: configFile, additionalFeeds: _sources, diff --git a/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs index a7b31ffd4856..44b2432400f6 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs @@ -8,6 +8,7 @@ using System.IO; using System.Linq; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolManifest; using Microsoft.DotNet.ToolPackage; @@ -26,30 +27,30 @@ internal class ToolRestoreCommand : CommandBase private readonly IFileSystem _fileSystem; private readonly IReporter _reporter; private readonly string[] _sources; - private readonly IToolPackageInstaller _toolPackageInstaller; + private readonly IToolPackageDownloader _toolPackageDownloader; private readonly string _verbosity; public ToolRestoreCommand( ParseResult result, - IToolPackageInstaller toolPackageInstaller = null, + IToolPackageDownloader toolPackageDownloader = null, IToolManifestFinder toolManifestFinder = null, ILocalToolsResolverCache localToolsResolverCache = null, IFileSystem fileSystem = null, IReporter reporter = null) : base(result) { - if (toolPackageInstaller == null) + if (toolPackageDownloader == null) { (IToolPackageStore, IToolPackageStoreQuery, - IToolPackageInstaller installer) toolPackageStoresAndInstaller - = ToolPackageFactory.CreateToolPackageStoresAndInstaller( + IToolPackageDownloader downloader) toolPackageStoresAndInstaller + = ToolPackageFactory.CreateToolPackageStoresAndDownloader( additionalRestoreArguments: result.OptionValuesToBeForwarded(ToolRestoreCommandParser.GetCommand())); - _toolPackageInstaller = toolPackageStoresAndInstaller.installer; + _toolPackageDownloader = toolPackageStoresAndInstaller.downloader; } else { - _toolPackageInstaller = toolPackageInstaller; + _toolPackageDownloader = toolPackageDownloader; } _toolManifestFinder @@ -129,7 +130,7 @@ private ToolRestoreResult InstallPackages( try { IToolPackage toolPackage = - _toolPackageInstaller.InstallPackageToExternalManagedLocation( + _toolPackageDownloader.InstallPackageAsync( new PackageLocation( nugetConfig: configFile, additionalFeeds: _sources, diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateLocalCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateLocalCommand.cs index 3631847cec02..a01b4ad1e30e 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateLocalCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateLocalCommand.cs @@ -7,6 +7,7 @@ using System.IO; using System.Linq; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolManifest; using Microsoft.DotNet.ToolPackage; @@ -21,7 +22,7 @@ internal class ToolUpdateLocalCommand : CommandBase private readonly IToolManifestFinder _toolManifestFinder; private readonly IToolManifestEditor _toolManifestEditor; private readonly ILocalToolsResolverCache _localToolsResolverCache; - private readonly IToolPackageInstaller _toolPackageInstaller; + private readonly IToolPackageDownloader _toolPackageDownloader; private readonly ToolInstallLocalInstaller _toolLocalPackageInstaller; private readonly Lazy _toolInstallLocalCommand; private readonly IReporter _reporter; @@ -31,7 +32,7 @@ internal class ToolUpdateLocalCommand : CommandBase public ToolUpdateLocalCommand( ParseResult parseResult, - IToolPackageInstaller toolPackageInstaller = null, + IToolPackageDownloader toolPackageDownloader = null, IToolManifestFinder toolManifestFinder = null, IToolManifestEditor toolManifestEditor = null, ILocalToolsResolverCache localToolsResolverCache = null, @@ -43,29 +44,30 @@ public ToolUpdateLocalCommand( _reporter = (reporter ?? Reporter.Output); - if (toolPackageInstaller == null) + if (toolPackageDownloader == null) { (IToolPackageStore, IToolPackageStoreQuery, - IToolPackageInstaller installer) toolPackageStoresAndInstaller - = ToolPackageFactory.CreateToolPackageStoresAndInstaller( + IToolPackageDownloader downloader) toolPackageStoresAndDownloader + = ToolPackageFactory.CreateToolPackageStoresAndDownloader( additionalRestoreArguments: parseResult.OptionValuesToBeForwarded(ToolUpdateCommandParser.GetCommand())); - _toolPackageInstaller = toolPackageStoresAndInstaller.installer; + _toolPackageDownloader = toolPackageStoresAndDownloader.downloader; } else { - _toolPackageInstaller = toolPackageInstaller; + _toolPackageDownloader = toolPackageDownloader; } _toolManifestFinder = toolManifestFinder ?? new ToolManifestFinder(new DirectoryPath(Directory.GetCurrentDirectory())); _toolManifestEditor = toolManifestEditor ?? new ToolManifestEditor(); _localToolsResolverCache = localToolsResolverCache ?? new LocalToolsResolverCache(); - _toolLocalPackageInstaller = new ToolInstallLocalInstaller(parseResult, toolPackageInstaller); + + _toolLocalPackageInstaller = new ToolInstallLocalInstaller(parseResult, toolPackageDownloader); _toolInstallLocalCommand = new Lazy( () => new ToolInstallLocalCommand( parseResult, - _toolPackageInstaller, + _toolPackageDownloader, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -74,7 +76,7 @@ public ToolUpdateLocalCommand( public override int Execute() { - (FilePath? manifestFileOptional, string warningMessage) = + (FilePath? manifestFileOptional, string warningMessage) = _toolManifestFinder.ExplicitManifestOrFindManifestContainPackageId(_explicitManifestFile, _packageId); var manifestFile = manifestFileOptional ?? _toolManifestFinder.FindFirst(); @@ -146,3 +148,4 @@ public override int Execute() } } } + diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index 1b556929217d..e331143c05ef 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -1,7 +1,12 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; using System.Reflection; +using System.Runtime.InteropServices; using System.Text.Json; using Microsoft.Build.Evaluation; using Microsoft.DotNet.Cli; diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs index 036f2b16b5c1..dbe17b17da56 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolInstallLocalCommandTests.cs @@ -6,20 +6,21 @@ using System.IO; using System.Linq; using FluentAssertions; +using System.CommandLine; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; +using Microsoft.DotNet.ToolManifest; using Microsoft.DotNet.ToolPackage; -using Microsoft.DotNet.Tools.Tool.Install; using Microsoft.DotNet.Tools.Tests.ComponentMocks; +using Microsoft.DotNet.Tools.Tool.Install; using Microsoft.Extensions.DependencyModel.Tests; using Microsoft.Extensions.EnvironmentAbstractions; using Xunit; +using NuGet.Frameworks; using NuGet.Versioning; using LocalizableStrings = Microsoft.DotNet.Tools.Tool.Install.LocalizableStrings; -using Microsoft.DotNet.ToolManifest; -using NuGet.Frameworks; using Microsoft.NET.TestFramework.Utilities; -using System.CommandLine; using System.CommandLine.Parsing; using Parser = Microsoft.DotNet.Cli.Parser; using Microsoft.NET.TestFramework; @@ -31,7 +32,7 @@ public class ToolInstallLocalCommandTests:SdkTest { private readonly IFileSystem _fileSystem; private readonly IToolPackageStore _toolPackageStore; - private readonly ToolPackageInstallerMock _toolPackageInstallerMock; + private readonly ToolPackageDownloaderMock _toolPackageDownloaderMock; private readonly ParseResult _parseResult; private readonly BufferedReporter _reporter; private readonly string _temporaryDirectory; @@ -55,28 +56,27 @@ public ToolInstallLocalCommandTests(ITestOutputHelper log):base(log) ToolPackageStoreMock toolPackageStoreMock = new ToolPackageStoreMock(new DirectoryPath(_pathToPlacePackages), _fileSystem); _toolPackageStore = toolPackageStoreMock; - _toolPackageInstallerMock = new ToolPackageInstallerMock( - _fileSystem, - _toolPackageStore, - new ProjectRestorerMock( - _fileSystem, - _reporter, - new List + + _toolPackageDownloaderMock = new ToolPackageDownloaderMock( + store: _toolPackageStore, + fileSystem: _fileSystem, + reporter: _reporter, + new List + { + new MockFeed { - new MockFeed + Type = MockFeedType.ImplicitAdditionalFeed, + Packages = new List { - Type = MockFeedType.ImplicitAdditionalFeed, - Packages = new List + new MockFeedPackage { - new MockFeedPackage - { - PackageId = _packageIdA.ToString(), - Version = _packageVersionA.ToNormalizedString(), - ToolCommandName = _toolCommandNameA.ToString() - } + PackageId = _packageIdA.ToString(), + Version = _packageVersionA.ToNormalizedString(), + ToolCommandName = _toolCommandNameA.ToString() } } - })); + } + }); _localToolsResolverCache = new LocalToolsResolverCache( @@ -153,7 +153,7 @@ public void WhenRunWithExplicitManifestFileItShouldAddEntryToExplicitManifestFil var installLocalCommand = new ToolInstallLocalCommand( parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -199,7 +199,7 @@ public void GivenFailedPackageInstallWhenRunWithPackageIdItShouldNotChangeManife var installLocalCommand = new ToolInstallLocalCommand( result, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -243,7 +243,7 @@ private ToolInstallLocalCommand GetDefaultTestToolInstallLocalCommand() { return new ToolInstallLocalCommand( _parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -258,7 +258,7 @@ public void WhenRunWithExactVersionItShouldSucceed() var installLocalCommand = new ToolInstallLocalCommand( result, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -276,7 +276,7 @@ public void WhenRunWithValidVersionRangeItShouldSucceed() var installLocalCommand = new ToolInstallLocalCommand( result, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -330,7 +330,7 @@ public void GivenNoManifestFileAndCreateManifestIfNeededFlagItShouldCreateManife var installLocalCommand = new ToolInstallLocalCommand( parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -354,7 +354,7 @@ public void GivenNoManifestFileAndCreateManifestIfNeededFlagItShouldCreateManife var installLocalCommand = new ToolInstallLocalCommand( parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -375,7 +375,7 @@ public void GivenNoManifestFileAndCreateManifestIfNeededFlagItShouldCreateManife var installLocalCommand = new ToolInstallLocalCommand( parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -385,7 +385,7 @@ public void GivenNoManifestFileAndCreateManifestIfNeededFlagItShouldCreateManife _fileSystem.File.Exists(Path.Combine(_temporaryDirectory, ".config", "dotnet-tools.json")).Should().BeTrue(); } - private IToolPackageInstaller GetToolToolPackageInstallerWithPreviewInFeed() + private IToolPackageDownloader GetToolToolPackageInstallerWithPreviewInFeed() { List feeds = new List { @@ -409,15 +409,14 @@ private IToolPackageInstaller GetToolToolPackageInstallerWithPreviewInFeed() } } }; - var toolToolPackageInstaller = (IToolPackageInstaller)new ToolPackageInstallerMock( + + var toolToolPackageDownloader = (IToolPackageDownloader)new ToolPackageDownloaderMock( fileSystem: _fileSystem, store: _toolPackageStore, - projectRestorer: new ProjectRestorerMock( - fileSystem: _fileSystem, - reporter: _reporter, - feeds: feeds), - installCallback: null); - return toolToolPackageInstaller; + reporter: _reporter, + feeds: feeds, + downloadCallback: null); + return toolToolPackageDownloader; } private void AssertDefaultInstallSuccess() diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandTests.cs index accf58ca9f2d..9ace42a9466c 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandTests.cs @@ -7,6 +7,7 @@ using System.CommandLine.Parsing; using System.IO; using FluentAssertions; +using System.Runtime.CompilerServices; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolManifest; @@ -28,7 +29,7 @@ public class ToolRestoreCommandTests { private readonly IFileSystem _fileSystem; private readonly IToolPackageStore _toolPackageStore; - private readonly ToolPackageInstallerMock _toolPackageInstallerMock; + private readonly ToolPackageDownloaderMock _toolPackageDownloaderMock; private readonly ParseResult _parseResult; private readonly BufferedReporter _reporter; private readonly string _temporaryDirectory; @@ -64,41 +65,40 @@ public ToolRestoreCommandTests() ToolPackageStoreMock toolPackageStoreMock = new ToolPackageStoreMock(new DirectoryPath(_pathToPlacePackages), _fileSystem); _toolPackageStore = toolPackageStoreMock; - _toolPackageInstallerMock = new ToolPackageInstallerMock( - _fileSystem, + + _toolPackageDownloaderMock = new ToolPackageDownloaderMock( _toolPackageStore, - new ProjectRestorerMock( - _fileSystem, - _reporter, - new List + _fileSystem, + _reporter, + new List + { + new MockFeed { - new MockFeed + Type = MockFeedType.ImplicitAdditionalFeed, + Packages = new List { - Type = MockFeedType.ImplicitAdditionalFeed, - Packages = new List + new MockFeedPackage { - new MockFeedPackage - { - PackageId = _packageIdA.ToString(), - Version = _packageVersionA.ToNormalizedString(), - ToolCommandName = _toolCommandNameA.ToString() - }, - new MockFeedPackage - { - PackageId = _packageIdB.ToString(), - Version = _packageVersionB.ToNormalizedString(), - ToolCommandName = _toolCommandNameB.ToString() - }, - new MockFeedPackage - { - PackageId = _packageIdWithCommandNameCollisionWithA.ToString(), - Version = _packageVersionWithCommandNameCollisionWithA.ToNormalizedString(), - ToolCommandName = "A" - } + PackageId = _packageIdA.ToString(), + Version = _packageVersionA.ToNormalizedString(), + ToolCommandName = _toolCommandNameA.ToString() + }, + new MockFeedPackage + { + PackageId = _packageIdB.ToString(), + Version = _packageVersionB.ToNormalizedString(), + ToolCommandName = _toolCommandNameB.ToString() + }, + new MockFeedPackage + { + PackageId = _packageIdWithCommandNameCollisionWithA.ToString(), + Version = _packageVersionWithCommandNameCollisionWithA.ToNormalizedString(), + ToolCommandName = "A" } } - }), - installCallback: () => _installCalledCount++); + } + }, + downloadCallback: () => _installCalledCount++); _parseResult = Parser.Instance.Parse("dotnet tool restore"); @@ -124,7 +124,7 @@ public void WhenRunItCanSaveCommandsToCache() }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, manifestFinder, _localToolsResolverCache, _fileSystem, @@ -161,7 +161,7 @@ public void WhenRunItCanSaveCommandsToCacheAndShowSuccessMessage() }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, manifestFinder, _localToolsResolverCache, _fileSystem, @@ -196,7 +196,7 @@ public void WhenRestoredCommandHasTheSameCommandNameItThrows() }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, manifestFinder, _localToolsResolverCache, _fileSystem, @@ -251,7 +251,7 @@ public void WhenSomePackageFailedToRestoreItCanRestorePartiallySuccessful() }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, manifestFinder, _localToolsResolverCache, _fileSystem, @@ -291,7 +291,7 @@ public void ItShouldFailWhenPackageCommandNameDoesNotMatchManifestCommands() }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, manifestFinder, _localToolsResolverCache, _fileSystem, @@ -313,7 +313,7 @@ public void WhenCannotFindManifestFileItPrintsWarning() new ToolManifestFinder(new DirectoryPath(Path.GetTempPath()), _fileSystem, new FakeDangerousFileDetector()); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, realManifestFinderImplementationWithMockFinderSystem, _localToolsResolverCache, _fileSystem, @@ -339,7 +339,7 @@ public void WhenPackageIsRestoredAlreadyItWillNotRestoreItAgain() }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, manifestFinder, _localToolsResolverCache, _fileSystem, @@ -366,7 +366,7 @@ public void WhenPackageIsRestoredAlreadyButDllIsRemovedItRestoresAgain() }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, manifestFinder, _localToolsResolverCache, _fileSystem, @@ -389,7 +389,7 @@ public void WhenRunWithoutManifestFileItShouldPrintSpecificRestoreErrorMessage() new CannotFindManifestFinder(); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, manifestFinder, _localToolsResolverCache, _fileSystem, @@ -446,3 +446,4 @@ public IReadOnlyList FindByPackageId(PackageId packageId) } } } + diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandWithMultipleNugetConfigTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandWithMultipleNugetConfigTests.cs index 3d11e6e9f1be..fc6674a390a6 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandWithMultipleNugetConfigTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolRestoreCommandWithMultipleNugetConfigTests.cs @@ -26,7 +26,7 @@ namespace Microsoft.DotNet.Tests.Commands.Tool public class ToolRestoreCommandWithMultipleNugetConfigTests { private readonly IFileSystem _fileSystem; - private ToolPackageInstallerMock _toolPackageInstallerMock; + private ToolPackageDownloaderMock _toolPackageDownloaderMock; private readonly ParseResult _parseResult; private readonly BufferedReporter _reporter; private readonly ILocalToolsResolverCache _localToolsResolverCache; @@ -76,44 +76,42 @@ private void SetupFileLayoutAndFeed(string temporaryDirectory, ToolPackageStoreM _nugetConfigUnderSubDir = Path.Combine(subDir, "nuget.config"); _fileSystem.File.CreateEmptyFile(_nugetConfigUnderSubDir); - _toolPackageInstallerMock = new ToolPackageInstallerMock( - _fileSystem, + _toolPackageDownloaderMock = new ToolPackageDownloaderMock( toolPackageStoreMock, - new ProjectRestorerMock( - _fileSystem, - _reporter, - new List + _fileSystem, + _reporter, + new List + { + new MockFeed { - new MockFeed + Type = MockFeedType.FeedFromLookUpNugetConfig, + Uri = _nugetConfigUnderTestRoot, + Packages = new List { - Type = MockFeedType.FeedFromLookUpNugetConfig, - Uri = _nugetConfigUnderTestRoot, - Packages = new List + new MockFeedPackage { - new MockFeedPackage - { - PackageId = _packageIdA.ToString(), - Version = _packageVersionA.ToNormalizedString(), - ToolCommandName = _toolCommandNameA.ToString() - }, - } - }, - - new MockFeed + PackageId = _packageIdA.ToString(), + Version = _packageVersionA.ToNormalizedString(), + ToolCommandName = _toolCommandNameA.ToString() + }, + } + }, + + new MockFeed + { + Type = MockFeedType.FeedFromLookUpNugetConfig, + Uri = _nugetConfigUnderSubDir, + Packages = new List { - Type = MockFeedType.FeedFromLookUpNugetConfig, - Uri = _nugetConfigUnderSubDir, - Packages = new List + new MockFeedPackage { - new MockFeedPackage - { - PackageId = _packageIdB.ToString(), - Version = _packageVersionB.ToNormalizedString(), - ToolCommandName = _toolCommandNameB.ToString() - }, - } + PackageId = _packageIdB.ToString(), + Version = _packageVersionB.ToNormalizedString(), + ToolCommandName = _toolCommandNameB.ToString() + }, } - })); + } + }); } [Fact] @@ -131,7 +129,7 @@ public void WhenManifestPackageAreFromDifferentDirectoryItCanFindTheRightNugetCo }); ToolRestoreCommand toolRestoreCommand = new ToolRestoreCommand(_parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, manifestFinder, _localToolsResolverCache, _fileSystem, @@ -189,3 +187,4 @@ public IReadOnlyList FindByPackageId(PackageId packageId) } } } + diff --git a/src/Tests/dotnet.Tests/CommandTests/ToolUpdateLocalCommandTests.cs b/src/Tests/dotnet.Tests/CommandTests/ToolUpdateLocalCommandTests.cs index f0fee37a567a..26b65bc0a5a8 100644 --- a/src/Tests/dotnet.Tests/CommandTests/ToolUpdateLocalCommandTests.cs +++ b/src/Tests/dotnet.Tests/CommandTests/ToolUpdateLocalCommandTests.cs @@ -41,7 +41,7 @@ public class ToolUpdateLocalCommandTests private readonly ToolUpdateLocalCommand _defaultToolUpdateLocalCommand; private readonly string _pathToPlacePackages; private readonly IToolPackageStore _toolPackageStore; - private readonly ToolPackageInstallerMock _toolPackageInstallerMock; + private readonly ToolPackageDownloaderMock _toolPackageDownloaderMock; private readonly NuGetVersion _packageOriginalVersionA; private readonly NuGetVersion _packageNewVersionA; private readonly PackageId _packageIdA = new PackageId("local.tool.console.a"); @@ -78,16 +78,15 @@ public ToolUpdateLocalCommandTests() } } }; - _toolPackageInstallerMock = new ToolPackageInstallerMock( - _fileSystem, - _toolPackageStore, - new ProjectRestorerMock( - _fileSystem, - _reporter, - new List - { - _mockFeed - })); + + _toolPackageDownloaderMock = new ToolPackageDownloaderMock( + store: _toolPackageStore, + fileSystem: _fileSystem, + reporter: _reporter, + new List + { + _mockFeed + }); _localToolsResolverCache = new LocalToolsResolverCache( @@ -105,7 +104,7 @@ public ToolUpdateLocalCommandTests() _toolRestoreCommand = new ToolRestoreCommand( _parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _localToolsResolverCache, _fileSystem, @@ -114,7 +113,7 @@ public ToolUpdateLocalCommandTests() _defaultToolUpdateLocalCommand = new ToolUpdateLocalCommand( _parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -202,7 +201,7 @@ ParseResult parseResult ToolUpdateLocalCommand toolUpdateLocalCommand = new ToolUpdateLocalCommand( parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -222,7 +221,7 @@ public void WhenRunFromToolUpdateRedirectCommandWithPackageIdItShouldUpdateFromM ToolUpdateLocalCommand toolUpdateLocalCommand = new ToolUpdateLocalCommand( parseResult, - _toolPackageInstallerMock, + _toolPackageDownloaderMock, _toolManifestFinder, _toolManifestEditor, _localToolsResolverCache, @@ -361,3 +360,4 @@ out RestoredCommand restoredCommand }"; } } + From 0c3c9a64f712baeb2d84ffeafd0e122498ed4754 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 10 Aug 2023 15:00:35 -0700 Subject: [PATCH 17/47] Update the part for local install in ToolPackageDownloaderMock.cs --- .../ToolPackageDownloaderMock.cs | 40 ++++++++++++++++--- 1 file changed, 34 insertions(+), 6 deletions(-) diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index e331143c05ef..af47dd54bbed 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -8,15 +8,12 @@ using System.Reflection; using System.Runtime.InteropServices; using System.Text.Json; -using Microsoft.Build.Evaluation; using Microsoft.DotNet.Cli; -using Microsoft.DotNet.Cli.NuGetPackageDownloader; using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; using Microsoft.Extensions.EnvironmentAbstractions; using NuGet.Client; -using NuGet.Common; using NuGet.ContentModel; using NuGet.Frameworks; using NuGet.LibraryModel; @@ -180,7 +177,22 @@ public IToolPackage InstallPackageAsync(PackageLocation packageLocation, Package // CreateAssetFiles(packageId, version, _toolDownloadDir, assetFileDirectory); - + if (!isGlobalTool) + { + packageDirectory = new DirectoryPath(NuGetGlobalPackagesFolder.GetLocation()).WithSubDirectories(packageId.ToString()); + _fileSystem.Directory.CreateDirectory(packageDirectory.Value); + var executable = packageDirectory.WithFile("exe"); + _fileSystem.File.CreateEmptyFile(executable.Value); + return new TestToolPackage + { + Id = packageId, + Version = NuGetVersion.Parse(feedPackage.Version), + Commands = new List { + new RestoredCommand(new ToolCommandName(feedPackage.ToolCommandName), "runner", executable) }, + Warnings = Array.Empty(), + PackagedShims = Array.Empty() + }; + } if (isGlobalTool) { _toolReturnPackageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); @@ -227,7 +239,7 @@ public IToolPackage InstallPackageAsync(PackageLocation packageLocation, Package }); } - private static void AddToolsAssets( + /*private static void AddToolsAssets( ManagedCodeConventions managedCodeConventions, LockFileTargetLibrary lockFileLib, ContentItemCollection contentItems, @@ -341,7 +353,7 @@ private static void CreateAssetFiles( lockFileTarget.Libraries.Add(lockFileLib); lockFile.Targets.Add(lockFileTarget); new LockFileFormat().Write(Path.Combine(assetFileDirectory.Value, "project.assets.json"), lockFile); - } + }*/ public MockFeedPackage GetPackage( string packageId, @@ -424,5 +436,21 @@ private static bool ExcludeOtherFeeds(FilePath nugetConfig, MockFeed f) return f.Type == MockFeedType.ImplicitAdditionalFeed || (f.Type == MockFeedType.ExplicitNugetConfig && f.Uri == nugetConfig.Value); } + + private class TestToolPackage : IToolPackage + { + public PackageId Id { get; set; } + + public NuGetVersion Version { get; set; } + public DirectoryPath PackageDirectory { get; set; } + + public IReadOnlyList Commands { get; set; } + + public IEnumerable Warnings { get; set; } + + public IReadOnlyList PackagedShims { get; set; } + + public IEnumerable Frameworks => throw new NotImplementedException(); + } } } From c63bd073cc2a8de7234f3edae3526670ed8bc16a Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 10 Aug 2023 17:52:06 -0700 Subject: [PATCH 18/47] Update the verbosity feature of Downloading tools using Nuget and change the tool verbosity test --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 7 ++++++- .../ToolPackageDownloaderMock.cs | 8 -------- .../dotnet-install-tool.Tests/GivenDotnetInstallTool.cs | 2 +- 3 files changed, 7 insertions(+), 10 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 7b154d469a0c..31c373b453bc 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -65,9 +65,14 @@ public IToolPackage InstallPackageAsync(PackageLocation packageLocation, Package return TransactionalAction.Run( action: () => { + ILogger nugetLogger = new NullLogger(); + if( verbosity != null && (verbosity == "d" || verbosity == "detailed" || verbosity == "diag" || verbosity == "diagnostic")) + { + nugetLogger = new NuGetConsoleLogger(); + } _toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; - _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir); + _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir, verboseLogger: nugetLogger); rollbackDirectory = _toolDownloadDir.Value; NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, _toolDownloadDir.Value).GetAwaiter().GetResult(); diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index af47dd54bbed..363a366edd0c 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -13,15 +13,7 @@ using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; using Microsoft.Extensions.EnvironmentAbstractions; -using NuGet.Client; -using NuGet.ContentModel; using NuGet.Frameworks; -using NuGet.LibraryModel; -using NuGet.Packaging; -using NuGet.Packaging.Core; -using NuGet.ProjectModel; -using NuGet.Repositories; -using NuGet.RuntimeModel; using NuGet.Versioning; using LocalizableStrings = Microsoft.DotNet.Tools.Tool.Install.LocalizableStrings; diff --git a/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs b/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs index 1e36696062ba..712da480f272 100644 --- a/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs +++ b/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs @@ -44,7 +44,7 @@ public void ItRunsWithTheSpecifiedVerbosity() result .StdOut .Should() - .ContainVisuallySameFragmentIfNotLocalized("Restoring"); + .BeEmpty(); } } } From b707d89f55001992bf5208a7dd08f55d804a7a0a Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 10 Aug 2023 19:49:30 -0700 Subject: [PATCH 19/47] Clean ToolPackageDownloaderMock --- .../ToolPackageDownloaderMock.cs | 163 ++---------------- 1 file changed, 15 insertions(+), 148 deletions(-) diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index 363a366edd0c..2269abb7352d 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -24,8 +24,6 @@ internal class ToolPackageDownloaderMock : IToolPackageDownloader private readonly IToolPackageStore _toolPackageStore; protected DirectoryPath _toolDownloadDir; - protected DirectoryPath _toolReturnPackageDirectory; - protected DirectoryPath _toolReturnJsonParentDirectory; protected readonly DirectoryPath _globalToolStageDir; protected readonly DirectoryPath _localToolDownloadDir; @@ -95,8 +93,6 @@ public ToolPackageDownloaderMock( } } - - public IToolPackage InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, VersionRange versionRange = null, string targetFramework = null, @@ -115,10 +111,7 @@ public IToolPackage InstallPackageAsync(PackageLocation packageLocation, Package _toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; rollbackDirectory = _toolDownloadDir.Value; - // _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir); - - // NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, _toolDownloadDir.Value).GetAwaiter().GetResult(); - + if (string.IsNullOrEmpty(packageId.ToString())) { throw new ToolPackageException(LocalizableStrings.ToolInstallationRestoreFailed); @@ -166,15 +159,13 @@ public IToolPackage InstallPackageAsync(PackageLocation packageLocation, Package version.ToNormalizedString())); } - - - // CreateAssetFiles(packageId, version, _toolDownloadDir, assetFileDirectory); if (!isGlobalTool) { packageDirectory = new DirectoryPath(NuGetGlobalPackagesFolder.GetLocation()).WithSubDirectories(packageId.ToString()); _fileSystem.Directory.CreateDirectory(packageDirectory.Value); var executable = packageDirectory.WithFile("exe"); _fileSystem.File.CreateEmptyFile(executable.Value); + return new TestToolPackage { Id = packageId, @@ -185,36 +176,28 @@ public IToolPackage InstallPackageAsync(PackageLocation packageLocation, Package PackagedShims = Array.Empty() }; } - if (isGlobalTool) + else { - _toolReturnPackageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); - _toolReturnJsonParentDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); - // Directory.CreateDirectory(packageRootDirectory.Value); - // FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, _toolReturnPackageDirectory.Value)); + _fileSystem.Directory.CreateDirectory(packageRootDirectory.Value); _fileSystem.Directory.Move(_toolDownloadDir.Value, packageDirectory.Value); rollbackDirectory = packageDirectory.Value; - } - else - { - _toolReturnPackageDirectory = _toolDownloadDir; - _toolReturnJsonParentDirectory = _localToolAssetDir; - } - IEnumerable warnings = null; - _warningsMap.TryGetValue(packageId, out warnings); + IEnumerable warnings = null; + _warningsMap.TryGetValue(packageId, out warnings); - IReadOnlyList packedShims = null; - _packagedShimsMap.TryGetValue(packageId, out packedShims); + IReadOnlyList packedShims = null; + _packagedShimsMap.TryGetValue(packageId, out packedShims); - IEnumerable frameworks = null; - _frameworksMap.TryGetValue(packageId, out frameworks); + IEnumerable frameworks = null; + _frameworksMap.TryGetValue(packageId, out frameworks); - return new ToolPackageMock(_fileSystem, id: packageId, - version: version, - packageDirectory: packageDirectory, - warnings: warnings, packagedShims: packedShims, frameworks: frameworks); + return new ToolPackageMock(_fileSystem, id: packageId, + version: version, + packageDirectory: packageDirectory, + warnings: warnings, packagedShims: packedShims, frameworks: frameworks); + } }, rollback: () => { @@ -231,122 +214,6 @@ public IToolPackage InstallPackageAsync(PackageLocation packageLocation, Package }); } - /*private static void AddToolsAssets( - ManagedCodeConventions managedCodeConventions, - LockFileTargetLibrary lockFileLib, - ContentItemCollection contentItems, - IReadOnlyList orderedCriteria) - { - var toolsGroup = GetLockFileItems( - orderedCriteria, - contentItems, - managedCodeConventions.Patterns.ToolsAssemblies); - - lockFileLib.ToolsAssemblies.AddRange(toolsGroup); - } - - private static IEnumerable GetLockFileItems( - IReadOnlyList criteria, - ContentItemCollection items, - params PatternSet[] patterns) - { - return GetLockFileItems(criteria, items, additionalAction: null, patterns); - } - - private static IEnumerable GetLockFileItems( - IReadOnlyList criteria, - ContentItemCollection items, - Action additionalAction, - params PatternSet[] patterns) - { - // Loop through each criteria taking the first one that matches one or more items. - foreach (var managedCriteria in criteria) - { - var group = items.FindBestItemGroup( - managedCriteria, - patterns); - - if (group != null) - { - foreach (var item in group.Items) - { - var newItem = new LockFileItem(item.Path); - object locale; - if (item.Properties.TryGetValue("locale", out locale)) - { - newItem.Properties["locale"] = (string)locale; - } - object related; - if (item.Properties.TryGetValue("related", out related)) - { - newItem.Properties["related"] = (string)related; - } - additionalAction?.Invoke(newItem); - yield return newItem; - } - // Take only the first group that has items - break; - } - } - - yield break; - } - - private static void CreateAssetFiles( - PackageId packageId, - NuGetVersion version, - DirectoryPath nugetLocalRepository, - DirectoryPath assetFileDirectory) - { - // To get runtimeGraph: - var runtimeJsonPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "runtimeIdentifierGraph.json"); - var runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonPath); - - // Create ManagedCodeConventions: - var conventions = new ManagedCodeConventions(runtimeGraph); - - // Create LockFileTargetLibrary - var lockFileLib = new LockFileTargetLibrary() - { - Name = packageId.ToString(), - Version = version, - Type = LibraryType.Package, - PackageType = new List() { PackageType.DotnetTool } - }; - - // Create NuGetv3LocalRepository - NuGetv3LocalRepository localRepository = new(nugetLocalRepository.Value); - var package = localRepository.FindPackage(packageId.ToString(), version); - - var collection = new ContentItemCollection(); - collection.Load(package.Files); - - // Create criteria - var managedCriteria = new List(1); - var currentTargetFramework = NuGetFramework.Parse("net8.0"); - - var standardCriteria = conventions.Criteria.ForFrameworkAndRuntime( - currentTargetFramework, - RuntimeInformation.RuntimeIdentifier); - managedCriteria.Add(standardCriteria); - - // Create asset file - if (lockFileLib.PackageType.Contains(PackageType.DotnetTool)) - { - AddToolsAssets(conventions, lockFileLib, collection, managedCriteria); - } - - var lockFile = new LockFile(); - var lockFileTarget = new LockFileTarget() - { - TargetFramework = currentTargetFramework, - RuntimeIdentifier = RuntimeInformation.RuntimeIdentifier - }; - lockFileTarget.Libraries.Add(lockFileLib); - lockFile.Targets.Add(lockFileTarget); - new LockFileFormat().Write(Path.Combine(assetFileDirectory.Value, "project.assets.json"), lockFile); - }*/ - public MockFeedPackage GetPackage( string packageId, VersionRange versionRange, From 226751976b925ac04e545d6042ec736244aeb637 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 15 Aug 2023 13:40:59 -0700 Subject: [PATCH 20/47] Updated the targetFramework to be dynamic; Adding comments for the folders the tools and asset files are located in ToolPackageDownloader; Updated the local tools folder to be the NugetCachePath; Updated verbosity using VerbosityOption; Comment on methods from LockFileUtils; Updated the order of checking duplicated packages; Updated the functions in ToolPackageDownloader to be sync; Remove incorrect path --- .../ToolPackage/IToolPackageDownloader.cs | 2 +- .../ToolPackage/ToolPackageDownloader.cs | 41 +++++++++++++++---- .../ToolInstallGlobalOrToolPathCommand.cs | 2 +- .../install/ToolInstallLocalInstaller.cs | 4 +- .../dotnet-tool/restore/ToolRestoreCommand.cs | 2 +- .../ToolUpdateGlobalOrToolPathCommand.cs | 2 +- .../ToolPackageDownloaderMock.cs | 2 +- 7 files changed, 39 insertions(+), 16 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs index 213bf9ba9b0f..72e7286db4fd 100644 --- a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs @@ -9,7 +9,7 @@ namespace Microsoft.DotNet.Cli.ToolPackage { internal interface IToolPackageDownloader { - IToolPackage InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, + IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, VersionRange versionRange = null, string targetFramework = null, string verbosity = null, diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 31c373b453bc..c80fd187f795 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; +using System.CommandLine; using System.Reflection; using System.Runtime.InteropServices; using System.Threading.Tasks; @@ -33,14 +34,29 @@ internal class ToolPackageDownloader:IToolPackageDownloader private INuGetPackageDownloader _nugetPackageDownloader; private readonly IToolPackageStore _toolPackageStore; + // The directory that the tool will be downloaded to protected DirectoryPath _toolDownloadDir; + + // The directory that the tool package is returned protected DirectoryPath _toolReturnPackageDirectory; + + // The directory that the tool asset file is returned protected DirectoryPath _toolReturnJsonParentDirectory; + // The directory that global tools first downloaded + // example: C:\Users\username\.dotnet\tools\.store\.stage\tempFolder protected readonly DirectoryPath _globalToolStageDir; + + // The directory that local tools first downloaded + // example: C:\Users\username\.nuget\package protected readonly DirectoryPath _localToolDownloadDir; + + // The directory that local tools' asset files located + // example: C:\Users\username\AppData\Local\Temp\tempFolder protected readonly DirectoryPath _localToolAssetDir; - + + public static readonly CliOption VerbosityOption = CommonOptions.VerbosityOption; + public ToolPackageDownloader( IToolPackageStore store @@ -48,11 +64,11 @@ IToolPackageStore store { _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); ; _globalToolStageDir = _toolPackageStore.GetRandomStagingDirectory(); - _localToolDownloadDir = new DirectoryPath(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package")); + _localToolDownloadDir = new DirectoryPath(Environment.GetEnvironmentVariable("NUGET_PACKAGES")); _localToolAssetDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); } - public IToolPackage InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, + public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, VersionRange versionRange = null, string targetFramework = null, string verbosity = null, @@ -66,7 +82,10 @@ public IToolPackage InstallPackageAsync(PackageLocation packageLocation, Package action: () => { ILogger nugetLogger = new NullLogger(); - if( verbosity != null && (verbosity == "d" || verbosity == "detailed" || verbosity == "diag" || verbosity == "diagnostic")) + if( verbosity != null && (verbosity == VerbosityOptions.d.ToString() || + verbosity == VerbosityOptions.detailed.ToString() || + verbosity == VerbosityOptions.diag.ToString() || + verbosity == VerbosityOptions.diagnostic.ToString())) { nugetLogger = new NuGetConsoleLogger(); } @@ -113,6 +132,7 @@ public IToolPackage InstallPackageAsync(PackageLocation packageLocation, Package }); } + // The following methods are copied from the LockFileUtils class in Nuget.Client private static void AddToolsAssets( ManagedCodeConventions managedCodeConventions, LockFileTargetLibrary lockFileLib, @@ -199,10 +219,6 @@ string hashPathLocation File.WriteAllText(hashPath, packageHash); } - // Extract the package - var nupkgDir = Path.Combine(hashPathLocation, packageId.ToString(), version.ToString()); - var filesInPackage = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(nupkgDir)); - if (Directory.Exists(packagePath)) { throw new ToolPackageException( @@ -211,6 +227,12 @@ string hashPathLocation packageId, version.ToNormalizedString())); } + + // Extract the package + var nupkgDir = Path.Combine(hashPathLocation, packageId.ToString(), version.ToString()); + var filesInPackage = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(nupkgDir)); + + return version; } @@ -245,7 +267,8 @@ private static void CreateAssetFiles( // Create criteria var managedCriteria = new List(1); - var currentTargetFramework = NuGetFramework.Parse("net8.0"); + // Use major.minor version of currently running version of .NET + var currentTargetFramework = new NuGetFramework(FrameworkConstants.FrameworkIdentifiers.NetCoreApp, new Version(Environment.Version.Major, Environment.Version.Minor)); var standardCriteria = conventions.Criteria.ForFrameworkAndRuntime( currentTargetFramework, diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 72d20bd2b182..dc3bd2a34e16 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -131,7 +131,7 @@ public override int Execute() TransactionScopeOption.Required, TimeSpan.Zero)) { - package = toolPackageDownloader.InstallPackageAsync( + package = toolPackageDownloader.InstallPackage( new PackageLocation(nugetConfig: configFile, additionalFeeds: _source), packageId: _packageId, versionRange: versionRange, diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs index 1614f91ad9c0..35414f6ada16 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs @@ -69,11 +69,11 @@ public IToolPackage Install(FilePath manifestFile) try { - IToolPackage toolDownloadedPackage = _toolPackageDownloader.InstallPackageAsync( + IToolPackage toolDownloadedPackage = _toolPackageDownloader.InstallPackage( new PackageLocation( nugetConfig: configFile, additionalFeeds: _sources, - rootConfigDirectory: manifestFile.GetDirectoryPath()), + rootConfigDirectory: manifestFile.GetDirectoryPath().GetParentPath()), _packageId, versionRange, TargetFrameworkToInstall, diff --git a/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs index 44b2432400f6..b6b97c4b802c 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs @@ -130,7 +130,7 @@ private ToolRestoreResult InstallPackages( try { IToolPackage toolPackage = - _toolPackageDownloader.InstallPackageAsync( + _toolPackageDownloader.InstallPackage( new PackageLocation( nugetConfig: configFile, additionalFeeds: _sources, diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs index b7adbbf0e5e0..68b738976f01 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs @@ -109,7 +109,7 @@ public override int Execute() RunWithHandlingInstallError(() => { - IToolPackage newInstalledPackage = toolPackageDownloader.InstallPackageAsync( + IToolPackage newInstalledPackage = toolPackageDownloader.InstallPackage( new PackageLocation(nugetConfig: GetConfigFile(), additionalFeeds: _additionalFeeds), packageId: _packageId, versionRange: versionRange, diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index 2269abb7352d..c32927c191b1 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -93,7 +93,7 @@ public ToolPackageDownloaderMock( } } - public IToolPackage InstallPackageAsync(PackageLocation packageLocation, PackageId packageId, + public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, VersionRange versionRange = null, string targetFramework = null, string verbosity = null, From ee5b27cdfbed7452c1c1a5bdfa2656a0b7a6c498 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 16 Aug 2023 12:42:07 -0700 Subject: [PATCH 21/47] Update the local nuget tool download folder --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index c80fd187f795..d6f6d7619cd2 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -25,6 +25,7 @@ using NuGet.Repositories; using NuGet.RuntimeModel; using NuGet.Versioning; +using System; namespace Microsoft.DotNet.Cli.ToolPackage @@ -64,7 +65,7 @@ IToolPackageStore store { _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); ; _globalToolStageDir = _toolPackageStore.GetRandomStagingDirectory(); - _localToolDownloadDir = new DirectoryPath(Environment.GetEnvironmentVariable("NUGET_PACKAGES")); + _localToolDownloadDir = new DirectoryPath((Environment.GetEnvironmentVariable("NUGET_PACKAGES")) ?? (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package"))); _localToolAssetDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); } From 2a16464ca9772cae86315c0fc0513a77cc15c0fd Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 23 Aug 2023 13:05:44 -0700 Subject: [PATCH 22/47] add package source mapping when loading nuget source --- .../NuGetPackageDownloader.cs | 20 ++++++++++++++++--- 1 file changed, 17 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index 7c03ec72c065..9d0aa37e0342 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -15,6 +15,8 @@ using NuGet.Common; using NuGet.Configuration; using NuGet.Credentials; +using NuGet.DependencyResolver; +using NuGet.LibraryModel; using NuGet.Packaging; using NuGet.Protocol; using NuGet.Protocol.Core.Types; @@ -226,7 +228,7 @@ public async Task> ExtractPackageAsync(string packagePath, D IPackageSearchMetadata packageMetadata; - IEnumerable packagesSources = LoadNuGetSources(packageSourceLocation); + IEnumerable packagesSources = LoadNuGetSources(packageId, packageSourceLocation); PackageSource source; if (packageVersion is null) @@ -290,7 +292,7 @@ private static bool PackageIsInAllowList(IEnumerable files) return true; } - private IEnumerable LoadNuGetSources(PackageSourceLocation packageSourceLocation = null) + private IEnumerable LoadNuGetSources(PackageId packageId, PackageSourceLocation packageSourceLocation = null) { IEnumerable defaultSources = new List(); string currentDirectory = Directory.GetCurrentDirectory(); @@ -312,6 +314,18 @@ private IEnumerable LoadNuGetSources(PackageSourceLocation packag PackageSourceProvider packageSourceProvider = new PackageSourceProvider(settings); defaultSources = packageSourceProvider.LoadPackageSources().Where(source => source.IsEnabled); + PackageSourceMapping packageSourceMapping = PackageSourceMapping.GetPackageSourceMapping(settings); + + // filter package patterns if enabled + if (packageSourceMapping?.IsEnabled == true) + { + IReadOnlyList sources = packageSourceMapping.GetConfiguredPackageSources(packageId.ToString()); + + if (sources.Count == 0) + { + throw new NuGetPackageInstallerException("No NuGet sources are defined or enabled"); + } + } if (packageSourceLocation?.AdditionalSourceFeed?.Any() ?? false) { @@ -575,7 +589,7 @@ public async Task GetLatestPackageVersion(PackageId packageId, { CancellationToken cancellationToken = CancellationToken.None; IPackageSearchMetadata packageMetadata; - IEnumerable packagesSources = LoadNuGetSources(packageSourceLocation); + IEnumerable packagesSources = LoadNuGetSources(packageId, packageSourceLocation); (_, packageMetadata) = await GetLatestVersionInternalAsync(packageId.ToString(), packagesSources, includePreview, cancellationToken).ConfigureAwait(false); From 38feeeeb3db7274e0981baecbd6b27dddc6fe28f Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 24 Aug 2023 16:13:08 -0700 Subject: [PATCH 23/47] Remove installer package in ToolPackageInstaller and all its tests; update the ToolPackageUninstallerTests to use the downloader; add unit tests for ToolPackageDownloader in ToolPackageDownloaderTests; Update the way to get RID graph in ToolPackageDownloader --- .../ToolPackage/IToolPackageInstaller.cs | 5 - .../ToolPackage/ToolPackageDownloader.cs | 56 ++- .../ToolPackage/ToolPackageInstaller.cs | 87 ---- ...Tests.cs => ToolPackageDownloaderTests.cs} | 383 +++++------------- .../ToolPackageUninstallerTests.cs | 56 +-- 5 files changed, 160 insertions(+), 427 deletions(-) rename src/Tests/Microsoft.DotNet.PackageInstall.Tests/{ToolPackageInstallerTests.cs => ToolPackageDownloaderTests.cs} (66%) diff --git a/src/Cli/dotnet/ToolPackage/IToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/IToolPackageInstaller.cs index c76809951ebb..e34929f926e4 100644 --- a/src/Cli/dotnet/ToolPackage/IToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/IToolPackageInstaller.cs @@ -10,11 +10,6 @@ namespace Microsoft.DotNet.ToolPackage { internal interface IToolPackageInstaller { - IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, - VersionRange versionRange = null, - string targetFramework = null, - string verbosity = null); - IToolPackage InstallPackageToExternalManagedLocation(PackageLocation packageLocation, PackageId packageId, VersionRange versionRange = null, string targetFramework = null, diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index d6f6d7619cd2..95d94db60221 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -30,7 +30,7 @@ namespace Microsoft.DotNet.Cli.ToolPackage { - internal class ToolPackageDownloader:IToolPackageDownloader + internal class ToolPackageDownloader : IToolPackageDownloader { private INuGetPackageDownloader _nugetPackageDownloader; private readonly IToolPackageStore _toolPackageStore; @@ -58,15 +58,18 @@ internal class ToolPackageDownloader:IToolPackageDownloader public static readonly CliOption VerbosityOption = CommonOptions.VerbosityOption; + protected readonly string _runtimeJsonPath; public ToolPackageDownloader( - IToolPackageStore store + IToolPackageStore store, + string runtimeJsonPathTest = null ) { _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); ; _globalToolStageDir = _toolPackageStore.GetRandomStagingDirectory(); _localToolDownloadDir = new DirectoryPath((Environment.GetEnvironmentVariable("NUGET_PACKAGES")) ?? (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package"))); - _localToolAssetDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); + _localToolAssetDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); + _runtimeJsonPath = runtimeJsonPathTest ?? Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "RuntimeIdentifierGraph.json"); } public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, @@ -78,12 +81,12 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa { var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); string rollbackDirectory = null; - + return TransactionalAction.Run( action: () => { ILogger nugetLogger = new NullLogger(); - if( verbosity != null && (verbosity == VerbosityOptions.d.ToString() || + if (verbosity != null && (verbosity == VerbosityOptions.d.ToString() || verbosity == VerbosityOptions.detailed.ToString() || verbosity == VerbosityOptions.diag.ToString() || verbosity == VerbosityOptions.diagnostic.ToString())) @@ -95,8 +98,8 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir, verboseLogger: nugetLogger); rollbackDirectory = _toolDownloadDir.Value; - NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, _toolDownloadDir.Value).GetAwaiter().GetResult(); - CreateAssetFiles(packageId, version, _toolDownloadDir, assetFileDirectory); + NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, _toolDownloadDir.Value, _toolPackageStore).GetAwaiter().GetResult(); + CreateAssetFiles(packageId, version, _toolDownloadDir, assetFileDirectory, _runtimeJsonPath); if (isGlobalTool) { @@ -199,7 +202,8 @@ private static async Task DownloadAndExtractPackage( PackageLocation packageLocation, PackageId packageId, INuGetPackageDownloader _nugetPackageDownloader, - string hashPathLocation + string hashPathLocation, + IToolPackageStore toolPackageStore ) { var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); @@ -213,6 +217,26 @@ string hashPathLocation PackageArchiveReader reader = new PackageArchiveReader(packageStream); version = new NuspecReader(reader.GetNuspec()).GetVersion(); + var packageDirectory = toolPackageStore.GetPackageDirectory(packageId, version); + + if (Directory.Exists(packageDirectory.Value)) + { + throw new ToolPackageException( + string.Format( + CommonLocalizableStrings.ToolPackageConflictPackageId, + packageId, + version.ToNormalizedString())); + } + + if (Directory.Exists(packagePath)) + { + throw new ToolPackageException( + string.Format( + CommonLocalizableStrings.ToolPackageConflictPackageId, + packageId, + version.ToNormalizedString())); + } + var packageHash = Convert.ToBase64String(new CryptoHashProvider("SHA512").CalculateHash(reader.GetNuspec())); var hashPath = new VersionFolderPathResolver(hashPathLocation).GetHashPath(packageId.ToString(), version); @@ -220,20 +244,10 @@ string hashPathLocation File.WriteAllText(hashPath, packageHash); } - if (Directory.Exists(packagePath)) - { - throw new ToolPackageException( - string.Format( - CommonLocalizableStrings.ToolPackageConflictPackageId, - packageId, - version.ToNormalizedString())); - } - // Extract the package var nupkgDir = Path.Combine(hashPathLocation, packageId.ToString(), version.ToString()); var filesInPackage = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(nupkgDir)); - return version; } @@ -241,11 +255,11 @@ private static void CreateAssetFiles( PackageId packageId, NuGetVersion version, DirectoryPath nugetLocalRepository, - DirectoryPath assetFileDirectory) + DirectoryPath assetFileDirectory, + string runtimeJsonGraph) { // To get runtimeGraph: - var runtimeJsonPath = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "RuntimeIdentifierGraph.json"); - var runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonPath); + var runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonGraph); // Create ManagedCodeConventions: var conventions = new ManagedCodeConventions(runtimeGraph); diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs index 7cb9f616679a..2d32049cd4b7 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs @@ -34,93 +34,6 @@ public ToolPackageInstaller( _offlineFeed = offlineFeed ?? new DirectoryPath(CliFolderPathCalculator.CliFallbackFolderPath); } - public IToolPackage InstallPackage( - PackageLocation packageLocation, - PackageId packageId, - VersionRange versionRange = null, - string targetFramework = null, - string verbosity = null) - { - var packageRootDirectory = _store.GetRootPackageDirectory(packageId); - string rollbackDirectory = null; - - return TransactionalAction.Run( - action: () => - { - try - { - var stageDirectory = _store.GetRandomStagingDirectory(); - Directory.CreateDirectory(stageDirectory.Value); - rollbackDirectory = stageDirectory.Value; - - string tempProject = CreateDirectoryWithTempProject( - packageId: packageId, - versionRange: versionRange, - targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, - restoreDirectory: stageDirectory, - assetJsonOutputDirectory: stageDirectory, - rootConfigDirectory: packageLocation.RootConfigDirectory, - additionalFeeds: packageLocation.AdditionalFeeds); - - try - { - _projectRestorer.Restore( - new FilePath(tempProject), - packageLocation, - verbosity: verbosity); - } - finally - { - File.Delete(tempProject); - } - - var version = _store.GetStagedPackageVersion(stageDirectory, packageId); - var packageDirectory = _store.GetPackageDirectory(packageId, version); - - if (Directory.Exists(packageDirectory.Value)) - { - throw new ToolPackageException( - string.Format( - CommonLocalizableStrings.ToolPackageConflictPackageId, - packageId, - version.ToNormalizedString())); - } - - Directory.CreateDirectory(packageRootDirectory.Value); - FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(stageDirectory.Value, packageDirectory.Value)); - rollbackDirectory = packageDirectory.Value; - - return new ToolPackageInstance(id: packageId, - version: version, - packageDirectory: packageDirectory, - assetsJsonParentDirectory: packageDirectory); - } - catch (Exception ex) when (ex is UnauthorizedAccessException || ex is IOException) - { - throw new ToolPackageException( - string.Format( - CommonLocalizableStrings.FailedToInstallToolPackage, - packageId, - ex.Message), - ex); - } - }, - rollback: () => - { - if (!string.IsNullOrEmpty(rollbackDirectory) && Directory.Exists(rollbackDirectory)) - { - Directory.Delete(rollbackDirectory, true); - } - - // Delete the root if it is empty - if (Directory.Exists(packageRootDirectory.Value) && - !Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any()) - { - Directory.Delete(packageRootDirectory.Value, false); - } - }); - } - public IToolPackage InstallPackageToExternalManagedLocation( PackageLocation packageLocation, PackageId packageId, diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs similarity index 66% rename from src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs rename to src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs index 72ccff69e7b2..6f2913adb32a 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs @@ -12,6 +12,7 @@ using FluentAssertions; using Microsoft.DotNet.Tools.Test.Utilities; using Microsoft.DotNet.Cli; +using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools; using Microsoft.DotNet.Tools.Tool.Install; @@ -48,67 +49,8 @@ public DotnetEnvironmentTestFixture() public void Dispose() => Environment.SetEnvironmentVariable(_PATH_VAR_NAME, _originalPath); } - public class ToolPackageInstallerTests : SdkTest, IClassFixture + public class ToolPackageDownloaderTests : SdkTest, IClassFixture { - [Theory] - [InlineData(false)] - [InlineData(true)] - public void GivenNoFeedInstallFailsWithException(bool testMockBehaviorIsInSync) - { - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( - useMock: testMockBehaviorIsInSync, - feeds: new List()); - - Action a = () => installer.InstallPackage(new PackageLocation(), packageId: TestPackageId, - versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework); - - a.Should().Throw().WithMessage(Tools.Tool.Install.LocalizableStrings.ToolInstallationRestoreFailed); - - reporter.Lines.Count.Should().Be(1); - reporter.Lines[0].Should().Contain(TestPackageId.ToString()); - } - - [Theory] - [InlineData(false)] - [InlineData(true)] - public void GivenOfflineFeedInstallSucceeds(bool testMockBehaviorIsInSync) - { - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( - useMock: testMockBehaviorIsInSync, - offlineFeed: new DirectoryPath(GetTestLocalFeedPath()), - feeds: GetOfflineMockFeed()); - - var package = installer.InstallPackage(new PackageLocation(), packageId: TestPackageId, - versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework); - - AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); - - uninstaller.Uninstall(package.PackageDirectory); - } - - [Theory] - [InlineData(false)] - [InlineData(true)] - public void GivenAEmptySourceAndOfflineFeedInstallSucceeds(bool testMockBehaviorIsInSync) - { - var emptySource = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); - Directory.CreateDirectory(emptySource); - - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( - useMock: testMockBehaviorIsInSync, - offlineFeed: new DirectoryPath(GetTestLocalFeedPath()), - feeds: GetOfflineMockFeed()); - - var package = installer.InstallPackage(new PackageLocation(additionalFeeds: new[] { emptySource }), - packageId: TestPackageId, - versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); - - AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); - - uninstaller.Uninstall(package.PackageDirectory); - } - [Theory] [InlineData(false)] [InlineData(true)] @@ -116,15 +58,16 @@ public void GivenNugetConfigInstallSucceeds(bool testMockBehaviorIsInSync) { var nugetConfigPath = GenerateRandomNugetConfigFilePath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, writeLocalFeedToNugetConfig: nugetConfigPath, identiifer: testMockBehaviorIsInSync.ToString()); - var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), + var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -138,7 +81,7 @@ public void GivenNugetConfigInstallSucceedsInTransaction(bool testMockBehaviorIs { var nugetConfigPath = GenerateRandomNugetConfigFilePath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, writeLocalFeedToNugetConfig: nugetConfigPath); @@ -147,10 +90,11 @@ public void GivenNugetConfigInstallSucceedsInTransaction(bool testMockBehaviorIs TransactionScopeOption.Required, TimeSpan.Zero)) { - package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), + package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); transactionScope.Complete(); } @@ -167,14 +111,15 @@ public void GivenNugetConfigInstallCreatesAnAssetFile(bool testMockBehaviorIsInS { var nugetConfigPath = GenerateRandomNugetConfigFilePath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, writeLocalFeedToNugetConfig: nugetConfigPath); - var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), + var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -224,18 +169,19 @@ public void GivenAConfigFileRootDirectoryPackageInstallSucceedsViaFindingNugetCo } }; - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, writeLocalFeedToNugetConfig: nugetConfigPath, feeds: onlyNugetConfigInParentDirHasPackagesFeed); fileSystem.Directory.CreateDirectory(subDirUnderNugetConfigPath.Value); - var package = installer.InstallPackage( + var package = downloader.InstallPackage( new PackageLocation(rootConfigDirectory: subDirUnderNugetConfigPath), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -249,104 +195,21 @@ public void GivenAllButNoPackageVersionItCanInstallThePackage(bool testMockBehav { var nugetConfigPath = GenerateRandomNugetConfigFilePath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, writeLocalFeedToNugetConfig: nugetConfigPath); - var package = installer.InstallPackage( + var package = downloader.InstallPackage( new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); uninstaller.Uninstall(package.PackageDirectory); } - [Theory] - [InlineData(false)] - [InlineData(true)] - public void GivenOfflineFeedInstallWhenCallWithprereleaseItSucceeds(bool testMockBehaviorIsInSync) - { - IToolPackageInstaller installer = null; - IToolPackageUninstaller uninstaller = null; - if (testMockBehaviorIsInSync == false) - { - var testFeedWithOnlyPreviewPackages = - Path.Combine(Path.GetTempPath(), - Path.GetRandomFileName()); - - Directory.CreateDirectory(testFeedWithOnlyPreviewPackages); - var tempFeed = GetTestLocalFeedPath(); - File.Copy(Path.Combine(GetTestLocalFeedPath(), "global.tool.console.demo.1.0.4.nupkg"), - Path.Combine(testFeedWithOnlyPreviewPackages, "global.tool.console.demo.1.0.4.nupkg")); - File.Copy(Path.Combine(GetTestLocalFeedPath(), "global.tool.console.demo.2.0.1-preview1.nupkg"), - Path.Combine(testFeedWithOnlyPreviewPackages, "global.tool.console.demo.2.0.1-preview1.nupkg")); - - var (store, storeQuery, realInstaller, realUninstaller, reporter, fileSystem) = Setup( - useMock: testMockBehaviorIsInSync, - offlineFeed: new DirectoryPath(testFeedWithOnlyPreviewPackages), - feeds: GetOfflineMockFeed()); - - installer = realInstaller; - uninstaller = realUninstaller; - } - else - { - var fileSystem = new FileSystemMockBuilder().Build(); - var root = new DirectoryPath(_testAssetsManager - .CreateTestDirectory(nameof(GivenOfflineFeedInstallWhenCallWithprereleaseItSucceeds) + - testMockBehaviorIsInSync).Path); - var toolPackageStoreMock = new ToolPackageStoreMock(root, fileSystem); - var store = toolPackageStoreMock; - var storeQuery = toolPackageStoreMock; - installer = new ToolPackageInstallerMock( - fileSystem: fileSystem, - store: toolPackageStoreMock, - projectRestorer: new ProjectRestorerMock( - fileSystem: fileSystem, - reporter: new BufferedReporter(), - feeds: new List - { - new MockFeed - { - Type = MockFeedType.ImplicitAdditionalFeed, - Packages = new List - { - new MockFeedPackage - { - PackageId = TestPackageId.ToString(), - Version = "1.0.4", - ToolCommandName = "SimulatorCommand" - }, - new MockFeedPackage - { - PackageId = TestPackageId.ToString(), - Version = "2.0.1-preview1", - ToolCommandName = "SimulatorCommand" - } - } - } - })); - uninstaller = new ToolPackageUninstallerMock(fileSystem, toolPackageStoreMock); - } - - - var package = installer.InstallPackage(new PackageLocation(), packageId: TestPackageId, - versionRange: VersionRange.Parse("*-*"), targetFramework: _testTargetframework); - - package.Version.ToNormalizedString().Should().Be("2.0.1-preview1"); - - uninstaller.Uninstall(package.PackageDirectory); - - var package2 = installer.InstallPackage(new PackageLocation(), packageId: TestPackageId, - versionRange: VersionRange.Parse("2.0*-*"), targetFramework: _testTargetframework); - - package2.Version.ToNormalizedString().Should().Be("2.0.1-preview1"); - - uninstaller.Uninstall(package.PackageDirectory); - } - [Theory] [InlineData(false)] [InlineData(true)] @@ -354,13 +217,14 @@ public void GivenAllButNoTargetFrameworkItCanDownloadThePackage(bool testMockBeh { var nugetConfigPath = GenerateRandomNugetConfigFilePath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, writeLocalFeedToNugetConfig: nugetConfigPath); - var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), + var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, - versionRange: VersionRange.Parse(TestPackageVersion)); + versionRange: VersionRange.Parse(TestPackageVersion), + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -374,14 +238,15 @@ public void GivenASourceInstallSucceeds(bool testMockBehaviorIsInSync) { var source = GetTestLocalFeedPath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: GetMockFeedsForSource(source)); - var package = installer.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + var package = downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -395,15 +260,16 @@ public void GivenARelativeSourcePathInstallSucceeds(bool testMockBehaviorIsInSyn { var source = GetTestLocalFeedPath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: GetMockFeedsForSource(source)); - var package = installer.InstallPackage( + var package = downloader.InstallPackage( new PackageLocation(additionalFeeds: new[] {Path.GetRelativePath(Directory.GetCurrentDirectory(), source)}), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -417,14 +283,15 @@ public void GivenAUriSourceInstallSucceeds(bool testMockBehaviorIsInSync) { var source = GetTestLocalFeedPath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: GetMockFeedsForSource(source)); - var package = installer.InstallPackage( + var package = downloader.InstallPackage( new PackageLocation(additionalFeeds: new[] { new Uri(source).AbsoluteUri }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -440,46 +307,22 @@ public void GivenAEmptySourceAndNugetConfigInstallSucceeds(bool testMockBehavior var emptySource = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(emptySource); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, writeLocalFeedToNugetConfig: nugetConfigPath); - var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath, + var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath, additionalFeeds: new[] { emptySource }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); uninstaller.Uninstall(package.PackageDirectory); } - [Theory] - [InlineData(false)] - [InlineData(true)] - public void GivenFailedRestoreInstallWillRollback(bool testMockBehaviorIsInSync) - { - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( - useMock: testMockBehaviorIsInSync); - - Action a = () => - { - using (var t = new TransactionScope( - TransactionScopeOption.Required, - TimeSpan.Zero)) - { - installer.InstallPackage(new PackageLocation(), new PackageId("non.existent.package.id")); - - t.Complete(); - } - }; - - a.Should().Throw().WithMessage(Tools.Tool.Install.LocalizableStrings.ToolInstallationRestoreFailed); - - AssertInstallRollBack(fileSystem, store); - } - [Theory] [InlineData(false)] [InlineData(true)] @@ -487,7 +330,7 @@ public void GivenFailureAfterRestoreInstallWillRollback(bool testMockBehaviorIsI { var source = GetTestLocalFeedPath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: GetMockFeedsForSource(source)); @@ -499,10 +342,11 @@ public void GivenFailureAfterRestoreInstallWillRollback(bool testMockBehaviorIsI TransactionScopeOption.Required, TimeSpan.Zero)) { - installer.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); FailedStepAfterSuccessRestore(); t.Complete(); @@ -521,7 +365,7 @@ public void GivenSecondInstallInATransactionTheFirstInstallShouldRollback(bool t { var source = GetTestLocalFeedPath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: GetMockFeedsForSource(source)); @@ -531,17 +375,19 @@ public void GivenSecondInstallInATransactionTheFirstInstallShouldRollback(bool t TransactionScopeOption.Required, TimeSpan.Zero)) { - Action first = () => installer.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + Action first = () => downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); first.Should().NotThrow(); - installer.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); t.Complete(); } @@ -564,21 +410,23 @@ public void GivenSecondInstallWithoutATransactionTheFirstShouldNotRollback(bool { var source = GetTestLocalFeedPath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: GetMockFeedsForSource(source)); - var package = installer.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + var package = downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); - Action secondCall = () => installer.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + Action secondCall = () => downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); reporter.Lines.Should().BeEmpty(); @@ -611,15 +459,16 @@ public void GivenAnInstalledPackageUninstallRemovesThePackage(bool testMockBehav { var source = GetTestLocalFeedPath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: GetMockFeedsForSource(source), identiifer: testMockBehaviorIsInSync.ToString()); - var package = installer.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + var package = downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -635,15 +484,16 @@ public void GivenAnInstalledPackageUninstallRollsbackWhenTransactionFails(bool t { var source = GetTestLocalFeedPath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: GetMockFeedsForSource(source)); - var package = installer.InstallPackage( + var package = downloader.InstallPackage( new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -669,14 +519,15 @@ public void GivenAnInstalledPackageUninstallRemovesThePackageWhenTransactionComm { var source = GetTestLocalFeedPath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: GetMockFeedsForSource(source)); - var package = installer.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + var package = downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -698,39 +549,14 @@ public void GivenAPackageNameWithDifferentCaseItCanInstallThePackage(bool testMo { var nugetConfigPath = GenerateRandomNugetConfigFilePath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, writeLocalFeedToNugetConfig: nugetConfigPath); - var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), + var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: new PackageId("GlObAl.TooL.coNsoLe.DemO"), - targetFramework: _testTargetframework); - - AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); - - uninstaller.Uninstall(package.PackageDirectory); - } - - [Fact] - public void GivenANuGetDiagnosticMessageItShouldNotContainTheTempProject() - { - var nugetConfigPath = GenerateRandomNugetConfigFilePath(); - var tempProject = GetUniqueTempProjectPathEachTest(); - - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( - useMock: false, - tempProject: tempProject, - writeLocalFeedToNugetConfig: nugetConfigPath); - - var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), - packageId: TestPackageId, - versionRange: VersionRange.Parse("1.0.0"), - targetFramework: _testTargetframework); - - reporter.Lines.Should().NotBeEmpty(); - reporter.Lines.Should().Contain(l => l.Contains("warning")); - reporter.Lines.Should().NotContain(l => l.Contains(tempProject.Value)); - reporter.Lines.Clear(); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -750,16 +576,18 @@ public void GivenARootWithNonAsciiCharacterInstallSucceeds() var fileSystem = new FileSystemWrapper(); var store = new ToolPackageStoreAndQuery(new DirectoryPath(root.Path)); WriteNugetConfigFileToPointToTheFeed(fileSystem, nugetConfigPath); - var installer = new ToolPackageInstaller( + var testRuntimeJsonPath = Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, "RuntimeIdentifierGraph.json"); + + var downloader = new ToolPackageDownloader( store: store, - projectRestorer: new Stage2ProjectRestorer(Log, reporter), - tempProject: GetUniqueTempProjectPathEachTest(), - offlineFeed: new DirectoryPath("does not exist")); + testRuntimeJsonPath + ); - var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), + var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, store); @@ -776,15 +604,16 @@ public void GivenAComplexVersionRangeInstallSucceeds(bool testMockBehaviorIsInSy var emptySource = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName()); Directory.CreateDirectory(emptySource); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, writeLocalFeedToNugetConfig: nugetConfigPath); - var package = installer.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath, + var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath, additionalFeeds: new[] { emptySource }), packageId: TestPackageId, versionRange: VersionRange.Parse("1.0.0-rc*"), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); AssertPackageInstall(reporter, fileSystem, package, store, storeQuery); @@ -818,7 +647,7 @@ public void GivenAPackageWithCasingAndenUSPOSIXInstallSucceeds(bool testMockBeha } }; - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: new List { feed }, writeLocalFeedToNugetConfig: nugetConfigPath); @@ -828,13 +657,14 @@ public void GivenAPackageWithCasingAndenUSPOSIXInstallSucceeds(bool testMockBeha { CultureInfo.CurrentCulture = new CultureInfo("en-US-POSIX"); IToolPackage package = null; - Action action = () => package = installer.InstallPackage( + Action action = () => package = downloader.InstallPackage( new PackageLocation( nugetConfig: nugetConfigPath, additionalFeeds: new[] { emptySource }), packageId: packageId, versionRange: VersionRange.Parse(packageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); action.Should().NotThrow(); @@ -972,12 +802,10 @@ private static List GetOfflineMockFeed() }; } - private (IToolPackageStore, IToolPackageStoreQuery, IToolPackageInstaller, IToolPackageUninstaller, BufferedReporter, IFileSystem + private (IToolPackageStore, IToolPackageStoreQuery, IToolPackageDownloader, IToolPackageUninstaller, BufferedReporter, IFileSystem ) Setup( bool useMock, List feeds = null, - FilePath? tempProject = null, - DirectoryPath? offlineFeed = null, FilePath? writeLocalFeedToNugetConfig = null, [CallerMemberName] string callingMethod = "", string identiifer = null) @@ -988,7 +816,7 @@ private static List GetOfflineMockFeed() IFileSystem fileSystem; IToolPackageStore store; IToolPackageStoreQuery storeQuery; - IToolPackageInstaller installer; + IToolPackageDownloader downloader; IToolPackageUninstaller uninstaller; if (useMock) { @@ -999,15 +827,13 @@ private static List GetOfflineMockFeed() var toolPackageStoreMock = new ToolPackageStoreMock(root, fileSystem, frameworksMap); store = toolPackageStoreMock; storeQuery = toolPackageStoreMock; - installer = new ToolPackageInstallerMock( - fileSystem: fileSystem, + downloader = new ToolPackageDownloaderMock( store: toolPackageStoreMock, - projectRestorer: new ProjectRestorerMock( - fileSystem: fileSystem, - reporter: reporter, - feeds: feeds == null + fileSystem: fileSystem, + reporter: reporter, + feeds: feeds == null ? GetMockFeedsForConfigFile(writeLocalFeedToNugetConfig) - : feeds.Concat(GetMockFeedsForConfigFile(writeLocalFeedToNugetConfig)).ToList()), + : feeds.Concat(GetMockFeedsForConfigFile(writeLocalFeedToNugetConfig)).ToList(), frameworksMap: frameworksMap); uninstaller = new ToolPackageUninstallerMock(fileSystem, toolPackageStoreMock); } @@ -1018,17 +844,14 @@ private static List GetOfflineMockFeed() var toolPackageStore = new ToolPackageStoreAndQuery(root); store = toolPackageStore; storeQuery = toolPackageStore; - installer = new ToolPackageInstaller( - store: store, - projectRestorer: new Stage2ProjectRestorer(Log, reporter), - tempProject: tempProject ?? GetUniqueTempProjectPathEachTest(), - offlineFeed: offlineFeed ?? new DirectoryPath("does not exist")); + var testRuntimeJsonPath = Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, "RuntimeIdentifierGraph.json"); + downloader = new ToolPackageDownloader(store, testRuntimeJsonPath); uninstaller = new ToolPackageUninstaller(store); } store.Root.Value.Should().Be(Path.GetFullPath(root.Value)); - return (store, storeQuery, installer, uninstaller, reporter, fileSystem); + return (store, storeQuery, downloader, uninstaller, reporter, fileSystem); } private static void WriteNugetConfigFileToPointToTheFeed(IFileSystem fileSystem, FilePath? filePath) @@ -1076,7 +899,7 @@ private static string GetTestLocalFeedPath() => private static readonly PackageId TestPackageId = new PackageId("global.tool.console.demo"); private static readonly IEnumerable TestFrameworks = new NuGetFramework[] { NuGetFramework.Parse("netcoreapp2.1") }; - public ToolPackageInstallerTests(ITestOutputHelper log) : base(log) + public ToolPackageDownloaderTests(ITestOutputHelper log) : base(log) { } } diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs index 6b50ec800d3e..a9bd0b4a92ae 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs @@ -13,6 +13,8 @@ using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.Tools; using Microsoft.DotNet.Tools.Tool.Install; +using Microsoft.DotNet.Cli.ToolPackage; +using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Tools.Tests.ComponentMocks; using Microsoft.Extensions.DependencyModel.Tests; using Microsoft.Extensions.EnvironmentAbstractions; @@ -35,15 +37,16 @@ public void GivenAnInstalledPackageUninstallRemovesThePackage(bool testMockBehav { var source = GetTestLocalFeedPath(); - var (store, storeQuery, installer, uninstaller, reporter, fileSystem) = Setup( + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( useMock: testMockBehaviorIsInSync, feeds: GetMockFeedsForSource(source), identifier: testMockBehaviorIsInSync.ToString()); - var package = installer.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + var package = downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), - targetFramework: _testTargetframework); + targetFramework: _testTargetframework, + isGlobalTool: true); package.PackagedShims.Should().ContainSingle(f => f.Value.Contains("demo.exe") || f.Value.Contains("demo")); @@ -52,15 +55,6 @@ public void GivenAnInstalledPackageUninstallRemovesThePackage(bool testMockBehav storeQuery.EnumeratePackages().Should().BeEmpty(); } - private static FilePath GetUniqueTempProjectPathEachTest() - { - var tempProjectDirectory = - new DirectoryPath(Path.GetTempPath()).WithSubDirectories(Path.GetRandomFileName()); - var tempProjectPath = - tempProjectDirectory.WithFile(Path.GetRandomFileName() + ".csproj"); - return tempProjectPath; - } - private static List GetMockFeedsForSource(string source) { return new List @@ -82,14 +76,12 @@ private static List GetMockFeedsForSource(string source) }; } - private (IToolPackageStore, IToolPackageStoreQuery, IToolPackageInstaller, IToolPackageUninstaller, BufferedReporter, IFileSystem - ) Setup( - bool useMock, - List feeds = null, - FilePath? tempProject = null, - DirectoryPath? offlineFeed = null, - [CallerMemberName] string testName = "", - string identifier = null) + private (IToolPackageStore, IToolPackageStoreQuery, IToolPackageDownloader, IToolPackageUninstaller, BufferedReporter, IFileSystem + ) Setup( + bool useMock, + List feeds = null, + [CallerMemberName] string testName = "", + string identifier = null) { var root = new DirectoryPath(_testAssetsManager.CreateTestDirectory(testName, identifier).Path); var reporter = new BufferedReporter(); @@ -97,7 +89,7 @@ private static List GetMockFeedsForSource(string source) IFileSystem fileSystem; IToolPackageStore store; IToolPackageStoreQuery storeQuery; - IToolPackageInstaller installer; + IToolPackageDownloader downloader; IToolPackageUninstaller uninstaller; if (useMock) { @@ -110,14 +102,13 @@ private static List GetMockFeedsForSource(string source) var toolPackageStoreMock = new ToolPackageStoreMock(root, fileSystem); store = toolPackageStoreMock; storeQuery = toolPackageStoreMock; - installer = new ToolPackageInstallerMock( - fileSystem: fileSystem, + + downloader = new ToolPackageDownloaderMock( store: toolPackageStoreMock, - projectRestorer: new ProjectRestorerMock( - fileSystem: fileSystem, - reporter: reporter, - feeds: feeds), - packagedShimsMap: packagedShimsMap); + fileSystem: fileSystem, + reporter: reporter, + feeds: feeds, + packagedShimsMap: packagedShimsMap); uninstaller = new ToolPackageUninstallerMock(fileSystem, toolPackageStoreMock); } else @@ -126,17 +117,14 @@ private static List GetMockFeedsForSource(string source) var toolPackageStore = new ToolPackageStoreAndQuery(root); store = toolPackageStore; storeQuery = toolPackageStore; - installer = new ToolPackageInstaller( - store: store, - projectRestorer: new Stage2ProjectRestorer(Log, reporter), - tempProject: tempProject ?? GetUniqueTempProjectPathEachTest(), - offlineFeed: offlineFeed ?? new DirectoryPath("does not exist")); + var testRuntimeJsonPath = Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, "RuntimeIdentifierGraph.json"); + downloader = new ToolPackageDownloader(store, testRuntimeJsonPath); uninstaller = new ToolPackageUninstaller(store); } store.Root.Value.Should().Be(Path.GetFullPath(root.Value)); - return (store, storeQuery, installer, uninstaller, reporter, fileSystem); + return (store, storeQuery, downloader, uninstaller, reporter, fileSystem); } private static string GetTestLocalFeedPath() => From 2a08e1c90907f502d2627a1fef576d749612c08d Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Fri, 25 Aug 2023 21:08:45 -0700 Subject: [PATCH 24/47] Remove ToolPackageInstaller class --- .../ToolPackage/IToolPackageInstaller.cs | 18 -- .../ToolPackage/ToolPackageDownloader.cs | 12 +- .../dotnet/ToolPackage/ToolPackageFactory.cs | 28 --- .../ToolPackage/ToolPackageInstaller.cs | 147 --------------- .../ToolPackageInstallerNugetCacheTests.cs | 58 ++---- .../ToolPackageUninstallerTests.cs | 14 +- .../ToolPackageDownloaderMock.cs | 3 +- .../ToolPackageInstallerMock.cs | 170 ------------------ 8 files changed, 30 insertions(+), 420 deletions(-) delete mode 100644 src/Cli/dotnet/ToolPackage/IToolPackageInstaller.cs delete mode 100644 src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs delete mode 100644 src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageInstallerMock.cs diff --git a/src/Cli/dotnet/ToolPackage/IToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/IToolPackageInstaller.cs deleted file mode 100644 index e34929f926e4..000000000000 --- a/src/Cli/dotnet/ToolPackage/IToolPackageInstaller.cs +++ /dev/null @@ -1,18 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using Microsoft.Extensions.EnvironmentAbstractions; -using NuGet.Versioning; - -namespace Microsoft.DotNet.ToolPackage -{ - internal interface IToolPackageInstaller - { - IToolPackage InstallPackageToExternalManagedLocation(PackageLocation packageLocation, PackageId packageId, - VersionRange versionRange = null, - string targetFramework = null, - string verbosity = null); - } -} diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 95d94db60221..0201812a13bf 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -25,7 +25,6 @@ using NuGet.Repositories; using NuGet.RuntimeModel; using NuGet.Versioning; -using System; namespace Microsoft.DotNet.Cli.ToolPackage @@ -56,18 +55,23 @@ internal class ToolPackageDownloader : IToolPackageDownloader // example: C:\Users\username\AppData\Local\Temp\tempFolder protected readonly DirectoryPath _localToolAssetDir; - public static readonly CliOption VerbosityOption = CommonOptions.VerbosityOption; + public static readonly Option VerbosityOption = CommonOptions.VerbosityOption; protected readonly string _runtimeJsonPath; public ToolPackageDownloader( IToolPackageStore store, - string runtimeJsonPathTest = null + string runtimeJsonPathTest = null, + string localToolPath = null ) { _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); ; _globalToolStageDir = _toolPackageStore.GetRandomStagingDirectory(); - _localToolDownloadDir = new DirectoryPath((Environment.GetEnvironmentVariable("NUGET_PACKAGES")) ?? (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package"))); + _localToolDownloadDir = new DirectoryPath((localToolPath) ?? ((Environment.GetEnvironmentVariable("NUGET_PACKAGES")))); + if(String.IsNullOrEmpty(_localToolDownloadDir.ToString())) + { + _localToolDownloadDir = new DirectoryPath((Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package"))); + } _localToolAssetDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); _runtimeJsonPath = runtimeJsonPathTest ?? Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "RuntimeIdentifierGraph.json"); } diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs b/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs index 73f6789f1dd5..2daf1d966e9e 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageFactory.cs @@ -12,17 +12,6 @@ namespace Microsoft.DotNet.ToolPackage { internal static class ToolPackageFactory { - public static (IToolPackageStore, IToolPackageStoreQuery, IToolPackageInstaller) CreateToolPackageStoresAndInstaller( - DirectoryPath? nonGlobalLocation = null, IEnumerable additionalRestoreArguments = null) - { - ToolPackageStoreAndQuery toolPackageStore = CreateConcreteToolPackageStore(nonGlobalLocation); - var toolPackageInstaller = new ToolPackageInstaller( - toolPackageStore, - new ProjectRestorer(additionalRestoreArguments: additionalRestoreArguments)); - - return (toolPackageStore, toolPackageStore, toolPackageInstaller); - } - public static (IToolPackageStore, IToolPackageStoreQuery, IToolPackageDownloader) CreateToolPackageStoresAndDownloader( DirectoryPath? nonGlobalLocation = null, IEnumerable additionalRestoreArguments = null) { @@ -42,23 +31,6 @@ public static (IToolPackageStore, IToolPackageStoreQuery, IToolPackageUninstalle return (toolPackageStore, toolPackageStore, toolPackageUninstaller); } - public static (IToolPackageStore, - IToolPackageStoreQuery, - IToolPackageInstaller, - IToolPackageUninstaller) - CreateToolPackageStoresAndInstallerAndUninstaller( - DirectoryPath? nonGlobalLocation = null, IEnumerable additionalRestoreArguments = null) - { - ToolPackageStoreAndQuery toolPackageStore = CreateConcreteToolPackageStore(nonGlobalLocation); - var toolPackageInstaller = new ToolPackageInstaller( - toolPackageStore, - new ProjectRestorer(additionalRestoreArguments: additionalRestoreArguments)); - var toolPackageUninstaller = new ToolPackageUninstaller( - toolPackageStore); - - return (toolPackageStore, toolPackageStore, toolPackageInstaller, toolPackageUninstaller); - } - public static (IToolPackageStore, IToolPackageStoreQuery, IToolPackageDownloader, diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs b/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs deleted file mode 100644 index 2d32049cd4b7..000000000000 --- a/src/Cli/dotnet/ToolPackage/ToolPackageInstaller.cs +++ /dev/null @@ -1,147 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Xml.Linq; -using Microsoft.DotNet.Cli; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Configurer; -using Microsoft.DotNet.Tools; -using Microsoft.Extensions.EnvironmentAbstractions; -using NuGet.Versioning; - -namespace Microsoft.DotNet.ToolPackage -{ - internal class ToolPackageInstaller : IToolPackageInstaller - { - private readonly IToolPackageStore _store; - private readonly IProjectRestorer _projectRestorer; - private readonly FilePath? _tempProject; - private readonly DirectoryPath _offlineFeed; - - public ToolPackageInstaller( - IToolPackageStore store, - IProjectRestorer projectRestorer, - FilePath? tempProject = null, - DirectoryPath? offlineFeed = null) - { - _store = store ?? throw new ArgumentNullException(nameof(store)); - _projectRestorer = projectRestorer ?? throw new ArgumentNullException(nameof(projectRestorer)); - _tempProject = tempProject; - _offlineFeed = offlineFeed ?? new DirectoryPath(CliFolderPathCalculator.CliFallbackFolderPath); - } - - public IToolPackage InstallPackageToExternalManagedLocation( - PackageLocation packageLocation, - PackageId packageId, - VersionRange versionRange = null, - string targetFramework = null, - string verbosity = null) - { - var tempDirectoryForAssetJson = PathUtilities.CreateTempSubdirectory(); - - string tempProject = CreateDirectoryWithTempProject( - packageId: packageId, - versionRange: versionRange, - targetFramework: string.IsNullOrEmpty(targetFramework) ? BundledTargetFramework.GetTargetFrameworkMoniker() : targetFramework, - assetJsonOutputDirectory: new DirectoryPath(tempDirectoryForAssetJson), - restoreDirectory: null, - rootConfigDirectory: packageLocation.RootConfigDirectory, - additionalFeeds: packageLocation.AdditionalFeeds); - - try - { - _projectRestorer.Restore( - new FilePath(tempProject), - packageLocation, - verbosity: verbosity); - } - finally - { - File.Delete(tempProject); - } - - return ToolPackageInstance.CreateFromAssetFile(packageId, new DirectoryPath(tempDirectoryForAssetJson)); - } - - private string CreateDirectoryWithTempProject( - PackageId packageId, - VersionRange versionRange, - string targetFramework, - DirectoryPath? restoreDirectory, - DirectoryPath assetJsonOutputDirectory, - DirectoryPath? rootConfigDirectory, - string[] additionalFeeds) - { - string tempProject; - if (_tempProject != null && _tempProject.HasValue) - { - tempProject = _tempProject.Value.Value; - Directory.CreateDirectory(Path.GetDirectoryName(tempProject)); - } - else - tempProject = Path.Combine(PathUtilities.CreateTempSubdirectory(), "restore.csproj"); - - var tempProjectContent = new XDocument( - new XElement("Project", - new XElement("PropertyGroup", - // due to https://github.com/Microsoft/msbuild/issues/1603 -- import SDK after setting MsBuildProjectExtensionsPath - new XElement("MsBuildProjectExtensionsPath", assetJsonOutputDirectory.Value)), // change the output directory of asset.json - new XElement(("Import"), - new XAttribute("Project", "Sdk.props"), - new XAttribute("Sdk", "Microsoft.NET.Sdk")), - new XElement("PropertyGroup", - new XElement("TargetFramework", targetFramework), - restoreDirectory.HasValue ? new XElement("RestorePackagesPath", restoreDirectory.Value.Value) : null, - new XElement("RestoreProjectStyle", "DotnetToolReference"), // without it, project cannot reference tool package - new XElement("RestoreRootConfigDirectory", rootConfigDirectory?.Value ?? Directory.GetCurrentDirectory()), // config file probing start directory - new XElement("DisableImplicitFrameworkReferences", "true"), // no Microsoft.NETCore.App in tool folder - new XElement("RestoreFallbackFolders", "clear"), // do not use fallbackfolder, tool package need to be copied to tool folder - new XElement("RestoreAdditionalProjectSources", JoinSourceAndOfflineCache(additionalFeeds)), - new XElement("RestoreAdditionalProjectFallbackFolders", string.Empty), // block other - new XElement("RestoreAdditionalProjectFallbackFoldersExcludes", string.Empty), // block other - new XElement("DisableImplicitNuGetFallbackFolder", "true")), // disable SDK side implicit NuGetFallbackFolder - new XElement("ItemGroup", - new XElement("PackageReference", - new XAttribute("Include", packageId.ToString()), - new XAttribute("Version", - versionRange?.ToString("N", new VersionRangeFormatter()) ?? "*"))), // nuget will restore latest stable for * and format N is the normalization format - new XElement(("Import"), - new XAttribute("Project", "Sdk.targets"), - new XAttribute("Sdk", "Microsoft.NET.Sdk")))); - - File.WriteAllText(tempProject, tempProjectContent.ToString()); - return tempProject; - } - - private string JoinSourceAndOfflineCache(string[] additionalFeeds) - { - var feeds = new List(); - if (additionalFeeds != null) - { - foreach (var feed in additionalFeeds) - { - if (Uri.IsWellFormedUriString(feed, UriKind.Absolute)) - { - feeds.Add(feed); - } - else - { - feeds.Add(Path.GetFullPath(feed)); - } - } - } - - // use fallbackfolder as feed to enable offline - if (Directory.Exists(_offlineFeed.Value)) - { - feeds.Add(_offlineFeed.ToXmlEncodeString()); - } - - return string.Join(";", feeds); - } - } -} diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs index 1607bea642a5..691eb4a04dd3 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs @@ -5,20 +5,17 @@ using System.IO; using System.Reflection; using FluentAssertions; -using Microsoft.DotNet.Tools.Test.Utilities; using Microsoft.DotNet.Cli; -using Microsoft.DotNet.Tools.Tool.Install; +using Microsoft.DotNet.Cli.ToolPackage; +using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Tools.Tests.ComponentMocks; using Microsoft.Extensions.DependencyModel.Tests; using Microsoft.Extensions.EnvironmentAbstractions; -using Xunit; -using NuGet.Versioning; -using Microsoft.NET.TestFramework.Utilities; using Microsoft.NET.TestFramework; +using Microsoft.NET.TestFramework.Utilities; +using NuGet.Versioning; +using Xunit; using Xunit.Abstractions; -using System.Linq; -using System.Runtime.CompilerServices; -using Microsoft.DotNet.ToolPackage; namespace Microsoft.DotNet.PackageInstall.Tests { @@ -43,12 +40,11 @@ public void GivenNugetConfigInstallSucceeds(bool testMockBehaviorIsInSync) feeds: GetMockFeedsForConfigFile(nugetConfigPath)); try - { var nugetCacheLocation = new DirectoryPath(testDirectory).WithSubDirectories(Path.GetRandomFileName()); - IToolPackage toolPackage = installer.InstallPackageToExternalManagedLocation( + IToolPackage toolPackage = installer.InstallPackage( packageId: TestPackageId, versionRange: VersionRange.Parse(TestPackageVersion), packageLocation: new PackageLocation(nugetConfig: nugetConfigPath), @@ -87,10 +83,7 @@ public void GivenNugetConfigVersionRangeInstallSucceeds(bool testMockBehaviorIsI testDirectory: testDirectory, feeds: GetMockFeedsForConfigFile(nugetConfigPath)); - var nugetCacheLocation = - new DirectoryPath(testDirectory).WithSubDirectories(Path.GetRandomFileName()); - - IToolPackage toolPackage = installer.InstallPackageToExternalManagedLocation( + IToolPackage toolPackage = installer.InstallPackage( packageId: TestPackageId, versionRange: VersionRange.Parse("1.0.0-*"), packageLocation: new PackageLocation(nugetConfig: nugetConfigPath), @@ -105,15 +98,6 @@ public void GivenNugetConfigVersionRangeInstallSucceeds(bool testMockBehaviorIsI toolPackage.Version.Should().Be(NuGetVersion.Parse(TestPackageVersion)); } - private static FilePath GetUniqueTempProjectPathEachTest(string testDirectory) - { - var tempProjectDirectory = - new DirectoryPath(testDirectory).WithSubDirectories(Path.GetRandomFileName()); - var tempProjectPath = - tempProjectDirectory.WithFile(Path.GetRandomFileName() + ".csproj"); - return tempProjectPath; - } - private static List GetMockFeedsForConfigFile(FilePath nugetConfig) { return new List @@ -135,43 +119,37 @@ private static List GetMockFeedsForConfigFile(FilePath nugetConfig) }; } - private (IToolPackageStore, IToolPackageInstaller, BufferedReporter, IFileSystem) Setup( + private (IToolPackageStore, IToolPackageDownloader, BufferedReporter, IFileSystem) Setup( bool useMock, string testDirectory, - List feeds = null, - FilePath? tempProject = null, - DirectoryPath? offlineFeed = null) + List feeds = null) { var root = new DirectoryPath(Path.Combine(Directory.GetCurrentDirectory(), Path.GetRandomFileName())); var reporter = new BufferedReporter(); IFileSystem fileSystem; IToolPackageStore store; - IToolPackageInstaller installer; + IToolPackageDownloader downloader; if (useMock) { fileSystem = new FileSystemMockBuilder().Build(); store = new ToolPackageStoreMock(root, fileSystem); - installer = new ToolPackageInstallerMock( - fileSystem: fileSystem, + downloader = new ToolPackageDownloaderMock( store: store, - projectRestorer: new ProjectRestorerMock( - fileSystem: fileSystem, - reporter: reporter, - feeds: feeds)); + fileSystem: fileSystem, + reporter: reporter, + feeds: feeds); } else { fileSystem = new FileSystemWrapper(); store = new ToolPackageStoreAndQuery(root); - installer = new ToolPackageInstaller( - store: store, - projectRestorer: new Stage2ProjectRestorer(Log, reporter), - tempProject: tempProject ?? GetUniqueTempProjectPathEachTest(testDirectory), - offlineFeed: offlineFeed ?? new DirectoryPath("does not exist")); + var testRuntimeJsonPath = Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, "RuntimeIdentifierGraph.json"); + var localToolPath = Path.Combine(TestContext.GetRepoRoot(), "artifacts", ".nuget", "packages"); + downloader = new ToolPackageDownloader(store, testRuntimeJsonPath, localToolPath); } - return (store, installer, reporter, fileSystem); + return (store, downloader, reporter, fileSystem); } private FilePath WriteNugetConfigFileToPointToTheFeed(string testDirectory) diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs index a9bd0b4a92ae..aca7351ea791 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs @@ -1,30 +1,22 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. -using System; using System.Collections.Generic; using System.IO; -using System.Linq; using System.Reflection; -using System.Transactions; +using System.Runtime.CompilerServices; using FluentAssertions; -using Microsoft.DotNet.Tools.Test.Utilities; using Microsoft.DotNet.Cli; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.Tools; -using Microsoft.DotNet.Tools.Tool.Install; using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Tools.Tests.ComponentMocks; using Microsoft.Extensions.DependencyModel.Tests; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.TestFramework; +using Microsoft.NET.TestFramework.Utilities; using NuGet.Versioning; using Xunit; -using Microsoft.NET.TestFramework.Utilities; -using Microsoft.NET.TestFramework; using Xunit.Abstractions; -using System.Runtime.CompilerServices; -using Microsoft.DotNet.ToolPackage; namespace Microsoft.DotNet.PackageInstall.Tests { diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index c32927c191b1..ca2340fa6f71 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -5,14 +5,13 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Reflection; -using System.Runtime.InteropServices; using System.Text.Json; using Microsoft.DotNet.Cli; using Microsoft.DotNet.Cli.ToolPackage; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; using Microsoft.Extensions.EnvironmentAbstractions; +using Microsoft.NET.TestFramework.Utilities; using NuGet.Frameworks; using NuGet.Versioning; using LocalizableStrings = Microsoft.DotNet.Tools.Tool.Install.LocalizableStrings; diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageInstallerMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageInstallerMock.cs deleted file mode 100644 index d35666e27737..000000000000 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageInstallerMock.cs +++ /dev/null @@ -1,170 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. - -using System; -using System.Collections.Generic; -using System.IO; -using System.Linq; -using System.Transactions; -using Microsoft.DotNet.Cli; -using Microsoft.DotNet.Cli.Utils; -using Microsoft.DotNet.ToolPackage; -using Microsoft.Extensions.EnvironmentAbstractions; -using Microsoft.NET.TestFramework.Utilities; -using NuGet.Frameworks; -using NuGet.Versioning; - -namespace Microsoft.DotNet.Tools.Tests.ComponentMocks -{ - internal class ToolPackageInstallerMock : IToolPackageInstaller - { - private const string ProjectFileName = "TempProject.csproj"; - - private readonly IToolPackageStore _store; - private readonly ProjectRestorerMock _projectRestorer; - private readonly IFileSystem _fileSystem; - private readonly Action _installCallback; - private readonly Dictionary> _warningsMap; - private readonly Dictionary> _packagedShimsMap; - private readonly Dictionary> _frameworksMap; - - public ToolPackageInstallerMock( - IFileSystem fileSystem, - IToolPackageStore store, - ProjectRestorerMock projectRestorer, - Action installCallback = null, - Dictionary> warningsMap = null, - Dictionary> packagedShimsMap = null, - Dictionary> frameworksMap = null) - { - _fileSystem = fileSystem ?? throw new ArgumentNullException(nameof(fileSystem)); - _store = store ?? throw new ArgumentNullException(nameof(store)); - _projectRestorer = projectRestorer ?? throw new ArgumentNullException(nameof(projectRestorer)); - _installCallback = installCallback; - _warningsMap = warningsMap ?? new Dictionary>(); - _packagedShimsMap = packagedShimsMap ?? new Dictionary>(); - _frameworksMap = frameworksMap ?? new Dictionary>(); - } - - public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, - VersionRange versionRange = null, - string targetFramework = null, - string verbosity = null) - { - var packageRootDirectory = _store.GetRootPackageDirectory(packageId); - string rollbackDirectory = null; - - return TransactionalAction.Run( - action: () => - { - var stageDirectory = _store.GetRandomStagingDirectory(); - _fileSystem.Directory.CreateDirectory(stageDirectory.Value); - rollbackDirectory = stageDirectory.Value; - - var tempProject = new FilePath(Path.Combine(stageDirectory.Value, ProjectFileName)); - - // Write a fake project with the requested package id, version, and framework - _fileSystem.File.WriteAllText( - tempProject.Value, - $"{packageId};{versionRange?.OriginalString ?? "*"};{targetFramework};{stageDirectory.Value}"); - - // Perform a restore on the fake project - _projectRestorer.Restore( - tempProject, - packageLocation, - verbosity); - - if (_installCallback != null) - { - _installCallback(); - } - - var version = _store.GetStagedPackageVersion(stageDirectory, packageId); - var packageDirectory = _store.GetPackageDirectory(packageId, version); - if (_fileSystem.Directory.Exists(packageDirectory.Value)) - { - throw new ToolPackageException( - string.Format( - CommonLocalizableStrings.ToolPackageConflictPackageId, - packageId, - version.ToNormalizedString())); - } - - _fileSystem.Directory.CreateDirectory(packageRootDirectory.Value); - _fileSystem.Directory.Move(stageDirectory.Value, packageDirectory.Value); - rollbackDirectory = packageDirectory.Value; - - IEnumerable warnings = null; - _warningsMap.TryGetValue(packageId, out warnings); - - IReadOnlyList packedShims = null; - _packagedShimsMap.TryGetValue(packageId, out packedShims); - - IEnumerable frameworks = null; - _frameworksMap.TryGetValue(packageId, out frameworks); - - return new ToolPackageMock(_fileSystem, packageId, version, - packageDirectory, warnings: warnings, packagedShims: packedShims, frameworks: frameworks); - }, - rollback: () => - { - if (rollbackDirectory != null && _fileSystem.Directory.Exists(rollbackDirectory)) - { - _fileSystem.Directory.Delete(rollbackDirectory, true); - } - if (_fileSystem.Directory.Exists(packageRootDirectory.Value) && - !_fileSystem.Directory.EnumerateFileSystemEntries(packageRootDirectory.Value).Any()) - { - _fileSystem.Directory.Delete(packageRootDirectory.Value, false); - } - }); - } - - public IToolPackage InstallPackageToExternalManagedLocation( - PackageLocation packageLocation, - PackageId packageId, - VersionRange versionRange = null, - string targetFramework = null, - string verbosity = null) - { - _installCallback?.Invoke(); - - var packageDirectory = new DirectoryPath(NuGetGlobalPackagesFolder.GetLocation()).WithSubDirectories(packageId.ToString()); - _fileSystem.Directory.CreateDirectory(packageDirectory.Value); - var executable = packageDirectory.WithFile("exe"); - _fileSystem.File.CreateEmptyFile(executable.Value); - - MockFeedPackage package = _projectRestorer.GetPackage( - packageId.ToString(), - versionRange ?? VersionRange.Parse("*"), - packageLocation.NugetConfig, - packageLocation.RootConfigDirectory); - - return new TestToolPackage - { - Id = packageId, - Version = NuGetVersion.Parse(package.Version), - Commands = new List { - new RestoredCommand(new ToolCommandName(package.ToolCommandName), "runner", executable) }, - Warnings = Array.Empty(), - PackagedShims = Array.Empty() - }; - } - - private class TestToolPackage : IToolPackage - { - public PackageId Id { get; set; } - - public NuGetVersion Version { get; set; } - public DirectoryPath PackageDirectory { get; set; } - - public IReadOnlyList Commands { get; set; } - - public IEnumerable Warnings { get; set; } - - public IReadOnlyList PackagedShims { get; set; } - - public IEnumerable Frameworks => throw new NotImplementedException(); - } - } -} From c7fe38005f19a050e3f485a9103221de38a57fdb Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Fri, 25 Aug 2023 23:58:46 -0700 Subject: [PATCH 25/47] Updated local tool path --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 0201812a13bf..a3105efbbf8b 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -67,11 +67,11 @@ public ToolPackageDownloader( { _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); ; _globalToolStageDir = _toolPackageStore.GetRandomStagingDirectory(); - _localToolDownloadDir = new DirectoryPath((localToolPath) ?? ((Environment.GetEnvironmentVariable("NUGET_PACKAGES")))); - if(String.IsNullOrEmpty(_localToolDownloadDir.ToString())) - { - _localToolDownloadDir = new DirectoryPath((Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package"))); - } + string localToolDownloadDir = localToolPath + ?? (Environment.GetEnvironmentVariable("NUGET_PACKAGES")) + ?? (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package")); + _localToolDownloadDir = new DirectoryPath(localToolDownloadDir); + _localToolAssetDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); _runtimeJsonPath = runtimeJsonPathTest ?? Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "RuntimeIdentifierGraph.json"); } From 50dcfd58d241b1b471b20659ff633ea1f61fab37 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 27 Aug 2023 18:06:59 -0700 Subject: [PATCH 26/47] Updated local tool path to use NUGET_PACKAGES env_var --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 10 ++++++---- .../ToolPackageInstallerNugetCacheTests.cs | 4 ++-- 2 files changed, 8 insertions(+), 6 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index a3105efbbf8b..7df4093364cd 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -61,15 +61,17 @@ internal class ToolPackageDownloader : IToolPackageDownloader public ToolPackageDownloader( IToolPackageStore store, - string runtimeJsonPathTest = null, - string localToolPath = null + string runtimeJsonPathTest = null + // string localToolPath = null ) { _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); ; _globalToolStageDir = _toolPackageStore.GetRandomStagingDirectory(); - string localToolDownloadDir = localToolPath + /*string localToolDownloadDir = localToolPath ?? (Environment.GetEnvironmentVariable("NUGET_PACKAGES")) - ?? (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package")); + ?? (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package"));*/ + string localToolDownloadDir = (Environment.GetEnvironmentVariable("NUGET_PACKAGES")) + ?? (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package")); _localToolDownloadDir = new DirectoryPath(localToolDownloadDir); _localToolAssetDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs index 691eb4a04dd3..2d79cda155ee 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs @@ -145,8 +145,8 @@ private static List GetMockFeedsForConfigFile(FilePath nugetConfig) fileSystem = new FileSystemWrapper(); store = new ToolPackageStoreAndQuery(root); var testRuntimeJsonPath = Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, "RuntimeIdentifierGraph.json"); - var localToolPath = Path.Combine(TestContext.GetRepoRoot(), "artifacts", ".nuget", "packages"); - downloader = new ToolPackageDownloader(store, testRuntimeJsonPath, localToolPath); + // var localToolPath = Path.Combine(TestContext.GetRepoRoot(), "artifacts", ".nuget", "packages"); + downloader = new ToolPackageDownloader(store, testRuntimeJsonPath); } return (store, downloader, reporter, fileSystem); From d3493e82dda7e30fe56511a26230f8093fc45a63 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 28 Aug 2023 17:28:46 -0700 Subject: [PATCH 27/47] Update the ToolPackageInstallerNugetCacheTests to expect user nuget folder --- .../dotnet/ToolPackage/ToolPackageDownloader.cs | 15 +++++---------- .../ToolPackageInstallerNugetCacheTests.cs | 13 ++++--------- 2 files changed, 9 insertions(+), 19 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 7df4093364cd..42f3dea8cf41 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -25,7 +25,7 @@ using NuGet.Repositories; using NuGet.RuntimeModel; using NuGet.Versioning; - +using NuGet.Configuration; namespace Microsoft.DotNet.Cli.ToolPackage { @@ -61,21 +61,16 @@ internal class ToolPackageDownloader : IToolPackageDownloader public ToolPackageDownloader( IToolPackageStore store, - string runtimeJsonPathTest = null - // string localToolPath = null + string runtimeJsonPathForTests = null ) { _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); ; _globalToolStageDir = _toolPackageStore.GetRandomStagingDirectory(); - /*string localToolDownloadDir = localToolPath - ?? (Environment.GetEnvironmentVariable("NUGET_PACKAGES")) - ?? (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package"));*/ - string localToolDownloadDir = (Environment.GetEnvironmentVariable("NUGET_PACKAGES")) - ?? (Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), "nuget", "package")); - _localToolDownloadDir = new DirectoryPath(localToolDownloadDir); + ISettings settings = Settings.LoadDefaultSettings(Directory.GetCurrentDirectory()); + _localToolDownloadDir = new DirectoryPath(SettingsUtility.GetGlobalPackagesFolder(settings)); _localToolAssetDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory()); - _runtimeJsonPath = runtimeJsonPathTest ?? Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "RuntimeIdentifierGraph.json"); + _runtimeJsonPath = runtimeJsonPathForTests ?? Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "RuntimeIdentifierGraph.json"); } public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs index 2d79cda155ee..c936d554b447 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs @@ -51,9 +51,7 @@ public void GivenNugetConfigInstallSucceeds(bool testMockBehaviorIsInSync) targetFramework: _testTargetframework); var commands = toolPackage.Commands; - var expectedPackagesFolder = testMockBehaviorIsInSync ? - NuGetGlobalPackagesFolder.GetLocation() : - TestContext.Current.NuGetCachePath; + var expectedPackagesFolder = NuGetGlobalPackagesFolder.GetLocation(); commands[0].Executable.Value.Should().StartWith(expectedPackagesFolder); fileSystem.File @@ -89,9 +87,7 @@ public void GivenNugetConfigVersionRangeInstallSucceeds(bool testMockBehaviorIsI packageLocation: new PackageLocation(nugetConfig: nugetConfigPath), targetFramework: _testTargetframework); - var expectedPackagesFolder = testMockBehaviorIsInSync ? - NuGetGlobalPackagesFolder.GetLocation() : - TestContext.Current.NuGetCachePath; + var expectedPackagesFolder = NuGetGlobalPackagesFolder.GetLocation(); var commands = toolPackage.Commands; commands[0].Executable.Value.Should().StartWith(expectedPackagesFolder); @@ -144,9 +140,8 @@ private static List GetMockFeedsForConfigFile(FilePath nugetConfig) { fileSystem = new FileSystemWrapper(); store = new ToolPackageStoreAndQuery(root); - var testRuntimeJsonPath = Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, "RuntimeIdentifierGraph.json"); - // var localToolPath = Path.Combine(TestContext.GetRepoRoot(), "artifacts", ".nuget", "packages"); - downloader = new ToolPackageDownloader(store, testRuntimeJsonPath); + var runtimeJsonPathForTests = Path.Combine(TestContext.Current.ToolsetUnderTest.SdkFolderUnderTest, "RuntimeIdentifierGraph.json"); + downloader = new ToolPackageDownloader(store, runtimeJsonPathForTests); } return (store, downloader, reporter, fileSystem); From 5cc6d7ff0868467497b43e004fc131db2730653d Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Tue, 29 Aug 2023 17:36:28 -0700 Subject: [PATCH 28/47] Updated PSM only applys to downloading NuGet tools; Updated PSM's error message --- .../NugetPackageDownloader/LocalizableStrings.resx | 5 ++++- .../NugetPackageDownloader/NuGetPackageDownloader.cs | 9 ++++++--- .../NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf | 5 +++++ .../NugetPackageDownloader/xlf/LocalizableStrings.de.xlf | 5 +++++ .../NugetPackageDownloader/xlf/LocalizableStrings.es.xlf | 5 +++++ .../NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf | 5 +++++ .../NugetPackageDownloader/xlf/LocalizableStrings.it.xlf | 5 +++++ .../NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf | 5 +++++ .../NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf | 5 +++++ .../NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf | 5 +++++ .../xlf/LocalizableStrings.pt-BR.xlf | 5 +++++ .../NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf | 5 +++++ .../NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf | 5 +++++ .../xlf/LocalizableStrings.zh-Hans.xlf | 5 +++++ .../xlf/LocalizableStrings.zh-Hant.xlf | 5 +++++ src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 2 +- 16 files changed, 76 insertions(+), 5 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx b/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx index 9d39bb327604..867e50a7294c 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx +++ b/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx @@ -138,4 +138,7 @@ Failed to validate package signing. - + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + \ No newline at end of file diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index 9d0aa37e0342..3e5270844d6f 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -44,6 +44,7 @@ internal class NuGetPackageDownloader : INuGetPackageDownloader private readonly IFirstPartyNuGetPackageSigningVerifier _firstPartyNuGetPackageSigningVerifier; private bool _validationMessagesDisplayed = false; private IDictionary _sourceRepositories; + private readonly bool _isNuGetTool; private bool _verifySignatures; @@ -55,7 +56,8 @@ public NuGetPackageDownloader( IReporter reporter = null, RestoreActionConfig restoreActionConfig = null, Func> timer = null, - bool verifySignatures = false) + bool verifySignatures = false, + bool isNuGetTool = false) { _packageInstallDir = packageInstallDir; _reporter = reporter ?? Reporter.Output; @@ -77,6 +79,7 @@ public NuGetPackageDownloader( DefaultCredentialServiceUtility.SetupDefaultCredentialService(new NuGetConsoleLogger(), !_restoreActionConfig.Interactive); + _isNuGetTool = isNuGetTool; } public async Task DownloadPackageAsync(PackageId packageId, @@ -317,13 +320,13 @@ private IEnumerable LoadNuGetSources(PackageId packageId, Package PackageSourceMapping packageSourceMapping = PackageSourceMapping.GetPackageSourceMapping(settings); // filter package patterns if enabled - if (packageSourceMapping?.IsEnabled == true) + if (_isNuGetTool && packageSourceMapping?.IsEnabled == true) { IReadOnlyList sources = packageSourceMapping.GetConfiguredPackageSources(packageId.ToString()); if (sources.Count == 0) { - throw new NuGetPackageInstallerException("No NuGet sources are defined or enabled"); + throw new NuGetPackageInstallerException(string.Format(LocalizableStrings.FailedToGetPackageUnderPackageSourceMapping, packageId)); } } diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf index 760b8f9c0208..9e4faf2c40d7 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf @@ -7,6 +7,11 @@ Stahování {0} verze {1} selhalo. + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} Nepovedlo se načíst zdroj NuGet {0}. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf index 83c6ce3c730b..6ce38a3100ef 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf @@ -7,6 +7,11 @@ Fehler beim Herunterladen der {0} Version {1}. + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} Fehler beim Laden der NuGet-Quelle {0} diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf index 4462767a2652..79d08d78f1c9 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf @@ -7,6 +7,11 @@ Error al descargar {0} versión {1}. + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} No se pudo cargar el origen de NuGet {0} diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf index da6c54e176df..3d36e16b07a8 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf @@ -7,6 +7,11 @@ Échec du téléchargement de {0}, version {1} . + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} Échec du chargement de la source DeNget {0} diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf index 5cc8dd6e64d1..b7992e1c6e97 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf @@ -7,6 +7,11 @@ Download {0} versione {1} non riuscito. + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} Non è stato possibile caricare l'origine NuGet {0} diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf index 31b0c8d0f38a..812d31420fe4 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf @@ -7,6 +7,11 @@ {0} バージョン {1} のダウンロードに失敗しました。 + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} NuGet ソース {0} の読み込みに失敗しました diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf index dfd1652be929..947b647c8c0c 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf @@ -7,6 +7,11 @@ {0} 버전 {1} 다운로드에 실패했습니다. + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} NuGet 원본 {0}을(를) 로드하지 못했습니다. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf index 11cc9088c02f..782d306b755e 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf @@ -7,6 +7,11 @@ Pobieranie {0} w wersji {1} nie powiodło się. + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} Nie można załadować źródła pakietu NuGet {0} diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf index cd6b41a1d698..af2830f8bfdd 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf @@ -7,6 +7,11 @@ Falhou ao baixar {0} versão {1}. + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} Falha no carregamento da fonte NuGet {0} diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf index 48e3edcead33..46d4530a9886 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf @@ -7,6 +7,11 @@ Не удалось скачать версию {0} {1}. + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} Не удалось загрузить источник NuGet {0} diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf index 7978957cf585..e718a7c6b05c 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf @@ -7,6 +7,11 @@ {0} sürüm {1} indirilemedi. + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} {0} NuGet kaynağı yüklemesi yüklenemedi diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf index 7c2878b9614c..ebe3ed6414bd 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf @@ -7,6 +7,11 @@ 下载 {0} 版本 {1} 失败。 + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} 无法加载 NuGet 源 {0} diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf index e9c0b948dd8c..b075e694b05b 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf @@ -7,6 +7,11 @@ 下載 {0} 版本 {1} 失敗。 + + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + + Failed to load NuGet source {0} 無法載入 NuGet 來源{0} diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 42f3dea8cf41..2abae99da535 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -96,7 +96,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa } _toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; - _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir, verboseLogger: nugetLogger); + _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true); rollbackDirectory = _toolDownloadDir.Value; NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, _toolDownloadDir.Value, _toolPackageStore).GetAwaiter().GetResult(); From 83eb50126e10a6775ded923d0b656a1d746bf6ab Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 30 Aug 2023 15:11:20 -0700 Subject: [PATCH 29/47] Resolve double ; in ToolPackageDownloader and PSM link --- src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.de.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.es.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.it.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf | 4 ++-- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 2 +- 15 files changed, 29 insertions(+), 29 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx b/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx index 867e50a7294c..435754d30861 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx +++ b/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx @@ -139,6 +139,6 @@ Failed to validate package signing. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - \ No newline at end of file + diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf index 9e4faf2c40d7..c840d94cd7de 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf index 6ce38a3100ef..dac2936391de 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf index 79d08d78f1c9..864e56135ffd 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf index 3d36e16b07a8..fcd6c7b97b4f 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf index b7992e1c6e97..5113218a9555 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf index 812d31420fe4..5d22baa1cbb8 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf index 947b647c8c0c..64ff3931f47a 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf index 782d306b755e..8241e95ef244 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf index af2830f8bfdd..8b360eab0d47 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf index 46d4530a9886..51526d2596ca 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf index e718a7c6b05c..73a5c0abb7a6 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf index ebe3ed6414bd..e9008e751405 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf index b075e694b05b..5ea3ad82fd81 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at https://learn.microsoft.com/nuget/consume-packages/package-source-mapping#enable-by-manually-editing-nugetconfig for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 2abae99da535..1c2aa6f5c883 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -64,7 +64,7 @@ public ToolPackageDownloader( string runtimeJsonPathForTests = null ) { - _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); ; + _toolPackageStore = store ?? throw new ArgumentNullException(nameof(store)); _globalToolStageDir = _toolPackageStore.GetRandomStagingDirectory(); ISettings settings = Settings.LoadDefaultSettings(Directory.GetCurrentDirectory()); _localToolDownloadDir = new DirectoryPath(SettingsUtility.GetGlobalPackagesFolder(settings)); From 0bcd7be62e4cf5276eae3188fdb48ec226d73601 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 31 Aug 2023 19:16:59 -0700 Subject: [PATCH 30/47] Update LocalizableStrings on PSM for spelling error, links, and comma --- src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.de.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.es.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.it.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf | 4 ++-- .../NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf | 4 ++-- 14 files changed, 28 insertions(+), 28 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx b/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx index 435754d30861..71abd1fd7476 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx +++ b/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx @@ -139,6 +139,6 @@ Failed to validate package signing. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - + \ No newline at end of file diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf index c840d94cd7de..f8ee5e6d8800 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf index dac2936391de..3d6b172342a6 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf index 864e56135ffd..68d3fbe21dda 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf index fcd6c7b97b4f..5290c71793f2 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf index 5113218a9555..8ce5b6c8b2fa 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf index 5d22baa1cbb8..6c796e8cc676 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf index 64ff3931f47a..bf3fa73cb257 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf index 8241e95ef244..0f464cd6abcf 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf index 8b360eab0d47..36a235e1c098 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf index 51526d2596ca..fd2d39c2026e 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf index 73a5c0abb7a6..4fecd44cb180 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf index e9008e751405..5235fe508408 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf index 5ea3ad82fd81..2f530ef5baf6 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf @@ -8,8 +8,8 @@ - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled but no feeds matched the specified packed ID: {0}. See the documentation for Package Source Mapping at aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. From 4d15bc444281ef607ff95bb58128ef457dc608c8 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 7 Sep 2023 13:04:59 -0700 Subject: [PATCH 31/47] Add PSM tests --- .../INuGetPackageDownloader.cs | 4 +- .../NuGetPackageDownloader.cs | 16 ++--- .../NuGetPackageInstallerTests.cs | 58 +++++++++++++++++-- .../FailingNuGetPackageInstaller.cs | 4 +- .../MockNuGetPackageInstaller.cs | 4 +- 5 files changed, 70 insertions(+), 16 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs index bfcf98ad3d84..700ac86ae13a 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs @@ -3,6 +3,7 @@ using Microsoft.DotNet.ToolPackage; using Microsoft.Extensions.EnvironmentAbstractions; +using NuGet.Configuration; using NuGet.Versioning; namespace Microsoft.DotNet.Cli.NuGetPackageDownloader @@ -13,7 +14,8 @@ Task DownloadPackageAsync(PackageId packageId, NuGetVersion packageVersion = null, PackageSourceLocation packageSourceLocation = null, bool includePreview = false, - DirectoryPath? downloadFolder = null); + DirectoryPath? downloadFolder = null, + PackageSourceMapping packageSourceMapping = null); Task GetPackageUrl(PackageId packageId, NuGetVersion packageVersion = null, diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index 4903eae7accd..2391ea07ceaa 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -8,8 +8,6 @@ using NuGet.Common; using NuGet.Configuration; using NuGet.Credentials; -using NuGet.DependencyResolver; -using NuGet.LibraryModel; using NuGet.Packaging; using NuGet.Protocol; using NuGet.Protocol.Core.Types; @@ -80,12 +78,13 @@ public async Task DownloadPackageAsync(PackageId packageId, NuGetVersion packageVersion = null, PackageSourceLocation packageSourceLocation = null, bool includePreview = false, - DirectoryPath? downloadFolder = null) + DirectoryPath? downloadFolder = null, + PackageSourceMapping packageSourceMapping = null) { CancellationToken cancellationToken = CancellationToken.None; (var source, var resolvedPackageVersion) = await GetPackageSourceAndVersion(packageId, packageVersion, - packageSourceLocation, includePreview); + packageSourceLocation, includePreview, packageSourceMapping); FindPackageByIdResource resource = null; SourceRepository repository = GetSourceRepository(source); @@ -219,13 +218,14 @@ public async Task> ExtractPackageAsync(string packagePath, D private async Task<(PackageSource, NuGetVersion)> GetPackageSourceAndVersion(PackageId packageId, NuGetVersion packageVersion = null, PackageSourceLocation packageSourceLocation = null, - bool includePreview = false) + bool includePreview = false, + PackageSourceMapping packageSourceMapping = null) { CancellationToken cancellationToken = CancellationToken.None; IPackageSearchMetadata packageMetadata; - IEnumerable packagesSources = LoadNuGetSources(packageId, packageSourceLocation); + IEnumerable packagesSources = LoadNuGetSources(packageId, packageSourceLocation, packageSourceMapping); PackageSource source; if (packageVersion is null) @@ -289,7 +289,7 @@ private static bool PackageIsInAllowList(IEnumerable files) return true; } - private IEnumerable LoadNuGetSources(PackageId packageId, PackageSourceLocation packageSourceLocation = null) + private IEnumerable LoadNuGetSources(PackageId packageId, PackageSourceLocation packageSourceLocation = null, PackageSourceMapping packageSourceMapping = null) { IEnumerable defaultSources = new List(); string currentDirectory = Directory.GetCurrentDirectory(); @@ -311,7 +311,7 @@ private IEnumerable LoadNuGetSources(PackageId packageId, Package PackageSourceProvider packageSourceProvider = new PackageSourceProvider(settings); defaultSources = packageSourceProvider.LoadPackageSources().Where(source => source.IsEnabled); - PackageSourceMapping packageSourceMapping = PackageSourceMapping.GetPackageSourceMapping(settings); + packageSourceMapping = packageSourceMapping ?? PackageSourceMapping.GetPackageSourceMapping(settings); // filter package patterns if enabled if (_isNuGetTool && packageSourceMapping?.IsEnabled == true) diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs index 790b337e16e0..e912250ebcfb 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs @@ -1,16 +1,18 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Collections.ObjectModel; using System.Reflection; using System.Security.Cryptography; using Microsoft.DotNet.Cli; -using Microsoft.Extensions.EnvironmentAbstractions; -using NuGet.Versioning; using Microsoft.DotNet.Cli.NuGetPackageDownloader; +using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; +using Microsoft.Extensions.EnvironmentAbstractions; +using NuGet.Configuration; using NuGet.Packaging; using NuGet.Packaging.Signing; -using Microsoft.DotNet.Cli.Utils; +using NuGet.Versioning; namespace Microsoft.DotNet.PackageInstall.Tests { @@ -20,6 +22,7 @@ public class NuGetPackageInstallerTests : SdkTest private const string TestPreviewPackageVersion = "2.0.1-preview1"; private static readonly PackageId TestPackageId = new PackageId("global.tool.console.demo"); private readonly NuGetPackageDownloader _installer; + private readonly NuGetPackageDownloader _toolInstaller; private readonly DirectoryPath _tempDirectory; @@ -33,6 +36,9 @@ public NuGetPackageInstallerTests(ITestOutputHelper log) : base(log) _installer = new NuGetPackageDownloader(_tempDirectory, null, new MockFirstPartyNuGetPackageSigningVerifier(), _logger, restoreActionConfig: new RestoreActionConfig(NoCache: true), timer: () => ExponentialRetry.Timer(ExponentialRetry.TestingIntervals)); + _toolInstaller = + new NuGetPackageDownloader(_tempDirectory, null, new MockFirstPartyNuGetPackageSigningVerifier(), _logger, + restoreActionConfig: new RestoreActionConfig(NoCache: true), timer: () => ExponentialRetry.Timer(ExponentialRetry.TestingIntervals), isNuGetTool: true); } [Fact] @@ -158,6 +164,48 @@ public async Task GivenARelativeSourcePathInstallSucceeds() packagePath.Should().Contain(_tempDirectory.Value, "Package should be downloaded to the input folder"); } + [Fact] + public void GivenNoPackageSourceMappingItShouldError() + { + string getTestLocalFeedPath = GetTestLocalFeedPath(); + string relativePath = Path.GetRelativePath(Environment.CurrentDirectory, getTestLocalFeedPath); + Log.WriteLine(relativePath); + var dictionary = new Dictionary> + { + { "sourceA", new List() { "a" } } + }; + var patterns = new ReadOnlyDictionary>(dictionary); + var mockPackageSourceMapping = new PackageSourceMapping(patterns); + + Action a = () => _toolInstaller.DownloadPackageAsync( + TestPackageId, + new NuGetVersion(TestPackageVersion), + new PackageSourceLocation(sourceFeedOverrides: new[] { relativePath }), + packageSourceMapping: mockPackageSourceMapping).GetAwaiter().GetResult(); + a.Should().Throw().And.Message.Should().Contain(string.Format(Cli.NuGetPackageDownloader.LocalizableStrings.FailedToGetPackageUnderPackageSourceMapping, TestPackageId)); + } + + [Fact] + public void GivenPackageSourceMappingFeedNotFoundItShouldError() + { + string getTestLocalFeedPath = GetTestLocalFeedPath(); + string relativePath = Path.GetRelativePath(Environment.CurrentDirectory, getTestLocalFeedPath); + Log.WriteLine(relativePath); + var dictionary = new Dictionary> + { + { "global.tool.console.demo", new List() { "nonexistentfeed" } } + }; + var patterns = new ReadOnlyDictionary>(dictionary); + var mockPackageSourceMapping = new PackageSourceMapping(patterns); + + Action a = () => _toolInstaller.DownloadPackageAsync( + TestPackageId, + new NuGetVersion(TestPackageVersion), + new PackageSourceLocation(sourceFeedOverrides: new[] { relativePath }), + packageSourceMapping: mockPackageSourceMapping).GetAwaiter().GetResult(); + a.Should().Throw().And.Message.Should().Contain(string.Format(Cli.NuGetPackageDownloader.LocalizableStrings.FailedToGetPackageUnderPackageSourceMapping, TestPackageId)); + } + [Fact] public async Task WhenPassedIncludePreviewItInstallSucceeds() { @@ -193,7 +241,7 @@ await nuGetPackageDownloader.DownloadPackageAsync( bufferedReporter.Lines.Should() .ContainSingle( - LocalizableStrings.NuGetPackageSignatureVerificationSkipped); + Cli.NuGetPackageDownloader.LocalizableStrings.NuGetPackageSignatureVerificationSkipped); File.Exists(packagePath).Should().BeTrue(); } @@ -234,7 +282,7 @@ await nuGetPackageDownloader.DownloadPackageAsync( bufferedReporter.Lines.Should() .ContainSingle( - LocalizableStrings.SkipNuGetpackageSigningValidationmacOSLinux); + Cli.NuGetPackageDownloader.LocalizableStrings.SkipNuGetpackageSigningValidationmacOSLinux); File.Exists(packagePath).Should().BeTrue(); } diff --git a/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs b/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs index a451efbed6c6..0871f30e21d4 100644 --- a/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs +++ b/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs @@ -3,6 +3,7 @@ using Microsoft.DotNet.ToolPackage; using Microsoft.Extensions.EnvironmentAbstractions; +using NuGet.Configuration; using NuGet.Versioning; namespace Microsoft.DotNet.Cli.NuGetPackageDownloader @@ -20,7 +21,8 @@ public FailingNuGetPackageDownloader(string testDir) public Task DownloadPackageAsync(PackageId packageId, NuGetVersion packageVersion, PackageSourceLocation packageSourceLocation = null, bool includePreview = false, - DirectoryPath? downloadFolder = null) + DirectoryPath? downloadFolder = null, + PackageSourceMapping packageSourceMapping = null) { var mockPackagePath = Path.Combine(MockPackageDir, $"{packageId}.{packageVersion}.nupkg"); File.WriteAllText(mockPackagePath, string.Empty); diff --git a/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs b/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs index c52e2f23e4f1..a4a496416229 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs @@ -3,6 +3,7 @@ using Microsoft.DotNet.ToolPackage; using Microsoft.Extensions.EnvironmentAbstractions; +using NuGet.Configuration; using NuGet.Versioning; namespace Microsoft.DotNet.Cli.NuGetPackageDownloader @@ -35,7 +36,8 @@ public Task DownloadPackageAsync(PackageId packageId, NuGetVersion packageVersion = null, PackageSourceLocation packageSourceLocation = null, bool includePreview = false, - DirectoryPath? downloadFolder = null) + DirectoryPath? downloadFolder = null, + PackageSourceMapping packageSourceMapping = null) { DownloadCallParams.Add((packageId, packageVersion, downloadFolder, packageSourceLocation)); From 729b4bc492eb599d9543c529420d7d76911962ea Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 7 Sep 2023 15:48:02 -0700 Subject: [PATCH 32/47] Commenting out ItRunsWithTheSpecificVerbosity --- src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs b/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs index 5b968bc06f64..af02c3c88a97 100644 --- a/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs +++ b/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs @@ -22,7 +22,7 @@ public void ItRunsWithQuietVerbosityByDefault() .NotHaveStdOutContaining("Restoring"); } - [Fact] + /*[Fact] public void ItRunsWithTheSpecifiedVerbosity() { var result = new DotnetToolCommand(Log) @@ -36,6 +36,6 @@ public void ItRunsWithTheSpecifiedVerbosity() .StdOut .Should() .BeEmpty(); - } + }*/ } } From e9542bfe54582c49e365d56cb12b243a8119c1f8 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Fri, 8 Sep 2023 15:47:46 -0700 Subject: [PATCH 33/47] Add configureAwait() for async tool method --- .../dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs | 2 +- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 2 +- src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index 2391ea07ceaa..24d033f90c09 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -84,7 +84,7 @@ public async Task DownloadPackageAsync(PackageId packageId, CancellationToken cancellationToken = CancellationToken.None; (var source, var resolvedPackageVersion) = await GetPackageSourceAndVersion(packageId, packageVersion, - packageSourceLocation, includePreview, packageSourceMapping); + packageSourceLocation, includePreview, packageSourceMapping).ConfigureAwait(false); FindPackageByIdResource resource = null; SourceRepository repository = GetSourceRepository(source); diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 74122413c5f7..0bd9d8986631 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -208,7 +208,7 @@ IToolPackageStore toolPackageStore ) { var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); - var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId, null, packageSourceLocation); + var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId, null, packageSourceLocation).ConfigureAwait(false); // look for package on disk and read the version NuGetVersion version; diff --git a/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs b/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs index af02c3c88a97..5b968bc06f64 100644 --- a/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs +++ b/src/Tests/dotnet-install-tool.Tests/GivenDotnetInstallTool.cs @@ -22,7 +22,7 @@ public void ItRunsWithQuietVerbosityByDefault() .NotHaveStdOutContaining("Restoring"); } - /*[Fact] + [Fact] public void ItRunsWithTheSpecifiedVerbosity() { var result = new DotnetToolCommand(Log) @@ -36,6 +36,6 @@ public void ItRunsWithTheSpecifiedVerbosity() .StdOut .Should() .BeEmpty(); - }*/ + } } } From 4dcc5aa15fed097692af9a184a24a1227363106e Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 13 Sep 2023 14:38:04 -0700 Subject: [PATCH 34/47] Resolve naming conventions, variable scopes, class range --- .../NuGetPackageDownloader.cs | 1 + .../ToolPackage/ToolPackageDownloader.cs | 39 ++++++++++--------- .../install/ToolInstallLocalInstaller.cs | 4 +- 3 files changed, 24 insertions(+), 20 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index 24d033f90c09..1285ea0cf732 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -322,6 +322,7 @@ private IEnumerable LoadNuGetSources(PackageId packageId, Package { throw new NuGetPackageInstallerException(string.Format(LocalizableStrings.FailedToGetPackageUnderPackageSourceMapping, packageId)); } + defaultSources = defaultSources.Where(source => sources.Contains(source.Name)); } if (packageSourceLocation?.AdditionalSourceFeed?.Any() ?? false) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 0bd9d8986631..a3fee751c505 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -34,9 +34,6 @@ internal class ToolPackageDownloader : IToolPackageDownloader private INuGetPackageDownloader _nugetPackageDownloader; private readonly IToolPackageStore _toolPackageStore; - // The directory that the tool will be downloaded to - protected DirectoryPath _toolDownloadDir; - // The directory that the tool package is returned protected DirectoryPath _toolReturnPackageDirectory; @@ -55,8 +52,6 @@ internal class ToolPackageDownloader : IToolPackageDownloader // example: C:\Users\username\AppData\Local\Temp\tempFolder protected readonly DirectoryPath _localToolAssetDir; - public static readonly CliOption VerbosityOption = CommonOptions.VerbosityOption; - protected readonly string _runtimeJsonPath; public ToolPackageDownloader( @@ -87,6 +82,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa action: () => { ILogger nugetLogger = new NullLogger(); + if (verbosity != null && (verbosity == VerbosityOptions.d.ToString() || verbosity == VerbosityOptions.detailed.ToString() || verbosity == VerbosityOptions.diag.ToString() || @@ -94,33 +90,40 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa { nugetLogger = new NuGetConsoleLogger(); } - _toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; + + var versionString = versionRange?.OriginalString ?? "*"; + versionRange = VersionRange.Parse(versionString); + + var toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; - _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(_toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true); - rollbackDirectory = _toolDownloadDir.Value; + _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true); + rollbackDirectory = toolDownloadDir.Value; + + NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, toolDownloadDir.Value, _toolPackageStore).GetAwaiter().GetResult(); + CreateAssetFile(packageId, version, toolDownloadDir, assetFileDirectory, _runtimeJsonPath); - NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, _toolDownloadDir.Value, _toolPackageStore).GetAwaiter().GetResult(); - CreateAssetFiles(packageId, version, _toolDownloadDir, assetFileDirectory, _runtimeJsonPath); + DirectoryPath toolReturnPackageDirectory; + DirectoryPath toolReturnJsonParentDirectory; if (isGlobalTool) { - _toolReturnPackageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); - _toolReturnJsonParentDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + toolReturnPackageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + toolReturnJsonParentDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); Directory.CreateDirectory(packageRootDirectory.Value); FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, _toolReturnPackageDirectory.Value)); - rollbackDirectory = _toolReturnPackageDirectory.Value; + rollbackDirectory = toolReturnPackageDirectory.Value; } else { - _toolReturnPackageDirectory = _toolDownloadDir; - _toolReturnJsonParentDirectory = _localToolAssetDir; + toolReturnPackageDirectory = toolDownloadDir; + toolReturnJsonParentDirectory = _localToolAssetDir; } return new ToolPackageInstance(id: packageId, version: version, - packageDirectory: _toolReturnPackageDirectory, - assetsJsonParentDirectory: _toolReturnJsonParentDirectory); + packageDirectory: toolReturnPackageDirectory, + assetsJsonParentDirectory: toolReturnJsonParentDirectory); }, rollback: () => { @@ -252,7 +255,7 @@ IToolPackageStore toolPackageStore return version; } - private static void CreateAssetFiles( + private static void CreateAssetFile( PackageId packageId, NuGetVersion version, DirectoryPath nugetLocalRepository, diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs index ef2c0742bee1..000d4f06e415 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs @@ -38,11 +38,11 @@ public ToolInstallLocalInstaller( (IToolPackageStore store, IToolPackageStoreQuery, - IToolPackageDownloader installer) toolPackageStoresAndDownloader + IToolPackageDownloader downloader) toolPackageStoresAndDownloader = ToolPackageFactory.CreateToolPackageStoresAndDownloader( additionalRestoreArguments: parseResult.OptionValuesToBeForwarded(ToolInstallCommandParser.GetCommand())); _toolPackageStore = toolPackageStoresAndDownloader.store; - _toolPackageDownloader = toolPackageDownloader?? toolPackageStoresAndDownloader.installer; + _toolPackageDownloader = toolPackageDownloader?? toolPackageStoresAndDownloader.downloader; TargetFrameworkToInstall = BundledTargetFramework.GetTargetFrameworkMoniker(); From 893d7946ba78a0924e714d42ba30ebe718d05ea6 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 13 Sep 2023 16:47:00 -0700 Subject: [PATCH 35/47] Resolve test failures 1 --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index a3fee751c505..c141b345d950 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -111,7 +111,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa toolReturnJsonParentDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); Directory.CreateDirectory(packageRootDirectory.Value); - FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, _toolReturnPackageDirectory.Value)); + FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, toolReturnPackageDirectory.Value)); rollbackDirectory = toolReturnPackageDirectory.Value; } else From b6a7c2d19bc670a8f5b7738458671047baee1181 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Wed, 13 Sep 2023 22:15:42 -0700 Subject: [PATCH 36/47] Pass in parameters and rename conventions --- .../INuGetPackageDownloader.cs | 6 + .../NuGetPackageDownloader.cs | 143 +++++++++++++++++- .../ShellShim/ShellShimTemplateFinder.cs | 4 +- .../ToolPackage/ToolPackageDownloader.cs | 58 +++---- .../NuGetPackageInstallerTests.cs | 2 + .../FailingNuGetPackageInstaller.cs | 11 ++ .../MockNuGetPackageInstaller.cs | 9 ++ 7 files changed, 204 insertions(+), 29 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs index 700ac86ae13a..df50767f7dac 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs @@ -17,6 +17,12 @@ Task DownloadPackageAsync(PackageId packageId, DirectoryPath? downloadFolder = null, PackageSourceMapping packageSourceMapping = null); + Task DownloadPackageAsync(PackageId packageId, + VersionRange packageVersion = null, + PackageSourceLocation packageSourceLocation = null, + DirectoryPath? downloadFolder = null, + PackageSourceMapping packageSourceMapping = null); + Task GetPackageUrl(PackageId packageId, NuGetVersion packageVersion = null, PackageSourceLocation packageSourceLocation = null, diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index 1285ea0cf732..ab1bfc4b3dd9 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -128,6 +128,59 @@ public async Task DownloadPackageAsync(PackageId packageId, return nupkgPath; } + public async Task DownloadPackageAsync(PackageId packageId, + VersionRange packageVersion = null, + PackageSourceLocation packageSourceLocation = null, + DirectoryPath? downloadFolder = null, + PackageSourceMapping packageSourceMapping = null) + { + CancellationToken cancellationToken = CancellationToken.None; + + (var source, var resolvedPackageVersion) = await GetPackageSourceAndVersion(packageId, packageVersion, + packageSourceLocation, packageSourceMapping).ConfigureAwait(false); + + FindPackageByIdResource resource = null; + SourceRepository repository = GetSourceRepository(source); + + resource = await repository.GetResourceAsync(cancellationToken) + .ConfigureAwait(false); + + if (resource == null) + { + throw new NuGetPackageNotFoundException( + string.Format(LocalizableStrings.IsNotFoundInNuGetFeeds, packageId, source.Source)); + } + + string nupkgPath = downloadFolder == null || !downloadFolder.HasValue + ? Path.Combine(_packageInstallDir.Value, packageId.ToString(), + resolvedPackageVersion.ToNormalizedString(), + $"{packageId}.{resolvedPackageVersion.ToNormalizedString()}.nupkg") + : Path.Combine(downloadFolder.Value.Value, + $"{packageId}.{resolvedPackageVersion.ToNormalizedString()}.nupkg"); + + Directory.CreateDirectory(Path.GetDirectoryName(nupkgPath)); + using FileStream destinationStream = File.Create(nupkgPath); + bool success = await ExponentialRetry.ExecuteWithRetryOnFailure(async () => await resource.CopyNupkgToStreamAsync( + packageId.ToString(), + resolvedPackageVersion, + destinationStream, + _cacheSettings, + _verboseLogger, + cancellationToken)); + destinationStream.Close(); + + if (!success) + { + throw new NuGetPackageInstallerException( + string.Format("Downloading {0} version {1} failed", packageId, + packageVersion.ToNormalizedString())); + } + + VerifySigning(nupkgPath); + + return nupkgPath; + } + private void VerifySigning(string nupkgPath) { if (!_verifySignatures) @@ -246,6 +299,39 @@ await GetPackageMetadataAsync(packageId.ToString(), packageVersion, packagesSour return (source, packageVersion); } + private async Task<(PackageSource, NuGetVersion)> GetPackageSourceAndVersion(PackageId packageId, + VersionRange versionRange = null, + PackageSourceLocation packageSourceLocation = null, + PackageSourceMapping packageSourceMapping = null) + { + CancellationToken cancellationToken = CancellationToken.None; + + IPackageSearchMetadata packageMetadata; + + IEnumerable packagesSources = LoadNuGetSources(packageId, packageSourceLocation, packageSourceMapping); + PackageSource source; + + (source, packageMetadata) = await GetMatchingVersionInternalAsync(packageId.ToString(), packagesSources, + versionRange, cancellationToken).ConfigureAwait(false); + + /*if (packageVersion is null) + { + (source, packageMetadata) = await GetMatchingVersionInternalAsync(packageId.ToString(), packagesSources, + includePreview, cancellationToken).ConfigureAwait(false); + } + else + { + packageVersion = new NuGetVersion(packageVersion); + (source, packageMetadata) = + await GetPackageMetadataAsync(packageId.ToString(), packageVersion, packagesSources, + cancellationToken).ConfigureAwait(false); + }*/ + + NuGetVersion packageVersion = packageMetadata.Identity.Version; + + return (source, packageVersion); + } + private string GetNupkgUrl(string baseUri, PackageId id, NuGetVersion version) => baseUri + id.ToString() + "/" + version.ToNormalizedString() + "/" + id.ToString() + "." + version.ToNormalizedString() + ".nupkg"; @@ -395,7 +481,62 @@ private IEnumerable LoadNuGetSources(PackageId packageId, Package return retrievedSources; } - private async Task<(PackageSource, IPackageSearchMetadata)> GetLatestVersionInternalAsync( + private async Task<(PackageSource, IPackageSearchMetadata)> GetMatchingVersionInternalAsync( + string packageIdentifier, IEnumerable packageSources, VersionRange versionRange, + CancellationToken cancellationToken) + { + if (packageSources == null) + { + throw new ArgumentNullException(nameof(packageSources)); + } + + if (string.IsNullOrWhiteSpace(packageIdentifier)) + { + throw new ArgumentException($"{nameof(packageIdentifier)} cannot be null or empty", + nameof(packageIdentifier)); + } + + (PackageSource source, IEnumerable foundPackages)[] foundPackagesBySource; + + if (_restoreActionConfig.DisableParallel) + { + foundPackagesBySource = packageSources.Select(source => GetPackageMetadataAsync(source, + packageIdentifier, + true, cancellationToken).ConfigureAwait(false).GetAwaiter().GetResult()).ToArray(); + } + else + { + foundPackagesBySource = + await Task.WhenAll( + packageSources.Select(source => GetPackageMetadataAsync(source, packageIdentifier, + true, cancellationToken))) + .ConfigureAwait(false); + } + + IEnumerable<(PackageSource source, IPackageSearchMetadata package)> accumulativeSearchResults = + foundPackagesBySource + .SelectMany(result => result.foundPackages.Select(package => (result.source, package))); + + var availableVersions = await Task.WhenAll(accumulativeSearchResults.Select(async t => (t.source, t.package, versions: await t.package.GetVersionsAsync()))); + var expandedVersions = availableVersions.SelectMany(t => t.versions.Select(versionInfo => (versionInfo.Version, t.source, t.package))); + var bestVersion = versionRange.FindBestMatch(expandedVersions.Select(t => t.Version)); + if (bestVersion != null) + { + var bestExpandedVersion = expandedVersions.First(v => v.Version == bestVersion); + return (bestExpandedVersion.source, bestExpandedVersion.package); + } + else + { + throw new NuGetPackageNotFoundException( + string.Format( + LocalizableStrings.IsNotFoundInNuGetFeeds, + packageIdentifier, + string.Join(", ", packageSources.Select(source => source.Source)))); + } + + } + + private async Task<(PackageSource, IPackageSearchMetadata)> GetLatestVersionInternalAsync( string packageIdentifier, IEnumerable packageSources, bool includePreview, CancellationToken cancellationToken) { diff --git a/src/Cli/dotnet/ShellShim/ShellShimTemplateFinder.cs b/src/Cli/dotnet/ShellShim/ShellShimTemplateFinder.cs index a17000004408..604c681faa0c 100644 --- a/src/Cli/dotnet/ShellShim/ShellShimTemplateFinder.cs +++ b/src/Cli/dotnet/ShellShim/ShellShimTemplateFinder.cs @@ -7,6 +7,7 @@ using Microsoft.DotNet.ToolPackage; using Microsoft.Extensions.EnvironmentAbstractions; using NuGet.Frameworks; +using NuGet.Versioning; using LocalizableStrings = Microsoft.DotNet.Tools.Tool.Install.LocalizableStrings; namespace Microsoft.DotNet.ShellShim @@ -57,7 +58,8 @@ public async Task ResolveAppHostSourceDirectoryAsync(string archOption, } var packageId = new PackageId($"microsoft.netcore.app.host.{rid}"); - var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId, packageSourceLocation: _packageSourceLocation); + NuGetVersion packageVersion = null; + var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId, packageVersion, packageSourceLocation: _packageSourceLocation); var content = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, _tempDir); return Path.Combine(_tempDir.Value, "runtimes", rid, "native"); diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index c141b345d950..58f6bd146a0a 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -31,7 +31,6 @@ namespace Microsoft.DotNet.Cli.ToolPackage { internal class ToolPackageDownloader : IToolPackageDownloader { - private INuGetPackageDownloader _nugetPackageDownloader; private readonly IToolPackageStore _toolPackageStore; // The directory that the tool package is returned @@ -96,11 +95,11 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa var toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; - _nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true); - rollbackDirectory = toolDownloadDir.Value; + var nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true); + rollbackDirectory = Path.Combine(toolDownloadDir.Value, packageId.ToString()); - NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, _nugetPackageDownloader, toolDownloadDir.Value, _toolPackageStore).GetAwaiter().GetResult(); - CreateAssetFile(packageId, version, toolDownloadDir, assetFileDirectory, _runtimeJsonPath); + NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, nugetPackageDownloader, toolDownloadDir.Value, _toolPackageStore, versionRange).GetAwaiter().GetResult(); + CreateAssetFile(packageId, version, toolDownloadDir, assetFileDirectory, _runtimeJsonPath, targetFramework); DirectoryPath toolReturnPackageDirectory; DirectoryPath toolReturnJsonParentDirectory; @@ -112,7 +111,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); Directory.CreateDirectory(packageRootDirectory.Value); FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, toolReturnPackageDirectory.Value)); - rollbackDirectory = toolReturnPackageDirectory.Value; + rollbackDirectory = Path.Combine(toolReturnPackageDirectory.Value, packageId.ToString(), version.ToString()); } else { @@ -205,32 +204,26 @@ private static IEnumerable GetLockFileItems( private static async Task DownloadAndExtractPackage( PackageLocation packageLocation, PackageId packageId, - INuGetPackageDownloader _nugetPackageDownloader, - string hashPathLocation, - IToolPackageStore toolPackageStore + INuGetPackageDownloader nugetPackageDownloader, + string packagesRootPath, + IToolPackageStore toolPackageStore, + VersionRange versionRange ) { + NuGetVersion packageVersion = null; var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); - var packagePath = await _nugetPackageDownloader.DownloadPackageAsync(packageId, null, packageSourceLocation).ConfigureAwait(false); + var packagePath = await nugetPackageDownloader.DownloadPackageAsync(packageId, packageVersion, packageSourceLocation).ConfigureAwait(false); // look for package on disk and read the version NuGetVersion version; + DirectoryPath packageDirectory; using (FileStream packageStream = File.OpenRead(packagePath)) { PackageArchiveReader reader = new PackageArchiveReader(packageStream); version = new NuspecReader(reader.GetNuspec()).GetVersion(); - var packageDirectory = toolPackageStore.GetPackageDirectory(packageId, version); - - if (Directory.Exists(packageDirectory.Value)) - { - throw new ToolPackageException( - string.Format( - CommonLocalizableStrings.ToolPackageConflictPackageId, - packageId, - version.ToNormalizedString())); - } + packageDirectory = toolPackageStore.GetPackageDirectory(packageId, version); if (Directory.Exists(packagePath)) { @@ -242,15 +235,24 @@ IToolPackageStore toolPackageStore } var packageHash = Convert.ToBase64String(new CryptoHashProvider("SHA512").CalculateHash(reader.GetNuspec())); - var hashPath = new VersionFolderPathResolver(hashPathLocation).GetHashPath(packageId.ToString(), version); + var hashPath = new VersionFolderPathResolver(packagesRootPath).GetHashPath(packageId.ToString(), version); Directory.CreateDirectory(Path.GetDirectoryName(hashPath)); File.WriteAllText(hashPath, packageHash); } + if (Directory.Exists(packageDirectory.Value)) + { + throw new ToolPackageException( + string.Format( + CommonLocalizableStrings.ToolPackageConflictPackageId, + packageId, + version.ToNormalizedString())); + } + // Extract the package - var nupkgDir = Path.Combine(hashPathLocation, packageId.ToString(), version.ToString()); - var filesInPackage = await _nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(nupkgDir)); + var nupkgDir = Path.Combine(packagesRootPath, packageId.ToString(), version.ToString()); + var filesInPackage = await nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(nupkgDir)); return version; } @@ -258,9 +260,11 @@ IToolPackageStore toolPackageStore private static void CreateAssetFile( PackageId packageId, NuGetVersion version, - DirectoryPath nugetLocalRepository, + DirectoryPath packagesRootPath, DirectoryPath assetFileDirectory, - string runtimeJsonGraph) + string runtimeJsonGraph, + string targetFramework = null + ) { // To get runtimeGraph: var runtimeGraph = JsonRuntimeFormat.ReadRuntimeGraph(runtimeJsonGraph); @@ -278,7 +282,7 @@ private static void CreateAssetFile( }; // Create NuGetv3LocalRepository - NuGetv3LocalRepository localRepository = new(nugetLocalRepository.Value); + NuGetv3LocalRepository localRepository = new(packagesRootPath.Value); var package = localRepository.FindPackage(packageId.ToString(), version); var collection = new ContentItemCollection(); @@ -287,7 +291,7 @@ private static void CreateAssetFile( // Create criteria var managedCriteria = new List(1); // Use major.minor version of currently running version of .NET - var currentTargetFramework = new NuGetFramework(FrameworkConstants.FrameworkIdentifiers.NetCoreApp, new Version(Environment.Version.Major, Environment.Version.Minor)); + var currentTargetFramework = new NuGetFramework(targetFramework ?? FrameworkConstants.FrameworkIdentifiers.NetCoreApp, new Version(Environment.Version.Major, Environment.Version.Minor)); var standardCriteria = conventions.Criteria.ForFrameworkAndRuntime( currentTargetFramework, diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs index e912250ebcfb..ae15d4071886 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs @@ -143,8 +143,10 @@ public async Task GivenAConfigFileRootDirectoryPackageInstallSucceedsViaFindingN [Fact] public async Task GivenNoPackageVersionItCanInstallLatestVersionOfPackage() { + NuGetVersion packageVersion = null; string packagePath = await _installer.DownloadPackageAsync( TestPackageId, + packageVersion, packageSourceLocation: new PackageSourceLocation(sourceFeedOverrides: new[] {GetTestLocalFeedPath()})); packagePath.Should().Contain("global.tool.console.demo.1.0.4.nupkg", "It can get the latest non preview version"); File.Exists(packagePath).Should().BeTrue(); diff --git a/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs b/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs index 0871f30e21d4..0e9202af1246 100644 --- a/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs +++ b/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs @@ -29,6 +29,17 @@ public Task DownloadPackageAsync(PackageId packageId, NuGetVersion packa return Task.FromResult(mockPackagePath); } + public Task DownloadPackageAsync(PackageId packageId, + VersionRange packageVersion = null, + PackageSourceLocation packageSourceLocation = null, + DirectoryPath? downloadFolder = null, + PackageSourceMapping packageSourceMapping = null) + { + var mockPackagePath = Path.Combine(MockPackageDir, $"{packageId}.{packageVersion}.nupkg"); + File.WriteAllText(mockPackagePath, string.Empty); + return Task.FromResult(mockPackagePath); + } + public Task> ExtractPackageAsync(string packagePath, DirectoryPath targetFolder) { Directory.CreateDirectory(targetFolder.Value); diff --git a/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs b/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs index a4a496416229..974f5b7d8a3f 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs @@ -56,6 +56,15 @@ public Task DownloadPackageAsync(PackageId packageId, return Task.FromResult(path); } + public Task DownloadPackageAsync(PackageId packageId, + VersionRange packageVersion = null, + PackageSourceLocation packageSourceLocation = null, + DirectoryPath? downloadFolder = null, + PackageSourceMapping packageSourceMapping = null) + { + throw new NotImplementedException(); + } + public Task> ExtractPackageAsync(string packagePath, DirectoryPath targetFolder) { ExtractCallParams.Add((packagePath, targetFolder)); From ae2934bf69e71cf49deace7cdea0187bae775a6b Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 14 Sep 2023 00:23:44 -0700 Subject: [PATCH 37/47] rollback directory unchanged --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 58f6bd146a0a..f38e8661d6c4 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -96,7 +96,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa var toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; var nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true); - rollbackDirectory = Path.Combine(toolDownloadDir.Value, packageId.ToString()); + rollbackDirectory = toolDownloadDir.Value; NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, nugetPackageDownloader, toolDownloadDir.Value, _toolPackageStore, versionRange).GetAwaiter().GetResult(); CreateAssetFile(packageId, version, toolDownloadDir, assetFileDirectory, _runtimeJsonPath, targetFramework); @@ -111,7 +111,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); Directory.CreateDirectory(packageRootDirectory.Value); FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, toolReturnPackageDirectory.Value)); - rollbackDirectory = Path.Combine(toolReturnPackageDirectory.Value, packageId.ToString(), version.ToString()); + rollbackDirectory = toolReturnPackageDirectory.Value; } else { @@ -291,7 +291,7 @@ private static void CreateAssetFile( // Create criteria var managedCriteria = new List(1); // Use major.minor version of currently running version of .NET - var currentTargetFramework = new NuGetFramework(targetFramework ?? FrameworkConstants.FrameworkIdentifiers.NetCoreApp, new Version(Environment.Version.Major, Environment.Version.Minor)); + var currentTargetFramework = new NuGetFramework(FrameworkConstants.FrameworkIdentifiers.NetCoreApp, new Version(Environment.Version.Major, Environment.Version.Minor)); var standardCriteria = conventions.Criteria.ForFrameworkAndRuntime( currentTargetFramework, From 6b5da76f28c89ad02a8e17a9f3457af485dbf616 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 14 Sep 2023 13:34:35 -0700 Subject: [PATCH 38/47] Change verbosityOptions --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index f38e8661d6c4..27eedd5615fe 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -81,13 +81,14 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa action: () => { ILogger nugetLogger = new NullLogger(); - - if (verbosity != null && (verbosity == VerbosityOptions.d.ToString() || - verbosity == VerbosityOptions.detailed.ToString() || - verbosity == VerbosityOptions.diag.ToString() || - verbosity == VerbosityOptions.diagnostic.ToString())) + if(verbosity != null) { - nugetLogger = new NuGetConsoleLogger(); + VerbosityOptions verbosityOption; + Enum.TryParse(verbosity, out verbosityOption); + if (verbosityOption.IsDetailedOrDiagnostic()) + { + nugetLogger = new NuGetConsoleLogger(); + } } var versionString = versionRange?.OriginalString ?? "*"; From 160244a7cad27dde9ea30941141e852311d4593a Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Thu, 14 Sep 2023 14:45:39 -0700 Subject: [PATCH 39/47] Resolve versionRange --- .../NugetPackageDownloader/NuGetPackageDownloader.cs | 9 ++++----- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 4 ++-- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index ab1bfc4b3dd9..e9cf8d8244b3 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -517,13 +517,12 @@ await Task.WhenAll( foundPackagesBySource .SelectMany(result => result.foundPackages.Select(package => (result.source, package))); - var availableVersions = await Task.WhenAll(accumulativeSearchResults.Select(async t => (t.source, t.package, versions: await t.package.GetVersionsAsync()))); - var expandedVersions = availableVersions.SelectMany(t => t.versions.Select(versionInfo => (versionInfo.Version, t.source, t.package))); - var bestVersion = versionRange.FindBestMatch(expandedVersions.Select(t => t.Version)); + var availableVersions = accumulativeSearchResults.Select(t => t.package.Identity.Version).ToList(); + var bestVersion = versionRange.FindBestMatch(availableVersions); if (bestVersion != null) { - var bestExpandedVersion = expandedVersions.First(v => v.Version == bestVersion); - return (bestExpandedVersion.source, bestExpandedVersion.package); + var bestResult = accumulativeSearchResults.First(t => t.package.Identity.Version == bestVersion); + return bestResult; } else { diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 27eedd5615fe..4231c7d8b678 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -211,9 +211,9 @@ private static async Task DownloadAndExtractPackage( VersionRange versionRange ) { - NuGetVersion packageVersion = null; + // NuGetVersion packageVersion = null; var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); - var packagePath = await nugetPackageDownloader.DownloadPackageAsync(packageId, packageVersion, packageSourceLocation).ConfigureAwait(false); + var packagePath = await nugetPackageDownloader.DownloadPackageAsync(packageId, versionRange, packageSourceLocation).ConfigureAwait(false); // look for package on disk and read the version NuGetVersion version; From 6b9c7c8b9d296d7905b087c48aaabed6c2c6e7d6 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Fri, 15 Sep 2023 15:43:21 -0700 Subject: [PATCH 40/47] Pass targetFramework and add GetBestPackageVersionAsync method --- .../INuGetPackageDownloader.cs | 12 +- .../NuGetPackageDownloader.cs | 104 +++--------------- .../ToolPackage/ToolPackageDownloader.cs | 18 +-- .../FailingNuGetPackageInstaller.cs | 13 +-- .../MockNuGetPackageInstaller.cs | 16 ++- 5 files changed, 42 insertions(+), 121 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs index df50767f7dac..ad97f22bd3c7 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/INuGetPackageDownloader.cs @@ -17,12 +17,6 @@ Task DownloadPackageAsync(PackageId packageId, DirectoryPath? downloadFolder = null, PackageSourceMapping packageSourceMapping = null); - Task DownloadPackageAsync(PackageId packageId, - VersionRange packageVersion = null, - PackageSourceLocation packageSourceLocation = null, - DirectoryPath? downloadFolder = null, - PackageSourceMapping packageSourceMapping = null); - Task GetPackageUrl(PackageId packageId, NuGetVersion packageVersion = null, PackageSourceLocation packageSourceLocation = null, @@ -33,5 +27,9 @@ Task GetPackageUrl(PackageId packageId, Task GetLatestPackageVersion(PackageId packageId, PackageSourceLocation packageSourceLocation = null, bool includePreview = false); - } + + Task GetBestPackageVersionAsync(PackageId packageId, + VersionRange versionRange, + PackageSourceLocation packageSourceLocation = null); + } } diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index e9cf8d8244b3..810682e2df02 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -1,6 +1,7 @@ // Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. +using System.Threading; using Microsoft.DotNet.Cli.Utils; using Microsoft.DotNet.ToolPackage; using Microsoft.DotNet.Tools; @@ -128,59 +129,6 @@ public async Task DownloadPackageAsync(PackageId packageId, return nupkgPath; } - public async Task DownloadPackageAsync(PackageId packageId, - VersionRange packageVersion = null, - PackageSourceLocation packageSourceLocation = null, - DirectoryPath? downloadFolder = null, - PackageSourceMapping packageSourceMapping = null) - { - CancellationToken cancellationToken = CancellationToken.None; - - (var source, var resolvedPackageVersion) = await GetPackageSourceAndVersion(packageId, packageVersion, - packageSourceLocation, packageSourceMapping).ConfigureAwait(false); - - FindPackageByIdResource resource = null; - SourceRepository repository = GetSourceRepository(source); - - resource = await repository.GetResourceAsync(cancellationToken) - .ConfigureAwait(false); - - if (resource == null) - { - throw new NuGetPackageNotFoundException( - string.Format(LocalizableStrings.IsNotFoundInNuGetFeeds, packageId, source.Source)); - } - - string nupkgPath = downloadFolder == null || !downloadFolder.HasValue - ? Path.Combine(_packageInstallDir.Value, packageId.ToString(), - resolvedPackageVersion.ToNormalizedString(), - $"{packageId}.{resolvedPackageVersion.ToNormalizedString()}.nupkg") - : Path.Combine(downloadFolder.Value.Value, - $"{packageId}.{resolvedPackageVersion.ToNormalizedString()}.nupkg"); - - Directory.CreateDirectory(Path.GetDirectoryName(nupkgPath)); - using FileStream destinationStream = File.Create(nupkgPath); - bool success = await ExponentialRetry.ExecuteWithRetryOnFailure(async () => await resource.CopyNupkgToStreamAsync( - packageId.ToString(), - resolvedPackageVersion, - destinationStream, - _cacheSettings, - _verboseLogger, - cancellationToken)); - destinationStream.Close(); - - if (!success) - { - throw new NuGetPackageInstallerException( - string.Format("Downloading {0} version {1} failed", packageId, - packageVersion.ToNormalizedString())); - } - - VerifySigning(nupkgPath); - - return nupkgPath; - } - private void VerifySigning(string nupkgPath) { if (!_verifySignatures) @@ -299,39 +247,6 @@ await GetPackageMetadataAsync(packageId.ToString(), packageVersion, packagesSour return (source, packageVersion); } - private async Task<(PackageSource, NuGetVersion)> GetPackageSourceAndVersion(PackageId packageId, - VersionRange versionRange = null, - PackageSourceLocation packageSourceLocation = null, - PackageSourceMapping packageSourceMapping = null) - { - CancellationToken cancellationToken = CancellationToken.None; - - IPackageSearchMetadata packageMetadata; - - IEnumerable packagesSources = LoadNuGetSources(packageId, packageSourceLocation, packageSourceMapping); - PackageSource source; - - (source, packageMetadata) = await GetMatchingVersionInternalAsync(packageId.ToString(), packagesSources, - versionRange, cancellationToken).ConfigureAwait(false); - - /*if (packageVersion is null) - { - (source, packageMetadata) = await GetMatchingVersionInternalAsync(packageId.ToString(), packagesSources, - includePreview, cancellationToken).ConfigureAwait(false); - } - else - { - packageVersion = new NuGetVersion(packageVersion); - (source, packageMetadata) = - await GetPackageMetadataAsync(packageId.ToString(), packageVersion, packagesSources, - cancellationToken).ConfigureAwait(false); - }*/ - - NuGetVersion packageVersion = packageMetadata.Identity.Version; - - return (source, packageVersion); - } - private string GetNupkgUrl(string baseUri, PackageId id, NuGetVersion version) => baseUri + id.ToString() + "/" + version.ToNormalizedString() + "/" + id.ToString() + "." + version.ToNormalizedString() + ".nupkg"; @@ -602,6 +517,23 @@ await Task.WhenAll( return latestVersion; } + public async Task GetBestPackageVersionAsync(PackageId packageId, + VersionRange versionRange, + PackageSourceLocation packageSourceLocation = null) + { + CancellationToken cancellationToken = CancellationToken.None; + IPackageSearchMetadata packageMetadata; + + IEnumerable packagesSources = LoadNuGetSources(packageId, packageSourceLocation); + PackageSource source; + + (source, packageMetadata) = await GetMatchingVersionInternalAsync(packageId.ToString(), packagesSources, + versionRange, cancellationToken).ConfigureAwait(false); + + NuGetVersion packageVersion = packageMetadata.Identity.Version; + return packageVersion; + } + private async Task<(PackageSource, IPackageSearchMetadata)> GetPackageMetadataAsync(string packageIdentifier, NuGetVersion packageVersion, IEnumerable sources, CancellationToken cancellationToken) { diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 4231c7d8b678..fd3692ef054f 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -90,10 +90,6 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa nugetLogger = new NuGetConsoleLogger(); } } - - var versionString = versionRange?.OriginalString ?? "*"; - versionRange = VersionRange.Parse(versionString); - var toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; var nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true); @@ -211,9 +207,9 @@ private static async Task DownloadAndExtractPackage( VersionRange versionRange ) { - // NuGetVersion packageVersion = null; var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); - var packagePath = await nugetPackageDownloader.DownloadPackageAsync(packageId, versionRange, packageSourceLocation).ConfigureAwait(false); + NuGetVersion packageVersion = await nugetPackageDownloader.GetBestPackageVersionAsync(packageId, versionRange, packageSourceLocation).ConfigureAwait(false); + var packagePath = await nugetPackageDownloader.DownloadPackageAsync(packageId, packageVersion, packageSourceLocation).ConfigureAwait(false); // look for package on disk and read the version NuGetVersion version; @@ -292,7 +288,15 @@ private static void CreateAssetFile( // Create criteria var managedCriteria = new List(1); // Use major.minor version of currently running version of .NET - var currentTargetFramework = new NuGetFramework(FrameworkConstants.FrameworkIdentifiers.NetCoreApp, new Version(Environment.Version.Major, Environment.Version.Minor)); + NuGetFramework currentTargetFramework; + if(targetFramework != null) + { + currentTargetFramework = NuGetFramework.Parse(targetFramework); + } + else + { + currentTargetFramework = new NuGetFramework(FrameworkConstants.FrameworkIdentifiers.NetCoreApp, new Version(Environment.Version.Major, Environment.Version.Minor)); + } var standardCriteria = conventions.Criteria.ForFrameworkAndRuntime( currentTargetFramework, diff --git a/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs b/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs index 0e9202af1246..03d720408836 100644 --- a/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs +++ b/src/Tests/dotnet-workload-install.Tests/FailingNuGetPackageInstaller.cs @@ -29,17 +29,6 @@ public Task DownloadPackageAsync(PackageId packageId, NuGetVersion packa return Task.FromResult(mockPackagePath); } - public Task DownloadPackageAsync(PackageId packageId, - VersionRange packageVersion = null, - PackageSourceLocation packageSourceLocation = null, - DirectoryPath? downloadFolder = null, - PackageSourceMapping packageSourceMapping = null) - { - var mockPackagePath = Path.Combine(MockPackageDir, $"{packageId}.{packageVersion}.nupkg"); - File.WriteAllText(mockPackagePath, string.Empty); - return Task.FromResult(mockPackagePath); - } - public Task> ExtractPackageAsync(string packagePath, DirectoryPath targetFolder) { Directory.CreateDirectory(targetFolder.Value); @@ -48,7 +37,7 @@ public Task> ExtractPackageAsync(string packagePath, Directo } public Task GetLatestPackageVersion(PackageId packageId, PackageSourceLocation packageSourceLocation = null, bool includePreview = false) => throw new NotImplementedException(); - + public Task GetBestPackageVersionAsync(PackageId packageId, VersionRange versionRange, PackageSourceLocation packageSourceLocation = null) => throw new NotImplementedException(); public Task GetPackageUrl(PackageId packageId, NuGetVersion packageVersion, PackageSourceLocation packageSourceLocation = null, diff --git a/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs b/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs index 974f5b7d8a3f..dfd2c165dff2 100644 --- a/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs +++ b/src/Tests/dotnet-workload-install.Tests/MockNuGetPackageInstaller.cs @@ -56,15 +56,6 @@ public Task DownloadPackageAsync(PackageId packageId, return Task.FromResult(path); } - public Task DownloadPackageAsync(PackageId packageId, - VersionRange packageVersion = null, - PackageSourceLocation packageSourceLocation = null, - DirectoryPath? downloadFolder = null, - PackageSourceMapping packageSourceMapping = null) - { - throw new NotImplementedException(); - } - public Task> ExtractPackageAsync(string packagePath, DirectoryPath targetFolder) { ExtractCallParams.Add((packagePath, targetFolder)); @@ -92,6 +83,13 @@ public Task GetLatestPackageVersion(PackageId packageId, PackageSo return Task.FromResult(new NuGetVersion("10.0.0")); } + public Task GetBestPackageVersionAsync(PackageId packageId, VersionRange versionRange, PackageSourceLocation packageSourceLocation = null) + { + return Task.FromResult(new NuGetVersion("10.0.0")); + } + + + public Task GetPackageUrl(PackageId packageId, NuGetVersion packageVersion, PackageSourceLocation packageSourceLocation = null, From 4245c833d440e41c909e104f436c5cd811a56cd1 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 17 Sep 2023 16:52:10 -0700 Subject: [PATCH 41/47] Update PSM test, update duplicate download error, remove unused code --- .../NuGetPackageDownloader.cs | 12 ++-- .../ToolPackage/ToolPackageDownloader.cs | 72 +++++++++++-------- .../install/ParseResultExtension.cs | 21 ------ .../NuGetPackageInstallerTests.cs | 2 +- 4 files changed, 51 insertions(+), 56 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index 810682e2df02..745040b28a0d 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -292,7 +292,7 @@ private static bool PackageIsInAllowList(IEnumerable files) private IEnumerable LoadNuGetSources(PackageId packageId, PackageSourceLocation packageSourceLocation = null, PackageSourceMapping packageSourceMapping = null) { - IEnumerable defaultSources = new List(); + List defaultSources = new List(); string currentDirectory = Directory.GetCurrentDirectory(); ISettings settings; if (packageSourceLocation?.NugetConfig != null) @@ -310,7 +310,7 @@ private IEnumerable LoadNuGetSources(PackageId packageId, Package } PackageSourceProvider packageSourceProvider = new PackageSourceProvider(settings); - defaultSources = packageSourceProvider.LoadPackageSources().Where(source => source.IsEnabled); + defaultSources = packageSourceProvider.LoadPackageSources().Where(source => source.IsEnabled).ToList(); packageSourceMapping = packageSourceMapping ?? PackageSourceMapping.GetPackageSourceMapping(settings); @@ -323,7 +323,11 @@ private IEnumerable LoadNuGetSources(PackageId packageId, Package { throw new NuGetPackageInstallerException(string.Format(LocalizableStrings.FailedToGetPackageUnderPackageSourceMapping, packageId)); } - defaultSources = defaultSources.Where(source => sources.Contains(source.Name)); + defaultSources = defaultSources.Where(source => sources.Contains(source.Name)).ToList(); + if (defaultSources.Count == 0) + { + throw new NuGetPackageInstallerException(string.Format(LocalizableStrings.FailedToGetPackageUnderPackageSourceMapping, packageId)); + } } if (packageSourceLocation?.AdditionalSourceFeed?.Any() ?? false) @@ -344,7 +348,7 @@ private IEnumerable LoadNuGetSources(PackageId packageId, Package continue; } - defaultSources = defaultSources.Append(packageSource); + defaultSources.Add(packageSource); } } diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index fd3692ef054f..b09d0beb6e9f 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -90,21 +90,55 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa nugetLogger = new NuGetConsoleLogger(); } } + var versionString = versionRange?.OriginalString ?? "*"; + versionRange = VersionRange.Parse(versionString); + var toolDownloadDir = isGlobalTool ? _globalToolStageDir : _localToolDownloadDir; var assetFileDirectory = isGlobalTool ? _globalToolStageDir : _localToolAssetDir; var nugetPackageDownloader = new NuGetPackageDownloader.NuGetPackageDownloader(toolDownloadDir, verboseLogger: nugetLogger, isNuGetTool: true); - rollbackDirectory = toolDownloadDir.Value; - NuGetVersion version = DownloadAndExtractPackage(packageLocation, packageId, nugetPackageDownloader, toolDownloadDir.Value, _toolPackageStore, versionRange).GetAwaiter().GetResult(); - CreateAssetFile(packageId, version, toolDownloadDir, assetFileDirectory, _runtimeJsonPath, targetFramework); + var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); + NuGetVersion packageVersion = nugetPackageDownloader.GetBestPackageVersionAsync(packageId, versionRange, packageSourceLocation).GetAwaiter().GetResult(); + + rollbackDirectory = isGlobalTool ? toolDownloadDir.Value: Path.Combine(toolDownloadDir.Value, packageId.ToString(), packageVersion.ToString()); + + NuGetv3LocalRepository nugetPackageRootDirectory = new(Path.Combine(_toolPackageStore.Root.ToString(), packageId.ToString(), packageVersion.ToString())); + var globalPackage = nugetPackageRootDirectory.FindPackage(packageId.ToString(), packageVersion); + + if(isGlobalTool && globalPackage != null) + { + throw new ToolPackageException( + string.Format( + CommonLocalizableStrings.ToolPackageConflictPackageId, + packageId, + packageVersion.ToNormalizedString())); + } + + NuGetv3LocalRepository localRepository = new(toolDownloadDir.Value); + var package = localRepository.FindPackage(packageId.ToString(), packageVersion); + + if (package == null) + { + DownloadAndExtractPackage(packageLocation, packageId, nugetPackageDownloader, toolDownloadDir.Value, _toolPackageStore, packageVersion, packageSourceLocation).GetAwaiter().GetResult(); + } + else if(isGlobalTool) + { + throw new ToolPackageException( + string.Format( + CommonLocalizableStrings.ToolPackageConflictPackageId, + packageId, + packageVersion.ToNormalizedString())); + } + + CreateAssetFile(packageId, packageVersion, toolDownloadDir, assetFileDirectory, _runtimeJsonPath, targetFramework); DirectoryPath toolReturnPackageDirectory; DirectoryPath toolReturnJsonParentDirectory; if (isGlobalTool) { - toolReturnPackageDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); - toolReturnJsonParentDirectory = _toolPackageStore.GetPackageDirectory(packageId, version); + toolReturnPackageDirectory = _toolPackageStore.GetPackageDirectory(packageId, packageVersion); + toolReturnJsonParentDirectory = _toolPackageStore.GetPackageDirectory(packageId, packageVersion); var packageRootDirectory = _toolPackageStore.GetRootPackageDirectory(packageId); Directory.CreateDirectory(packageRootDirectory.Value); FileAccessRetrier.RetryOnMoveAccessFailure(() => Directory.Move(_globalToolStageDir.Value, toolReturnPackageDirectory.Value)); @@ -117,7 +151,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa } return new ToolPackageInstance(id: packageId, - version: version, + version: packageVersion, packageDirectory: toolReturnPackageDirectory, assetsJsonParentDirectory: toolReturnJsonParentDirectory); }, @@ -204,33 +238,20 @@ private static async Task DownloadAndExtractPackage( INuGetPackageDownloader nugetPackageDownloader, string packagesRootPath, IToolPackageStore toolPackageStore, - VersionRange versionRange + NuGetVersion packageVersion, + PackageSourceLocation packageSourceLocation ) { - var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); - NuGetVersion packageVersion = await nugetPackageDownloader.GetBestPackageVersionAsync(packageId, versionRange, packageSourceLocation).ConfigureAwait(false); var packagePath = await nugetPackageDownloader.DownloadPackageAsync(packageId, packageVersion, packageSourceLocation).ConfigureAwait(false); // look for package on disk and read the version NuGetVersion version; - DirectoryPath packageDirectory; using (FileStream packageStream = File.OpenRead(packagePath)) { PackageArchiveReader reader = new PackageArchiveReader(packageStream); version = new NuspecReader(reader.GetNuspec()).GetVersion(); - packageDirectory = toolPackageStore.GetPackageDirectory(packageId, version); - - if (Directory.Exists(packagePath)) - { - throw new ToolPackageException( - string.Format( - CommonLocalizableStrings.ToolPackageConflictPackageId, - packageId, - version.ToNormalizedString())); - } - var packageHash = Convert.ToBase64String(new CryptoHashProvider("SHA512").CalculateHash(reader.GetNuspec())); var hashPath = new VersionFolderPathResolver(packagesRootPath).GetHashPath(packageId.ToString(), version); @@ -238,15 +259,6 @@ VersionRange versionRange File.WriteAllText(hashPath, packageHash); } - if (Directory.Exists(packageDirectory.Value)) - { - throw new ToolPackageException( - string.Format( - CommonLocalizableStrings.ToolPackageConflictPackageId, - packageId, - version.ToNormalizedString())); - } - // Extract the package var nupkgDir = Path.Combine(packagesRootPath, packageId.ToString(), version.ToString()); var filesInPackage = await nugetPackageDownloader.ExtractPackageAsync(packagePath, new DirectoryPath(nupkgDir)); diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs index cba71972a2c1..25befc5e7458 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ParseResultExtension.cs @@ -43,27 +43,6 @@ public static VersionRange GetVersionRange(this ParseResult parseResult) LocalizableStrings.InvalidNuGetVersionRange, packageVersion)); } - - if (string.IsNullOrEmpty(packageVersion)) - { - var nugetToolSearchApiRequest = new NugetToolSearchApiRequest(); - NugetSearchApiParameter nugetSearchApiParameter = new(searchTerm: packageId, prerelease: prerelease); - IReadOnlyCollection searchResultPackages = - NugetSearchApiResultDeserializer.Deserialize( - nugetToolSearchApiRequest.GetResult(nugetSearchApiParameter).GetAwaiter().GetResult()); - var packageData = searchResultPackages.Where(p => p.Id.ToString().Equals(packageId)).FirstOrDefault(); - if (packageData != null) - { - string latestVersion = packageData.LatestVersion; - if (!VersionRange.TryParse(latestVersion, out versionRange)) - { - throw new GracefulException( - string.Format( - LocalizableStrings.InvalidNuGetVersionRange, - latestVersion)); - } - } - } return versionRange; } } diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs index ae15d4071886..d81c7b4fc600 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs @@ -195,7 +195,7 @@ public void GivenPackageSourceMappingFeedNotFoundItShouldError() Log.WriteLine(relativePath); var dictionary = new Dictionary> { - { "global.tool.console.demo", new List() { "nonexistentfeed" } } + { "nonexistentfeed", new List() { TestPackageId.ToString() } } }; var patterns = new ReadOnlyDictionary>(dictionary); var mockPackageSourceMapping = new PackageSourceMapping(patterns); From ea5eaa6b6233858d6365bf2b7f6673a1a19c0085 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 17 Sep 2023 18:44:12 -0700 Subject: [PATCH 42/47] fix check duplicate global packages --- src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index b09d0beb6e9f..72f68d772eba 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -102,7 +102,7 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa rollbackDirectory = isGlobalTool ? toolDownloadDir.Value: Path.Combine(toolDownloadDir.Value, packageId.ToString(), packageVersion.ToString()); - NuGetv3LocalRepository nugetPackageRootDirectory = new(Path.Combine(_toolPackageStore.Root.ToString(), packageId.ToString(), packageVersion.ToString())); + NuGetv3LocalRepository nugetPackageRootDirectory = new(Path.Combine(_toolPackageStore.GetRootPackageDirectory(packageId).ToString().Trim('"'), packageVersion.ToString())); var globalPackage = nugetPackageRootDirectory.FindPackage(packageId.ToString(), packageVersion); if(isGlobalTool && globalPackage != null) From c1e3177930c19824390a71e80458b8fadfab8ba2 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 17 Sep 2023 20:31:23 -0700 Subject: [PATCH 43/47] Change verbosity type and add packageSourceMapping tests --- .../LocalizableStrings.resx | 7 ++++-- .../NuGetPackageDownloader.cs | 4 ++-- .../xlf/LocalizableStrings.cs.xlf | 11 ++++++--- .../xlf/LocalizableStrings.de.xlf | 11 ++++++--- .../xlf/LocalizableStrings.es.xlf | 11 ++++++--- .../xlf/LocalizableStrings.fr.xlf | 11 ++++++--- .../xlf/LocalizableStrings.it.xlf | 11 ++++++--- .../xlf/LocalizableStrings.ja.xlf | 11 ++++++--- .../xlf/LocalizableStrings.ko.xlf | 11 ++++++--- .../xlf/LocalizableStrings.pl.xlf | 11 ++++++--- .../xlf/LocalizableStrings.pt-BR.xlf | 11 ++++++--- .../xlf/LocalizableStrings.ru.xlf | 11 ++++++--- .../xlf/LocalizableStrings.tr.xlf | 11 ++++++--- .../xlf/LocalizableStrings.zh-Hans.xlf | 11 ++++++--- .../xlf/LocalizableStrings.zh-Hant.xlf | 11 ++++++--- .../ToolPackage/IToolPackageDownloader.cs | 2 +- .../ToolPackage/ToolPackageDownloader.cs | 11 +++------ .../ToolInstallGlobalOrToolPathCommand.cs | 4 ++-- .../install/ToolInstallLocalInstaller.cs | 9 +++---- .../dotnet-tool/restore/ToolRestoreCommand.cs | 8 +++---- .../ToolUpdateGlobalOrToolPathCommand.cs | 4 ++-- .../NuGetPackageInstallerTests.cs | 4 ++-- .../ToolPackageDownloaderTests.cs | 24 ++++++++++++++++++- .../ToolPackageInstallerNugetCacheTests.cs | 3 +++ .../ToolPackageUninstallerTests.cs | 3 ++- .../ToolPackageDownloaderMock.cs | 2 +- 26 files changed, 159 insertions(+), 69 deletions(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx b/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx index 71abd1fd7476..bfb61a0a4c16 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx +++ b/src/Cli/dotnet/NugetPackageDownloader/LocalizableStrings.resx @@ -138,7 +138,10 @@ Failed to validate package signing. - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. \ No newline at end of file diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index 745040b28a0d..a3630022a4e2 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -321,12 +321,12 @@ private IEnumerable LoadNuGetSources(PackageId packageId, Package if (sources.Count == 0) { - throw new NuGetPackageInstallerException(string.Format(LocalizableStrings.FailedToGetPackageUnderPackageSourceMapping, packageId)); + throw new NuGetPackageInstallerException(string.Format(LocalizableStrings.FailedToFindSourceUnderPackageSourceMapping, packageId)); } defaultSources = defaultSources.Where(source => sources.Contains(source.Name)).ToList(); if (defaultSources.Count == 0) { - throw new NuGetPackageInstallerException(string.Format(LocalizableStrings.FailedToGetPackageUnderPackageSourceMapping, packageId)); + throw new NuGetPackageInstallerException(string.Format(LocalizableStrings.FailedToMapSourceUnderPackageSourceMapping, packageId)); } } diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf index f8ee5e6d8800..d718f9bce02f 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.cs.xlf @@ -7,9 +7,9 @@ Stahování {0} verze {1} selhalo. - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ Nepovedlo se načíst zdroj Nuget {0}: zdroj není platný. Při dalším zpracování se přeskočí. + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. Nepodařilo se ověřit podepisování balíčku. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf index 3d6b172342a6..3a6842dc7c1d 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.de.xlf @@ -7,9 +7,9 @@ Fehler beim Herunterladen der {0} Version {1}. - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ Fehler beim Laden der NuGet-Quelle {0}: die Quelle ist ungültig. Sie wird bei der weiteren Verarbeitung übersprungen. + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. Fehler bei der Überprüfung der Paketsignierung. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf index 68d3fbe21dda..f3d60d660b21 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.es.xlf @@ -7,9 +7,9 @@ Error al descargar {0} versión {1}. - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ No se pudo cargar el origen de NuGet {0}: el origen no es válido. Se omitirá en un proceso posterior. + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. No se pudo validar la firma del paquete. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf index 5290c71793f2..ddfd43fc0325 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.fr.xlf @@ -7,9 +7,9 @@ Échec du téléchargement de {0}, version {1} . - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ Échec du chargement de la source NuGet {0} : la source n’est pas valide. Il sera ignoré en cours de traitement. + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. Échec de la validation de la signature du package. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf index 8ce5b6c8b2fa..df306e261a43 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.it.xlf @@ -7,9 +7,9 @@ Download {0} versione {1} non riuscito. - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ Non è stato possibile caricare l'origine NuGet {0}: l'origine non è valida. Verrà ignorata in elaborazioni successive. + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. Impossibile convalidare la firma del pacchetto. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf index 6c796e8cc676..4b5563549bfa 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ja.xlf @@ -7,9 +7,9 @@ {0} バージョン {1} のダウンロードに失敗しました。 - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ NuGet ソース {0} の読み込みに失敗しました: このソースが有効ではありません。今後の処理ではスキップされます。 + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. パッケージ署名を検証できませんでした。 diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf index bf3fa73cb257..692e06800ea7 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ko.xlf @@ -7,9 +7,9 @@ {0} 버전 {1} 다운로드에 실패했습니다. - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ NuGet 원본 {0}을(를) 로드하지 못했습니다. 원본이 유효하지 않습니다. 추가 처리에서 건너뛰세요. + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. 패키지 서명의 유효성을 검사하지 못했습니다. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf index 0f464cd6abcf..f8170e0f42be 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pl.xlf @@ -7,9 +7,9 @@ Pobieranie {0} w wersji {1} nie powiodło się. - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ Nie można załadować źródła pakietu NuGet {0}: źródło jest nieprawidłowe. Zostanie ono pominięte podczas dalszego przetwarzania. + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. Nie można zweryfikować podpisywania pakietu. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf index 36a235e1c098..fbb786af1bed 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.pt-BR.xlf @@ -7,9 +7,9 @@ Falhou ao baixar {0} versão {1}. - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ Falha no carregamento da fonte NuGet {0}: a fonte não é válida. Ela será ignorada num processamento posterior. + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. Falhou ao validar a assinatura do pacote. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf index fd2d39c2026e..7e3aaed5f651 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.ru.xlf @@ -7,9 +7,9 @@ Не удалось скачать версию {0} {1}. - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ Не удалось загрузить источник NuGet {0}: недопустимый источник. Он будет пропущен при дальнейшей обработке. + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. Не удалось проверить подпись пакета. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf index 4fecd44cb180..be6e5c7d8c07 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.tr.xlf @@ -7,9 +7,9 @@ {0} sürüm {1} indirilemedi. - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ {0} NuGet kaynağı yüklenemedi: kaynak geçerli değil. Daha fazla işlemede atlanacak. + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. Paket imzası doğrulanamadı. diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf index 5235fe508408..0e870c10196e 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hans.xlf @@ -7,9 +7,9 @@ 下载 {0} 版本 {1} 失败。 - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ 无法加载 NuGet 源 {0}: 源无效。进一步处理中将跳过它。 + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. 验证包签名失败。 diff --git a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf index 2f530ef5baf6..86a44e1fae5b 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf +++ b/src/Cli/dotnet/NugetPackageDownloader/xlf/LocalizableStrings.zh-Hant.xlf @@ -7,9 +7,9 @@ 下載 {0} 版本 {1} 失敗。 - - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. - Package Source Mapping is enabled, but no feeds matched the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source found under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. @@ -22,6 +22,11 @@ 無法載入 NuGet 來源 {0}: 來源無效。進一步處理時會跳過此情況。 + + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + Package Source Mapping is enabled, but no source mapped under the specified package ID: {0}. See the documentation for Package Source Mapping at https://aka.ms/nuget-package-source-mapping for more details. + + Failed to validate package signing. 無法驗證套件簽署。 diff --git a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs index 72e7286db4fd..816ead4cdf73 100644 --- a/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/IToolPackageDownloader.cs @@ -10,9 +10,9 @@ namespace Microsoft.DotNet.Cli.ToolPackage internal interface IToolPackageDownloader { IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, + VerbosityOptions verbosity, VersionRange versionRange = null, string targetFramework = null, - string verbosity = null, bool isGlobalTool = false ); } diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index 72f68d772eba..aea839976f38 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -68,9 +68,9 @@ public ToolPackageDownloader( } public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, + VerbosityOptions verbosity, VersionRange versionRange = null, string targetFramework = null, - string verbosity = null, bool isGlobalTool = false ) { @@ -81,14 +81,9 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa action: () => { ILogger nugetLogger = new NullLogger(); - if(verbosity != null) + if (verbosity.IsDetailedOrDiagnostic()) { - VerbosityOptions verbosityOption; - Enum.TryParse(verbosity, out verbosityOption); - if (verbosityOption.IsDetailedOrDiagnostic()) - { - nugetLogger = new NuGetConsoleLogger(); - } + nugetLogger = new NuGetConsoleLogger(); } var versionString = versionRange?.OriginalString ?? "*"; versionRange = VersionRange.Parse(versionString); diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs index 9571aa7b3570..a9cbfe8d1a63 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallGlobalOrToolPathCommand.cs @@ -39,7 +39,7 @@ internal class ToolInstallGlobalOrToolPathCommand : CommandBase private readonly string _framework; private readonly string[] _source; private readonly bool _global; - private readonly string _verbosity; + private readonly VerbosityOptions _verbosity; private readonly string _toolPath; private readonly string _architectureOption; private IEnumerable _forwardRestoreArguments; @@ -59,7 +59,7 @@ public ToolInstallGlobalOrToolPathCommand( _framework = parseResult.GetValue(ToolInstallCommandParser.FrameworkOption); _source = parseResult.GetValue(ToolInstallCommandParser.AddSourceOption); _global = parseResult.GetValue(ToolAppliedOption.GlobalOption); - _verbosity = Enum.GetName(parseResult.GetValue(ToolInstallCommandParser.VerbosityOption)); + _verbosity = parseResult.GetValue(ToolInstallCommandParser.VerbosityOption); _toolPath = parseResult.GetValue(ToolAppliedOption.ToolPathOption); _architectureOption = parseResult.GetValue(ToolInstallCommandParser.ArchitectureOption); diff --git a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs index 000d4f06e415..4c370c34523f 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/install/ToolInstallLocalInstaller.cs @@ -23,7 +23,7 @@ internal class ToolInstallLocalInstaller private readonly string _packageVersion; private readonly string _configFilePath; private readonly string[] _sources; - private readonly string _verbosity; + private readonly VerbosityOptions _verbosity; public ToolInstallLocalInstaller( ParseResult parseResult, @@ -34,7 +34,7 @@ public ToolInstallLocalInstaller( _packageVersion = parseResult.GetValue(ToolInstallCommandParser.VersionOption); _configFilePath = parseResult.GetValue(ToolInstallCommandParser.ConfigOption); _sources = parseResult.GetValue(ToolInstallCommandParser.AddSourceOption); - _verbosity = Enum.GetName(parseResult.GetValue(ToolInstallCommandParser.VerbosityOption)); + _verbosity = parseResult.GetValue(ToolInstallCommandParser.VerbosityOption); (IToolPackageStore store, IToolPackageStoreQuery, @@ -74,9 +74,10 @@ public IToolPackage Install(FilePath manifestFile) additionalFeeds: _sources, rootConfigDirectory: manifestFile.GetDirectoryPath().GetParentPath()), _packageId, + verbosity: _verbosity, versionRange, - TargetFrameworkToInstall, - verbosity: _verbosity); + TargetFrameworkToInstall + ); return toolDownloadedPackage; } diff --git a/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs index f35848655881..5666d6245143 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/restore/ToolRestoreCommand.cs @@ -23,7 +23,7 @@ internal class ToolRestoreCommand : CommandBase private readonly IReporter _reporter; private readonly string[] _sources; private readonly IToolPackageDownloader _toolPackageDownloader; - private readonly string _verbosity; + private readonly VerbosityOptions _verbosity; public ToolRestoreCommand( ParseResult result, @@ -60,7 +60,7 @@ public ToolRestoreCommand( _configFilePath = result.GetValue(ToolRestoreCommandParser.ConfigOption); _sources = result.GetValue(ToolRestoreCommandParser.AddSourceOption); - _verbosity = Enum.GetName(result.GetValue(ToolRestoreCommandParser.VerbosityOption)); + _verbosity = result.GetValue(ToolRestoreCommandParser.VerbosityOption); } public override int Execute() @@ -130,8 +130,8 @@ private ToolRestoreResult InstallPackages( nugetConfig: configFile, additionalFeeds: _sources, rootConfigDirectory: package.FirstEffectDirectory), - package.PackageId, ToVersionRangeWithOnlyOneVersion(package.Version), targetFramework, - verbosity: _verbosity); + package.PackageId, verbosity: _verbosity, ToVersionRangeWithOnlyOneVersion(package.Version), targetFramework + ); if (!ManifestCommandMatchesActualInPackage(package.CommandNames, toolPackage.Commands)) { diff --git a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs index b0e1087fb371..86a737cb6693 100644 --- a/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs +++ b/src/Cli/dotnet/commands/dotnet-tool/update/ToolUpdateGlobalOrToolPathCommand.cs @@ -33,7 +33,7 @@ internal class ToolUpdateGlobalOrToolPathCommand : CommandBase private readonly string _framework; private readonly string[] _additionalFeeds; private readonly bool _global; - private readonly string _verbosity; + private readonly VerbosityOptions _verbosity; private readonly string _toolPath; private readonly IEnumerable _forwardRestoreArguments; private readonly string _packageVersion; @@ -50,7 +50,7 @@ public ToolUpdateGlobalOrToolPathCommand(ParseResult parseResult, _additionalFeeds = parseResult.GetValue(ToolUpdateCommandParser.AddSourceOption); _packageVersion = parseResult.GetValue(ToolUpdateCommandParser.VersionOption); _global = parseResult.GetValue(ToolUpdateCommandParser.GlobalOption); - _verbosity = Enum.GetName(parseResult.GetValue(ToolUpdateCommandParser.VerbosityOption)); + _verbosity = parseResult.GetValue(ToolUpdateCommandParser.VerbosityOption); _toolPath = parseResult.GetValue(ToolUpdateCommandParser.ToolPathOption); _forwardRestoreArguments = parseResult.OptionValuesToBeForwarded(ToolUpdateCommandParser.GetCommand()); diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs index d81c7b4fc600..4d245248ad93 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/NuGetPackageInstallerTests.cs @@ -184,7 +184,7 @@ public void GivenNoPackageSourceMappingItShouldError() new NuGetVersion(TestPackageVersion), new PackageSourceLocation(sourceFeedOverrides: new[] { relativePath }), packageSourceMapping: mockPackageSourceMapping).GetAwaiter().GetResult(); - a.Should().Throw().And.Message.Should().Contain(string.Format(Cli.NuGetPackageDownloader.LocalizableStrings.FailedToGetPackageUnderPackageSourceMapping, TestPackageId)); + a.Should().Throw().And.Message.Should().Contain(string.Format(Cli.NuGetPackageDownloader.LocalizableStrings.FailedToFindSourceUnderPackageSourceMapping, TestPackageId)); } [Fact] @@ -205,7 +205,7 @@ public void GivenPackageSourceMappingFeedNotFoundItShouldError() new NuGetVersion(TestPackageVersion), new PackageSourceLocation(sourceFeedOverrides: new[] { relativePath }), packageSourceMapping: mockPackageSourceMapping).GetAwaiter().GetResult(); - a.Should().Throw().And.Message.Should().Contain(string.Format(Cli.NuGetPackageDownloader.LocalizableStrings.FailedToGetPackageUnderPackageSourceMapping, TestPackageId)); + a.Should().Throw().And.Message.Should().Contain(string.Format(Cli.NuGetPackageDownloader.LocalizableStrings.FailedToMapSourceUnderPackageSourceMapping, TestPackageId)); } [Fact] diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs index d812bb64393a..6920c99a64a0 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs @@ -50,6 +50,7 @@ public void GivenNugetConfigInstallSucceeds(bool testMockBehaviorIsInSync) var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -77,6 +78,7 @@ public void GivenNugetConfigInstallSucceedsInTransaction(bool testMockBehaviorIs { package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -102,6 +104,7 @@ public void GivenNugetConfigInstallCreatesAnAssetFile(bool testMockBehaviorIsInS var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -164,6 +167,7 @@ public void GivenAConfigFileRootDirectoryPackageInstallSucceedsViaFindingNugetCo var package = downloader.InstallPackage( new PackageLocation(rootConfigDirectory: subDirUnderNugetConfigPath), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -187,6 +191,7 @@ public void GivenAllButNoPackageVersionItCanInstallThePackage(bool testMockBehav var package = downloader.InstallPackage( new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, + verbosity: TestVerbosity, targetFramework: _testTargetframework, isGlobalTool: true); @@ -208,6 +213,7 @@ public void GivenAllButNoTargetFrameworkItCanDownloadThePackage(bool testMockBeh var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), isGlobalTool: true); @@ -229,6 +235,7 @@ public void GivenASourceInstallSucceeds(bool testMockBehaviorIsInSync) var package = downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -252,6 +259,7 @@ public void GivenARelativeSourcePathInstallSucceeds(bool testMockBehaviorIsInSyn var package = downloader.InstallPackage( new PackageLocation(additionalFeeds: new[] {Path.GetRelativePath(Directory.GetCurrentDirectory(), source)}), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -274,6 +282,7 @@ public void GivenAUriSourceInstallSucceeds(bool testMockBehaviorIsInSync) var package = downloader.InstallPackage( new PackageLocation(additionalFeeds: new[] { new Uri(source).AbsoluteUri }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -299,6 +308,7 @@ public void GivenAEmptySourceAndNugetConfigInstallSucceeds(bool testMockBehavior var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath, additionalFeeds: new[] { emptySource }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -329,6 +339,7 @@ public void GivenFailureAfterRestoreInstallWillRollback(bool testMockBehaviorIsI { downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -362,6 +373,7 @@ public void GivenSecondInstallInATransactionTheFirstInstallShouldRollback(bool t { Action first = () => downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -370,6 +382,7 @@ public void GivenSecondInstallInATransactionTheFirstInstallShouldRollback(bool t downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -401,6 +414,7 @@ public void GivenSecondInstallWithoutATransactionTheFirstShouldNotRollback(bool var package = downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -409,6 +423,7 @@ public void GivenSecondInstallWithoutATransactionTheFirstShouldNotRollback(bool Action secondCall = () => downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -451,6 +466,7 @@ public void GivenAnInstalledPackageUninstallRemovesThePackage(bool testMockBehav var package = downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -476,6 +492,7 @@ public void GivenAnInstalledPackageUninstallRollsbackWhenTransactionFails(bool t var package = downloader.InstallPackage( new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -510,6 +527,7 @@ public void GivenAnInstalledPackageUninstallRemovesThePackageWhenTransactionComm var package = downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -540,6 +558,7 @@ public void GivenAPackageNameWithDifferentCaseItCanInstallThePackage(bool testMo var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: new PackageId("GlObAl.TooL.coNsoLe.DemO"), + verbosity: TestVerbosity, targetFramework: _testTargetframework, isGlobalTool: true); @@ -570,6 +589,7 @@ public void GivenARootWithNonAsciiCharacterInstallSucceeds() var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -596,6 +616,7 @@ public void GivenAComplexVersionRangeInstallSucceeds(bool testMockBehaviorIsInSy var package = downloader.InstallPackage(new PackageLocation(nugetConfig: nugetConfigPath, additionalFeeds: new[] { emptySource }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse("1.0.0-rc*"), targetFramework: _testTargetframework, isGlobalTool: true); @@ -647,6 +668,7 @@ public void GivenAPackageWithCasingAndenUSPOSIXInstallSucceeds(bool testMockBeha nugetConfig: nugetConfigPath, additionalFeeds: new[] { emptySource }), packageId: packageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(packageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -883,7 +905,7 @@ private static string GetTestLocalFeedPath() => private const string TestPackageVersion = "1.0.4"; private static readonly PackageId TestPackageId = new PackageId("global.tool.console.demo"); private static readonly IEnumerable TestFrameworks = new NuGetFramework[] { NuGetFramework.Parse("netcoreapp2.1") }; - + private static readonly VerbosityOptions TestVerbosity = new VerbosityOptions(); public ToolPackageDownloaderTests(ITestOutputHelper log) : base(log) { } diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs index 19a24cb3de4f..3aedbf9a3a98 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageInstallerNugetCacheTests.cs @@ -39,6 +39,7 @@ public void GivenNugetConfigInstallSucceeds(bool testMockBehaviorIsInSync) IToolPackage toolPackage = installer.InstallPackage( packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), packageLocation: new PackageLocation(nugetConfig: nugetConfigPath), targetFramework: _testTargetframework); @@ -76,6 +77,7 @@ public void GivenNugetConfigVersionRangeInstallSucceeds(bool testMockBehaviorIsI IToolPackage toolPackage = installer.InstallPackage( packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse("1.0.0-*"), packageLocation: new PackageLocation(nugetConfig: nugetConfigPath), targetFramework: _testTargetframework); @@ -157,6 +159,7 @@ private FilePath WriteNugetConfigFileToPointToTheFeed(string testDirectory) private static string GetTestLocalFeedPath() => Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "TestAssetLocalNugetFeed"); private readonly string _testTargetframework = BundledTargetFramework.GetTargetFrameworkMoniker(); private const string TestPackageVersion = "1.0.4"; + private static readonly VerbosityOptions TestVerbosity = new VerbosityOptions(); private static readonly PackageId TestPackageId = new PackageId("global.tool.console.demo"); } } diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs index 1e41c301056a..4e5750f81d61 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageUninstallerTests.cs @@ -29,6 +29,7 @@ public void GivenAnInstalledPackageUninstallRemovesThePackage(bool testMockBehav var package = downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, + verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework, isGlobalTool: true); @@ -118,7 +119,7 @@ private static string GetTestLocalFeedPath() => private readonly string _testTargetframework = BundledTargetFramework.GetTargetFrameworkMoniker(); private const string TestPackageVersion = "1.0.4"; private static readonly PackageId TestPackageId = new PackageId("global.tool.console.demo.with.shim"); - + private static readonly VerbosityOptions TestVerbosity = new VerbosityOptions(); public ToolPackageUninstallerTests(ITestOutputHelper log) : base(log) { } diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index ca2340fa6f71..07811468486b 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -93,9 +93,9 @@ public ToolPackageDownloaderMock( } public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, + VerbosityOptions verbosity, VersionRange versionRange = null, string targetFramework = null, - string verbosity = null, bool isGlobalTool = false ) { From 797ebb4c4f3d830a25635aaa295406b1a2e63d14 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 17 Sep 2023 21:33:31 -0700 Subject: [PATCH 44/47] Add test for when local tool rollback, it should delete the \ --- .../ToolPackageDownloaderTests.cs | 86 +++++++++++++++++++ 1 file changed, 86 insertions(+) diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs index 6920c99a64a0..f45ae76ceef3 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs @@ -16,6 +16,7 @@ using System.Runtime.CompilerServices; using Microsoft.DotNet.ToolPackage; using NuGet.Frameworks; +using NuGet.Configuration; namespace Microsoft.DotNet.PackageInstall.Tests { @@ -401,6 +402,91 @@ public void GivenSecondInstallInATransactionTheFirstInstallShouldRollback(bool t AssertInstallRollBack(fileSystem, store); } + [Theory] + [InlineData(false)] + [InlineData(true)] + public void GivenFailureWhenInstallLocalToolsItWillRollbackPackageVersion(bool testMockBehaviorIsInSync) + { + var source = GetTestLocalFeedPath(); + + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( + useMock: testMockBehaviorIsInSync, + feeds: GetMockFeedsForSource(source)); + + static void FailedStepAfterSuccessDownload() => throw new GracefulException("simulated error"); + + Action a = () => + { + using (var t = new TransactionScope( + TransactionScopeOption.Required, + TimeSpan.Zero)) + { + downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + packageId: TestPackageId, + verbosity: TestVerbosity, + versionRange: VersionRange.Parse(TestPackageVersion), + targetFramework: _testTargetframework); + + FailedStepAfterSuccessDownload(); + t.Complete(); + } + }; + + a.Should().Throw().WithMessage("simulated error"); + + ISettings settings = Settings.LoadDefaultSettings(Directory.GetCurrentDirectory()); + var localToolDownloadDir = Path.Combine(new DirectoryPath(SettingsUtility.GetGlobalPackagesFolder(settings)).ToString().Trim('"'), TestPackageId.ToString()); + fileSystem + .Directory + .Exists(localToolDownloadDir) + .Should() + .BeTrue(); + + fileSystem + .Directory + .EnumerateFileSystemEntries(localToolDownloadDir) + .Should() + .BeEmpty(); + } + + [Theory] + [InlineData(false)] + [InlineData(true)] + public void GivenSecondInstallOfLocalToolItShouldNotThrowException(bool testMockBehaviorIsInSync) + { + var source = GetTestLocalFeedPath(); + + var (store, storeQuery, downloader, uninstaller, reporter, fileSystem) = Setup( + useMock: testMockBehaviorIsInSync, + feeds: GetMockFeedsForSource(source)); + + Action a = () => + { + using (var t = new TransactionScope( + TransactionScopeOption.Required, + TimeSpan.Zero)) + { + Action first = () => downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + packageId: TestPackageId, + verbosity: TestVerbosity, + versionRange: VersionRange.Parse(TestPackageVersion), + targetFramework: _testTargetframework); + + first.Should().NotThrow(); + + Action second = () => downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + packageId: TestPackageId, + verbosity: TestVerbosity, + versionRange: VersionRange.Parse(TestPackageVersion), + targetFramework: _testTargetframework); + + second.Should().NotThrow(); + + t.Complete(); + } + }; + } + [Theory] [InlineData(false)] [InlineData(true)] From 3b9dddce91e92646bca575695a5aea4bbf01a5f9 Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Sun, 17 Sep 2023 23:07:52 -0700 Subject: [PATCH 45/47] update rollback directory test --- .../ToolPackageDownloaderTests.cs | 5 +++-- .../ToolPackageDownloaderMock.cs | 6 +++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs index f45ae76ceef3..f07b1a59ab61 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs @@ -442,11 +442,12 @@ public void GivenFailureWhenInstallLocalToolsItWillRollbackPackageVersion(bool t .Should() .BeTrue(); + var localToolVersionDir = Path.Combine(localToolDownloadDir, TestPackageVersion.ToString()); fileSystem .Directory - .EnumerateFileSystemEntries(localToolDownloadDir) + .Exists(localToolVersionDir) .Should() - .BeEmpty(); + .BeFalse(); } [Theory] diff --git a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs index 07811468486b..8ce41aef115d 100644 --- a/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs +++ b/src/Tests/Microsoft.DotNet.Tools.Tests.ComponentMocks/ToolPackageDownloaderMock.cs @@ -125,6 +125,8 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa var packageVersion = feedPackage.Version; targetFramework = string.IsNullOrEmpty(targetFramework) ? "targetFramework" : targetFramework; + rollbackDirectory = isGlobalTool ? _toolDownloadDir.Value : Path.Combine(_toolDownloadDir.Value, packageId.ToString(), packageVersion.ToString()); + var fakeExecutableSubDirectory = Path.Combine( packageId.ToString().ToLowerInvariant(), packageVersion.ToLowerInvariant(), @@ -163,7 +165,9 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa packageDirectory = new DirectoryPath(NuGetGlobalPackagesFolder.GetLocation()).WithSubDirectories(packageId.ToString()); _fileSystem.Directory.CreateDirectory(packageDirectory.Value); var executable = packageDirectory.WithFile("exe"); - _fileSystem.File.CreateEmptyFile(executable.Value); + _fileSystem.File.CreateEmptyFile(executable.Value); + rollbackDirectory = Path.Combine(packageDirectory.Value, packageVersion); + return new TestToolPackage { From e7568cba9a740a0a9bdfa1c90964ce3fd64f8c2c Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 18 Sep 2023 11:21:37 -0700 Subject: [PATCH 46/47] Adding scope to global tool duplicate download check; clean up te; refine tests in ToolPackageDownloaderTests --- .../ToolPackage/ToolPackageDownloader.cs | 26 ++++++++++--------- .../ToolPackageDownloaderTests.cs | 19 ++++++++------ 2 files changed, 25 insertions(+), 20 deletions(-) diff --git a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs index aea839976f38..674e7fbff105 100644 --- a/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs +++ b/src/Cli/dotnet/ToolPackage/ToolPackageDownloader.cs @@ -68,7 +68,7 @@ public ToolPackageDownloader( } public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId packageId, - VerbosityOptions verbosity, + VerbosityOptions verbosity = VerbosityOptions.normal, VersionRange versionRange = null, string targetFramework = null, bool isGlobalTool = false @@ -95,20 +95,22 @@ public IToolPackage InstallPackage(PackageLocation packageLocation, PackageId pa var packageSourceLocation = new PackageSourceLocation(packageLocation.NugetConfig, packageLocation.RootConfigDirectory, null, packageLocation.AdditionalFeeds); NuGetVersion packageVersion = nugetPackageDownloader.GetBestPackageVersionAsync(packageId, versionRange, packageSourceLocation).GetAwaiter().GetResult(); - rollbackDirectory = isGlobalTool ? toolDownloadDir.Value: Path.Combine(toolDownloadDir.Value, packageId.ToString(), packageVersion.ToString()); + rollbackDirectory = isGlobalTool ? toolDownloadDir.Value: Path.Combine(toolDownloadDir.Value, packageId.ToString(), packageVersion.ToString()); - NuGetv3LocalRepository nugetPackageRootDirectory = new(Path.Combine(_toolPackageStore.GetRootPackageDirectory(packageId).ToString().Trim('"'), packageVersion.ToString())); - var globalPackage = nugetPackageRootDirectory.FindPackage(packageId.ToString(), packageVersion); - - if(isGlobalTool && globalPackage != null) + if (isGlobalTool) { - throw new ToolPackageException( - string.Format( - CommonLocalizableStrings.ToolPackageConflictPackageId, - packageId, - packageVersion.ToNormalizedString())); - } + NuGetv3LocalRepository nugetPackageRootDirectory = new(Path.Combine(_toolPackageStore.GetRootPackageDirectory(packageId).ToString().Trim('"'), packageVersion.ToString())); + var globalPackage = nugetPackageRootDirectory.FindPackage(packageId.ToString(), packageVersion); + if (globalPackage != null) + { + throw new ToolPackageException( + string.Format( + CommonLocalizableStrings.ToolPackageConflictPackageId, + packageId, + packageVersion.ToNormalizedString())); + } + } NuGetv3LocalRepository localRepository = new(toolDownloadDir.Value); var package = localRepository.FindPackage(packageId.ToString(), packageVersion); diff --git a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs index f07b1a59ab61..702ae3ce0142 100644 --- a/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs +++ b/src/Tests/Microsoft.DotNet.PackageInstall.Tests/ToolPackageDownloaderTests.cs @@ -414,6 +414,8 @@ public void GivenFailureWhenInstallLocalToolsItWillRollbackPackageVersion(bool t feeds: GetMockFeedsForSource(source)); static void FailedStepAfterSuccessDownload() => throw new GracefulException("simulated error"); + ISettings settings = Settings.LoadDefaultSettings(Directory.GetCurrentDirectory()); + var localToolDownloadDir = Path.Combine(new DirectoryPath(SettingsUtility.GetGlobalPackagesFolder(settings)).ToString().Trim('"'), TestPackageId.ToString()); Action a = () => { @@ -427,15 +429,19 @@ public void GivenFailureWhenInstallLocalToolsItWillRollbackPackageVersion(bool t versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework); + fileSystem + .Directory + .Exists(localToolDownloadDir) + .Should() + .BeTrue(); + FailedStepAfterSuccessDownload(); t.Complete(); } }; a.Should().Throw().WithMessage("simulated error"); - - ISettings settings = Settings.LoadDefaultSettings(Directory.GetCurrentDirectory()); - var localToolDownloadDir = Path.Combine(new DirectoryPath(SettingsUtility.GetGlobalPackagesFolder(settings)).ToString().Trim('"'), TestPackageId.ToString()); + fileSystem .Directory .Exists(localToolDownloadDir) @@ -467,22 +473,19 @@ public void GivenSecondInstallOfLocalToolItShouldNotThrowException(bool testMock TransactionScopeOption.Required, TimeSpan.Zero)) { - Action first = () => downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework); - first.Should().NotThrow(); - Action second = () => downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), + downloader.InstallPackage(new PackageLocation(additionalFeeds: new[] { source }), packageId: TestPackageId, verbosity: TestVerbosity, versionRange: VersionRange.Parse(TestPackageVersion), targetFramework: _testTargetframework); - second.Should().NotThrow(); - t.Complete(); } }; From 38ee802634f33a5b87693586e6561976fe6122bd Mon Sep 17 00:00:00 2001 From: annie <59816815+JL03-Yue@users.noreply.github.com> Date: Mon, 18 Sep 2023 11:31:33 -0700 Subject: [PATCH 47/47] Include package version in cannot match version error --- src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs index a3630022a4e2..05e05396f90f 100644 --- a/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs +++ b/src/Cli/dotnet/NugetPackageDownloader/NuGetPackageDownloader.cs @@ -448,7 +448,7 @@ await Task.WhenAll( throw new NuGetPackageNotFoundException( string.Format( LocalizableStrings.IsNotFoundInNuGetFeeds, - packageIdentifier, + $"{packageIdentifier}::{versionRange}", string.Join(", ", packageSources.Select(source => source.Source)))); }