Skip to content

feature: Option to disable built-in / cli branch commands #74

@Kiruyuto

Description

@Kiruyuto

Is your feature request related to a problem? Please describe.

I've built simple CLI app that I tried publishing with assembly trimming enabled and even though my application does not use the built-in Spectre CLI commands, they are still registered internally by, I believe, this part

// Add built-in (hidden) commands.
_configurator.AddBranch(CliConstants.Commands.Branch, cli =>
{
cli.HideBranch();
cli.AddCommand<VersionCommand>(CliConstants.Commands.Version);
cli.AddCommand<XmlDocCommand>(CliConstants.Commands.XmlDoc);
cli.AddCommand<ExplainCommand>(CliConstants.Commands.Explain);
cli.AddCommand<OpenCliGeneratorCommand>(CliConstants.Commands.OpenCli);
});

In a trimmed publish, this causes runtime failures when invoking commands:

# in .csproj:
#    <PublishTrimmed>true</PublishTrimmed>
#    <TrimMode>full</TrimMode>
dotnet publish myApp -c Release -r win-x64 -p:SelfContained=true -p:PublishSingleFile=true -o artifacts/

# Custom command
./myApp.exe myCommand
Error: Could not get settings type for command of type 'Spectre.Console.Cli.VersionCommand'.

# Built-in
./myApp.exe cli version
Error: Could not get settings type for command of type 'Spectre.Console.Cli.VersionCommand'.
Image

Also, since the VersionCommand is internal I cannot add dynamic dependency to my code

[DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(VersionCommand))] // <== Cannot access internal class 'VersionCommand' here

Describe the solution you'd like

My preferred option would be to disable built-in commands entirely, since Im not planning to use them.
This could be done for example during app configuration via

config.Settings.EnableBuiltInCommands = false;
// Or
config.DisableBuiltInCommands();

Alternatively, make those types public so they could be referenced

Describe alternatives you've considered

I used overload of DynamicDependency to preserve the built-in command to get around trimming failures, but it quickly gets messy. Also, as mentioned before it keeps commands that I do not need or really want to ship

Additional context

No additional context but if the maintainers consider this feature useful, Im happy to work on it
From a quick look, it seems like a relatively simple change

Metadata

Metadata

Assignees

No one assigned
    No fields configured for Feature.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions