Skip to content
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

Showing Mutiple Examples #1180

Closed
RealDotNetDave opened this issue Feb 22, 2023 · 14 comments · Fixed by #1259
Closed

Showing Mutiple Examples #1180

RealDotNetDave opened this issue Feb 22, 2023 · 14 comments · Fixed by #1259
Assignees
Labels
area-CLI Command-Line Interface bug Something isn't working

Comments

@RealDotNetDave
Copy link

I am setting examples (see below), but when I run the program, I do not see the examples from the backup command. Am I doing something wrong?

//Clean commands
_ = config.AddCommand<CleanCommand>("clean")
.WithExample(new[] { "clean" })
.WithExample(new[] { "clean", "--af", "c:\\temp" })
.WithExample(new[] { "clean", "--addfolder", "c:\\temp" })
.WithExample(new[] { "clean", "--rf", "c:\\temp" })
.WithExample(new[] { "clean", "--removefolder", "c:\\temp" })
;

//Backup commands
_ = config.AddCommand<BackupCommand>("backup")
.WithExample(new[] { "backup" })
.WithExample(new[] { "backup", "--turbo" })
.WithExample(new[] { "backup", "--af", "c:\\temp" })
.WithExample(new[] { "backup", "--addfolder", "c:\\temp" })
.WithExample(new[] { "backup", "--rf", "c:\\temp" })
.WithExample(new[] { "backup", "--removefolder", "c:\\temp" })
;

ScreenShot-1

@cp-prashanthrao
Copy link

@RealDotNetDave Only 5 examples are shown from the commands(when examples are not added at the root). If you can remove few examples from the first command and check, may be it will confirm.

@FrankRay78 FrankRay78 added the area-CLI Command-Line Interface label May 13, 2023
@RealDotNetDave
Copy link
Author

Yes, after removing a few of the examples, the ones for the second command showed up. Is there a 5 example limit?

@patriksvensson
Copy link
Contributor

@RealDotNetDave If the example isn't specific to the current command, the max number of examples is 5: https://github.com/spectreconsole/spectre.console/blob/main/src/Spectre.Console.Cli/Internal/HelpWriter.cs#L186

@RealDotNetDave
Copy link
Author

Oh, I did not see that. Thanks.

@RealDotNetDave
Copy link
Author

How do I get the examples to show up when someone uses --help?

@patriksvensson
Copy link
Contributor

Running spargine backup --help will show all examples for the backup command.
Maybe we could add some mechanism to provide explicit top-level help examples.

@patriksvensson
Copy link
Contributor

@FrankRay78 What are your thoughts on this?

@RealDotNetDave
Copy link
Author

When I removed the examples, they stopped showing up when I run --help. Maybe WithExample needs a flag on where to show it?

@FrankRay78
Copy link
Contributor

There are a few bugs/feature requests related to examples, branches and help. Somewhat overlapping in functionality. Now that the 0.47.0 release is out of the way I'm happy to spend some time this week looking into this and the others. I can provide an update once I've made some progress investigating... perhaps also prepare a branch for you to test on @RealDotNetDave

@FrankRay78
Copy link
Contributor

Update: I've cleared my backlog of open-source issues and can look at this next.

@FrankRay78 FrankRay78 self-assigned this May 25, 2023
@FrankRay78
Copy link
Contributor

FrankRay78 commented May 26, 2023

So, I've had a proper look at this now...

Issue 1. Max 5 examples

There is an arbitary restriction of displaying only 5 examples (as highlighted above), which could easily be made configurable if required. Let me know if that would be useful @RealDotNetDave .

Issue 2. Display examples in an intuitive and user-friendly manner

The behaviour I would generally expect for displaying examples is that only examples relating to the specified command to be shown, and if at the root, then the examples added through config.AddExample() to be shown. eg.

Scenarios

  1. spargine should execute the default command (if set) or alternatively behaves the same as spargine --help (see next line)
  2. spargine --help to display any examples added by config.AddExample() [Notes 1]
  3. spargine clean --help to display any examples chained to the AddCommand<CleanCommand>("clean") by WithExample(...)
  4. spargine backup --help to display any examples chained to the AddCommand<BackupCommand>("backup") by WithExample(...)

Notes

  1. app.SetDefaultCommand<EchoCommand>() doesn't have an extension method for .WithExample(), these must be added by calling config.AddExample() instead. I'm not sure how I feel about this, it kind of makes sense adding root-level examples through the config object, alternatively it would be more consistent and probably less confusing for users if examples can only be directly added to their command, even the default command

Testing how examples are displayed in scenarios 1 - 4 above

I used the following console app code to 'replicate' @RealDotNetDave's application:

using Spectre.Console;
using Spectre.Console.Cli;

public class Program
{
    public static void Main(string[] args)
    {
        var app = new CommandApp();

        app.SetDefaultCommand<EchoCommand>();

        app.Configure(config =>
        {
            config.PropagateExceptions();

            config.AddExample("xyz", "--argument1");
            config.AddExample("xyz", "--argument1", "--argument2");

            //Clean commands
            config.AddCommand<EchoCommand>("clean")
                .WithDescription("Clean temp and cached files generated by Visual Studio, SQL Server and more")
                .WithExample(new[] { "clean" })
                .WithExample(new[] { "clean", "--af", "c:\\temp" })
                .WithExample(new[] { "clean", "--addfolder", "c:\\temp" })
                .WithExample(new[] { "clean", "--rf", "c:\\temp" })
                .WithExample(new[] { "clean", "--removefolder", "c:\\temp" })
                .WithExample(new[] { "clean", "--sixth-example-to-demonstrate-truncation" });

            //Backup commands
            config.AddCommand<EchoCommand>("backup")
                .WithDescription("Backup code of Visual Studio solutions")
                .WithExample(new[] { "backup" })
                .WithExample(new[] { "backup", "--turbo" })
                .WithExample(new[] { "backup", "--af", "c:\\temp" })
                .WithExample(new[] { "backup", "--addfolder", "c:\\temp" })
                .WithExample(new[] { "backup", "--rf", "c:\\temp" })
                .WithExample(new[] { "backup", "--removefolder", "c:\\temp" })
                .WithExample(new[] { "backup", "--sixth-example-to-demonstrate-truncation" });
        });

        app.Run(args);
    }
}

public class EchoCommand : Command
{
    private readonly IAnsiConsole _console;

    public EchoCommand(IAnsiConsole console)
    {
        _console = console;
    }

    public override int Execute(CommandContext context)
    {
        _console.WriteLine($"Command: {context.Name}");
        return 0;
    }
}

I commented out/uncommented the following sections to exercise all 4 combinations, compiling and running scenarios 1 - 4 above each time to fully exercise spectre.console's handling of examples:

image

Outcome

Scenarios 1 - 4 above generally behaved as expected (ie. only examples relating to the specified command to be shown), except for the following issues which were discovered:

(nb. with regard to the following screenshots, my console app is called ConsoleApp2 rather than spargine)

Issue 1. Examples for child commands are incorrectly showing

With the following main function, compile the console application.

    public static void Main(string[] args)
    {
        var app = new CommandApp();

        //app.SetDefaultCommand<EchoCommand>();

        app.Configure(config =>
        {
            config.PropagateExceptions();

            //config.AddExample("xyz", "--argument1");
            //config.AddExample("xyz", "--argument1", "--argument2");

            //Clean commands
            config.AddCommand<EchoCommand>("clean")
                .WithDescription("Clean temp and cached files generated by Visual Studio, SQL Server and more")
                .WithExample(new[] { "clean" })
                .WithExample(new[] { "clean", "--af", "c:\\temp" })
                .WithExample(new[] { "clean", "--addfolder", "c:\\temp" })
                .WithExample(new[] { "clean", "--rf", "c:\\temp" })
                .WithExample(new[] { "clean", "--removefolder", "c:\\temp" })
                .WithExample(new[] { "clean", "--sixth-example-to-demonstrate-truncation" });

            //Backup commands
            config.AddCommand<EchoCommand>("backup")
                .WithDescription("Backup code of Visual Studio solutions")
                .WithExample(new[] { "backup" })
                .WithExample(new[] { "backup", "--turbo" })
                .WithExample(new[] { "backup", "--af", "c:\\temp" })
                .WithExample(new[] { "backup", "--addfolder", "c:\\temp" })
                .WithExample(new[] { "backup", "--rf", "c:\\temp" })
                .WithExample(new[] { "backup", "--removefolder", "c:\\temp" })
                .WithExample(new[] { "backup", "--sixth-example-to-demonstrate-truncation" });
        });

        app.Run(args);
    }

Run ConsoleApp2.exe --help

Actual result

Yikes, it arbitrarily/incorrectly displays the examples for the clean command:

image

Expected result

It should not display any examples (ie. it should be the same behaviour for when the default command has been added but without any examples):

image

Issue 2. Command argument missing, version option missing

With the following main function, compile the console application.

    public static void Main(string[] args)
    {
        var app = new CommandApp();

        app.SetDefaultCommand<EchoCommand>(); // <-- UNCOMMENTED

        app.Configure(config =>
        {
            config.PropagateExceptions();

            //config.AddExample("xyz", "--argument1");
            //config.AddExample("xyz", "--argument1", "--argument2");

            //Clean commands
            config.AddCommand<EchoCommand>("clean")
                .WithDescription("Clean temp and cached files generated by Visual Studio, SQL Server and more")
                .WithExample(new[] { "clean" })
                .WithExample(new[] { "clean", "--af", "c:\\temp" })
                .WithExample(new[] { "clean", "--addfolder", "c:\\temp" })
                .WithExample(new[] { "clean", "--rf", "c:\\temp" })
                .WithExample(new[] { "clean", "--removefolder", "c:\\temp" })
                .WithExample(new[] { "clean", "--sixth-example-to-demonstrate-truncation" });

            //Backup commands
            config.AddCommand<EchoCommand>("backup")
                .WithDescription("Backup code of Visual Studio solutions")
                .WithExample(new[] { "backup" })
                .WithExample(new[] { "backup", "--turbo" })
                .WithExample(new[] { "backup", "--af", "c:\\temp" })
                .WithExample(new[] { "backup", "--addfolder", "c:\\temp" })
                .WithExample(new[] { "backup", "--rf", "c:\\temp" })
                .WithExample(new[] { "backup", "--removefolder", "c:\\temp" })
                .WithExample(new[] { "backup", "--sixth-example-to-demonstrate-truncation" });
        });

        app.Run(args);
    }

Run ConsoleApp2.exe --help

Actual result

The help text does not include a placeholder for commands and also the version option is missing

image

Expected result

image

@FrankRay78 FrankRay78 linked a pull request Jul 5, 2023 that will close this issue
@FrankRay78 FrankRay78 linked a pull request Sep 2, 2023 that will close this issue
@github-project-automation github-project-automation bot moved this from Todo 🕑 to Done 🚀 in Spectre Console Sep 8, 2023
@RealDotNetDave
Copy link
Author

I finally got back around to this. I changed the configuration to this:
Screen Grab
But it's still cutting anything after 5 WithExample:
SCREEN GRAB1
Please let me know if you need anything else to fix this.

@FrankRay78
Copy link
Contributor

There is an arbitary restriction of displaying only 5 examples (as highlighted above), which could easily be made configurable if required. Let me know if that would be useful @RealDotNetDave.

Sounds like lifting this restriction is what you are after.

@FrankRay78 FrankRay78 reopened this Jul 31, 2024
@github-project-automation github-project-automation bot moved this from Done 🚀 to In Progress 👨‍💻 in Spectre Console Jul 31, 2024
@FrankRay78
Copy link
Contributor

This should be fixed already @RealDotNetDave, the default number of examples shown (across child commands at the same level) is 5 (to retain backward compatibility), however there is now the ability to override this. eg

//nb. show 8 examples
config.Settings.MaximumIndirectExamples = 8; 

There is a unit test covering exactly your issue above, see here:

configurator.Settings.MaximumIndirectExamples = 8;

I'm going to close this issue, but feel free to ping me if there is anything else you need help with.

@github-project-automation github-project-automation bot moved this from In Progress 👨‍💻 to Done 🚀 in Spectre Console Aug 2, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-CLI Command-Line Interface bug Something isn't working
Projects
Status: Done 🚀
4 participants