fabrica

hanna/fabrica

2008 bytes
Raw
1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at https://mozilla.org/MPL/2.0/.
4
5//! `fabrica config check` and `fabrica config show`.
6
7use std::path::Path;
8use std::process::ExitCode;
9
10use clap::Subcommand;
11
12/// Actions under `fabrica config`.
13#[derive(Debug, Subcommand)]
14pub(crate) enum ConfigCommand {
15 /// Validate the effective configuration and exit non-zero on any error.
16 Check,
17 /// Print the effective, merged configuration with secrets redacted.
18 Show,
19}
20
21/// Dispatch a `config` subcommand.
22///
23/// Warnings are always written to stderr; on `check` they do not affect the exit
24/// status. A validation failure is reported to stderr and yields
25/// [`ExitCode::FAILURE`] without returning an `Err`, so no backtrace-style
26/// wrapper is printed for the expected "your config is wrong" case.
27pub(crate) fn run(
28 command: &ConfigCommand,
29 config_path: Option<&Path>,
30 json: bool,
31) -> anyhow::Result<ExitCode> {
32 match command {
33 ConfigCommand::Check => match config::load(config_path) {
34 Ok(loaded) => {
35 warn(&loaded.warnings);
36 println!("configuration ok");
37 Ok(ExitCode::SUCCESS)
38 }
39 Err(err) => {
40 eprintln!("error: {err}");
41 Ok(ExitCode::FAILURE)
42 }
43 },
44 ConfigCommand::Show => {
45 let loaded = config::load(config_path)?;
46 warn(&loaded.warnings);
47 if json {
48 println!("{}", serde_json::to_string_pretty(&loaded.config)?);
49 } else {
50 print!("{}", loaded.config.to_toml_string()?);
51 }
52 Ok(ExitCode::SUCCESS)
53 }
54 }
55}
56
57/// Write each warning to stderr, prefixed, leaving stdout for real output.
58fn warn(warnings: &[String]) {
59 for warning in warnings {
60 eprintln!("warning: {warning}");
61 }
62}