v1.1.9
This commit is contained in:
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -1221,7 +1221,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "runrs"
|
name = "runrs"
|
||||||
version = "1.1.8"
|
version = "1.1.9"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"argh",
|
"argh",
|
||||||
"reqwest",
|
"reqwest",
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "runrs"
|
name = "runrs"
|
||||||
version = "1.1.8"
|
version = "1.1.9"
|
||||||
edition = "2018"
|
edition = "2018"
|
||||||
license = "MIT/Apache-2.0"
|
license = "MIT/Apache-2.0"
|
||||||
description = "A Tool for Run Rust/TypeScript Scripts"
|
description = "A Tool for Run Rust/TypeScript Scripts"
|
||||||
|
|||||||
@@ -31,8 +31,11 @@ struct RunScriptArgs {
|
|||||||
#[argh(switch, short = 'i')]
|
#[argh(switch, short = 'i')]
|
||||||
install: bool,
|
install: bool,
|
||||||
/// update listed scripts
|
/// update listed scripts
|
||||||
#[argh(switch)]
|
#[argh(switch, short = 'U')]
|
||||||
update_listed_scripts: bool,
|
update_listed_scripts: bool,
|
||||||
|
/// force update https script file
|
||||||
|
#[argh(switch)]
|
||||||
|
force_update: bool,
|
||||||
/// script repo
|
/// script repo
|
||||||
#[argh(option, short = 'R')]
|
#[argh(option, short = 'R')]
|
||||||
script_repo: Option<String>,
|
script_repo: Option<String>,
|
||||||
|
|||||||
@@ -1,10 +1,31 @@
|
|||||||
use crate::util;
|
use crate::util;
|
||||||
|
use rust_util::util_time::get_current_millis;
|
||||||
use rust_util::XResult;
|
use rust_util::XResult;
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::fs;
|
use std::fs;
|
||||||
use std::path::Path;
|
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://
|
// 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://") {
|
if script_file.starts_with("http://") {
|
||||||
return simple_error!("Insecure script file: {}", script_file);
|
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_sha256 = sha256::digest(script_file);
|
||||||
let file_name = get_file_name(script_file)?;
|
let file_name = get_file_name(script_file)?;
|
||||||
let cache_file_path = format!(
|
let cache_file_path = format!(
|
||||||
"{}/.cache/runrs/{}/{}",
|
"{}/.cache/{}/{}/{}",
|
||||||
util::get_user_home_or_die(),
|
util::get_user_home_or_die(),
|
||||||
|
get_script_cache_dir(),
|
||||||
file_sha256,
|
file_sha256,
|
||||||
file_name
|
file_name
|
||||||
);
|
);
|
||||||
let cache_file_path_url = format!(
|
let cache_file_path_meta = format!(
|
||||||
"{}/.cache/runrs/{}.url",
|
"{}/.cache/{}/{}.meta",
|
||||||
util::get_user_home_or_die(),
|
util::get_user_home_or_die(),
|
||||||
|
get_script_cache_dir(),
|
||||||
file_sha256
|
file_sha256
|
||||||
);
|
);
|
||||||
debugging!("Cache file: {}", cache_file_path);
|
let is_script_path_latest_version = script_file.contains("/@latest/");
|
||||||
if let Ok(metadata) = fs::metadata(&cache_file_path) {
|
let cache_file_path_exists = fs::metadata(&cache_file_path).is_ok();
|
||||||
if metadata.is_file() {
|
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);
|
debugging!("Found cache file: {}", cache_file_path);
|
||||||
return Ok(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
|
// 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);
|
let get_script_response_result = reqwest::blocking::get(script_file);
|
||||||
debugging!("Get script response: {:#?}", &get_script_response_result);
|
debugging!("Get script response: {:#?}", &get_script_response_result);
|
||||||
let get_script_response = match 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,
|
Ok(response) => response,
|
||||||
};
|
};
|
||||||
let get_script_response_status = get_script_response.status().as_u16();
|
let get_script_response_status = get_script_response.status().as_u16();
|
||||||
if get_script_response_status == 404 {
|
if get_script_response_status == 404 {
|
||||||
|
// when 404 do not reuse local cache file
|
||||||
return simple_error!("Script not found!");
|
return simple_error!("Script not found!");
|
||||||
} else if get_script_response_status != 200 {
|
} 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);
|
return simple_error!("Get script failed: {}", get_script_response_status);
|
||||||
}
|
}
|
||||||
let remote_script_content = match get_script_response.text() {
|
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) {
|
if let Err(e) = fs::write(&cache_file_path, remote_script_content) {
|
||||||
return simple_error!("Write script: {} failed: {}", cache_file_path, e);
|
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
|
// JUST IGNORE
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Ok(cache_file_path)
|
Ok(cache_file_path)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ pub fn do_run_script(args: &RunScriptArgs) {
|
|||||||
failure_and_exit!("Must assign a script file name");
|
failure_and_exit!("Must assign a script file name");
|
||||||
}
|
}
|
||||||
let script_file = &args.arguments[0];
|
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));
|
.unwrap_or_else(|e| failure_and_exit!("Failed to resolve script: {}", e));
|
||||||
let script_file = &script_file;
|
let script_file = &script_file;
|
||||||
|
|
||||||
|
|||||||
@@ -26,7 +26,7 @@ pub fn do_run_script(args: &RunScriptArgs) {
|
|||||||
}
|
}
|
||||||
(&args.arguments[args.arguments.len() - 1], false)
|
(&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));
|
.unwrap_or_else(|e| failure_and_exit!("Failed to resolve script: {}", e));
|
||||||
let script_file = &script_file;
|
let script_file = &script_file;
|
||||||
verify::verify_script(script_file, is_env_on("RUNTS_SKIP_VERIFY"));
|
verify::verify_script(script_file, is_env_on("RUNTS_SKIP_VERIFY"));
|
||||||
|
|||||||
Reference in New Issue
Block a user