CLI Integration
English | 中文 | 日本語 | 한국어 | Français | Deutsch | Español | Português | Svenska | Suomi | Nederlands
ConfigCommand provides reusable clap subcommands:
config-templateconfig-schemaconfig-validatecompletionsinstall-completionsuninstall-completions
These built-in subcommands are separate from application-specific config override flags. Merge config override flags as Figment providers in the runtime loading path.
Config override flags remain part of the consuming application’s CLI. Their
names do not need to match dotted config paths. For example, the application can
parse --server-port and map it to the nested server.port config key.
Only flags that the application maps into CliOverrides affect config values.
Flatten it into an application command enum:
- Keep the application’s own
Parsertype. - Keep the application’s own
Subcommandenum. - Add
#[command(flatten)] Config(ConfigCommand)to that enum. - Clap expands the flattened
ConfigCommandvariants into the same command level as the application’s own variants. - Match the
Config(command)variant and pass it tohandle_config_command.
use std::path::PathBuf;
use clap::{Parser, Subcommand};
use confique::Config;
use schemars::JsonSchema;
use rust_config_tree::{ConfigCommand, ConfigSchema, handle_config_command, load_config};
#[derive(Debug, Config, JsonSchema)]
struct AppConfig {
#[config(default = [])]
include: Vec<PathBuf>,
}
impl ConfigSchema for AppConfig {
fn include_paths(layer: &<Self as Config>::Layer) -> Vec<PathBuf> {
layer.include.clone().unwrap_or_default()
}
}
#[derive(Debug, Parser)]
#[command(name = "demo")]
struct Cli {
#[arg(long, default_value = "config.yaml")]
config: PathBuf,
#[command(subcommand)]
command: Command,
}
#[derive(Debug, Subcommand)]
enum Command {
Run,
#[command(flatten)]
Config(ConfigCommand),
}
fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> {
let cli = Cli::parse();
match cli.command {
Command::Run => {
let config = load_config::<AppConfig>(&cli.config)?;
println!("{config:#?}");
}
Command::Config(command) => {
handle_config_command::<Cli, AppConfig>(command, &cli.config)?;
}
}
Ok(())
}
Config Templates
demo config-template
The command writes templates under config/<root_config_name>/. If --output
receives a path, only the file name is used. If no output file name is provided,
the command writes
config/<root_config_name>/<root_config_name>.example.yaml. Add
--schema schemas/myapp.schema.json to bind generated TOML, YAML, JSON, and JSON5 templates
to generated JSON Schemas. Split YAML templates bind the matching section
schema. The command also writes the root and section schemas to the selected
schema path.
demo config-template --output app_config.example.toml --schema schemas/myapp.schema.json
Generate root and section JSON Schemas:
demo config-schema
Without --output, config-schema writes the root schema to
config/<root_config_name>/<root_config_name>.schema.json.
Validate the complete runtime config tree:
demo config-validate
Generated editor schemas intentionally avoid required-field diagnostics for
split files. config-validate loads includes, applies defaults, and runs final
confique validation, including validators declared with
#[config(validate = Self::validate)]. Generated *.schema.json files remain
for IDE completion and basic editor checks, not field value legality. It prints
Configuration is ok when validation succeeds.
Shell Completions
Print completions to stdout:
demo completions zsh
Install completions:
demo install-completions zsh
Uninstall completions:
demo uninstall-completions zsh
The installer supports Bash, Elvish, Fish, PowerShell, and Zsh. It writes the completion file under the user’s home directory and updates the shell startup file for shells that require it.
Before changing an existing shell startup file such as ~/.zshrc, ~/.bashrc,
an Elvish rc file, or a PowerShell profile, the command writes a backup next to
the original file:
<rc-file>.backup.by.<program-name>.<timestamp>