use clap::{Args, Parser, Subcommand};
use std::env;
use std::process::ExitCode;
use txtpp::{txtpp, Config, Mode, Verbosity, TXTPP_FILE};
#[derive(Debug, Parser)]
#[command(author, version, about)]
struct Cli {
#[command(subcommand)]
subcommand: Option<Command>,
#[command(flatten)]
flags: Flags,
#[command(flatten)]
shell: BuildFlags,
#[arg(short = 'N', long)]
needed: bool,
}
impl Cli {
fn apply_to(&self, config: &mut Config) {
match &self.subcommand {
Some(subcommand) => subcommand.apply_to(config),
None => {
config.mode = if self.needed {
Mode::InMemoryBuild
} else {
Mode::Build
};
self.flags.apply_to(config);
self.shell.apply_to(config);
}
}
}
}
#[derive(Debug, Clone, Subcommand)]
enum Command {
Clean {
#[command(flatten)]
flags: Flags,
},
Verify {
#[command(flatten)]
flags: Flags,
#[command(flatten)]
shell: BuildFlags,
},
}
impl Command {
fn apply_to(&self, config: &mut Config) {
match self {
Command::Clean { flags } => {
config.mode = Mode::Clean;
flags.apply_to(config);
}
Command::Verify { flags, shell } => {
config.mode = Mode::Verify;
flags.apply_to(config);
shell.apply_to(config);
}
}
}
}
#[derive(Debug, Clone, Args)]
struct Flags {
#[arg(short, long)]
quiet: bool,
#[arg(short, long, conflicts_with = "quiet")]
verbose: bool,
#[arg(short, long)]
recursive: bool,
#[arg(short = 'j', long, default_value = "4")]
threads: usize,
#[arg(default_value = ".")]
inputs: Vec<String>,
}
impl Flags {
fn apply_to(&self, config: &mut Config) {
if self.quiet {
config.verbosity = Verbosity::Quiet;
} else if self.verbose {
config.verbosity = Verbosity::Verbose;
}
config.recursive = self.recursive;
config.num_threads = self.threads;
config.inputs = self.inputs.clone();
}
}
#[derive(Debug, Clone, Args)]
struct BuildFlags {
#[arg(short, long, default_value = "")]
shell: String,
#[arg(short, long)]
no_trailing_newline: bool,
}
impl BuildFlags {
fn apply_to(&self, config: &mut Config) {
config.shell_cmd = self.shell.clone();
config.trailing_newline = !self.no_trailing_newline;
}
}
fn main() -> ExitCode {
if let Ok(f) = env::var(TXTPP_FILE) {
if !f.is_empty() {
eprintln!("Cannot run txtpp as a subcommand!");
return ExitCode::FAILURE;
}
}
env_logger::init();
let args = Cli::parse();
log::debug!("{:?}", args);
let mut config = Config::default();
args.apply_to(&mut config);
match txtpp(config) {
Ok(()) => ExitCode::SUCCESS,
Err(_) => ExitCode::FAILURE,
}
}