use clap::{Parser, Subcommand};
use std::env;
use std::io::Write;
use std::path::PathBuf;
use std::process::Command;
use crate::check_chars::{check_paths, resolve_charsets};
const RELEASE_SCRIPT: &str = include_str!("../release.sh");
#[derive(Parser)]
#[command(name = "apdev-rs", about = "Shared development tools for Rust projects", version)]
struct Cli {
#[command(subcommand)]
command: Option<Commands>,
}
#[derive(Subcommand)]
enum Commands {
CheckChars {
files: Vec<PathBuf>,
#[arg(long = "charset", action = clap::ArgAction::Append)]
charset: Vec<String>,
#[arg(long = "charset-file", action = clap::ArgAction::Append)]
charset_files: Vec<String>,
},
Release {
#[arg(long, short = 'y')]
yes: bool,
version: Option<String>,
},
}
pub fn run() -> i32 {
let cli = Cli::parse();
match cli.command {
None => {
use clap::CommandFactory;
Cli::command().print_help().ok();
0
}
Some(Commands::CheckChars {
files,
mut charset,
mut charset_files,
}) => {
if charset.is_empty() && charset_files.is_empty() {
if let Ok(env_val) = env::var("APDEV_EXTRA_CHARS") {
for item in env_val.split(',') {
let item = item.trim();
if item.is_empty() {
continue;
}
if item.contains(std::path::MAIN_SEPARATOR) || item.ends_with(".json") {
charset_files.push(item.to_string());
} else {
charset.push(item.to_string());
}
}
}
}
let (extra_ranges, dangerous) = match resolve_charsets(&charset, &charset_files) {
Ok(v) => v,
Err(e) => {
eprintln!("Error: {}", e);
return 1;
}
};
check_paths(files, &extra_ranges, &dangerous)
}
Some(Commands::Release { yes, version }) => {
if !PathBuf::from("Cargo.toml").is_file() {
eprintln!("Error: Cargo.toml not found in current directory");
eprintln!("Hint: run `apdev-rs release` from your project root");
return 1;
}
let mut tmp = match tempfile::NamedTempFile::new() {
Ok(f) => f,
Err(e) => {
eprintln!("Error creating temp file: {}", e);
return 1;
}
};
if let Err(e) = tmp.write_all(RELEASE_SCRIPT.as_bytes()) {
eprintln!("Error writing release script: {}", e);
return 1;
}
let mut cmd = Command::new("bash");
cmd.arg(tmp.path());
if yes {
cmd.arg("--yes");
}
if let Some(v) = version {
cmd.arg(v);
}
match cmd.status() {
Ok(status) => status.code().unwrap_or(1),
Err(e) => {
eprintln!("Error running release.sh: {}", e);
1
}
}
}
}
}