Skip to content

Support RID-specific .NET Tool packages #48575

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 86 commits into from
Jun 6, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
86 commits
Select commit Hold shift + click to select a range
b3e952b
Start of support for packing tools with RID-specific packages
dsplaisted Apr 7, 2025
e3bac63
Support packing NativeAot .NET Tools
dsplaisted Apr 8, 2025
839eae4
Start of support for downloading RID-specific tool packages
dsplaisted Apr 10, 2025
54611eb
Copilot WIP
dsplaisted Apr 15, 2025
2b316c3
Copilot WIP
dsplaisted Apr 15, 2025
be491e8
Refactoring
dsplaisted Apr 16, 2025
eb7bd6e
Refactoring global tool installation
dsplaisted Apr 16, 2025
0db06fb
Refactoring local tool installation
dsplaisted Apr 16, 2025
8fff9de
Download RID-specific tool package in ToolPackageDownloader
dsplaisted Apr 17, 2025
2b7d6fc
Handle RID-specific packages for global tools
dsplaisted Apr 17, 2025
c658286
Fix handling tool assets files with RID-less targets
dsplaisted Apr 17, 2025
2825c91
Fix packing tool shims
dsplaisted Apr 23, 2025
e54cbc7
Use transaction helper API for tool install and uninstall
dsplaisted Apr 23, 2025
654cc87
Rename RestoredCommand to ToolCommand
dsplaisted Apr 23, 2025
49c1f3f
Copilot edits: Create ToolPackageDownloaderBase
dsplaisted Apr 24, 2025
96b8f68
Fix copilot: Duplicate ToolPackageDownnloaderBase
dsplaisted Apr 24, 2025
f5be4e9
Make methods non-virtual
dsplaisted Apr 24, 2025
897cd47
Copilot refactoring
dsplaisted Apr 24, 2025
9979e7d
Copilot refactor: remove extra method arguments
dsplaisted Apr 24, 2025
76e11ee
Copilot refactoring
dsplaisted Apr 24, 2025
ad10115
Copilot refactoring
dsplaisted Apr 24, 2025
57f7827
Make DownloadAndExtractPackage an abstract method and move implementa…
dsplaisted Apr 24, 2025
1a3a87e
Make ToolPackageDownlnoader more mockable
dsplaisted Apr 28, 2025
a98b140
More making more mockable
dsplaisted Apr 30, 2025
d59f303
Use test root in ToolPackageDownloaderTests
dsplaisted May 1, 2025
ca05289
Fix mock filesystem issue with additional volume
dsplaisted May 1, 2025
d36bd6b
Delete downloaded package on rollback
dsplaisted May 1, 2025
3879a60
Update to higher major version for test
dsplaisted May 1, 2025
f8a71f5
Create new mock for ToolPackageDownloader
dsplaisted May 7, 2025
e3d0f17
Fix a lot of ToolPackageDownloader mock tests
dsplaisted May 9, 2025
715b05a
ToolPackageDownloader test improvements
dsplaisted May 21, 2025
c7fe91a
Fix ToolPackageDownloaderTests
dsplaisted May 21, 2025
52a876b
Fix nullability
dsplaisted May 21, 2025
a50b825
Support shims in new mock
dsplaisted May 26, 2025
5efe2e3
Fix tool install tests
dsplaisted May 26, 2025
e4b0dab
Fix ToolUpdateGlobalOrToolPathCommandTests
dsplaisted May 26, 2025
ca4cb72
Fix tool uninstall tests
dsplaisted May 27, 2025
e07e506
Fix code formatting calls (CA2241)
dsplaisted May 30, 2025
12617cb
Disable analyzer which is throwing NullReferenceException
dsplaisted May 30, 2025
557f205
Add code to debug what looks like stale NuGet package on CI
dsplaisted Jun 1, 2025
89adcf5
Pass ToolCommand to ShellShimRepository
dsplaisted Jun 1, 2025
18f16d9
Create batch file for tools with runner=executable
dsplaisted Jun 1, 2025
a234b47
Set _IsPublishing when packing a tool
dsplaisted Jun 1, 2025
9e88dfb
Fix tests when running on non-Windows, add more CI debugging
dsplaisted Jun 1, 2025
eae9bc4
Remove test that self-contained tools should fail
dsplaisted Jun 1, 2025
b2c282e
Copilot: Create symbolic link for shims to executable tools
dsplaisted Jun 1, 2025
33e96e1
Clean up copilot code
dsplaisted Jun 1, 2025
a5db0b5
Add CI debugging logging
dsplaisted Jun 1, 2025
910d1f2
Support running local tools with runner type of executable
dsplaisted Jun 1, 2025
4e9346f
Update package type for RID-specific packages, etc
dsplaisted Jun 3, 2025
c1bf6cc
Copilot: Add RemoveTargetFromList target
dsplaisted Jun 3, 2025
a09bc83
Don't build when packing primary tool package that has RID-specific p…
dsplaisted Jun 3, 2025
f7103e6
Copilot refactoring: Use array for output parameter to avoid escaping…
dsplaisted Jun 3, 2025
f258f1e
Copilot: Delete unused ILocalToolsResolverCache.TryLoadHighestVersion…
dsplaisted Jun 3, 2025
39a3a7e
Copilot and comment cleanup
dsplaisted Jun 3, 2025
4a47a53
Copilot: Set TargetFramework folder to "any" for SelfContained tools
dsplaisted Jun 3, 2025
dc47b23
Generate error when trying to use non-tool package as a tool
dsplaisted Jun 3, 2025
c3d9c7e
Remove tool failure restore guidance
dsplaisted Jun 3, 2025
0801775
Better handle config directory for installing local tools
dsplaisted Jun 3, 2025
b738962
Support -r option for dotnet pack
dsplaisted Jun 3, 2025
6f320fd
Copilot: Switch to AddPackageType task for adding DotnetTool package …
dsplaisted Jun 3, 2025
bcb9710
Copilot: Fix task to use lists instead of so much string manipulation
dsplaisted Jun 3, 2025
b052a4c
Fix copilot code and add back comment it removed
dsplaisted Jun 4, 2025
2845c9b
Fix compile error
dsplaisted Jun 4, 2025
efdf6cc
Delete unused code
dsplaisted Jun 4, 2025
e2792ab
Fix bug checking tool package type
dsplaisted Jun 4, 2025
573c959
Fix duplicate --runtime option on pack
dsplaisted Jun 4, 2025
111cee6
Start on new infrastructure to create test dotnet tools
dsplaisted Jun 4, 2025
ff5e754
Copilot: Add method to compare directory contents
dsplaisted Jun 4, 2025
4d0242f
Treat files as text files when comparing
dsplaisted Jun 4, 2025
e375276
Don't add global tools folder to global path in .NET SDK build and te…
dsplaisted Jun 5, 2025
ee217d0
Fix logging of non-dotnet commands in tests
dsplaisted Jun 5, 2025
95ed8fc
Add basic end to end tool tests
dsplaisted Jun 5, 2025
9aa2a74
Fix test on non-Windows
dsplaisted Jun 5, 2025
5914521
Fix test (hopefully)
dsplaisted Jun 5, 2025
6c6bf33
Fix issues with ToolTestBuilder
dsplaisted Jun 5, 2025
e296230
Update completions for pack -r option
dsplaisted Jun 5, 2025
acd52ee
Use current working directory for NuGet sources
dsplaisted Jun 5, 2025
846fa13
Attempt to fix test in CI
dsplaisted Jun 5, 2025
78a0509
Fix test
dsplaisted Jun 5, 2025
b6b1c58
Try to fix test in CI
dsplaisted Jun 6, 2025
b76fd91
Localize exception message
dsplaisted Jun 6, 2025
efcdd4a
Fix exception message
dsplaisted Jun 6, 2025
fac0117
Address / remove TODOs
dsplaisted Jun 6, 2025
922242b
Apply code review feedback
dsplaisted Jun 6, 2025
ce1bba1
Improve tests
dsplaisted Jun 6, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions eng/dogfood.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ try {

$env:PATH = "$TestDotnetRoot;$env:Path"
$env:DOTNET_ROOT = $TestDotnetRoot
$env:DOTNET_ADD_GLOBAL_TOOLS_TO_PATH="0"

# Avoid downloading Microsoft.Net.Sdk.Compilers.Toolset from feed
# Locally built SDK package version is Major.Minor.0-dev, which won't be available.
Expand Down
1 change: 1 addition & 0 deletions eng/dogfood.sh
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,5 @@ export MicrosoftNETBuildExtensionsTargets="$artifacts_dir/bin/$configuration/Sdk

export PATH=$testDotnetRoot:$PATH
export DOTNET_ROOT=$testDotnetRoot
export DOTNET_ADD_GLOBAL_TOOLS_TO_PATH=0
export PS1="(dogfood) $PS1"
2 changes: 2 additions & 0 deletions eng/restore-toolset.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,7 @@ set DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=$env:DOTNET_INSTALL_DIR

set PATH=$env:DOTNET_INSTALL_DIR;%PATH%
set NUGET_PACKAGES=$env:NUGET_PACKAGES
set DOTNET_ADD_GLOBAL_TOOLS_TO_PATH=0

DOSKEY killdotnet=taskkill /F /IM dotnet.exe /T ^& taskkill /F /IM VSTest.Console.exe /T ^& taskkill /F /IM msbuild.exe /T
"@
Expand All @@ -70,6 +71,7 @@ DOSKEY killdotnet=taskkill /F /IM dotnet.exe /T ^& taskkill /F /IM VSTest.Consol

`$env:PATH="$env:DOTNET_INSTALL_DIR;" + `$env:PATH
`$env:NUGET_PACKAGES="$env:NUGET_PACKAGES"
`$env:DOTNET_ADD_GLOBAL_TOOLS_TO_PATH="0"

function killdotnet {
taskkill /F /IM dotnet.exe /T
Expand Down
1 change: 1 addition & 0 deletions eng/restore-toolset.sh
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ export DOTNET_MSBUILD_SDK_RESOLVER_CLI_DIR=$DOTNET_INSTALL_DIR

export PATH=$DOTNET_INSTALL_DIR:\$PATH
export NUGET_PACKAGES=$NUGET_PACKAGES
export DOTNET_ADD_GLOBAL_TOOLS_TO_PATH=0
"

echo "$scriptContents" > ${scriptPath}
Expand Down
11 changes: 10 additions & 1 deletion src/Cli/dotnet/CliStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -319,6 +319,9 @@
<data name="ToolSettingsUnsupportedRunner" xml:space="preserve">
<value>Command '{0}' uses unsupported runner '{1}'."</value>
</data>
<data name="ToolUnsupportedRuntimeIdentifier" xml:space="preserve">
<value>The tool does not support the current architecture or operating system ({0}). Supported runtimes: {1}</value>
</data>
<data name="ShellShimConflict" xml:space="preserve">
<value>Command '{0}' conflicts with an existing command from another tool.</value>
</data>
Expand Down Expand Up @@ -413,6 +416,9 @@ setx PATH "%PATH%;{0}"
<data name="ToolPackageConflictPackageId" xml:space="preserve">
<value>Tool '{0}' (version '{1}') is already installed.</value>
</data>
<data name="ToolPackageNotATool" xml:space="preserve">
<value>Package {0} is not a .NET tool.</value>
</data>
<data name="FailedToFindStagedToolPackage" xml:space="preserve">
<value>Failed to find staged tool package '{0}'.</value>
</data>
Expand All @@ -435,7 +441,10 @@ setx PATH "%PATH%;{0}"
<value>More than one packaged shim is available: {0}.</value>
</data>
<data name="FailedToReadNuGetLockFile" xml:space="preserve">
<value>Failed to read NuGet LockFile for tool package '{0}': {1}</value>
<value>Failed to read NuGet assets file for tool package '{0}': {1}</value>
</data>
<data name="FailedToFindLibraryInAssetsFile" xml:space="preserve">
<value>Failed to find library in NuGet assets file for tool package '{0}': {1}</value>
</data>
<data name="LevelArgumentName" xml:space="preserve">
<value>LEVEL</value>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using Microsoft.DotNet.Cli.ToolPackage;
using Microsoft.DotNet.Cli.Utils;
using Microsoft.Extensions.EnvironmentAbstractions;
using NuGet.DependencyResolver;
using NuGet.Frameworks;

namespace Microsoft.DotNet.Cli.CommandFactory.CommandResolution;
Expand Down Expand Up @@ -82,22 +83,39 @@ private CommandSpec GetPackageCommandSpecUsingMuxer(CommandResolverArguments arg
NuGetFramework.Parse(BundledTargetFramework.GetTargetFrameworkMoniker()),
Constants.AnyRid,
toolCommandName),
out var restoredCommand))
out var toolCommand))
{
if (!_fileSystem.File.Exists(restoredCommand.Executable.Value))
if (!_fileSystem.File.Exists(toolCommand.Executable.Value))
{
throw new GracefulException(string.Format(CliStrings.NeedRunToolRestore,
toolCommandName.ToString()));
}

if (toolManifestPackage.RollForward || allowRollForward)
if (toolCommand.Runner == "dotnet")
{
arguments.CommandArguments = ["--allow-roll-forward", .. arguments.CommandArguments];
if (toolManifestPackage.RollForward || allowRollForward)
{
arguments.CommandArguments = ["--allow-roll-forward", .. arguments.CommandArguments];
}

return MuxerCommandSpecMaker.CreatePackageCommandSpecUsingMuxer(
toolCommand.Executable.Value,
arguments.CommandArguments);
}
else if (toolCommand.Runner == "executable")
{
var escapedArgs = ArgumentEscaper.EscapeAndConcatenateArgArrayForProcessStart(
arguments.CommandArguments);

return MuxerCommandSpecMaker.CreatePackageCommandSpecUsingMuxer(
restoredCommand.Executable.Value,
arguments.CommandArguments);
return new CommandSpec(
toolCommand.Executable.Value,
escapedArgs);
}
else
{
throw new GracefulException(string.Format(CliStrings.ToolSettingsUnsupportedRunner,
toolCommand.Name, toolCommand.Runner));
}
}
else
{
Expand Down
12 changes: 1 addition & 11 deletions src/Cli/dotnet/Commands/CliCommandStrings.resx
Original file line number Diff line number Diff line change
Expand Up @@ -1938,16 +1938,6 @@ Your project targets multiple frameworks. Specify which framework to run using '
<data name="ToolInstallationFailedContactAuthor" xml:space="preserve">
<value>Tool '{0}' failed to install. Contact the tool author for assistance.</value>
</data>
<data name="ToolInstallationFailedWithRestoreGuidance" xml:space="preserve">
<value>Tool '{0}' failed to install. This failure may have been caused by:

* You are attempting to install a preview release and did not use the --version option to specify the version.
* A package by this name was found, but it was not a .NET tool.
* The required NuGet feed cannot be accessed, perhaps because of an Internet connection problem.
* You mistyped the name of the tool.

For more reasons, including package naming enforcement, visit https://aka.ms/failure-installing-tool</value>
</data>
<data name="ToolInstallationRestoreFailed" xml:space="preserve">
<value>The tool package could not be restored.</value>
</data>
Expand Down Expand Up @@ -2486,4 +2476,4 @@ To display a value, specify the corresponding command-line option without provid
<data name="SolutionAddReferencedProjectsOptionDescription" xml:space="preserve">
<value>Recursively add projects' ReferencedProjects to solution</value>
</data>
</root>
</root>
5 changes: 4 additions & 1 deletion src/Cli/dotnet/Commands/Pack/PackCommandParser.cs
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,10 @@ private static Command ConstructCommand()
command.Options.Add(CommonOptions.VersionSuffixOption);
command.Options.Add(ConfigurationOption);
command.Options.Add(CommonOptions.DisableBuildServersOption);
RestoreCommandParser.AddImplicitRestoreOptions(command, includeRuntimeOption: true, includeNoDependenciesOption: true);

// Don't include runtime option because we want to include it specifically and allow the short version ("-r") to be used
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for this comment, it was helpful 👍

RestoreCommandParser.AddImplicitRestoreOptions(command, includeRuntimeOption: false, includeNoDependenciesOption: true);
command.Options.Add(CommonOptions.RuntimeOption(CliCommandStrings.BuildRuntimeOptionDescription));

command.SetAction(PackCommand.Run);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ public static void SaveToolPackage(
}

localToolsResolverCache.Save(
new Dictionary<RestoredCommandIdentifier, RestoredCommand>
new Dictionary<RestoredCommandIdentifier, ToolCommand>
{
[new RestoredCommandIdentifier(
toolDownloadedPackage.Id,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,7 @@ internal static class InstallToolCommandLowLevelErrorConverter
{
public static IEnumerable<string> GetUserFacingMessages(Exception ex, PackageId packageId)
{
if (ex is ToolPackageException)
{
yield return ex.Message;
yield return string.Format(CliCommandStrings.ToolInstallationFailedWithRestoreGuidance, packageId);
}
else if (ex is ToolConfigurationException)
if (ex is ToolConfigurationException)
{
yield return string.Format(CliCommandStrings.InvalidToolConfiguration, ex.Message);
yield return string.Format(CliCommandStrings.ToolInstallationFailedContactAuthor, packageId);
Expand All @@ -31,8 +26,7 @@ public static IEnumerable<string> GetUserFacingMessages(Exception ex, PackageId

public static bool ShouldConvertToUserFacingError(Exception ex)
{
return ex is ToolPackageException
|| ex is ToolConfigurationException
return ex is ToolConfigurationException
|| ex is ShellShimException;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ public ToolInstallGlobalOrToolPathCommand(
var tempDir = new DirectoryPath(PathUtilities.CreateTempSubdirectory());
var configOption = parseResult.GetValue(ToolInstallCommandParser.ConfigOption);
var sourceOption = parseResult.GetValue(ToolInstallCommandParser.AddSourceOption);
var packageSourceLocation = new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), additionalSourceFeeds: sourceOption);
var packageSourceLocation = new PackageSourceLocation(string.IsNullOrEmpty(configOption) ? null : new FilePath(configOption), additionalSourceFeeds: sourceOption, basePath: _currentWorkingDirectory);
restoreActionConfig = new RestoreActionConfig(DisableParallel: parseResult.GetValue(ToolCommandRestorePassThroughOptions.DisableParallelOption),
NoCache: parseResult.GetValue(ToolCommandRestorePassThroughOptions.NoCacheOption) || parseResult.GetValue(ToolCommandRestorePassThroughOptions.NoHttpCacheOption),
IgnoreFailedSources: parseResult.GetValue(ToolCommandRestorePassThroughOptions.IgnoreFailedSourcesOption),
Expand Down Expand Up @@ -175,15 +175,13 @@ private int ExecuteInstallCommand(PackageId packageId)
}
}

using (var scope = new TransactionScope(
TransactionScopeOption.Required,
TimeSpan.Zero))
TransactionalAction.Run(() =>
{
if (oldPackageNullable != null)
{
RunWithHandlingUninstallError(() =>
{
shellShimRepository.RemoveShim(oldPackageNullable.Command.Name);
shellShimRepository.RemoveShim(oldPackageNullable.Command);
toolPackageUninstaller.Uninstall(oldPackageNullable.PackageDirectory);
}, packageId);
}
Expand Down Expand Up @@ -219,7 +217,7 @@ private int ExecuteInstallCommand(PackageId packageId)
}
string appHostSourceDirectory = _shellShimTemplateFinder.ResolveAppHostSourceDirectoryAsync(_architectureOption, framework, RuntimeInformation.ProcessArchitecture).Result;

shellShimRepository.CreateShim(newInstalledPackage.Command.Executable, newInstalledPackage.Command.Name, newInstalledPackage.PackagedShims);
shellShimRepository.CreateShim(newInstalledPackage.Command, newInstalledPackage.PackagedShims);

foreach (string w in newInstalledPackage.Warnings)
{
Expand All @@ -232,10 +230,7 @@ private int ExecuteInstallCommand(PackageId packageId)

PrintSuccessMessage(oldPackageNullable, newInstalledPackage);
}, packageId);

scope.Complete();

}
});
return 0;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -66,11 +66,17 @@ public IToolPackage Install(FilePath manifestFile, PackageId packageId)

try
{
// NOTE: The manifest file may or may not be under a .config folder. If it is, we will use
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Are these comments split up due to the line length linter limit? It would be easier to read if it was a sentence per line.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I usually manually word wrap my comments at roughly the line length of the surrounding code.

// that directory as the root config directory. This should be OK, as usually there won't be
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: Extra space in the comment

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you mean after the period? I often put two spaces after the end of a sentence as that's what I learned when I was learning to type (on a mechanical typewriter!).

// a NuGet.config in the .config folder, and if there is it's better to use it than to go one
// more level up and miss the root repo folder if the manifest file is not under a .config folder.
var rootConfigDirectory = manifestFile.GetDirectoryPath();

IToolPackage toolDownloadedPackage = _toolPackageDownloader.InstallPackage(
new PackageLocation(
nugetConfig: configFile,
additionalFeeds: _sources,
rootConfigDirectory: manifestFile.GetDirectoryPath().GetParentPath()),
rootConfigDirectory: rootConfigDirectory),
packageId,
verbosity: _verbosity,
versionRange,
Expand Down
16 changes: 8 additions & 8 deletions src/Cli/dotnet/Commands/Tool/Restore/ToolRestoreCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -108,7 +108,7 @@ [.. packagesFromManifest
.AsEnumerable()
.Select(package => InstallPackages(package, configFile))];

Dictionary<RestoredCommandIdentifier, RestoredCommand> downloaded =
Dictionary<RestoredCommandIdentifier, ToolCommand> downloaded =
toolRestoreResults.SelectMany(result => result.SaveToCache)
.ToDictionary(pair => pair.Item1, pair => pair.Item2);

Expand Down Expand Up @@ -216,7 +216,7 @@ private int PrintConclusionAndReturn(ToolRestoreResult[] toolRestoreResults)

private static bool ManifestCommandMatchesActualInPackage(
ToolCommandName[] commandsFromManifest,
IReadOnlyList<RestoredCommand> toolPackageCommands)
IReadOnlyList<ToolCommand> toolPackageCommands)
{
ToolCommandName[] commandsFromPackage = [.. toolPackageCommands.Select(t => t.Name)];
foreach (var command in commandsFromManifest)
Expand Down Expand Up @@ -251,8 +251,8 @@ private bool PackageHasBeenRestored(

return _localToolsResolverCache.TryLoad(
sampleRestoredCommandIdentifierOfThePackage,
out var restoredCommand)
&& _fileSystem.File.Exists(restoredCommand.Executable.Value);
out var toolCommand)
&& _fileSystem.File.Exists(toolCommand.Executable.Value);
}

private FilePath? GetCustomManifestFileLocation()
Expand All @@ -271,7 +271,7 @@ private bool PackageHasBeenRestored(
return customManifestFileLocation;
}

private static void EnsureNoCommandNameCollision(Dictionary<RestoredCommandIdentifier, RestoredCommand> dictionary)
private static void EnsureNoCommandNameCollision(Dictionary<RestoredCommandIdentifier, ToolCommand> dictionary)
{
string[] errors = [.. dictionary
.Select(pair => (pair.Key.PackageId, pair.Key.CommandName))
Expand Down Expand Up @@ -308,12 +308,12 @@ private static VersionRange ToVersionRangeWithOnlyOneVersion(NuGetVersion versio

private struct ToolRestoreResult
{
public (RestoredCommandIdentifier, RestoredCommand)[] SaveToCache { get; }
public (RestoredCommandIdentifier, ToolCommand)[] SaveToCache { get; }
public bool IsSuccess { get; }
public string Message { get; }

private ToolRestoreResult(
(RestoredCommandIdentifier, RestoredCommand)[] saveToCache,
(RestoredCommandIdentifier, ToolCommand)[] saveToCache,
bool isSuccess, string message)
{
if (string.IsNullOrWhiteSpace(message))
Expand All @@ -327,7 +327,7 @@ private ToolRestoreResult(
}

public static ToolRestoreResult Success(
(RestoredCommandIdentifier, RestoredCommand)[] saveToCache,
(RestoredCommandIdentifier, ToolCommand)[] saveToCache,
string message)
{
return new ToolRestoreResult(saveToCache, true, message);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,16 +70,12 @@ public override int Execute()

try
{
using (var scope = new TransactionScope(
TransactionScopeOption.Required,
TimeSpan.Zero))
TransactionalAction.Run(() =>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like this new TransactionalAction refactor! Thank you!

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, we were already using TransactionalAction in other places, this makes it more consistent and easier to find all the places that participate in the transaction.

{
shellShimRepository.RemoveShim(package.Command.Name);
shellShimRepository.RemoveShim(package.Command);

toolPackageUninstaller.Uninstall(package.PackageDirectory);

scope.Complete();
}
});

_reporter.WriteLine(
string.Format(
Expand Down
19 changes: 0 additions & 19 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.cs.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

19 changes: 0 additions & 19 deletions src/Cli/dotnet/Commands/xlf/CliCommandStrings.de.xlf

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading