index : git-mirror-sync.git

ascending towards madness

use std::env;

use clap::Parser;
use cli::CliArgs;
use log::{error, info};
use tokio::{process::Command, signal, time::sleep};
use walkdir::WalkDir;

mod cli;
mod error;

#[tokio::main]
async fn main() {
    env::set_var("RUST_LOG", "info");
    env_logger::init();

    let args = CliArgs::parse();

    loop {
        tokio::select! {
            _ = do_sync_task(args.clone()) => {}

            _ = signal::ctrl_c() => {
                info!("Shutting down...");
                break;
            }
        }
    }
}

async fn do_sync_task(args: CliArgs) {
    info!("Performing sync task.");

    for dir in WalkDir::new(args.directory)
        .max_depth(args.max_recursion_depth)
        .into_iter()
        .filter_map(|err| err.ok())
    {
        // this is a proof of concept.
        // TODO: sync with git2
        let refs_tag = Command::new("git")
            .arg("--git-dir")
            .arg(dir.clone().into_path())
            .arg("config")
            .arg("--get")
            .arg("remote.origin.fetch")
            .output()
            .await
            .expect("Failed to retrieve upstream URL")
            .stdout;

        if !refs_tag.is_empty() {
            let status = Command::new("git")
                .arg("--git-dir")
                .arg(dir.clone().into_path())
                .arg("fetch")
                .arg("--all")
                .status()
                .await
                .expect("Unable to fetch repository");
            if !status.success() {
                error!("Failed to update repository {:?}", dir.path())
            }
        }
    }

    info!("Sleeping until the next refresh.");
    sleep(args.refresh_time.into()).await;
}