Skip to content

Conversation

Copilot
Copy link
Contributor

@Copilot Copilot AI commented Sep 25, 2025

Customer Issue

Customers that read the dnx help are guided into using a package that isn't a tool - leading to an immediate failure when using dnx. We should instead at least provide examples that are invokable via dnx. Thanks to @mikekistler for reporting.

Description

Tiny help text change to suggest different packages in different scenarios.

Testing

Automated snapshot testing.

Risk

Low - only updates strings.

Copilot details

Fixes the issue where dnx --help, dotnet tool install --help, and other tool commands display Newtonsoft.Json as an example package, which is not a valid .NET tool.

@baronfel's note: I've reviewed this change and am happy with it. I need a team member review for the actual merge.

Changes Made

  • Single Format String Approach: Refactored to use a single format string in PackageIdentityArgumentDescription with placeholders {0} and {1} for package name and version, eliminating duplicate resource strings
  • Parameterized CommonArguments: Implemented parameterized methods for package identity arguments that accept example package and version parameters:
    • RequiredPackageIdentityArgument(string examplePackage, string exampleVersion) - parameterized version
    • OptionalPackageIdentityArgument(string examplePackage, string exampleVersion) - parameterized version
    • Backward-compatible overloads maintained for existing callers
  • Context-Specific Examples: Updated tool command parsers to use appropriate examples:
    • Tool commands (install/update/execute/dnx): use "dotnetsay", "2.1.7" parameters
    • Non-tool commands: use "Newtonsoft.Json", "13.0.3" parameters (default)
  • Runtime Formatting: Uses string.Format() to populate placeholders dynamically at runtime
  • Updated CLI Snapshot Baselines: Updated completion test baselines to reflect the new tool examples
  • Documentation: Updated copilot-instructions with the dogfood testing approach for verifying CLI command changes

Commands Affected

All tool-related commands now show appropriate .NET tool examples:

  • dnx --help
  • dotnet tool install --help
  • dotnet tool exec --help
  • dotnet tool execute --help
  • dotnet tool update --help

Non-tool commands continue to use the generic package examples (e.g., dotnet package add --help still shows Newtonsoft.Json@13.0.3).

The changes maintain backward compatibility while providing more helpful and accurate examples for users working with .NET tools. The implementation uses a single source of truth for the format string, making it more maintainable and eliminating duplicate content.

Fixes #51008

Original prompt

This section details on the original issue you should resolve

<issue_title>dnx --help suggests use of a package that is not a .NET SDK Tool</issue_title>
<issue_description>### Describe the bug

dnx --help provides the following help output:

dnx --help
Description:
  Executes a tool from source without permanently installing it.

Usage:
  dotnet dnx <packageId> [<commandArguments>...] [options]

Arguments:
  <packageId>         Package reference in the form of a package identifier like 'Newtonsoft.Json' or package identifier and version separated by '@' like
                      'Newtonsoft.Json@13.0.3'.
  <commandArguments>  Arguments forwarded to the tool

Options:
  --version <VERSION>       The version of the tool package to install.
  -y, --yes                 Accept all confirmation prompts using "yes." [default: False]
  --interactive             Allows the command to stop and wait for user input or action (for example to complete authentication). [default: True]
  --allow-roll-forward      Allow a .NET tool to roll forward to newer versions of the .NET runtime if the runtime it targets isn't installed. [default:
                            False]
  --prerelease              Include pre-release packages. [default: False]
  --configfile <FILE>       The NuGet configuration file to use.
  --source <SOURCE>         Replace all NuGet package sources to use during installation with these.
  --add-source <ADDSOURCE>  Add an additional NuGet package source to use during installation.
  --disable-parallel        Prevent restoring multiple projects in parallel. [default: False]
  --ignore-failed-sources   Treat package source failures as warnings. [default: False]
  --no-http-cache           Do not cache packages and http requests. [default: False]
  -v, --verbosity <LEVEL>   Set the MSBuild verbosity level. Allowed values are q[uiet], m[inimal], n[ormal], d[etailed], and diag[nostic]. [default:
                            normal]
  -?, -h, --help            Show command line help.

The packageId argument's help description calls out Newtonsoft.Json, but this package isn't a valid .NET Tool. We need to make the Description of the shared 'packageId argument structure accept different descriptions, and then provide a better description for the tool-related use cases (dnx, dotnet dnx, dotnet tool exec, dotnet tool install`, etc).

The tool-related examples should use dotnetsay@2.1.7.

This change should be done against the release/10.0.1xx branch.

To Reproduce

Install any 10 preview 7 and above. Run dnx --help.</issue_description>

Comments on the Issue (you are @copilot in this section)

Fixes #51008

Copy link
Contributor

This PR is targeting main, which is now for .NET 11-facing work. If you intended to target .NET 10, either retarget this PR to release/10.0.1xx or make sure you backport the change to release/10.0.1xx after merging. See #50394 for more details.

@baronfel
Copy link
Member

@copilot I noticed that you were getting stuck testing your changes. When you need to test a change to a command, you need to build the new 'redist' SDK, and then use the 'dogfood' scripts to create an environment in which you can easily run the newly created CLI commands.

To build the new redist SDK, you run ./build.sh from the repo root. Then, you can create a new shell environment and source the eng/dogfood.sh script to make that shell environment inherently use the redist SDK. Once you do this, you should see your changes take effect. Try solving this problem and using this information to help you verify. If that works for you, update the copilot-instructions so that you know how to verify CLI changes in the future.

…amples

Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
Copy link
Contributor Author

Copilot AI commented Sep 25, 2025

@copilot I noticed that you were getting stuck testing your changes. When you need to test a change to a command, you need to build the new 'redist' SDK, and then use the 'dogfood' scripts to create a...

Thank you for the guidance on using the dogfood script! I followed your approach:

  1. Built the redist SDK using ./build.sh
  2. Created a dogfood environment by sourcing eng/dogfood.sh
  3. Tested my changes using dotnet tool install --help and dnx --help

The dogfood script works perfectly for testing CLI changes. However, I'm encountering a build/caching issue where the help output still shows the old Newtonsoft.Json examples despite:

  • The resource files containing the correct dotnetsay@2.1.7 examples
  • The generated C# code having the right resource accessors
  • Building and redistributing the CLI components

I've committed the core changes in 7c016c0. The changes are minimal and targeted:

  • Added ToolPackageIdentityArgumentDescription resource with dotnetsay@2.1.7
  • Extended CommonArguments with RequiredToolPackageIdentityArgument()
  • Updated ToolInstallCommandParser to use the tool-specific description

I've also updated the copilot-instructions to document this dogfood testing approach for future CLI changes.

…nges

Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
@Copilot Copilot AI changed the title [WIP] dnx --help suggests use of a package that is not a .NET SDK Tool Fix dnx --help and tool commands to use valid .NET tool examples Sep 25, 2025
Copilot finished work on behalf of baronfel September 25, 2025 14:57
Comment on lines 30 to 37
public static DynamicArgument<PackageIdentityWithRange> RequiredToolPackageIdentityArgument() =>
new("packageId")
{
Description = CliStrings.ToolPackageIdentityArgumentDescription,
CustomParser = (ArgumentResult argumentResult) => ParsePackageIdentityWithVersionSeparator(argumentResult.Tokens[0]?.Value)!.Value,
Arity = ArgumentArity.ExactlyOne,
};

Copy link
Member

Choose a reason for hiding this comment

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

@copilot instead of creating a new parallel packageId argument, use a single shared implementation that takes a description as input. Then update call sites to pass the description that is most appropriate. Don't forget that when you change argument/option names or descriptions, you need to update the cli's snapshot test baselines as well.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored to use a single shared implementation with parameterized description as suggested. The changes in b03b828:

  1. Replaced duplicate methods with parameterized versions:

    • RequiredPackageIdentityArgument(string description)
    • OptionalPackageIdentityArgument(string description)
    • Backward-compatible overloads maintained
  2. Updated call sites to pass appropriate descriptions:

    • Tool commands (install/update/execute/dnx): use CliStrings.ToolPackageIdentityArgumentDescription with dotnetsay@2.1.7
    • Package commands: continue using generic description with Newtonsoft.Json@13.0.3
  3. Updated CLI snapshot baselines using the MSBuild targets - the snapshot tests now pass and show the tool commands correctly use the new examples.

The CLI completion system now properly distinguishes between tool and package contexts while maintaining a clean, shared implementation.

Copilot AI and others added 2 commits September 25, 2025 16:24
…eview feedback

Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
@Copilot Copilot AI requested a review from baronfel September 25, 2025 16:28
Copilot finished work on behalf of baronfel September 25, 2025 16:28
Comment on lines 822 to 824
<data name="ToolPackageIdentityArgumentDescription" xml:space="preserve">
<value>Package reference in the form of a package identifier like 'dotnetsay' or package identifier and version separated by '@' like 'dotnetsay@2.1.7'.</value>
</data>
Copy link
Member

Choose a reason for hiding this comment

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

@copilot I'm going to nitpick once again. Instead of separate Description strings for tool packages and non-tool-packages, make a single format string with placeholders for a package id and version, and then update the callsites to use the templated format string, passing in the existing/appropriate package id and version.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Refactored to use a single format string with placeholders as suggested. Changes in bc0f3a2:

  1. Single format string: Replaced duplicate resource strings with PackageIdentityArgumentDescription using {0} and {1} placeholders
  2. Updated method signatures: Changed CommonArguments methods to accept examplePackage and exampleVersion parameters
  3. Context-specific examples:
    • Tool commands: "dotnetsay", "2.1.7"
    • Non-tool commands: "Newtonsoft.Json", "13.0.3" (default)
  4. Runtime formatting: Uses string.Format() to populate placeholders

This eliminates the duplicate resource string while maintaining clean separation between contexts through parameterization.

…ce strings

Co-authored-by: baronfel <573979+baronfel@users.noreply.github.com>
@Copilot Copilot AI requested a review from baronfel September 25, 2025 17:34
Copilot finished work on behalf of baronfel September 25, 2025 17:34
@baronfel baronfel requested a review from a team September 25, 2025 17:42
@baronfel baronfel marked this pull request as ready for review September 25, 2025 18:21
@Copilot Copilot AI review requested due to automatic review settings September 25, 2025 18:21
Copy link
Contributor

@Copilot Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull Request Overview

This PR fixes the issue where dnx --help, dotnet tool install --help, and other tool commands display Newtonsoft.Json as an example package, which is not a valid .NET tool. The changes implement a parameterized approach to package identity argument descriptions, allowing different examples based on context.

  • Refactored PackageIdentityArgumentDescription to use placeholders {0} and {1} for dynamic package name and version examples
  • Added parameterized overloads to CommonArguments methods while maintaining backward compatibility
  • Updated tool command parsers to use appropriate .NET tool examples (dotnetsay@2.1.7)

Reviewed Changes

Copilot reviewed 19 out of 19 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/Cli/dotnet/CliStrings.resx Modified the base resource string to use format placeholders instead of hardcoded examples
src/Cli/dotnet/xlf/*.xlf Updated localization files with new format string and marked as needing translation
src/Cli/dotnet/CommonArguments.cs Added parameterized methods for package identity arguments with example package/version parameters
src/Cli/dotnet/Commands/Tool/Install/ToolInstallCommandParser.cs Updated to use tool-specific examples (dotnetsay@2.1.7)
src/Cli/dotnet/Commands/Tool/Update/ToolUpdateCommandParser.cs Updated to use tool-specific examples (dotnetsay@2.1.7)
test/dotnet.Tests/CompletionTests/snapshots/zsh/DotnetCliSnapshotTests.VerifyCompletions.verified.zsh Updated completion test baseline with new tool examples
.github/copilot-instructions.md Added documentation for dogfood testing approach for CLI changes

@baronfel
Copy link
Member

/backport to release/10.0.1xx

Copy link
Contributor

Started backporting to release/10.0.1xx: https://github.com/dotnet/sdk/actions/runs/18080502142

@baronfel baronfel merged commit 8b95e27 into main Sep 29, 2025
31 of 32 checks passed
@baronfel baronfel deleted the copilot/fix-c0a951d4-e0f3-4238-814b-64deb537b388 branch September 29, 2025 17:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

dnx --help suggests use of a package that is not a .NET SDK Tool

3 participants