#![deny(missing_debug_implementations, rust_2018_idioms)]
use clap::{CommandFactory, Parser, Subcommand};
use cross::docker;
use cross::shell::MessageInfo;
mod commands;
#[derive(Parser, Debug)]
#[clap(version, about, long_about = None)]
struct Cli {
#[clap(value_parser = is_toolchain)]
toolchain: Option<String>,
#[clap(subcommand)]
command: Commands,
}
#[derive(Parser, Debug)]
struct CliHidden {
#[clap(subcommand)]
command: Commands,
}
#[derive(Subcommand, Debug)]
enum Commands {
#[clap(subcommand)]
Images(commands::Images),
#[clap(subcommand)]
Volumes(commands::Volumes),
#[clap(subcommand)]
Containers(commands::Containers),
Clean(commands::Clean),
}
fn is_toolchain(toolchain: &str) -> cross::Result<String> {
if toolchain.starts_with('+') {
Ok(toolchain.chars().skip(1).collect())
} else {
let _ = <CliHidden as CommandFactory>::command().get_matches();
unreachable!();
}
}
fn get_container_engine(
engine: Option<&str>,
docker_in_docker: bool,
msg_info: &mut MessageInfo,
) -> cross::Result<docker::Engine> {
let engine = if let Some(ce) = engine {
which::which(ce)?
} else {
docker::get_container_engine()?
};
let in_docker = match docker_in_docker {
true => Some(true),
false => None,
};
docker::Engine::from_path(engine, in_docker, None, msg_info)
}
macro_rules! get_engine {
($args:ident, $docker_in_docker:expr, $msg_info: ident) => {{
get_container_engine($args.engine(), $docker_in_docker, &mut $msg_info)
}};
}
macro_rules! get_msg_info {
($args:ident) => {{
MessageInfo::create($args.verbose(), $args.quiet(), $args.color())
}};
}
pub fn main() -> cross::Result<()> {
cross::install_panic_hook()?;
let cli = Cli::parse();
match cli.command {
Commands::Images(args) => {
let mut msg_info = get_msg_info!(args)?;
let engine = get_engine!(args, false, msg_info)?;
args.run(engine, &mut msg_info)?;
}
Commands::Volumes(args) => {
let mut msg_info = get_msg_info!(args)?;
let engine = get_engine!(args, args.docker_in_docker(), msg_info)?;
args.run(engine, cli.toolchain.as_deref(), &mut msg_info)?;
}
Commands::Containers(args) => {
let mut msg_info = get_msg_info!(args)?;
let engine = get_engine!(args, false, msg_info)?;
args.run(engine, &mut msg_info)?;
}
Commands::Clean(args) => {
let mut msg_info = get_msg_info!(args)?;
let engine = get_engine!(args, false, msg_info)?;
args.run(engine, &mut msg_info)?;
}
}
Ok(())
}