mkit_cli/commands/
pull.rs1use std::io::Write;
5
6use clap::Parser;
7
8use crate::clap_shim;
9use crate::config;
10use crate::exit;
11use crate::remote_dispatch;
12
13#[derive(Debug, Parser)]
14#[command(name = "mkit pull", about = "Pull changes from the configured remote.")]
15struct PullOpts {
16 remote: Option<String>,
18}
19
20#[must_use]
21pub fn run(args: &[String]) -> u8 {
22 let opts = match clap_shim::parse::<PullOpts>("mkit pull", args) {
23 Ok(o) => o,
24 Err(code) => return code,
25 };
26 let cwd = match std::env::current_dir() {
27 Ok(p) => p,
28 Err(e) => return emit_err(&format!("cwd: {e}"), exit::NOINPUT),
29 };
30 let cfg = match config::read_layered(&cwd) {
31 Ok(c) => c,
32 Err(e) => return emit_err(&format!("config: {e}"), exit::CONFIG_ERROR),
33 };
34 let Some(resolved) = config::resolve_remote(&cfg, opts.remote.as_deref().unwrap_or("")) else {
35 return emit_err(
36 &match opts.remote.as_deref() {
37 Some(name) => format!("unknown remote '{name}'"),
38 None => "no remote configured — use `mkit remote add <url>`".to_owned(),
39 },
40 exit::CONFIG_ERROR,
41 );
42 };
43 let endpoint = resolved.endpoint.as_str();
44 match remote_dispatch::open_trusted(endpoint, resolved.repo_chosen, &cfg) {
45 Ok(tx) => match remote_dispatch::pull_all(&cwd, tx.as_ref(), &resolved.name) {
46 Ok(n) => {
47 let mut stderr = std::io::stderr().lock();
48 let _ = writeln!(stderr, "pulled {n} ref(s) from {endpoint}");
49 exit::OK
50 }
51 Err(remote_dispatch::DispatchError::Interrupted) => {
52 emit_err("pull: interrupted", exit::TEMPFAIL)
53 }
54 Err(e) => emit_err(&format!("pull: {e}"), exit::GENERAL_ERROR),
55 },
56 Err(remote_dispatch::DispatchError::UntrustedRemote(msg)) => {
57 emit_err(&msg, exit::CONFIG_ERROR)
58 }
59 Err(e) => emit_err(&format!("open remote: {e}"), exit::PROTOCOL_ERROR),
60 }
61}
62
63fn emit_err(msg: &str, code: u8) -> u8 {
64 let mut stderr = std::io::stderr().lock();
65 let _ = writeln!(stderr, "error: {msg}");
66 code
67}