Files
runrs/src/main.rs
2025-01-11 00:56:45 +08:00

188 lines
5.3 KiB
Rust

#[macro_use]
extern crate rust_util;
use argh::FromArgs;
use rust_util::util_os::get_user_home;
use std::os::unix::fs::PermissionsExt;
use std::{env, fs};
use crate::install::install_script;
use crate::list::list_scripts;
use crate::util::{
build_script_command, get_run_script_bin_name, read_file_and_digest, run_script_command,
};
#[cfg(feature = "switch-dart-lang")]
mod help_dart;
#[cfg(feature = "switch-go-lang")]
mod help_go;
#[cfg(feature = "switch-js-lang")]
mod help_js;
#[cfg(feature = "switch-rust-lang")]
mod help_rs;
mod install;
mod list;
mod util;
#[cfg(feature = "switch-rust-lang")]
const CMD_NAME: &str = "runrs";
#[cfg(feature = "switch-go-lang")]
const CMD_NAME: &str = "rungo";
#[cfg(feature = "switch-js-lang")]
const CMD_NAME: &str = "runjs";
#[cfg(feature = "switch-dart-lang")]
const CMD_NAME: &str = "rundart";
#[derive(FromArgs, PartialEq, Debug)]
/// Run script
struct RunScriptArgs {
/// help message
#[argh(switch, short = 'h')]
help_message: bool,
/// script template
#[argh(switch, short = 't')]
template: bool,
/// list scripts
#[argh(switch, short = 'l')]
list: bool,
/// install script
#[argh(switch, short = 'i')]
install: bool,
/// output
#[argh(option, short = 'o')]
output: Option<String>,
/// arguments
#[argh(positional, greedy)]
arguments: Vec<String>,
}
fn main() {
let rs_args: RunScriptArgs = argh::from_env();
// println!("{:#?}", rs_args);
if env::args().len() == 1 {
failure_and_exit!(
"{} v{}, need arguments, `{} -h` or `{} --help-message` for help",
CMD_NAME,
env!("CARGO_PKG_VERSION"),
CMD_NAME,
CMD_NAME,
);
}
if rs_args.help_message {
print_help();
return;
}
if rs_args.template {
print_template(&rs_args.output);
return;
}
if rs_args.list {
list_scripts(rs_args.arguments.get(1));
return;
}
if rs_args.install {
if rs_args.arguments.is_empty() {
failure_and_exit!("No scripts assigned.");
}
for (i, script_name) in rs_args.arguments.iter().enumerate() {
information!(
"Installing script: {} [ {} / {} ]",
script_name,
(i + 1),
rs_args.arguments.len()
);
install_script(script_name);
}
return;
}
#[cfg(any(
feature = "switch-go-lang",
feature = "switch-js-lang",
feature = "switch-dart-lang"
))]
if true {
failure_and_exit!("Only rust supports run by runrs.");
}
if rs_args.arguments.is_empty() {
failure_and_exit!("Must assign a script file name");
}
let script_file = &rs_args.arguments[0];
let (_, script_sha256) = read_file_and_digest(script_file);
debugging!("File {} -> sha256: {}", script_file, script_sha256);
let user_home = get_user_home().unwrap_or_else(|| failure_and_exit!("$HOME not found!"));
let rust_script = get_run_script_bin_name(&user_home);
let cache_script_bin_name = get_cache_script_bin_name(&user_home, &script_sha256);
let mut run_script_cmd = build_script_command(
rust_script,
script_file,
&script_sha256,
&cache_script_bin_name,
);
for arg in rs_args.arguments.iter().skip(1) {
run_script_cmd.arg(arg);
}
run_script_command(script_file, &cache_script_bin_name, &mut run_script_cmd)
}
fn print_help() {
#[cfg(feature = "switch-rust-lang")]
help_rs::print_help();
#[cfg(feature = "switch-go-lang")]
help_go::print_help();
#[cfg(feature = "switch-js-lang")]
help_js::print_help();
#[cfg(feature = "switch-dart-lang")]
help_dart::print_help();
}
fn print_template(output: &Option<String>) {
#[cfg(feature = "switch-rust-lang")]
let script = include_str!("script.template.rs");
#[cfg(feature = "switch-go-lang")]
let script = include_str!("script.template.go");
#[cfg(feature = "switch-js-lang")]
let script = include_str!("script.template.js");
#[cfg(feature = "switch-dart-lang")]
let script = include_str!("script.template.dart");
match output {
None => {
println!("{}", script);
}
Some(output_file) => {
if fs::metadata(output_file).is_ok() {
failure!("Output script file exists: {}", output_file);
} else {
match fs::write(output_file, script) {
Ok(_) => {
success!("Write script file success: {}", output_file);
let _ = fs::set_permissions(&output_file, PermissionsExt::from_mode(0o755));
}
Err(e) => {
failure!("Write script file: {}, failed: {}", output_file, e);
}
}
}
}
}
}
fn get_cache_script_bin_name(user_home: &str, script_sha256: &str) -> String {
#[cfg(target_os = "macos")]
let cache_script_bin_name = format!(
"{}/Library/Caches/rust-script/binaries/release/{}",
user_home, script_sha256
);
// #[cfg(target_os = "linux")]
#[cfg(not(target_os = "macos"))]
let cache_script_bin_name = format!(
"{}/.cache/rust-script/binaries/release/{}",
user_home, script_sha256
);
cache_script_bin_name
}