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