v1.1.9
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1221,7 +1221,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "runrs"
|
||||
version = "1.1.8"
|
||||
version = "1.1.9"
|
||||
dependencies = [
|
||||
"argh",
|
||||
"reqwest",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
[package]
|
||||
name = "runrs"
|
||||
version = "1.1.8"
|
||||
version = "1.1.9"
|
||||
edition = "2018"
|
||||
license = "MIT/Apache-2.0"
|
||||
description = "A Tool for Run Rust/TypeScript Scripts"
|
||||
|
||||
@@ -31,8 +31,11 @@ struct RunScriptArgs {
|
||||
#[argh(switch, short = 'i')]
|
||||
install: bool,
|
||||
/// update listed scripts
|
||||
#[argh(switch)]
|
||||
#[argh(switch, short = 'U')]
|
||||
update_listed_scripts: bool,
|
||||
/// force update https script file
|
||||
#[argh(switch)]
|
||||
force_update: bool,
|
||||
/// script repo
|
||||
#[argh(option, short = 'R')]
|
||||
script_repo: Option<String>,
|
||||
|
||||
@@ -1,10 +1,31 @@
|
||||
use crate::util;
|
||||
use rust_util::util_time::get_current_millis;
|
||||
use rust_util::XResult;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use std::fs;
|
||||
use std::path::Path;
|
||||
|
||||
#[allow(unreachable_code)]
|
||||
fn get_script_cache_dir() -> &'static str {
|
||||
#[cfg(feature = "switch-rust-lang")]
|
||||
{
|
||||
return "runrs";
|
||||
}
|
||||
#[cfg(feature = "switch-ts-lang")]
|
||||
{
|
||||
return "runts";
|
||||
}
|
||||
failure_and_exit!("Only rust/ts script supported.");
|
||||
}
|
||||
|
||||
#[derive(Debug, Serialize, Deserialize)]
|
||||
struct HttpsScriptMeta {
|
||||
url: String,
|
||||
download_time: u128,
|
||||
}
|
||||
|
||||
// download from internet if starts with https://
|
||||
pub fn resolve_file(script_file: &str) -> XResult<String> {
|
||||
pub fn resolve_file(script_file: &str, force_update: bool) -> XResult<String> {
|
||||
if script_file.starts_with("http://") {
|
||||
return simple_error!("Insecure script file: {}", script_file);
|
||||
}
|
||||
@@ -14,23 +35,55 @@ pub fn resolve_file(script_file: &str) -> XResult<String> {
|
||||
let file_sha256 = sha256::digest(script_file);
|
||||
let file_name = get_file_name(script_file)?;
|
||||
let cache_file_path = format!(
|
||||
"{}/.cache/runrs/{}/{}",
|
||||
"{}/.cache/{}/{}/{}",
|
||||
util::get_user_home_or_die(),
|
||||
get_script_cache_dir(),
|
||||
file_sha256,
|
||||
file_name
|
||||
);
|
||||
let cache_file_path_url = format!(
|
||||
"{}/.cache/runrs/{}.url",
|
||||
let cache_file_path_meta = format!(
|
||||
"{}/.cache/{}/{}.meta",
|
||||
util::get_user_home_or_die(),
|
||||
get_script_cache_dir(),
|
||||
file_sha256
|
||||
);
|
||||
debugging!("Cache file: {}", cache_file_path);
|
||||
if let Ok(metadata) = fs::metadata(&cache_file_path) {
|
||||
if metadata.is_file() {
|
||||
let is_script_path_latest_version = script_file.contains("/@latest/");
|
||||
let cache_file_path_exists = fs::metadata(&cache_file_path).is_ok();
|
||||
debugging!(
|
||||
"Cache file: {}, is latest version: {}, cache file exists: {}",
|
||||
cache_file_path,
|
||||
is_script_path_latest_version,
|
||||
cache_file_path_exists
|
||||
);
|
||||
|
||||
if force_update {
|
||||
debugging!("Force update is on, skip cache file check");
|
||||
} else if is_script_path_latest_version {
|
||||
// force update is not on, and script file is @latest version
|
||||
if let Ok(cache_file_path_meta_content) = fs::read_to_string(&cache_file_path_meta) {
|
||||
if let Ok(http_script_meta) =
|
||||
serde_json::from_str::<HttpsScriptMeta>(&cache_file_path_meta_content)
|
||||
{
|
||||
let current_millis = get_current_millis();
|
||||
debugging!(
|
||||
"Read from meta: {:?}, current millis: {}",
|
||||
http_script_meta,
|
||||
current_millis
|
||||
);
|
||||
if current_millis - http_script_meta.download_time < 12 * 60 * 60 * 1000
|
||||
&& cache_file_path_exists
|
||||
{
|
||||
// script file is download in 12 hours
|
||||
return Ok(cache_file_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// force update is not on, and script is static version, check file existence only
|
||||
if cache_file_path_exists {
|
||||
debugging!("Found cache file: {}", cache_file_path);
|
||||
return Ok(cache_file_path);
|
||||
}
|
||||
return simple_error!("Cache file is not a file: {}", cache_file_path);
|
||||
}
|
||||
|
||||
// create cache file parent path if not exists
|
||||
@@ -59,13 +112,31 @@ pub fn resolve_file(script_file: &str) -> XResult<String> {
|
||||
let get_script_response_result = reqwest::blocking::get(script_file);
|
||||
debugging!("Get script response: {:#?}", &get_script_response_result);
|
||||
let get_script_response = match get_script_response_result {
|
||||
Err(e) => return simple_error!("Get script failed: {}", e),
|
||||
Err(e) => {
|
||||
if cache_file_path_exists {
|
||||
warning!(
|
||||
"Get script failed, reuse local cache file: {}",
|
||||
cache_file_path
|
||||
);
|
||||
return Ok(cache_file_path);
|
||||
}
|
||||
return simple_error!("Get script failed: {}", e);
|
||||
}
|
||||
Ok(response) => response,
|
||||
};
|
||||
let get_script_response_status = get_script_response.status().as_u16();
|
||||
if get_script_response_status == 404 {
|
||||
// when 404 do not reuse local cache file
|
||||
return simple_error!("Script not found!");
|
||||
} else if get_script_response_status != 200 {
|
||||
if cache_file_path_exists {
|
||||
warning!(
|
||||
"Get script failed, status: {}, reuse local cache file: {}",
|
||||
get_script_response_status,
|
||||
cache_file_path
|
||||
);
|
||||
return Ok(cache_file_path);
|
||||
}
|
||||
return simple_error!("Get script failed: {}", get_script_response_status);
|
||||
}
|
||||
let remote_script_content = match get_script_response.text() {
|
||||
@@ -78,9 +149,15 @@ pub fn resolve_file(script_file: &str) -> XResult<String> {
|
||||
if let Err(e) = fs::write(&cache_file_path, remote_script_content) {
|
||||
return simple_error!("Write script: {} failed: {}", cache_file_path, e);
|
||||
}
|
||||
if let Err(_) = fs::write(&cache_file_path_url, script_file) {
|
||||
let meta = HttpsScriptMeta {
|
||||
url: script_file.to_string(),
|
||||
download_time: get_current_millis(),
|
||||
};
|
||||
if let Ok(meta_json) = serde_json::to_string_pretty(&meta) {
|
||||
if let Err(_) = fs::write(&cache_file_path_meta, &meta_json) {
|
||||
// JUST IGNORE
|
||||
}
|
||||
}
|
||||
|
||||
Ok(cache_file_path)
|
||||
}
|
||||
|
||||
@@ -8,7 +8,7 @@ pub fn do_run_script(args: &RunScriptArgs) {
|
||||
failure_and_exit!("Must assign a script file name");
|
||||
}
|
||||
let script_file = &args.arguments[0];
|
||||
let script_file = resolve_file(script_file)
|
||||
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;
|
||||
|
||||
|
||||
@@ -26,7 +26,7 @@ pub fn do_run_script(args: &RunScriptArgs) {
|
||||
}
|
||||
(&args.arguments[args.arguments.len() - 1], false)
|
||||
})();
|
||||
let script_file = resolve_file(raw_script_file)
|
||||
let script_file = resolve_file(raw_script_file, args.force_update)
|
||||
.unwrap_or_else(|e| failure_and_exit!("Failed to resolve script: {}", e));
|
||||
let script_file = &script_file;
|
||||
verify::verify_script(script_file, is_env_on("RUNTS_SKIP_VERIFY"));
|
||||
|
||||
Reference in New Issue
Block a user