use crate::{pos, ResultLogError, GREEN, RED, RESET, YELLOW};
const CARGO_PKG_VERSION: &str = env!("CARGO_PKG_VERSION");
pub fn parse_args(args: &mut std::env::Args) -> anyhow::Result<()> {
let arg_1 = args.next();
match arg_1 {
None => print_help_from_cargo_auto()?,
Some(task) => {
if task != "auto" {
match_first_argument(&task, args).log(pos!())?;
} else {
let arg_2 = args.next();
match arg_2 {
None => print_help_from_cargo_auto()?,
Some(task) => match_first_argument(&task, args)?,
}
}
}
}
Ok(())
}
fn already_exists_automation_tasks_rs() -> bool {
crate::PATH_AUTOMATION_TASKS_RS.exists()
}
fn print_help_from_cargo_auto() -> anyhow::Result<()> {
if !crate::PATH_CARGO_TOML.exists() || !crate::PATH_SRC_MAIN_RS.exists() {
println!(
r#"
{YELLOW}Welcome to cargo-auto v.{CARGO_PKG_VERSION}!
This program automates your custom tasks when developing a Rust project.
To start using `cargo auto` inside your Rust project, you must create a new `automation_tasks_rs` directory with the command:{RESET}
{GREEN}cargo auto new_auto_for_cli{RESET}
{YELLOW}© 2026 bestia.dev MIT License codeberg.org/automation-tasks-rs/cargo-auto{RESET}
"#
);
} else {
compile_automation_tasks_rs_if_needed().log(pos!())?;
let _success = crate::utils_mod::run_shell_command_success(&crate::PATH_TARGET_DEBUG_AUTOMATION_TASKS_RS.to_string_lossy());
}
Ok(())
}
fn match_first_argument(task: &str, args: &mut std::env::Args) -> anyhow::Result<()> {
if task == "completion" {
completion();
} else if task == "new_auto_for_cli" {
if already_exists_automation_tasks_rs() {
println!("{RED}Error: Directory automation_tasks_rs already exists. Cannot create new directory automation_tasks_rs.{RESET}");
std::process::exit(0);
}
crate::template_new_auto_for_cli_mod::new_auto_for_cli().log(pos!())?;
} else if task == "-v" {
println!("cargo-auto v.{CARGO_PKG_VERSION}");
} else if task == "update_automation_tasks_rs" {
if !already_exists_automation_tasks_rs() {
println!("{RED}Error: Directory automation_tasks_rs does not exists. Use 'cargo auto new_auto_for_cli'.{RESET}");
std::process::exit(0);
}
crate::template_new_auto_for_cli_mod::update_automation_tasks_rs().log(pos!())?;
} else {
if !already_exists_automation_tasks_rs() {
println!("{RED}Error: Directory automation_tasks_rs does not exist.{RESET}");
print_help_from_cargo_auto().log(pos!())?;
std::process::exit(0);
}
compile_automation_tasks_rs_if_needed().log(pos!())?;
let mut command = std::process::Command::new(crate::PATH_TARGET_DEBUG_AUTOMATION_TASKS_RS.as_os_str());
command.arg(task);
for arg_x in args.by_ref() {
command.arg(&arg_x);
}
let mut child = command.spawn().log(pos!())?;
child.wait().log(pos!())?;
}
Ok(())
}
fn completion() {
fn completion_return_one_or_more_sub_commands(sub_commands: Vec<&str>, word_being_completed: &str) {
let mut sub_found = false;
for sub_command in sub_commands.iter() {
if sub_command.starts_with(word_being_completed) {
println!("{}", sub_command);
sub_found = true;
}
}
if !sub_found {
for sub_command in sub_commands.iter() {
println!("{}", sub_command);
}
}
}
let args: Vec<String> = std::env::args().collect();
let last_word = args[2].as_str();
let mut word_being_completed = " ";
if args.len() > 3 {
word_being_completed = args[3].as_str();
}
if last_word == "cargo-auto" || last_word == "auto" {
let sub_commands = vec!["new_auto_for_cli"];
completion_return_one_or_more_sub_commands(sub_commands, word_being_completed);
}
}
pub fn compile_automation_tasks_rs_if_needed() -> anyhow::Result<()> {
if !crate::PATH_TARGET_DEBUG_AUTOMATION_TASKS_RS.exists() || crate::file_hashes_mod::is_project_changed()? {
compile_project_automation_tasks_rs().log(pos!())?;
let vec_of_metadata = crate::file_hashes_mod::read_file_metadata().log(pos!())?;
crate::file_hashes_mod::save_json_file_for_file_meta_data(vec_of_metadata).log(pos!())?;
}
Ok(())
}
pub fn compile_project_automation_tasks_rs() -> anyhow::Result<()> {
if !crate::utils_mod::run_shell_command_success("cargo build --manifest-path=automation_tasks_rs/Cargo.toml") {
anyhow::bail!("{RED}Cannot compile automation_tasks_rs.{RESET}");
}
Ok(())
}