feat: v1.1.4, fix runts shebang issue

This commit is contained in:
2025-01-24 23:02:23 +08:00
parent d581809696
commit 69288f9203
4 changed files with 95 additions and 14 deletions

2
Cargo.lock generated
View File

@@ -1221,7 +1221,7 @@ dependencies = [
[[package]]
name = "runrs"
version = "1.1.3"
version = "1.1.4"
dependencies = [
"argh",
"reqwest",

View File

@@ -1,6 +1,6 @@
[package]
name = "runrs"
version = "1.1.3"
version = "1.1.4"
edition = "2018"
license = "MIT/Apache-2.0"
description = "A Tool for Run Rust Scripts"

View File

@@ -2,11 +2,11 @@ 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(rs_args: &RunScriptArgs) {
if rs_args.arguments.is_empty() {
pub fn do_run_script(args: &RunScriptArgs) {
if args.arguments.is_empty() {
failure_and_exit!("Must assign a script file name");
}
let script_file = &rs_args.arguments[0];
let script_file = &args.arguments[0];
verify::verify_script(script_file, is_env_on("RUNRS_SKIP_VERIFY"));
let (_, script_sha256) = util::read_file_and_digest(script_file);
@@ -21,7 +21,7 @@ pub fn do_run_script(rs_args: &RunScriptArgs) {
&script_sha256,
&cache_script_bin_name,
);
for arg in rs_args.arguments.iter().skip(1) {
for arg in args.arguments.iter().skip(1) {
run_script_cmd.arg(arg);
}
util::run_script_command(script_file, &cache_script_bin_name, &mut run_script_cmd)

View File

@@ -1,26 +1,36 @@
use crate::{verify, RunScriptArgs};
use rust_util::util_cmd;
use rust_util::util_env::is_env_on;
use std::fs;
use std::process::Command;
pub fn do_run_script(ts_args: &RunScriptArgs) {
if ts_args.arguments.is_empty() {
pub fn do_run_script(args: &RunScriptArgs) {
if args.arguments.is_empty() {
failure_and_exit!("Must assign a script file name");
}
debugging!("Run ts args: {:?}", ts_args.arguments);
let script_file = (|| {
for arg in &ts_args.arguments {
debugging!("Run ts args: {:?}", args.arguments);
let (script_file, first_arg) = (|| {
for (i, arg) in args.arguments.iter().enumerate() {
if !arg.starts_with("--") {
return arg;
return (arg, i == 0);
}
}
&ts_args.arguments[ts_args.arguments.len() - 1]
(&args.arguments[args.arguments.len() - 1], false)
})();
verify::verify_script(script_file, is_env_on("RUNTS_SKIP_VERIFY"));
let mut cmd = Command::new("/usr/bin/env");
cmd.args(["-S", "deno", "run"]);
for arg in &ts_args.arguments {
if first_arg {
let first_line_args = read_first_line_parse_args(script_file);
let left_first_line_args = first_line_args
.iter()
.skip_while(|arg| *arg != "--" && *arg != "run")
.skip(1)
.collect::<Vec<_>>();
cmd.args(left_first_line_args);
}
for arg in &args.arguments {
cmd.arg(arg);
}
@@ -29,3 +39,74 @@ pub fn do_run_script(ts_args: &RunScriptArgs) {
failure_and_exit!("Run deno: {script_file} failed: {e}");
}
}
fn read_first_line_parse_args(script_file: &str) -> Vec<String> {
if let Ok(script_content) = fs::read_to_string(script_file) {
if let Some(first_line) = script_content.lines().next() {
if first_line.starts_with("#!") {
return parse_args_line(&first_line);
}
}
}
vec![]
}
fn parse_args_line(line: &str) -> Vec<String> {
let mut args = vec![];
let mut ln = String::new();
let mut in_quota = false;
let mut single_quota = false;
let chars = line.chars().collect::<Vec<_>>();
let mut i = 0;
while i < chars.len() {
let c = chars[i];
if in_quota {
if (single_quota && c == '\'') || (!single_quota && c == '"') {
in_quota = false;
} else if c == '\\' {
if i + 1 < chars.len() {
i += 1;
let nc = chars[i];
ln.push(nc);
} else {
ln.push(c);
}
} else {
ln.push(c);
}
} else if c == ' ' || c == '\t' {
if !ln.is_empty() {
args.push(ln.clone());
ln.clear();
}
} else if c == '\'' {
in_quota = true;
single_quota = true;
} else if c == '"' {
in_quota = true;
single_quota = false;
} else {
ln.push(c);
}
i += 1;
}
if !ln.is_empty() {
args.push(ln);
}
args
}
#[test]
fn test_parse_args_line() {
assert!(parse_args_line("").is_empty());
assert_eq!(vec!["a".to_string()], parse_args_line("a"));
assert_eq!(
vec!["a".to_string(), "aaaa'bbb".to_string()],
parse_args_line("a 'aaaa\\'bbb'")
);
assert_eq!(
vec!["--allow-a".to_string(), "--allow-b".to_string()],
parse_args_line(" --allow-a --allow-b")
);
}