Skip to content

dotnet package list command should restore first #47400

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

Closed
wants to merge 6 commits into from

Conversation

Nigusu-Allehu
Copy link
Member

@Nigusu-Allehu Nigusu-Allehu commented Mar 9, 2025

Fixes: NuGet/Home#13406

Description

This PR

@ghost ghost added Area-Infrastructure untriaged Request triage from a team member labels Mar 9, 2025
@Nigusu-Allehu Nigusu-Allehu self-assigned this Mar 9, 2025
@Nigusu-Allehu Nigusu-Allehu changed the title Implicit restore dotnet list package dotnet package list command should restore first Mar 10, 2025
// Licensed to the .NET Foundation under one or more agreements.
// The .NET Foundation licenses this file to you under the MIT license.

#nullable disable
Copy link
Member Author

Choose a reason for hiding this comment

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

These tests are copied from dotnet-list-package.Tests\GivenDotnetListPackage.cs. They are the same commands. #45384

@Nigusu-Allehu Nigusu-Allehu marked this pull request as ready for review March 10, 2025 22:48
@Nigusu-Allehu Nigusu-Allehu requested a review from a team as a code owner March 10, 2025 22:48
<value>Do not restore before running the command.</value>
</data>
<data name="Error_restore" xml:space="preserve">
<value>Restore failed. Please try running `dotnet restore`.</value>
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm wondering if the Please try running dotnet restore`` is the right action to suggest to the user.
I'd expect that restore fails as well.

Copy link
Member Author

Choose a reason for hiding this comment

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

Good point! I see how the message could be misleading, as it might imply that running dotnet restore would necessarily fix the issue. A more accurate message could be:
"Restore failed. Run dotnet restore for more details on the issue."

Copy link
Contributor

Choose a reason for hiding this comment

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

After this change, how does the restore error appear?

Basically, can you show us a full output of a dotnet list package call that has a failed restore (say becausie a package does not exist).

Copy link
Member Author

Choose a reason for hiding this comment

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

It would look as follows

Restore failed. Please try running dotnet restore.

Restore is executed with the "-noConsoleLogger" option to suppress all logging from the restore process. This ensures that restore messages do not interfere with the package listing logs. If restore fails, we detect it via the exit code and log an error message.

The primary reason for suppressing restore logs is to prevent them from disrupting structured outputs, such as when the user specifies --format json, where additional messages could result in invalid JSON. Given this, the approach is to avoid logging any restore output and, in case of failure, simply inform the user and recommend running dotnet restore to investigate the issue.

Copy link
Contributor

Choose a reason for hiding this comment

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

If a user specifies --format json and we put this custom error, doesn't that still break the structured log?
It's going to be pretty challenging to chain the commands and get the output.

Copy link
Contributor

Choose a reason for hiding this comment

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

Hmm, that complicates the integration effectively, cause we'd need to write that from this code right, not the NuGet side code.

Is there a way we can "capture" the logs?

Copy link
Member Author

Choose a reason for hiding this comment

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

We could have it on the nuget side by forwarding through an option like
--restore-failed and do the logging from xplat

Copy link
Contributor

Choose a reason for hiding this comment

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

@dotnet/nuget-team thoughts?

Copy link
Member

Choose a reason for hiding this comment

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

My opinion is that dotnet add package already knows how to restore, dotnet package update is going to need to as well, and dotnet nuget why also needs it, in addition to dotnet list package. I think we should make the effort to do everything in the NuGet.Client repo, which also makes it easier for us to test. Splitting our business logic across multiple repos increases tech debt.

Copy link
Member Author

Choose a reason for hiding this comment

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

For all these commands, we could move their invocation methods into the NuGet.Client repo, allowing the SDK to call these methods directly instead of forwarding command arguments to xplat.

By doing so, we can introduce a wrapper on the SDK side—let’s call it RestoringCommandsWrapper. This class would ensure that restore operations execute before any dependent command runs.

Example:
Instead of directly executing commands like dotnet nuget why, we could wrap them in a RestoringCommandsWrapper:

public class RestoringCommandsWrapper
{
    public static void Execute()
    {
        // Execute restore first
        RestoreCommand.Execute();

        // Execute the actual command
        command(argss);
    }
}

Then, for commands like dotnet nuget why, we would update the invocation to:

RestoringCommandsWrapper.Execute(() => 
    NuGet.CommandLine.XPlat.Commands.Why.WhyCommand.RunWhyCommand(whyArgs), whyArgs);

Currently, for dotnet nuget why, we invoke a method on the client side that adds nuget why to the root command:

NuGet.CommandLine.XPlat.Commands.Why.WhyCommand.GetWhyCommand(command);

Instead of this approach, we could perform all parsing on the SDK side and use:

NuGet.CommandLine.XPlat.Commands.Why.WhyCommand.RunWhyCommand(whyArgs);

If why is a restoring command, we could use the RestoringCommandsWrapper to ensure restore runs before executing the command.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Infrastructure untriaged Request triage from a team member
Projects
None yet
Development

Successfully merging this pull request may close these issues.

dotnet list package doesn't restore
3 participants