feat: script-meta-v2
This commit is contained in:
6
script-config.json
Normal file
6
script-config.json
Normal file
@@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"file_ext": "rs",
|
||||||
|
"simple_script_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/master/single-scripts/$NAME",
|
||||||
|
"project_script_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/$NAME/src/main.rs",
|
||||||
|
"skip_dirs": []
|
||||||
|
}
|
||||||
87
script-meta-v2.json
Normal file
87
script-meta-v2.json
Normal file
@@ -0,0 +1,87 @@
|
|||||||
|
{
|
||||||
|
"bit-address.rs": {
|
||||||
|
"script_name": "bit-address.rs",
|
||||||
|
"script_length": 3877,
|
||||||
|
"script_sha256": "806980fef2db63d42024010bc7bc010664ec616662164fb6490ca9389502d869",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/bit-address-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"commit-msg.rs": {
|
||||||
|
"script_name": "commit-msg.rs",
|
||||||
|
"script_length": 6618,
|
||||||
|
"script_sha256": "63d1569f1ae8b5b9c14e3be8a79841dbf67e954c16e1bb16f07c2b2f6660c88f",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/commit-msg-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"current-time.rs": {
|
||||||
|
"script_name": "current-time.rs",
|
||||||
|
"script_length": 3301,
|
||||||
|
"script_sha256": "51536795cafedf593184a2690f08ee8fc2be9b5dccdd8a52fafa025d66c26e96",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/current-time-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"decrypt.rs": {
|
||||||
|
"script_name": "decrypt.rs",
|
||||||
|
"script_length": 3087,
|
||||||
|
"script_sha256": "7f5bb37855da9b350fb1ca646fd75a3a71533a8f5f7913ac81036ad1b2082f3c",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/decrypt-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"derparse.rs": {
|
||||||
|
"script_name": "derparse.rs",
|
||||||
|
"script_length": 7368,
|
||||||
|
"script_sha256": "423eb3c6ce57baf7bc8c9f452fdead2f3dc3d86f3724aa8bd7016ece8ce1853b",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/derparse-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"helloworld.rs": {
|
||||||
|
"script_name": "helloworld.rs",
|
||||||
|
"script_length": 64,
|
||||||
|
"script_sha256": "b1cf245146e6684986b1f0788d2282fdb1c617eac0961a84bfbd65f386975993",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/master/single-scripts/helloworld.rs",
|
||||||
|
"single_script_file": true
|
||||||
|
},
|
||||||
|
"makepassword.rs": {
|
||||||
|
"script_name": "makepassword.rs",
|
||||||
|
"script_length": 1966,
|
||||||
|
"script_sha256": "0ca721d3531a9cc94c95193e7148c0316551fd65d84de7f54bd4b6418ff37f01",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/makepassword-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"myip.rs": {
|
||||||
|
"script_name": "myip.rs",
|
||||||
|
"script_length": 933,
|
||||||
|
"script_sha256": "9756186298cf6a65561760603e6369ee961e3271ea0cf86361b88c2250c3e690",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/myip-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"osssendfile.rs": {
|
||||||
|
"script_name": "osssendfile.rs",
|
||||||
|
"script_length": 13853,
|
||||||
|
"script_sha256": "218eecef46329fb6d73986d3db1a07dd29fe99269f46290eda165e5f3d663ca9",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/osssendfile-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"post.rs": {
|
||||||
|
"script_name": "post.rs",
|
||||||
|
"script_length": 10494,
|
||||||
|
"script_sha256": "fe3571fdcd170608575c610ba51fcaeee7aea0fe82ae4bc22032f61c7787d22f",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/post-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"rpm-read.rs": {
|
||||||
|
"script_name": "rpm-read.rs",
|
||||||
|
"script_length": 637,
|
||||||
|
"script_sha256": "2338fb99c2803fc36ecdb09ec04eeb9aefb3524f8a68db4875562fdf3c8ba3f8",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/rpm-read-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"script-sign.rs": {
|
||||||
|
"script_name": "script-sign.rs",
|
||||||
|
"script_length": 16506,
|
||||||
|
"script_sha256": "d8dc82553a5300ecee3364ed04596163295139f8b18e0d1a95b89ea6540ebfe5",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/script-sign-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"sync.rs": {
|
||||||
|
"script_name": "sync.rs",
|
||||||
|
"script_length": 1818,
|
||||||
|
"script_sha256": "d947c179820a9d13284de9b8d0173f1738a06fbcacb40473a02aa94417c53454",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/sync-rs/src/main.rs"
|
||||||
|
},
|
||||||
|
"xattr.rs": {
|
||||||
|
"script_name": "xattr.rs",
|
||||||
|
"script_length": 1822,
|
||||||
|
"script_sha256": "b49aadee8bdb76217ee3ce880b1ac8fbcc2af14a7c99053a7e847079ef5822b4",
|
||||||
|
"script_full_url": "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/xattr-rs/src/main.rs"
|
||||||
|
}
|
||||||
|
}
|
||||||
5
single-scripts/helloworld.rs
Executable file
5
single-scripts/helloworld.rs
Executable file
@@ -0,0 +1,5 @@
|
|||||||
|
#!/usr/bin/env runrs
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println!("Hello World.");
|
||||||
|
}
|
||||||
@@ -8,26 +8,68 @@
|
|||||||
//! rust_util = { version = "0.6" }
|
//! rust_util = { version = "0.6" }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
use rust_util::{debugging, failure_and_exit, opt_result, opt_value_result, success, XResult};
|
use rust_util::{
|
||||||
use serde::Serialize;
|
debugging, failure_and_exit, iff, opt_result, opt_value_result, success, warning, XResult,
|
||||||
|
};
|
||||||
|
use serde::{Deserialize, Serialize};
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::fs;
|
use std::fs;
|
||||||
|
use std::option::Option;
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
const SCRIPT_META_FILE: &str = "script-meta.json";
|
const SCRIPT_META_FILE: &str = "script-meta-v2.json";
|
||||||
|
const SCRIPT_CONFIG_FILE: &str = "script-config.json";
|
||||||
|
const SINGLE_SCRIPTS_DIR: &str = "single-scripts";
|
||||||
|
|
||||||
|
#[derive(Debug, Deserialize)]
|
||||||
|
struct ScriptConfig {
|
||||||
|
file_ext: String,
|
||||||
|
simple_script_url: String,
|
||||||
|
project_script_url: String,
|
||||||
|
skip_dirs: Vec<String>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ScriptConfig {
|
||||||
|
fn skip_dir(&self, dir: &str) -> bool {
|
||||||
|
for skip_dir in &self.skip_dirs {
|
||||||
|
if skip_dir == dir {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
dir == "update-meta-rs" || dir == SINGLE_SCRIPTS_DIR || dir.starts_with(".")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Serialize)]
|
#[derive(Serialize)]
|
||||||
struct ScriptMeta {
|
struct ScriptMeta {
|
||||||
script_name: String,
|
script_name: String,
|
||||||
script_length: u64,
|
script_length: u64,
|
||||||
script_sha256: String,
|
script_sha256: String,
|
||||||
|
script_full_url: String,
|
||||||
|
#[serde(skip_serializing_if = "Option::is_none")]
|
||||||
|
single_script_file: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() -> XResult<()> {
|
fn main() -> XResult<()> {
|
||||||
|
if fs::metadata(SCRIPT_CONFIG_FILE).is_err() {
|
||||||
|
failure_and_exit!("Script config file {} not found.", SCRIPT_CONFIG_FILE);
|
||||||
|
}
|
||||||
if fs::metadata(SCRIPT_META_FILE).is_err() {
|
if fs::metadata(SCRIPT_META_FILE).is_err() {
|
||||||
failure_and_exit!("Script meta file {} not found.", SCRIPT_META_FILE);
|
failure_and_exit!("Script meta file {} not found.", SCRIPT_META_FILE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let script_config_content = opt_result!(
|
||||||
|
fs::read_to_string(SCRIPT_CONFIG_FILE),
|
||||||
|
"Read {}, failed: {}",
|
||||||
|
SCRIPT_CONFIG_FILE
|
||||||
|
);
|
||||||
|
let script_config: ScriptConfig = opt_result!(
|
||||||
|
serde_json::from_str(&script_config_content),
|
||||||
|
"Parse {}, failed: {}",
|
||||||
|
SCRIPT_CONFIG_FILE
|
||||||
|
);
|
||||||
|
debugging!("Script config: {:#?}", script_config);
|
||||||
|
|
||||||
let mut script_meta_map = BTreeMap::new();
|
let mut script_meta_map = BTreeMap::new();
|
||||||
|
|
||||||
let current_read_dir = opt_result!(fs::read_dir("."), "Read dir '.' failed: {}");
|
let current_read_dir = opt_result!(fs::read_dir("."), "Read dir '.' failed: {}");
|
||||||
@@ -40,19 +82,67 @@ fn main() -> XResult<()> {
|
|||||||
debugging!("Skip none dir: {}", script_dir);
|
debugging!("Skip none dir: {}", script_dir);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if "update-meta-rs" == script_dir || script_dir.starts_with(".") {
|
if script_config.skip_dir(&script_dir) {
|
||||||
debugging!("Skip update meta rs: {}", script_dir);
|
debugging!("Skip update skip dirs: {}", script_dir);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let abs_dir_entry = std::path::absolute(&dir_entry.path())?;
|
let abs_dir_entry = std::path::absolute(&dir_entry.path())?;
|
||||||
let main_rs = abs_dir_entry
|
let main_script = abs_dir_entry
|
||||||
.join("src")
|
.join("src")
|
||||||
.join("main.rs");
|
.join(format!("main.{}", script_config.file_ext));
|
||||||
|
|
||||||
script_meta_map.insert(
|
if let Some(script_file_name) =
|
||||||
script_dir.to_string(),
|
translate_script_dir_to_script_name(script_dir, &script_config)
|
||||||
read_script_meta(script_dir, &main_rs)?,
|
{
|
||||||
);
|
script_meta_map.insert(
|
||||||
|
script_file_name.clone(),
|
||||||
|
read_script_meta(
|
||||||
|
script_dir,
|
||||||
|
script_file_name.clone(),
|
||||||
|
&main_script,
|
||||||
|
false,
|
||||||
|
&script_config,
|
||||||
|
)?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Ok(single_script_meta) = fs::metadata(SINGLE_SCRIPTS_DIR) {
|
||||||
|
if single_script_meta.is_dir() {
|
||||||
|
let single_scripts_read_dir =
|
||||||
|
opt_result!(fs::read_dir(SINGLE_SCRIPTS_DIR), "Read dir '.' failed: {}");
|
||||||
|
for file in single_scripts_read_dir {
|
||||||
|
let file_entry = opt_result!(file, "Get dir failed: {}");
|
||||||
|
let dir_file_type = opt_result!(file_entry.file_type(), "Get dir type failed: {}");
|
||||||
|
let file_name_os_string = file_entry.file_name();
|
||||||
|
let script_file =
|
||||||
|
opt_value_result!(file_name_os_string.to_str(), "Cannot get file name.");
|
||||||
|
if !dir_file_type.is_file() {
|
||||||
|
debugging!("Skip none file: {}", script_file);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let abs_file_entry = std::path::absolute(&file_entry.path())?;
|
||||||
|
let script_file_ext = format!(".{}", script_config.file_ext);
|
||||||
|
if !script_file.ends_with(&script_file_ext) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
let script_file_name = script_file.to_string();
|
||||||
|
if script_meta_map.contains_key(&script_file_name) {
|
||||||
|
warning!("Script: {script_file_name} exists.");
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
script_meta_map.insert(
|
||||||
|
script_file_name.clone(),
|
||||||
|
read_script_meta(
|
||||||
|
"",
|
||||||
|
script_file_name.clone(),
|
||||||
|
&abs_file_entry,
|
||||||
|
true,
|
||||||
|
&script_config,
|
||||||
|
)?,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let script_meta_json = serde_json::to_string_pretty(&script_meta_map)?;
|
let script_meta_json = serde_json::to_string_pretty(&script_meta_map)?;
|
||||||
@@ -64,13 +154,52 @@ fn main() -> XResult<()> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn read_script_meta(file_name: &str, main_rs: &PathBuf) -> XResult<ScriptMeta> {
|
// translate filename-ext to filename.ext
|
||||||
let main_rs_meta = opt_result!(main_rs.metadata(), "Read file: {:?} meta failed: {}", main_rs);
|
fn translate_script_dir_to_script_name(
|
||||||
let main_rs_content = fs::read(main_rs)?;
|
script_dir: &str,
|
||||||
let script_sha256 = sha256::digest(&main_rs_content);
|
script_config: &ScriptConfig,
|
||||||
|
) -> Option<String> {
|
||||||
|
let script_dir_ext = format!("-{}", script_config.file_ext);
|
||||||
|
if script_dir.ends_with(&script_dir_ext) {
|
||||||
|
let remove_ext_dir_name = script_dir
|
||||||
|
.chars()
|
||||||
|
.take(script_dir.len() - script_dir_ext.len())
|
||||||
|
.collect::<String>();
|
||||||
|
Some(format!("{remove_ext_dir_name}.{}", script_config.file_ext))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn read_script_meta(
|
||||||
|
script_dir: &str,
|
||||||
|
script_name: String,
|
||||||
|
script_path: &PathBuf,
|
||||||
|
is_simple_script: bool,
|
||||||
|
script_config: &ScriptConfig,
|
||||||
|
) -> XResult<ScriptMeta> {
|
||||||
|
let script_meta = opt_result!(
|
||||||
|
script_path.metadata(),
|
||||||
|
"Read file: {:?} meta failed: {}",
|
||||||
|
script_path
|
||||||
|
);
|
||||||
|
let script_path_content = fs::read(script_path)?;
|
||||||
|
let script_sha256 = sha256::digest(&script_path_content);
|
||||||
|
let script_full_url = if is_simple_script {
|
||||||
|
script_config
|
||||||
|
.simple_script_url
|
||||||
|
.replace("$NAME", &script_name)
|
||||||
|
} else {
|
||||||
|
script_config
|
||||||
|
.project_script_url
|
||||||
|
.replace("$NAME", script_dir)
|
||||||
|
};
|
||||||
|
let single_script_file = iff!(is_simple_script, Some(true), None);
|
||||||
Ok(ScriptMeta {
|
Ok(ScriptMeta {
|
||||||
script_name: file_name.to_string(),
|
script_name: script_name.clone(),
|
||||||
script_length: main_rs_meta.len(),
|
script_length: script_meta.len(),
|
||||||
script_sha256,
|
script_sha256,
|
||||||
|
script_full_url,
|
||||||
|
single_script_file,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user