use std::fs;
use std::path::Path;
use anyhow::bail;
use anyhow::Result;
use argh::FromArgs;
use lium::arc::lookup_arc_version;
use lium::arc::setup_arc_repo;
use lium::cros::lookup_full_version;
use lium::cros::setup_cros_repo;
use lium::repo::get_cros_dir_unchecked;
use lium::repo::get_current_synced_arc_version;
use lium::repo::get_current_synced_version;
use lium::repo::repo_sync;
use tracing::info;
use tracing::warn;
#[derive(FromArgs, PartialEq, Debug)]
#[argh(subcommand, name = "sync")]
pub struct Args {
#[argh(option)]
repo: Option<String>,
#[argh(option)]
reference: Option<String>,
#[argh(option)]
version: String,
#[argh(switch)]
arc: bool,
#[argh(switch)]
force: bool,
}
#[tracing::instrument(level = "trace")]
pub fn run(args: &Args) -> Result<()> {
let version = extract_version(args)?;
let repo = get_cros_dir_unchecked(&args.repo)?;
info!(
"Syncing {} to {} {}",
&repo,
version,
if args.force { "forcibly..." } else { "..." }
);
let is_arc = prepare_repo_paths(&repo)?.unwrap_or(args.arc);
if let Some(reference) = &args.reference {
warn!("Updating the mirror at {reference}...");
repo_sync(reference, args.force)?;
}
if is_arc {
setup_arc_repo(&repo, &version)?;
} else {
setup_cros_repo(&repo, &version, &args.reference)?;
}
repo_sync(&repo, args.force)
}
fn extract_version(args: &Args) -> Result<String> {
let version = if !args.arc {
if args.version == "tot" {
args.version.clone()
} else {
lookup_full_version(&args.version, "eve")?
}
} else {
lookup_arc_version(&args.version)?
};
Ok(version)
}
fn prepare_repo_paths(repo: &str) -> Result<Option<bool>> {
if !Path::new(repo).is_dir() {
info!("Creating {repo} ...");
fs::create_dir_all(repo)?;
return Ok(None);
}
if Path::new(&format!("{}/Android.bp", repo)).exists() {
warn!("Arc repo detected...");
let prev_version = get_current_synced_arc_version(repo)?;
info!("Previous ARC version was: {}", prev_version);
return Ok(true.into());
}
if let Ok(prev_version) = get_current_synced_version(repo) {
info!("Previous CROS version was: {}", prev_version);
return Ok(false.into());
}
if Path::new(repo).read_dir()?.next().is_some() {
bail!("{repo} is not a cros, arc, or empty directory.");
}
Ok(None)
}