stryker-mutator / stryker-net

Mutation testing for .NET core and .NET framework!
https://stryker-mutator.io
Apache License 2.0
1.76k stars 175 forks source link

Rework options setup to allow for global and command specific options #2726

Open danihengeveld opened 10 months ago

danihengeveld commented 10 months ago

Is your feature request related to a problem? Please describe. The current setup for registering commands and options makes it difficult to share options (globally) between commands. Also, scoping options to specific nested commands requires code duplication. See the code example below:

app.Command("baseline", baselineCmd =>
{
    baselineCmd.Description = "Enables the baseline feature";
    cmdConfigReader.RegisterCommandLineOptions(baselineCmd, inputs);
    var targetInput = new CliInput()
    {
        Input = new BaselineTargetInput(),
        ArgumentName = "target",
        ArgumentShortName = "t",
        Description = @"The target for the compare. For example, when runnin on branch feat-2 and wanting to compare to branch ""main"", set this value to ""main""",
        Category = InputCategory.Mutation
    };
    var targetOption = new CommandOption("-t|--target <value>", CommandOptionType.SingleValue)
    {
        LongName = "target",
        ShortName = "t",
        Description = @"The target for the compare. For example, when runnin on branch feat-2 and wanting to compare to branch ""main"", set this value to ""main""",
        ShowInHelpText = true
    };
    cmdConfigReader.RegisterCliInput(app, targetInput);
    cmdConfigReader.AddCliInput(targetInput.Input, "--target", "-t", CommandOptionType.SingleValue, InputCategory.Mutation);
    baselineCmd.AddOption(targetOption);
    baselineCmd.Command("recreate", createCmd =>
    {
        cmdConfigReader.RegisterCommandLineOptions(createCmd, inputs);
        cmdConfigReader.RegisterCliInput(app, targetInput);
        cmdConfigReader.AddCliInput(targetInput.Input, "--target", "-t", CommandOptionType.SingleValue, InputCategory.Mutation);
        createCmd.AddOption(targetOption);

        createCmd.OnExecute(() =>
        {
            inputs.WithBaselineInput.SuppliedInput = true;
            createCmd.Description = "Creates a new baseline by doing a full stryker run";
            inputs.BaselineRecreateEnabledInput.SuppliedInput = true;
            return StartApp(inputs, args, app, cmdConfigReader);
        });
    });
    baselineCmd.OnExecute(() =>
    {
        inputs.WithBaselineInput.SuppliedInput = true;
        return StartApp(inputs, args, app, cmdConfigReader);
    });
});

This would be the required code for adding a baseline command with --target options and a nested recreate command that also needs to accept the target option.

Describe the solution you'd like It would be beneficial to split the options in groups: 'global' and 'command specific' and add a method to only register the options for a selected group. Also, I would like to see a method added for adding a command that copies it's parent's options.

Describe alternatives you've considered Some other libraries like Spectre.Console.Cli have a more robust setup for nested command composing, but swapping the command line utility library would be a LOT more work, we could do a POC to verify this. We would also need to check if the --since:dfosdfih2f42f4f syntax can be supported, as this is a prerequisite.