feat: v1.0.0
This commit is contained in:
20
src/help.rs
Normal file
20
src/help.rs
Normal file
@@ -0,0 +1,20 @@
|
||||
pub fn print_help() {
|
||||
let help = get_help()
|
||||
.replace("{CARGO_PKG_NAME}", env!("CARGO_PKG_NAME"))
|
||||
.replace("{CARGO_PKG_VERSION}", env!("CARGO_PKG_VERSION"))
|
||||
.replace("{CARGO_PKG_DESCRIPTION}", env!("CARGO_PKG_DESCRIPTION"));
|
||||
println!("{}", help);
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
fn get_help() -> &'static str {
|
||||
#[cfg(feature = "switch-rust-lang")]
|
||||
return include_str!("script.help.rust.txt");
|
||||
#[cfg(feature = "switch-go-lang")]
|
||||
return include_str!("script.help.go.txt");
|
||||
#[cfg(feature = "switch-ts-lang")]
|
||||
return include_str!("script.help.ts.txt");
|
||||
#[cfg(feature = "switch-dart-lang")]
|
||||
return include_str!("script.help.dart.txt");
|
||||
panic!("Unknown feature assigned.");
|
||||
}
|
||||
@@ -1,54 +1,39 @@
|
||||
use crate::util;
|
||||
use crate::util::ScriptMeta;
|
||||
use std::collections::BTreeMap;
|
||||
use std::fs;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
use std::path::PathBuf;
|
||||
|
||||
use crate::util::{SCRIPT_DOT_EXT, SCRIPT_HYPHEN_EXT};
|
||||
use rust_util::util_os::get_user_home;
|
||||
pub fn install_scripts(arguments: &[String]) {
|
||||
if arguments.is_empty() {
|
||||
failure_and_exit!("No scripts assigned.");
|
||||
}
|
||||
let script_meta_map = util::fetch_script_meta_or_die();
|
||||
for (i, script_name) in arguments.iter().enumerate() {
|
||||
information!(
|
||||
"Installing script: {} [ {} / {} ]",
|
||||
script_name,
|
||||
(i + 1),
|
||||
arguments.len()
|
||||
);
|
||||
install_script(script_name, &script_meta_map);
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "switch-rust-lang")]
|
||||
const SCRIPT_PATTERN: &str =
|
||||
"https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/$NAME/src/main.rs";
|
||||
#[cfg(feature = "switch-go-lang")]
|
||||
const SCRIPT_PATTERN: &str =
|
||||
"https://git.hatter.ink/hatter/go-scripts/raw/branch/main/$NAME/main.go";
|
||||
#[cfg(feature = "switch-ts-lang")]
|
||||
const SCRIPT_PATTERN: &str =
|
||||
"https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/$NAME/main.ts";
|
||||
#[cfg(feature = "switch-dart-lang")]
|
||||
const SCRIPT_PATTERN: &str =
|
||||
"https://git.hatter.ink/hatter/dart-scripts/raw/branch/main/$NAME/main.dart";
|
||||
|
||||
pub fn install_script(script_name: &str) {
|
||||
let normalized_script_name = if script_name.ends_with(SCRIPT_DOT_EXT) {
|
||||
script_name
|
||||
.chars()
|
||||
.take(script_name.len() - SCRIPT_DOT_EXT.len())
|
||||
.collect::<String>()
|
||||
+ SCRIPT_HYPHEN_EXT
|
||||
} else if script_name.ends_with(SCRIPT_HYPHEN_EXT) {
|
||||
script_name.to_string()
|
||||
} else {
|
||||
failure!("Invalid script name: {}", script_name);
|
||||
return;
|
||||
pub fn install_script(script_name: &str, script_meta_map: &BTreeMap<String, ScriptMeta>) {
|
||||
let script_meta = match script_meta_map.get(script_name) {
|
||||
None => {
|
||||
failure!("Script not found: {}", script_name);
|
||||
return;
|
||||
}
|
||||
Some(script_meta) => script_meta,
|
||||
};
|
||||
|
||||
let script_file_name = normalized_script_name
|
||||
.chars()
|
||||
.take(normalized_script_name.len() - SCRIPT_HYPHEN_EXT.len())
|
||||
.collect::<String>()
|
||||
+ SCRIPT_DOT_EXT;
|
||||
let user_home = get_user_home().expect("Get user home failed!");
|
||||
let output_file_name = PathBuf::from(&user_home)
|
||||
.join("bin")
|
||||
.join(&script_file_name);
|
||||
if output_file_name.exists() {
|
||||
warning!("Script file: {} exists", output_file_name.to_string_lossy());
|
||||
}
|
||||
|
||||
let script_url = SCRIPT_PATTERN.replace("$NAME", &normalized_script_name);
|
||||
let script_url = &script_meta.script_full_url;
|
||||
information!("Script URL: {}", &script_url);
|
||||
|
||||
let get_script_response_result = reqwest::blocking::get(&script_url);
|
||||
let get_script_response_result = reqwest::blocking::get(script_url);
|
||||
debugging!("Get script response: {:#?}", &get_script_response_result);
|
||||
|
||||
let get_script_response = match get_script_response_result {
|
||||
@@ -66,16 +51,22 @@ pub fn install_script(script_name: &str) {
|
||||
failure!("Get script failed: {}", get_script_response_status);
|
||||
return;
|
||||
}
|
||||
|
||||
let text = match get_script_response.text() {
|
||||
let remote_script_content = match get_script_response.text() {
|
||||
Err(e) => {
|
||||
failure!("Get script: {} failed: {}", &script_url, e);
|
||||
return;
|
||||
}
|
||||
Ok(text) => text,
|
||||
Ok(remote_script_content) => remote_script_content,
|
||||
};
|
||||
let user_home = util::get_user_home_or_die();
|
||||
let output_file_name = PathBuf::from(&user_home)
|
||||
.join("bin")
|
||||
.join(&script_meta.script_name);
|
||||
if output_file_name.exists() {
|
||||
warning!("Script file: {} exists", output_file_name.to_string_lossy());
|
||||
}
|
||||
if let Ok(script_content) = fs::read_to_string(&output_file_name) {
|
||||
if text == script_content {
|
||||
if remote_script_content == script_content {
|
||||
success!(
|
||||
"File is extract same, skip write file: {}",
|
||||
output_file_name.to_string_lossy()
|
||||
@@ -83,7 +74,7 @@ pub fn install_script(script_name: &str) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if let Err(e) = fs::write(&output_file_name, text) {
|
||||
if let Err(e) = fs::write(&output_file_name, remote_script_content) {
|
||||
failure!(
|
||||
"Write script: {} failed: {}",
|
||||
output_file_name.to_string_lossy(),
|
||||
|
||||
74
src/list.rs
74
src/list.rs
@@ -1,60 +1,22 @@
|
||||
use rust_util::util_os::get_user_home;
|
||||
use serde::Deserialize;
|
||||
use std::collections::BTreeMap;
|
||||
use crate::util;
|
||||
use std::fs;
|
||||
use std::path::PathBuf;
|
||||
use crate::util::{SCRIPT_DOT_EXT, SCRIPT_HYPHEN_EXT};
|
||||
|
||||
#[cfg(feature = "switch-rust-lang")]
|
||||
const FILE_META: &str = "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/script-meta.json";
|
||||
#[cfg(feature = "switch-go-lang")]
|
||||
const FILE_META: &str = "https://git.hatter.ink/hatter/go-scripts/raw/branch/main/script-meta.json";
|
||||
#[cfg(feature = "switch-ts-lang")]
|
||||
const FILE_META: &str = "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/script-meta.json";
|
||||
#[cfg(feature = "switch-dart-lang")]
|
||||
const FILE_META: &str = "https://git.hatter.ink/hatter/dart-scripts/raw/branch/main/script-meta.json";
|
||||
|
||||
#[derive(Deserialize)]
|
||||
struct ScriptMeta {
|
||||
script_name: String,
|
||||
script_length: u64,
|
||||
script_sha256: String,
|
||||
}
|
||||
|
||||
pub fn list_scripts(filter: Option<&String>) {
|
||||
debugging!("Loading URL: {}", FILE_META);
|
||||
let response = reqwest::blocking::get(FILE_META).unwrap_or_else(|e| {
|
||||
failure_and_exit!("Get file-meta.json failed: {}", e);
|
||||
});
|
||||
debugging!("Load response: {}", response.status().as_u16());
|
||||
if response.status().as_u16() != 200 {
|
||||
failure_and_exit!("Get file-meta.json failed, status: {}", response.status().as_u16());
|
||||
}
|
||||
let text = response.text().unwrap_or_else(|e| {
|
||||
failure_and_exit!("Get file-meta.json failed: {}", e);
|
||||
});
|
||||
debugging!("Response text: {}", &text);
|
||||
|
||||
let user_home = get_user_home().expect("Get user home failed!");
|
||||
let script_meta_map: BTreeMap<String, ScriptMeta> = serde_json::from_str(&text).expect("Parse script-meta.json failed.");
|
||||
let script_meta_map = util::fetch_script_meta_or_die();
|
||||
|
||||
let mut messages = vec![];
|
||||
for (_, script_meta) in &script_meta_map {
|
||||
for script_meta in script_meta_map.values() {
|
||||
let script_name = &script_meta.script_name;
|
||||
let real_script_name = if script_name.ends_with(SCRIPT_HYPHEN_EXT) {
|
||||
script_name.chars().take(script_name.len() - SCRIPT_HYPHEN_EXT.len()).collect::<String>() + SCRIPT_DOT_EXT
|
||||
} else {
|
||||
script_name.to_string()
|
||||
};
|
||||
|
||||
if let Some(filter) = filter {
|
||||
if !real_script_name.contains(filter) {
|
||||
if !script_name.contains(filter) {
|
||||
// NOT CONTAINS `filter`, SKIP
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
let full_script_path = PathBuf::from(&user_home).join("bin").join(&real_script_name);
|
||||
let user_home = util::get_user_home_or_die();
|
||||
let full_script_path = PathBuf::from(&user_home).join("bin").join(script_name);
|
||||
let is_script_exists = full_script_path.is_file();
|
||||
let script_sha256 = if is_script_exists {
|
||||
let script_content = fs::read(&full_script_path).unwrap_or(vec![]);
|
||||
@@ -64,18 +26,26 @@ pub fn list_scripts(filter: Option<&String>) {
|
||||
};
|
||||
let is_script_matches = script_sha256 == script_meta.script_sha256;
|
||||
let script_size = rust_util::util_size::get_display_size(script_meta.script_length as i64);
|
||||
let padding_length = 40 - real_script_name.len();
|
||||
messages.push(format!("- {} {} {} {}",
|
||||
iff!(is_script_exists, iff!(is_script_matches, "✅", "✔️ "), "➖"),
|
||||
real_script_name,
|
||||
".".repeat(iff!(padding_length < 1, 1, padding_length)),
|
||||
script_size,
|
||||
let padding_length = 40 - script_name.len();
|
||||
messages.push(format!(
|
||||
"- {} {} {} {}",
|
||||
iff!(is_script_exists, iff!(is_script_matches, "✅", "✔️ "), "➖"),
|
||||
script_name,
|
||||
".".repeat(iff!(padding_length < 1, 1, padding_length)),
|
||||
script_size,
|
||||
));
|
||||
}
|
||||
if filter.is_some() {
|
||||
messages.insert(0, format!("Total {} script(s), found {} script(s):", script_meta_map.len(), messages.len()));
|
||||
messages.insert(
|
||||
0,
|
||||
format!(
|
||||
"Total {} script(s), found {} script(s):",
|
||||
script_meta_map.len(),
|
||||
messages.len()
|
||||
),
|
||||
);
|
||||
} else {
|
||||
messages.insert(0, format!("Found {} script(s):", script_meta_map.len()));
|
||||
}
|
||||
success!("{}", messages.join("\n"));
|
||||
}
|
||||
}
|
||||
|
||||
90
src/main.rs
90
src/main.rs
@@ -3,36 +3,19 @@ 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 std::env;
|
||||
|
||||
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-ts-lang")]
|
||||
mod help_ts;
|
||||
#[cfg(feature = "switch-rust-lang")]
|
||||
mod help_rs;
|
||||
mod help;
|
||||
mod install;
|
||||
mod list;
|
||||
mod template;
|
||||
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-ts-lang")]
|
||||
const CMD_NAME: &str = "runts";
|
||||
#[cfg(feature = "switch-dart-lang")]
|
||||
const CMD_NAME: &str = "rundart";
|
||||
|
||||
#[derive(FromArgs, PartialEq, Debug)]
|
||||
/// Run script
|
||||
struct RunScriptArgs {
|
||||
@@ -60,22 +43,20 @@ fn main() {
|
||||
let rs_args: RunScriptArgs = argh::from_env();
|
||||
// println!("{:#?}", rs_args);
|
||||
|
||||
let cmd_name = util::get_cmd_name();
|
||||
let cmd_version = env!("CARGO_PKG_VERSION");
|
||||
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,
|
||||
"{cmd_name} v{cmd_version}, need arguments, `{cmd_name} -h` or `{cmd_name} --help-message` for help"
|
||||
);
|
||||
}
|
||||
|
||||
if rs_args.help_message {
|
||||
print_help();
|
||||
help::print_help();
|
||||
return;
|
||||
}
|
||||
if rs_args.template {
|
||||
print_template(&rs_args.output);
|
||||
template::print_template(&rs_args.output);
|
||||
return;
|
||||
}
|
||||
if rs_args.list {
|
||||
@@ -83,18 +64,7 @@ fn main() {
|
||||
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);
|
||||
}
|
||||
install::install_scripts(&rs_args.arguments);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -129,48 +99,6 @@ fn main() {
|
||||
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-ts-lang")]
|
||||
help_ts::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-ts-lang")]
|
||||
let script = include_str!("script.template.ts");
|
||||
#[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!(
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
pub fn print_help() {
|
||||
println!(r##"rundart v{} - A Tool for Run dart Scripts
|
||||
rundart v{CARGO_PKG_VERSION} - A Tool for Run dart Scripts
|
||||
|
||||
Show help:
|
||||
$ rundart -h|--help
|
||||
@@ -12,8 +11,3 @@ $ rundart -l|--list
|
||||
|
||||
Install script:
|
||||
$ rundart -i|--install <script.dart>
|
||||
|
||||
"##,
|
||||
env!("CARGO_PKG_VERSION")
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
pub fn print_help() {
|
||||
println!(r##"rungo v{} - A Tool for Run Go Scripts
|
||||
rungo v{CARGO_PKG_VERSION} - A Tool for Run Go Scripts
|
||||
|
||||
Show help:
|
||||
$ rungo -h|--help
|
||||
@@ -14,8 +13,3 @@ Install script:
|
||||
$ rungo -i|--install <script.go>
|
||||
|
||||
Powered by gorun, know more reference: https://github.com/erning/gorun
|
||||
|
||||
"##,
|
||||
env!("CARGO_PKG_VERSION")
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
pub fn print_help() {
|
||||
println!(r##"{} v{} - {}
|
||||
runrs v{CARGO_PKG_VERSION} - {CARGO_PKG_DESCRIPTION}
|
||||
|
||||
Show help:
|
||||
$ runrs -h|--help
|
||||
@@ -31,9 +30,3 @@ Environment variables:
|
||||
│ RUNRS_MAX_SCRIPT_LEN │ Max script length, default 1MB │
|
||||
└──────────────────────┴────────────────────────────────────────────────┘
|
||||
> Type `bool`: `true`, `yes`, `on` or `1` for true, otherwise false
|
||||
"##,
|
||||
env!("CARGO_PKG_NAME"),
|
||||
env!("CARGO_PKG_VERSION"),
|
||||
env!("CARGO_PKG_DESCRIPTION")
|
||||
);
|
||||
}
|
||||
@@ -1,5 +1,4 @@
|
||||
pub fn print_help() {
|
||||
println!(r##"runts v{} - A Tool for Run TS Scripts
|
||||
runts v{CARGO_PKG_VERSION} - A Tool for Run TS Scripts
|
||||
|
||||
Show help:
|
||||
$ runts -h|--help
|
||||
@@ -12,8 +11,3 @@ $ runts -l|--list
|
||||
|
||||
Install script:
|
||||
$ runts -i|--install <script.ts>
|
||||
|
||||
"##,
|
||||
env!("CARGO_PKG_VERSION")
|
||||
);
|
||||
}
|
||||
39
src/template.rs
Normal file
39
src/template.rs
Normal file
@@ -0,0 +1,39 @@
|
||||
use std::fs;
|
||||
use std::os::unix::fs::PermissionsExt;
|
||||
|
||||
pub fn print_template(output: &Option<String>) {
|
||||
let script = get_script_template();
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
fn get_script_template() -> &'static str {
|
||||
#[cfg(feature = "switch-rust-lang")]
|
||||
return include_str!("script.template.rs");
|
||||
#[cfg(feature = "switch-go-lang")]
|
||||
return include_str!("script.template.go");
|
||||
#[cfg(feature = "switch-ts-lang")]
|
||||
return include_str!("script.template.ts");
|
||||
#[cfg(feature = "switch-dart-lang")]
|
||||
return include_str!("script.template.dart");
|
||||
panic!("Unknown feature assigned.");
|
||||
}
|
||||
164
src/util.rs
164
src/util.rs
@@ -1,36 +1,92 @@
|
||||
use rust_util::util_cmd;
|
||||
use rust_util::util_env::is_env_on;
|
||||
use rust_util::util_os::get_user_home;
|
||||
use serde::Deserialize;
|
||||
use std::collections::BTreeMap;
|
||||
use std::path::PathBuf;
|
||||
use std::process::Command;
|
||||
use std::time::SystemTime;
|
||||
use std::{env, fs, process};
|
||||
|
||||
#[cfg(feature = "switch-rust-lang")]
|
||||
pub const SCRIPT_HYPHEN_EXT: &str = "-rs";
|
||||
#[cfg(feature = "switch-go-lang")]
|
||||
pub const SCRIPT_HYPHEN_EXT: &str = "-go";
|
||||
#[cfg(feature = "switch-ts-lang")]
|
||||
pub const SCRIPT_HYPHEN_EXT: &str = "-ts";
|
||||
#[cfg(feature = "switch-dart-lang")]
|
||||
pub const SCRIPT_HYPHEN_EXT: &str = "-dart";
|
||||
#[allow(dead_code)]
|
||||
#[derive(Deserialize)]
|
||||
pub struct ScriptMeta {
|
||||
pub script_name: String,
|
||||
pub script_length: u64,
|
||||
pub script_sha256: String,
|
||||
pub script_full_url: String,
|
||||
pub single_script_file: Option<bool>,
|
||||
}
|
||||
|
||||
#[cfg(feature = "switch-rust-lang")]
|
||||
pub const SCRIPT_DOT_EXT: &str = ".rs";
|
||||
#[cfg(feature = "switch-go-lang")]
|
||||
pub const SCRIPT_DOT_EXT: &str = ".go";
|
||||
#[cfg(feature = "switch-ts-lang")]
|
||||
pub const SCRIPT_DOT_EXT: &str = ".ts";
|
||||
#[cfg(feature = "switch-dart-lang")]
|
||||
pub const SCRIPT_DOT_EXT: &str = ".dart";
|
||||
#[allow(unreachable_code)]
|
||||
pub fn get_script_meta_url() -> &'static str {
|
||||
#[cfg(feature = "switch-rust-lang")]
|
||||
return "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/script-meta-v2.json";
|
||||
#[cfg(feature = "switch-go-lang")]
|
||||
return "https://git.hatter.ink/hatter/go-scripts/raw/branch/main/script-meta-v2.json";
|
||||
#[cfg(feature = "switch-ts-lang")]
|
||||
return "https://git.hatter.ink/hatter/ts-scripts/raw/branch/main/script-meta-v2.json";
|
||||
#[cfg(feature = "switch-dart-lang")]
|
||||
return "https://git.hatter.ink/hatter/dart-scripts/raw/branch/main/script-meta-v2.json";
|
||||
panic!("Unknown feature assigned.");
|
||||
}
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
pub fn get_cmd_name() -> &'static str {
|
||||
#[cfg(feature = "switch-rust-lang")]
|
||||
return "runrs";
|
||||
#[cfg(feature = "switch-go-lang")]
|
||||
return "rungo";
|
||||
#[cfg(feature = "switch-ts-lang")]
|
||||
return "runts";
|
||||
#[cfg(feature = "switch-dart-lang")]
|
||||
return "rundart";
|
||||
panic!("Unknown feature assigned.");
|
||||
}
|
||||
|
||||
pub fn build_script_command(rust_script: PathBuf, script_file: &str, script_sha256: &str, cache_script_bin_name: &str) -> Command {
|
||||
pub fn fetch_script_meta_or_die() -> BTreeMap<String, ScriptMeta> {
|
||||
let file_meta_url = get_script_meta_url();
|
||||
debugging!("Loading URL: {}", file_meta_url);
|
||||
let response = reqwest::blocking::get(file_meta_url).unwrap_or_else(|e| {
|
||||
failure_and_exit!("Get file-meta.json failed: {}", e);
|
||||
});
|
||||
debugging!("Load response: {}", response.status().as_u16());
|
||||
if response.status().as_u16() != 200 {
|
||||
failure_and_exit!(
|
||||
"Get file-meta.json failed, status: {}",
|
||||
response.status().as_u16()
|
||||
);
|
||||
}
|
||||
let text = response.text().unwrap_or_else(|e| {
|
||||
failure_and_exit!("Get file-meta.json failed: {}", e);
|
||||
});
|
||||
debugging!("Response text: {}", &text);
|
||||
|
||||
let script_meta_map: BTreeMap<String, ScriptMeta> =
|
||||
serde_json::from_str(&text).expect("Parse script-meta.json failed.");
|
||||
script_meta_map
|
||||
}
|
||||
|
||||
pub fn get_user_home_or_die() -> String {
|
||||
get_user_home().expect("Get user home failed!")
|
||||
}
|
||||
|
||||
pub fn build_script_command(
|
||||
rust_script: PathBuf,
|
||||
script_file: &str,
|
||||
script_sha256: &str,
|
||||
cache_script_bin_name: &str,
|
||||
) -> Command {
|
||||
let skip_cache = is_env_on("RUNRS_SKIP_CACHE");
|
||||
let rebuild = is_env_on("RUNRS_REBUILD");
|
||||
let cache_script_bin_name_exists = fs::metadata(&cache_script_bin_name).is_ok();
|
||||
debugging!("Bin name: {} {}exists", cache_script_bin_name, iff!(cache_script_bin_name_exists, "", "not "));
|
||||
let cache_script_bin_name_exists = fs::metadata(cache_script_bin_name).is_ok();
|
||||
debugging!(
|
||||
"Bin name: {} {}exists",
|
||||
cache_script_bin_name,
|
||||
iff!(cache_script_bin_name_exists, "", "not ")
|
||||
);
|
||||
if !rebuild && !skip_cache && cache_script_bin_name_exists {
|
||||
Command::new(&cache_script_bin_name)
|
||||
Command::new(cache_script_bin_name)
|
||||
} else {
|
||||
let mut cmd = Command::new(rust_script);
|
||||
if !is_env_on("RUNRS_SILENT_BUILD") {
|
||||
@@ -40,37 +96,52 @@ pub fn build_script_command(rust_script: PathBuf, script_file: &str, script_sha2
|
||||
if rebuild {
|
||||
cmd.arg("--force");
|
||||
}
|
||||
cmd.args(&["--bin-name", &script_sha256, script_file]);
|
||||
cmd.args(["--bin-name", script_sha256, script_file]);
|
||||
cmd
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_script_command(script_file: &str, cache_script_bin_name: &str, mut run_script_cmd: &mut Command) -> ! {
|
||||
pub fn run_script_command(
|
||||
script_file: &str,
|
||||
cache_script_bin_name: &str,
|
||||
run_script_cmd: &mut Command,
|
||||
) -> ! {
|
||||
debugging!("Run command: {:?}", run_script_cmd);
|
||||
let run_command_start = SystemTime::now();
|
||||
match util_cmd::run_command_and_wait(&mut run_script_cmd) {
|
||||
match util_cmd::run_command_and_wait(run_script_cmd) {
|
||||
Err(e) => failure_and_exit!("Run rust-script failed: {}", e),
|
||||
Ok(exit_status) => {
|
||||
write_script_file_to_src(script_file, cache_script_bin_name);
|
||||
if let Ok(run_command_cost) = SystemTime::now().duration_since(run_command_start) {
|
||||
debugging!("Run command cost: {}ms", run_command_cost.as_millis());
|
||||
}
|
||||
process::exit(exit_status.code().unwrap_or_else(|| 0))
|
||||
process::exit(exit_status.code().unwrap_or(0))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn write_script_file_to_src(script_file: &str, cache_script_bin_name: &str) {
|
||||
if let Ok(Some(canonicalized_script_file)) = PathBuf::from(script_file)
|
||||
.canonicalize().map(|f| f.to_str().map(|f| f.to_string())) {
|
||||
.canonicalize()
|
||||
.map(|f| f.to_str().map(|f| f.to_string()))
|
||||
{
|
||||
let cache_script_bin_name_src = format!("{}.src", cache_script_bin_name);
|
||||
let src_content = fs::read_to_string(&cache_script_bin_name_src).ok();
|
||||
if src_content.as_ref().map(|c| c.contains(&canonicalized_script_file)).unwrap_or_else(|| false) {
|
||||
if src_content
|
||||
.as_ref()
|
||||
.map(|c| c.contains(&canonicalized_script_file))
|
||||
.unwrap_or_else(|| false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
let new_src_content = src_content.unwrap_or_else(|| "".to_string()) + &format!("{}\n", canonicalized_script_file);
|
||||
if let Ok(_) = fs::write(&cache_script_bin_name_src, &new_src_content) {
|
||||
debugging!("Add {} to {}", canonicalized_script_file, cache_script_bin_name_src);
|
||||
let new_src_content = src_content.unwrap_or_else(|| "".to_string())
|
||||
+ &format!("{}\n", canonicalized_script_file);
|
||||
if fs::write(&cache_script_bin_name_src, &new_src_content).is_ok() {
|
||||
debugging!(
|
||||
"Add {} to {}",
|
||||
canonicalized_script_file,
|
||||
cache_script_bin_name_src
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -87,13 +158,20 @@ pub fn get_run_script_bin_name(home: &str) -> PathBuf {
|
||||
if !rust_script.exists() {
|
||||
warning!("rust-script not found, install it...");
|
||||
let mut cargo_install_rust_script = Command::new("cargo");
|
||||
cargo_install_rust_script.args(&["install", "--git", "https://git.hatter.ink/hatter/runrs", "rust-script"]);
|
||||
cargo_install_rust_script.args([
|
||||
"install",
|
||||
"--git",
|
||||
"https://git.hatter.ink/hatter/runrs",
|
||||
"rust-script",
|
||||
]);
|
||||
debugging!("Run command: {:?}", cargo_install_rust_script);
|
||||
match util_cmd::run_command_and_wait(&mut cargo_install_rust_script) {
|
||||
Err(e) => failure_and_exit!("Install rust-script failed: {}", e),
|
||||
Ok(exist_status) => if !exist_status.success() {
|
||||
failure!("Install rust-script not success: {}", exist_status);
|
||||
},
|
||||
Ok(exist_status) => {
|
||||
if !exist_status.success() {
|
||||
failure!("Install rust-script not success: {}", exist_status);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
rust_script
|
||||
@@ -102,19 +180,21 @@ pub fn get_run_script_bin_name(home: &str) -> PathBuf {
|
||||
pub fn read_file_and_digest(script_file: &str) -> (String, String) {
|
||||
let default_max_script_len = 1024 * 1024;
|
||||
let max_script_len: u64 = env::var("RUNRS_MAX_SCRIPT_LEN")
|
||||
.map(|len| len.parse().unwrap_or_else(|_| default_max_script_len)).unwrap_or_else(|_| default_max_script_len);
|
||||
.map(|len| len.parse().unwrap_or(default_max_script_len))
|
||||
.unwrap_or(default_max_script_len);
|
||||
match fs::metadata(script_file) {
|
||||
Err(_) => failure_and_exit!("Script file not exists: {}", script_file),
|
||||
Ok(metadata) => if metadata.is_dir() {
|
||||
failure_and_exit!("Assigned input is dir: {}", script_file);
|
||||
} else if metadata.len() > max_script_len {
|
||||
failure_and_exit!("Script file: {} too large: {}", script_file, metadata.len());
|
||||
Ok(metadata) => {
|
||||
if metadata.is_dir() {
|
||||
failure_and_exit!("Assigned input is dir: {}", script_file);
|
||||
} else if metadata.len() > max_script_len {
|
||||
failure_and_exit!("Script file: {} too large: {}", script_file, metadata.len());
|
||||
}
|
||||
}
|
||||
}
|
||||
let script_content = fs::read_to_string(script_file).unwrap_or_else(|e|
|
||||
failure_and_exit!("Read file: {}, failed: {}", script_file, e)
|
||||
);
|
||||
let script_content = fs::read_to_string(script_file)
|
||||
.unwrap_or_else(|e| failure_and_exit!("Read file: {}, failed: {}", script_file, e));
|
||||
let script_sha256 = sha256::digest(script_content.as_str());
|
||||
|
||||
(script_content, script_sha256)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user