use crate::errors::Error;
#[derive(Debug, clap::Parser)]
pub(crate) struct SyncCmd {
#[arg(short, long)]
gather: bool,
}
impl super::Command for SyncCmd {
fn run(
&self,
_: &super::nedots::RootCmd,
config: &crate::config::Config,
) -> anyhow::Result<()> {
if self.gather {
for source in &config.sources {
super::gather::gather_file(source, &config.get_dst_from_src(source)?)?;
}
}
let cmd = "git";
let initial_args = ["-C", &config.root.display().to_string()];
let spinner = start_spinner();
let mut args = Vec::new();
args.extend_from_slice(&initial_args);
args.extend_from_slice(&["submodule", "foreach", "git", "pull"]);
run_cmd(cmd, &args, &spinner)?;
args = Vec::new();
args.extend_from_slice(&initial_args);
args.extend_from_slice(&["add", "."]);
run_cmd(cmd, &args, &spinner)?;
args = Vec::new();
args.extend_from_slice(&initial_args);
let datetime = format!("Latest {}", chrono::offset::Local::now());
args.extend_from_slice(&["commit", "-m", &datetime]);
let res = run_cmd(cmd, &args, &spinner);
if res.is_err() {
log::trace!("expected `git commit` to error and it did, moving on");
}
args = Vec::new();
args.extend_from_slice(&initial_args);
args.extend_from_slice(&["pull"]);
run_cmd(cmd, &args, &spinner)?;
args = Vec::new();
args.extend_from_slice(&initial_args);
args.extend_from_slice(&["push"]);
run_cmd(cmd, &args, &spinner)?;
spinner.finish_and_clear();
log::info!("✅ Synced");
Ok(())
}
}
fn start_spinner() -> indicatif::ProgressBar {
let tick_rate = std::time::Duration::from_millis(500);
let spinner = indicatif::ProgressBar::new_spinner();
spinner.enable_steady_tick(tick_rate);
spinner
}
fn run_cmd(prog: &str, args: &[&str], spinner: &indicatif::ProgressBar) -> anyhow::Result<()> {
spinner.set_message(format!("{} {}", prog, args.join(" ")));
let output = std::process::Command::new(prog).args(args).output()?;
match output.status.success() {
true => Ok(()),
false => {
if !output.stderr.is_empty() {
eprintln!("{}", String::from_utf8(output.stderr)?);
}
Err(Error::Command(prog.to_string()).into())
}
}
}