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
use clap::Arg;
use seaplane::api::compute::v2::FormationId;
use crate::{
cli::{cmds::formation::SeaplaneFormationFetch, errors, CliCommand},
context::Ctx,
error::{CliErrorKind, Result},
ops::formation::FormationNameId,
};
pub fn name_id(required: bool) -> Arg {
arg!(name_id = ["NAME|ID"])
.value_parser(clap::value_parser!(FormationNameId))
.required(required)
}
pub fn fetch(short: bool) -> Arg {
let arg = arg!(--fetch | sync | synchronize).help(
"Fetch remote Formation Instances and synchronize local DB prior to running this command",
);
if short {
return arg.short('F');
}
arg
}
pub fn all() -> Arg {
arg!(--all - ('a'))
.help("Operate on all matching local Formation Plans even when the name or ID is ambiguous")
}
pub fn oids_matching_name_id(ctx: &Ctx) -> Result<Vec<FormationId>> {
let formation_ctx = ctx.formation_ctx.get_or_init();
let name_id = formation_ctx.name_id.as_ref().unwrap();
match indices_matching_name_id(ctx) {
Ok(indices) => {
if indices.is_empty() {
if let FormationNameId::Oid(oid) = name_id {
Ok(vec![*oid])
} else {
unreachable!("this is a bug");
}
} else {
Ok(ctx.db.formations.oids_from_indices(&indices))
}
}
Err(e) => {
if matches!(e.kind(), CliErrorKind::NoMatchingItem(_)) {
if let FormationNameId::Oid(oid) = name_id {
return Ok(vec![*oid]);
}
}
Err(e)
}
}
}
pub fn indices_matching_name_id(ctx: &Ctx) -> Result<Vec<usize>> {
let formation_ctx = ctx.formation_ctx.get_or_init();
let name_id = formation_ctx.name_id.as_ref().unwrap();
let indices = if ctx.args.all {
ctx.db
.formations
.formation_indices_of_partial_matches(name_id)
} else {
ctx.db.formations.formation_indices_of_matches(name_id)
};
match indices.len() {
0 => {
if name_id.is_oid() {
return Ok(Vec::new());
} else {
errors::no_matching_item(name_id.to_string(), false, ctx.args.all)?;
}
}
1 => (),
_ => {
if !(ctx.args.all || ctx.args.force) {
errors::ambiguous_item(name_id.to_string(), true)?;
}
}
}
Ok(indices)
}
pub fn run_fetch(ctx: &mut Ctx) -> Result<()> {
if ctx.args.fetch {
let old_name = { ctx.formation_ctx.get_mut_or_init().name_id.take() };
let old_ir = ctx.internal_run;
ctx.internal_run = true;
SeaplaneFormationFetch.run(ctx)?;
ctx.internal_run = old_ir;
ctx.formation_ctx.get_mut_or_init().name_id = old_name;
}
Ok(())
}