seaplane_cli/cli/cmds/flight/
copy.rs1use clap::{ArgMatches, Command};
2
3use super::SeaplaneFlightCommonArgMatches;
4use crate::{
5 cli::{
6 cmds::flight::common,
7 errors::wrap_cli_context,
8 specs::IMAGE_SPEC,
9 validator::{validate_flight_name, validate_name_id},
10 CliCommand,
11 },
12 context::{Ctx, FlightCtx},
13 error::Result,
14};
15
16#[derive(Copy, Clone, Debug)]
17pub struct SeaplaneFlightCopy;
18
19impl SeaplaneFlightCopy {
20 pub fn command() -> Command {
21 let validator = |s: &str| validate_name_id(validate_flight_name, s);
22
23 Command::new("copy")
25 .visible_alias("clone")
26 .about("Copy a local Flight Plan (optionally make changes to the copy)")
27 .after_help(IMAGE_SPEC)
28 .override_usage(
29 "
30 seaplane flight copy [OPTIONS] <NAME|ID> --name=<DEST_NAME>
31 seaplane flight copy [OPTION] <NAME|ID> [OPTIONS]",
32 )
33 .arg(
34 arg!(name_id =["NAME|ID"] required)
35 .value_parser(validator)
36 .help("The source name or ID of the Flight Plan to copy"),
37 )
38 .arg(arg!(--exact - ('x')).help("The given SOURCE must be an exact match"))
39 .args(common::args(false))
40 }
41}
42
43impl CliCommand for SeaplaneFlightCopy {
44 fn run(&self, ctx: &mut Ctx) -> Result<()> {
45 if ctx.args.stateless {
46 cli_eprint!(@Red, "error: ");
47 cli_eprint!("'");
48 cli_eprint!(@Yellow, "--stateless");
49 cli_eprint!("' cannot be used with the '");
50 cli_eprint!(@Yellow, "seaplane flight copy");
51 cli_eprintln!("' command");
52 cli_eprintln!("(hint: 'seaplane flight ...' only modifies local plans)");
53 std::process::exit(1);
54 }
55 let mut dest_flight = match ctx
57 .db
58 .flights
59 .clone_flight(ctx.args.name_id.as_ref().unwrap(), ctx.args.exact)
60 {
61 Ok(f) => f,
62 Err(e) => return wrap_cli_context(e, ctx.args.exact, false),
63 };
64
65 dest_flight.update_from(ctx.flight_ctx.get_or_init(), false)?;
67
68 let id = dest_flight.id.to_string();
69 let name = dest_flight.model.name().to_owned();
70
71 ctx.db.flights.add_flight(dest_flight);
73
74 ctx.persist_flights()?;
75
76 cli_print!("Successfully copied Flight Plan '");
77 cli_print!(@Yellow, "{}", ctx.args.name_id.as_ref().unwrap());
78 cli_print!("' to new Flight Plan '");
79 cli_print!(@Green, "{name}");
80 cli_print!("' with ID '");
81 cli_print!(@Green, "{}", &id[..8]);
82 cli_println!("'");
83
84 Ok(())
85 }
86
87 fn update_ctx(&self, matches: &ArgMatches, ctx: &mut Ctx) -> Result<()> {
88 ctx.args.name_id = matches.get_one::<String>("name_id").map(ToOwned::to_owned);
90 ctx.flight_ctx
91 .init(FlightCtx::from_flight_common(&SeaplaneFlightCommonArgMatches(matches), ctx)?);
92 Ok(())
93 }
94}