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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
use std::collections::HashSet;
use clap::{ArgMatches, Command};
use crate::{api::FormationsReq, cli::CliCommand, error::Result, printer::Pb, Ctx};
#[derive(Copy, Clone, Debug)]
pub struct SeaplaneFormationFetch;
impl SeaplaneFormationFetch {
pub fn command() -> Command {
Command::new("fetch-remote")
.visible_aliases(["fetch", "sync", "synchronize"])
.about("Fetch remote Formation Instances and create/synchronize local Plan definitions")
.override_usage("
seaplane formation fetch-remote
seaplane formation fetch-remote [NAME|ID]",
)
.arg(
arg!(formation = ["NAME|ID"])
.help("The NAME or ID of the remote Formation Instance to fetch, omit to fetch all Formation Instances"),
)
}
}
impl CliCommand for SeaplaneFormationFetch {
fn run(&self, ctx: &mut Ctx) -> Result<()> {
let pb = Pb::new(ctx);
pb.set_message("Gathering Formation Names...");
let mut req = FormationsReq::new_delay_token(ctx)?;
if let Some(name) = &ctx.args.name_id {
req.set_name(name)?;
}
let names = req.get_formation_names()?;
pb.set_message("Syncing Formations...");
let mut remote_instances = req.get_all_formations(&names, &pb)?;
let mut flights_added = HashSet::new();
let mut formations_added = HashSet::new();
let mut configs_updated = HashSet::new();
for formation in remote_instances.formations.iter_mut() {
for cfg in formation.configs().iter().filter_map(|id| {
if let Some(i) = remote_instances
.configurations
.iter()
.enumerate()
.find_map(|(i, cfg)| if &cfg.id == id { Some(i) } else { None })
{
Some(remote_instances.configurations.swap_remove(i))
} else {
None
}
}) {
for flight in cfg.model.flights() {
let names_ids = ctx.db.flights.update_or_create_flight(flight);
flights_added.extend(names_ids);
}
let old_id = cfg.id;
if let Some(real_id) = ctx.db.formations.update_or_create_configuration(cfg) {
formation.replace_id(&old_id, real_id);
configs_updated.insert((formation.name.clone().unwrap(), real_id));
}
}
if let Some(id) = ctx
.db
.formations
.update_or_create_formation(formation.clone())
{
formations_added.insert((formation.name.clone().unwrap(), id));
}
}
pb.finish_and_clear();
if !ctx.internal_run {
let mut count = 0;
for (name, id) in formations_added {
count += 1;
cli_print!("Successfully synchronized Formation Instance '");
cli_print!(@Green, "{name}");
cli_print!("' with local Formation ID '");
cli_print!(@Green, "{}", &id.to_string()[..8]);
cli_println!("'");
}
for (name, id) in configs_updated {
count += 1;
cli_print!("Successfully synchronized Formation Configuration in Formation '");
cli_print!(@Green, "{name}");
cli_print!("' with local Formation Configuration ID '");
cli_print!(@Green, "{}", &id.to_string()[..8]);
cli_println!("'");
}
for (name, id) in flights_added {
count += 1;
cli_print!("Successfully synchronized Flight Plan '");
cli_print!(@Green, "{name}");
cli_print!("' with local Flight Plan ID '");
cli_print!(@Green, "{}", &id.to_string()[..8]);
cli_println!("'!");
}
if names.is_empty() {
cli_println!("No remote Formation Instances found");
} else if count > 0 {
cli_println!("");
cli_println!("Successfully fetched {count} items");
} else {
cli_println!("All local definitions are up to date!");
}
}
ctx.persist_flights()?;
ctx.persist_formations()?;
Ok(())
}
fn update_ctx(&self, matches: &ArgMatches, ctx: &mut Ctx) -> Result<()> {
ctx.args.name_id = matches
.get_one::<String>("formation")
.map(ToOwned::to_owned);
Ok(())
}
}