seaplane_cli/cli/cmds/
init.rs1use std::fs;
2
3use clap::{ArgMatches, Command};
4
5use crate::{cli::CliCommand, config::RawConfig, context::Ctx, error::Result, fs::conf_dirs};
6
7static LONG_FORCE: &str =
8 "Force create the files and directories (DANGER: will overwrite existing files)
9
10Using --force is the same as using --overwrite=all";
11static LONG_OVERWRITE: &str =
12 "Overwrite select files or directories (DANGER: will overwrite existing data)
13
14Using --overwrite=all is the same as using --force
15
16Multiple items can be passed as a comma separated list, or by using the argument
17multiple times.";
18
19#[derive(Copy, Clone, Debug)]
20pub struct SeaplaneInit;
21
22impl SeaplaneInit {
23 pub fn command() -> Command {
24 Command::new("init")
25 .about("Create the Seaplane directory structure at the appropriate locations")
26 .arg(arg!(--force)
27 .help("Force create the files and directories (DANGER: will overwrite existing files)")
28 .long_help(LONG_FORCE))
29 .arg(arg!(--overwrite =["ITEM"]...)
30 .help("Overwrite select files or directories (DANGER: will overwrite existing data) (supports comma separated list, or multiple uses)")
31 .long_help(LONG_OVERWRITE)
32 .value_parser(["all", "formations", "flights", "config"]))
33 }
34}
35
36impl CliCommand for SeaplaneInit {
37 fn run(&self, ctx: &mut Ctx) -> Result<()> {
38 cli_debugln!("Creating or using data directory {:?}", ctx.data_dir());
40 fs::create_dir_all(ctx.data_dir())?;
41
42 let conf_dir = &conf_dirs()[0];
45 cli_debugln!("Creating or using config directory {:?}", conf_dir);
46 fs::create_dir_all(conf_dir)?;
47
48 let to_create = &[
50 (
51 conf_dir.join("seaplane.toml"),
52 toml::to_string_pretty(&RawConfig::default()).unwrap(),
53 "config",
54 ),
55 (ctx.formations_file(), "{}".to_string(), "formations"),
56 (ctx.flights_file(), "[]".to_string(), "flights"),
57 ];
58 let mut did_create = false;
60 for (file, empty_bytes, opt) in to_create {
61 if file.exists() && !(ctx.did_init || ctx.internal_run) {
62 if ctx.args.force
64 || ctx
65 .args
66 .overwrite
67 .iter()
68 .any(|item| item == opt || item == "all")
69 {
70 cli_warn!(@Yellow, "warn: ");
71 cli_warn!("overwriting existing file ");
72 cli_warn!("{:?} ", file);
73 cli_warn!("due to '");
74 cli_warn!(@Green, "{}", if ctx.args.force { "--force".into() } else { format!("--overwrite={opt}")});
75 cli_warnln!(@noprefix, "'\n");
76 } else {
77 cli_warn!(@Yellow, "warn: ");
80 cli_warn!("{:?} ", file);
81 cli_warnln!(@noprefix, "already exists");
82 cli_warn!("(hint: use '");
83 cli_warn!(@Green, "seaplane init --overwrite={}", opt);
84 cli_warnln!(@noprefix, "' to erase and overwrite it)\n");
85 continue;
86 }
87 }
88 did_create = true;
89 cli_debugln!("creating file {:?}", file);
90 fs::write(file, empty_bytes)?;
91 }
92
93 if !ctx.internal_run {
94 if did_create {
95 cli_println!("Successfully created Seaplane files and directories");
96 } else {
97 cli_println!("All Seaplane files and directories already exist");
98 }
99 }
100
101 Ok(())
102 }
103
104 fn update_ctx(&self, matches: &ArgMatches, ctx: &mut Ctx) -> Result<()> {
105 ctx.args.force = matches.get_flag("force");
106 ctx.args.overwrite = matches
107 .get_many::<String>("overwrite")
108 .unwrap_or_default()
109 .map(ToOwned::to_owned)
110 .collect();
111
112 Ok(())
113 }
114}