Skip to main content

lux_cli/
config.rs

1use inquire::Confirm;
2use lux_lib::{
3    config::{Config, ConfigBuilder},
4    workspace::Workspace,
5};
6use miette::{miette, Context, IntoDiagnostic, Result};
7
8#[derive(clap::Subcommand)]
9pub enum ConfigCmd {
10    /// Initialise a new config file
11    Init(Init),
12    /// Edit the current config file.
13    Edit {
14        /// Edit the current workspace config.
15        #[arg(long)]
16        workspace: bool,
17    },
18    /// Show the current config.
19    /// This includes options picked up from CLI flags.
20    Show,
21}
22
23#[derive(clap::Args)]
24pub struct Init {
25    /// Initialise the default config for this system.
26    /// If this flag is not set, an empty config file will be created.
27    #[arg(long, conflicts_with = "current")]
28    default: bool,
29
30    /// Initialise the config file using the current config,
31    /// with options picked up from CLI flags.
32    #[arg(long, conflicts_with = "default")]
33    current: bool,
34
35    /// Initialise the config in the current workspace.
36    #[arg(long)]
37    workspace: bool,
38}
39
40pub fn config(cmd: ConfigCmd, config: Config) -> Result<()> {
41    match cmd {
42        ConfigCmd::Init(init) => {
43            let config_file = if init.workspace {
44                Workspace::current_or_err().into_diagnostic()?.config_file()
45            } else {
46                ConfigBuilder::config_file()?
47            };
48            if !config_file.is_file() && !config.no_prompt()
49                || Confirm::new("Config already exists. Overwrite?")
50                    .with_default(false)
51                    .prompt()
52                    .into_diagnostic()
53                    .wrap_err("error prompting to overwrite config")?
54            {
55                std::fs::create_dir_all(
56                    config_file
57                        .parent()
58                        .ok_or_else(|| miette!("error getting lux config parent directory"))?,
59                )
60                .into_diagnostic()?;
61                let content = if init.default {
62                    let cfg: ConfigBuilder = ConfigBuilder::default().build()?.into();
63                    toml::to_string(&cfg).into_diagnostic()?
64                } else if init.current {
65                    let cfg: ConfigBuilder = config.into();
66                    toml::to_string(&cfg).into_diagnostic()?
67                } else {
68                    String::default()
69                };
70                std::fs::write(&config_file, content).into_diagnostic()?;
71                print!("Config initialised at {}", config_file.display());
72            }
73        }
74        ConfigCmd::Edit { workspace } => {
75            let config_file = if workspace {
76                Workspace::current_or_err().into_diagnostic()?.config_file()
77            } else {
78                ConfigBuilder::config_file()?
79            };
80            if !config_file.is_file() {
81                let workspace_flag = if workspace { " --workspace " } else { "" };
82                return Err(miette!(
83                    help = format!(
84                        r#"
85Use 'lx config init{workspace_flag}', 'lx config init{workspace_flag} --default',
86or 'lx config init{workspace_flag} --current' to initialise a config file.
87"#
88                    ),
89                    "No config file found."
90                ));
91            }
92            edit::edit_file(config_file).into_diagnostic()?;
93        }
94        ConfigCmd::Show => {
95            let cfg: ConfigBuilder = config.into();
96            print!("{}", toml::to_string(&cfg).into_diagnostic()?);
97        }
98    }
99    Ok(())
100}