93 lines
3.1 KiB
Rust
93 lines
3.1 KiB
Rust
use crate::{
|
|
dev::log::elog,
|
|
run::{Order, Task, TaskKind},
|
|
};
|
|
use std::{env, path::PathBuf};
|
|
|
|
pub fn parse(mut raw_args: env::Args) -> Order {
|
|
let (argument, parameters): (String, Vec<String>) = if let Some(first) = raw_args.next() {
|
|
if is_executable_path(&first) {
|
|
elog("First argument is the executable path");
|
|
if let Some(second) = raw_args.next() {
|
|
elog(&format!(
|
|
"Assembled command {second}, arguments {raw_args:?}"
|
|
));
|
|
(second, raw_args.collect())
|
|
} else {
|
|
elog("No arguments provided");
|
|
return Order::default();
|
|
}
|
|
} else {
|
|
elog("First argument is not the executable path");
|
|
elog(&format!(
|
|
"Assembled command {first}, arguments {raw_args:?}"
|
|
));
|
|
(first, raw_args.collect())
|
|
}
|
|
} else {
|
|
elog("No arguments provided");
|
|
return Order::default();
|
|
};
|
|
|
|
let make_order = |kind: TaskKind| -> Order {
|
|
Order {
|
|
tasks: vec![Task::new(kind, &argument, parameters)],
|
|
}
|
|
};
|
|
|
|
elog(&format!("Command is {argument}"));
|
|
|
|
match argument.as_str() {
|
|
"version" | "-v" | "--version" => make_order(TaskKind::Version),
|
|
"help" | "-h" | "--help" => make_order(TaskKind::Help),
|
|
"install" => make_order(TaskKind::PackageInstall),
|
|
"uninstall" => make_order(TaskKind::PackageUninstall),
|
|
"auto" => make_order(TaskKind::PackageListAuto),
|
|
"manual" => make_order(TaskKind::PackageListManual),
|
|
_ => make_order(TaskKind::Unrecognized),
|
|
}
|
|
}
|
|
|
|
fn is_executable_path(candidate: &str) -> bool {
|
|
fn assume(message: &str) -> bool {
|
|
elog(&format!("Assuming args[0] is the executable {message}"));
|
|
true
|
|
}
|
|
|
|
let Ok(executable_path) = env::current_exe() else {
|
|
return assume("Failed to get executable path");
|
|
};
|
|
let Some(executable_file) = executable_path.file_name() else {
|
|
return assume("Executable path lacks a file component");
|
|
};
|
|
|
|
let argument_path = PathBuf::from(candidate);
|
|
let Some(argument_file) = argument_path.file_name() else {
|
|
return assume("Argument path lacks a file component");
|
|
};
|
|
|
|
elog(&format!(
|
|
"Executable path: {executable_path:?}, file {executable_file:?} \
|
|
Argument path: {argument_path:?}, file {argument_file:?} "
|
|
));
|
|
|
|
if argument_path.exists() {
|
|
if let Ok(argument_canonical) = argument_path.canonicalize()
|
|
&& let Ok(executable_canonical) = executable_path.canonicalize()
|
|
{
|
|
let judgment = argument_canonical == executable_canonical;
|
|
elog(&format!(
|
|
"args[0] canonically is executable path: {judgment}"
|
|
));
|
|
judgment
|
|
} else {
|
|
assume("Could not canonicalize executable and argument paths")
|
|
}
|
|
} else {
|
|
let judgment = argument_file == executable_file;
|
|
elog(&format!(
|
|
"args[0] matches executable path by name only: {judgment}"
|
|
));
|
|
judgment
|
|
}
|
|
}
|