pub mod cli;
pub mod commands;
pub mod config;
use anyhow::Result;
use clap::{CommandFactory, Parser};
use clap_complete::generate;
use etcetera::{choose_app_strategy, AppStrategy, AppStrategyArgs};
use std::time::Duration;
use cli::{Cli, Command};
fn resolve_flag(cli_true: bool, cli_false: bool, config_val: Option<bool>) -> bool {
if cli_true {
true
} else if cli_false {
false
} else {
config_val.unwrap_or(false)
}
}
pub fn run() -> Result<()> {
let cli = Cli::parse();
if let Command::Completions { shell } = cli.command {
generate(shell, &mut Cli::command(), "jgl", &mut std::io::stdout());
return Ok(());
}
let config_path = config_path()?;
match cli.command {
Command::Completions { .. } => unreachable!(),
Command::Add { path } => commands::add::run(&config_path, &path, &mut std::io::stdout()),
Command::Fetch {
verbose,
rebase,
no_rebase,
with_conflicts,
without_conflicts,
idle_timeout,
} => {
let config = config::Config::load_or_default(&config_path)?;
let effective_rebase = resolve_flag(rebase, no_rebase, config.fetch.rebase);
let effective_with_conflicts = resolve_flag(
with_conflicts,
without_conflicts,
config.fetch.with_conflicts,
);
let idle_timeout_secs = idle_timeout
.or(config.fetch.idle_timeout)
.unwrap_or(commands::fetch::DEFAULT_IDLE_TIMEOUT_SECS);
commands::fetch::run(
&config_path,
&commands::fetch::FetchOptions {
verbose,
rebase: effective_rebase,
with_conflicts: effective_with_conflicts,
idle_timeout: Duration::from_secs(idle_timeout_secs),
},
&mut std::io::stdout(),
)
}
}
}
fn config_path() -> Result<std::path::PathBuf> {
let strategy = choose_app_strategy(AppStrategyArgs {
top_level_domain: "io".into(),
author: "jgl".into(),
app_name: "jgl".into(),
})
.map_err(|e| anyhow::anyhow!("failed to determine config dir: {e}"))?;
Ok(strategy.config_dir().join("config.toml"))
}