CLI UX improvement: Propogate options to subcommands
@michaeltlombardi is already working on this.
Since Jul 9, 2026.
- Dominant language
- Rust
- Stars
- 523
- Forks
- 75
- Avg merge
- 3d 16h
- Merged PRs (30d)
- 24
Description
Summary of the new feature / enhancement
As a user, I want to quickly specify options like
--trace-levelor--parametersto my command
without needing to move backwards in the command definition to the appropriate parent command,
so that I can modify the command I'm invoking more quickly in my terminal
Currently, DSC defines some parameters that apply to all children of the current command where the current command doesn't actually have functionality itself except to provide information and namespacing for the subcommands (dsc, dsc config).
To set the trace level for a command, the user needs to add the option to the root command, e.g.
# Initial command
dsc resource test --resource Examle/Resource --input $instance
# With current design to set tracing to `info`
dsc --trace-level info resource test --resource Example/Resource --input $instance
# With proposed design to set tracing to `info`
dsc resource test --resource Examle/Resource --input $instance --trace-level info
Or for the config subcommands, which all share the --parameters and --parameters-file option:
# Initial command
dsc config test --input $config
# With current design to pass parameters
dsc config --parameters $params test --input $config
# With proposed design to set tracing to `info`
dsc config test --input $config --parameters $params
Proposed technical implementation details (optional)
This can be effectively addressed by adding the global option to the argument definition attributes for the following options:
Args.trace_levelArgs.trace_formatArgs.progress_formatSubCommand::Config.parametersSubCommmand::Config.parameters_fileSubCommmand::Config.system_root
For example, the updated implementation for Args:
#[derive(Debug, Parser)]
#[clap(name = "dsc", version = env!("CARGO_PKG_VERSION"), about = t!("args.about").to_string(), long_about = None)]
pub struct Args {
/// The subcommand to run
#[clap(subcommand)]
pub subcommand: SubCommand,
#[clap(short = 'l', long, help = t!("args.traceLevel").to_string(), value_enum, global = true)]
pub trace_level: Option<TraceLevel>,
#[clap(short = 't', long, help = t!("args.traceFormat").to_string(), value_enum, global = true)]
pub trace_format: Option<TraceFormat>,
#[clap(short = 'p', long, help = t!("args.progressFormat").to_string(), value_enum, global = true)]
pub progress_format: Option<ProgressFormat>,
}
Which results in the following output for dsc extension list --help:
List or find extensions
Usage: dsc.exe extension list [OPTIONS] [EXTENSION_NAME]
Arguments:
[EXTENSION_NAME]
Optional extension name to filter the list
[default: *]
Options:
-o, --output-format <OUTPUT_FORMAT>
The output format to use
[possible values: json, pretty-json, yaml, table-no-truncate]
-l, --trace-level <TRACE_LEVEL>
Trace level to use
[possible values: error, warn, info, debug, trace]
-t, --trace-format <TRACE_FORMAT>
Trace format to use
[possible values: default, plaintext, json]
-p, --progress-format <PROGRESS_FORMAT>
Progress format to use
Possible values:
- default: If interactive, use a progress bar. If not interactive, no progress is shown
- none: No progress is shown
- json: Show progress as JSON
-h, --help
Print help (see a summary with '-h')
Specifying these options on the subcommands propagates their value back to the parent (or in the case of the root command arguments, to the root command) - no other code changes are required to propagate these values.
[!NOTE]
While out of scope for this improvement, this does also mean that we can take other reusable arguments for thedsc configanddsc resourcesubcommands, hoist them to those parent commands, and make it easier to maintain the arguments in the long run since we would only need to update them in one place.The downside to this is cluttering the parent command and the
dsc resource listsubcommand not actually using the input/resource options, which would likely need special casing.Alternatively, we can extract the argument definitions into new types as reusable arguments and include them in the subcommands with the
flattenattribute option, still simplifying maintenance.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.