use std::path::PathBuf;
use std::process::ExitCode;
use anyhow::Result;
use clap::{Parser, Subcommand, ValueEnum};
use ejectest::{FileFilter, OutputFormat, read_file_list};
#[derive(Parser)]
#[command(name = "ejectest", version, about)]
struct Cli {
#[command(subcommand)]
command: Command,
}
#[derive(Subcommand)]
enum Command {
Apply {
path: PathBuf,
#[arg(long)]
dry_run: bool,
#[arg(long, value_enum, default_value_t = Format::Text)]
format: Format,
#[arg(long)]
files_from: Option<String>,
#[arg(long)]
lenient: bool,
},
Check {
path: PathBuf,
#[arg(long, value_enum, default_value_t = Format::Text)]
format: Format,
#[arg(long)]
files_from: Option<String>,
#[arg(long)]
lenient: bool,
},
}
#[derive(Clone, Copy, ValueEnum)]
enum Format {
Text,
Json,
}
impl From<Format> for OutputFormat {
fn from(format: Format) -> Self {
match format {
Format::Text => Self::Text,
Format::Json => Self::Json,
}
}
}
fn build_filter(
files_from: Option<&str>,
root: &std::path::Path,
lenient: bool,
) -> Result<Option<FileFilter>> {
match files_from {
Some(source) => {
let paths = read_file_list(source)?;
Ok(Some(FileFilter::from_paths(root, paths, lenient)?))
}
None => Ok(None),
}
}
fn main() -> Result<ExitCode> {
env_logger::init();
match Cli::parse().command {
Command::Apply {
path,
dry_run,
format,
files_from,
lenient,
} => {
let filter = build_filter(files_from.as_deref(), &path, lenient)?;
let report = ejectest::apply_path(&path, dry_run, filter.as_ref())?;
print!(
"{}",
ejectest::render_apply(&report, format.into(), dry_run)
);
Ok(ExitCode::SUCCESS)
}
Command::Check {
path,
format,
files_from,
lenient,
} => {
let filter = build_filter(files_from.as_deref(), &path, lenient)?;
let report = ejectest::check_path(&path, filter.as_ref())?;
print!("{}", ejectest::render_check(&report, format.into()));
if report.has_inline() {
Ok(ExitCode::FAILURE)
} else {
Ok(ExitCode::SUCCESS)
}
}
}
}