use std::fs; use crate::resolver::resolve_file; use crate::{util, verify, RunScriptArgs}; use rust_util::util_env::is_env_on; use rust_util::util_os::get_user_home; pub fn do_run_script(args: &RunScriptArgs) { if args.arguments.is_empty() { failure_and_exit!("Must assign a script file name"); } let script_file = &args.arguments[0]; let script_file = resolve_file(script_file, args.force_update) .unwrap_or_else(|e| failure_and_exit!("Failed to resolve script: {}", e)); let script_file = &script_file; let script_file_name = get_script_name(script_file); verify::verify_script(script_file, is_env_on("RUNRS_SKIP_VERIFY") || is_env_on("RSV")); let (_, script_sha256) = util::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 = util::get_run_script_bin_name(&user_home); let script_bin_name = get_cache_script_bin_name(&user_home, &script_sha256); let cache_script_bin_name = get_cache_script_bin_name_with_rs(&user_home, &script_sha256, &script_file_name); let (mut run_script_cmd, cached) = util::build_script_command( rust_script, script_file, &script_sha256, &cache_script_bin_name, ); for arg in args.arguments.iter().skip(1) { run_script_cmd.arg(arg); } util::run_script_command(script_file, &script_bin_name, &mut run_script_cmd, || { if !cached { debugging!("Checking file : {}", &script_bin_name); if fs::metadata(&script_bin_name).is_ok() { debugging!("Linking file: {} & {}", &script_bin_name, &cache_script_bin_name); match std::os::unix::fs::symlink(&script_bin_name, &cache_script_bin_name) { Ok(_) => debugging!("Link file success"), Err(e) => failure!("Linked file: {} and {} failed: {}", &script_bin_name, &cache_script_bin_name, &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 } fn get_cache_script_bin_name_with_rs(user_home: &str, script_sha256: &str, script_file_name: &str) -> String { #[cfg(target_os = "macos")] let cache_script_bin_path = format!( "{}/Library/Caches/rust-script/binaries/release/{}-bin", user_home, script_sha256 ); // #[cfg(target_os = "linux")] #[cfg(not(target_os = "macos"))] let cache_script_bin_path = format!( "{}/.cache/rust-script/binaries/release/{}-bin", user_home, script_sha256 ); if fs::metadata(&cache_script_bin_path).is_err() { debugging!("Creating cache script bin: {}", cache_script_bin_path); fs::create_dir_all(&cache_script_bin_path).ok(); } #[cfg(target_os = "macos")] let cache_script_bin_name = format!( "{}/{}", cache_script_bin_path, script_file_name ); // #[cfg(target_os = "linux")] #[cfg(not(target_os = "macos"))] let cache_script_bin_name = format!( "{}/{}", cache_script_bin_path, script_file_name ); cache_script_bin_name } fn get_script_name(script_file: &str) -> String { let last_part = script_file.split("/").last(); if let Some(last_part) = last_part { return last_part.to_string(); } script_file.to_string() }