From 3ace53b509ba7c4f34d8f6b92162f6e1c2092814 Mon Sep 17 00:00:00 2001 From: Hatter Jiang Date: Sun, 29 Dec 2024 17:13:41 +0800 Subject: [PATCH] feat: v0.2.5, support go scripts --- Cargo.lock | 4 +- Cargo.toml | 6 +- justfile | 3 + src/help_go.rs | 24 ++++++ src/{help.rs => help_rs.rs} | 0 src/install.rs | 12 ++- src/list.rs | 14 ++-- src/main.rs | 81 ++++++++++++++++----- src/script.template.go | 40 ++++++++++ src/{script.template => script.template.rs} | 0 src/util.rs | 10 +++ 11 files changed, 163 insertions(+), 31 deletions(-) create mode 100644 src/help_go.rs rename src/{help.rs => help_rs.rs} (100%) create mode 100644 src/script.template.go rename src/{script.template => script.template.rs} (100%) diff --git a/Cargo.lock b/Cargo.lock index eb3c6fe..f23a7a3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "addr2line" @@ -710,7 +710,7 @@ dependencies = [ [[package]] name = "runrs" -version = "0.2.4" +version = "0.2.5" dependencies = [ "reqwest", "rust_util", diff --git a/Cargo.toml b/Cargo.toml index 86440d3..9de3d0f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "runrs" -version = "0.2.4" +version = "0.2.5" edition = "2018" license = "MIT/Apache-2.0" description = "A Tool for Run Rust Scripts" @@ -8,6 +8,10 @@ readme = "README.md" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html +[features] +default = [] +switch-go-lang = [] + [dependencies] reqwest = { version = "0.11.14", features = ["blocking"] } rust_util = "0.6.41" diff --git a/justfile b/justfile index be2599d..ad3398a 100644 --- a/justfile +++ b/justfile @@ -4,3 +4,6 @@ _: install: cargo install --path . +build-run-go: + cargo build --release --features switch-go-lang + diff --git a/src/help_go.rs b/src/help_go.rs new file mode 100644 index 0000000..f4de7ce --- /dev/null +++ b/src/help_go.rs @@ -0,0 +1,24 @@ +pub fn print_help() { + println!(r##"rungo v{} - A Tool for Run Go Scripts + +Show help: +$ rungo -h|--help + +Show template: +$ rungo -t|--template + +Show scriptions: +$ rungo -l|--list + +Install script: +$ rungo -i|--install + +Run script: +$ rungo [arguments] + +Powered by gorun, know more reference: https://github.com/erning/gorun + +"##, + env!("CARGO_PKG_VERSION") + ); +} \ No newline at end of file diff --git a/src/help.rs b/src/help_rs.rs similarity index 100% rename from src/help.rs rename to src/help_rs.rs diff --git a/src/install.rs b/src/install.rs index 0dbf73a..ac1dfbf 100644 --- a/src/install.rs +++ b/src/install.rs @@ -3,24 +3,28 @@ use std::os::unix::fs::PermissionsExt; use std::path::PathBuf; use rust_util::util_os::get_user_home; +use crate::util::{SCRIPT_DOT_EXT, SCRIPT_HYPHEN_EXT}; +#[cfg(not(feature = "switch-go-lang"))] const SCRIPT_PATTERN: &'static str = "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/$NAME/src/main.rs"; +#[cfg(feature = "switch-go-lang")] +const SCRIPT_PATTERN: &'static str = "https://git.hatter.ink/hatter/go-scripts/raw/branch/main/$NAME/main.go"; pub fn install_script(args: Vec<&String>) { if args.is_empty() { failure_and_exit!("No script name assigned!"); } let script_name = &args[0]; - let normalized_script_name = if script_name.ends_with(".rs") { - script_name.chars().take(script_name.len() - 3).collect::() + "-rs" - } else if script_name.ends_with("-rs") { + let normalized_script_name = if script_name.ends_with(SCRIPT_DOT_EXT) { + script_name.chars().take(script_name.len() - 3).collect::() + SCRIPT_HYPHEN_EXT + } else if script_name.ends_with(SCRIPT_HYPHEN_EXT) { script_name.to_string() } else { failure_and_exit!("Invalid script name: {}", script_name); }; let script_file_name = normalized_script_name - .chars().take(normalized_script_name.len() - 3).collect::() + ".rs"; + .chars().take(normalized_script_name.len() - 3).collect::() + 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() { diff --git a/src/list.rs b/src/list.rs index 33d4401..0aa0919 100644 --- a/src/list.rs +++ b/src/list.rs @@ -3,8 +3,12 @@ use serde::Deserialize; use std::collections::BTreeMap; use std::fs; use std::path::PathBuf; +use crate::util::{SCRIPT_DOT_EXT, SCRIPT_HYPHEN_EXT}; +#[cfg(not(feature = "switch-go-lang"))] const FILE_META: &'static str = "https://git.hatter.ink/rust-scripts/scriptbase/raw/branch/main/script-meta.json"; +#[cfg(feature = "switch-go-lang")] +const FILE_META: &'static str = "https://git.hatter.ink/hatter/go-scripts/raw/branch/main/script-meta.json"; #[derive(Deserialize)] struct ScriptMeta { @@ -16,14 +20,14 @@ struct ScriptMeta { pub fn list_scripts() { debugging!("Loading URL: {}", FILE_META); let response = reqwest::blocking::get(FILE_META).unwrap_or_else(|e| { - failure_and_exit!("Get file-meta.txt failed: {}", 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.txt failed, status: {}", response.status().as_u16()); + 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.txt failed: {}", e); + failure_and_exit!("Get file-meta.json failed: {}", e); }); debugging!("Response text: {}", &text); @@ -33,8 +37,8 @@ pub fn list_scripts() { messages.push(format!("Found {} script(s):", script_meta_map.len())); for (_, script_meta) in &script_meta_map { let script_name = &script_meta.script_name; - let real_script_name = if script_name.ends_with("-rs") { - script_name.chars().take(script_name.len() - 3).collect::() + ".rs" + let real_script_name = if script_name.ends_with(SCRIPT_HYPHEN_EXT) { + script_name.chars().take(script_name.len() - 3).collect::() + SCRIPT_DOT_EXT } else { script_name.to_string() }; diff --git a/src/main.rs b/src/main.rs index 121d121..1d63c91 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,27 +5,48 @@ use std::env; use rust_util::util_os::get_user_home; -use crate::help::print_help; +#[cfg(not(feature = "switch-go-lang"))] +use crate::help_rs::print_help; +#[cfg(feature = "switch-go-lang")] +use crate::help_go::print_help; 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}; +use crate::util::{ + build_script_command, get_run_script_bin_name, read_file_and_digest, run_script_command, +}; -mod util; -mod help; -mod list; +#[cfg(feature = "switch-go-lang")] +mod help_go; +#[cfg(not(feature = "switch-go-lang"))] +mod help_rs; mod install; +mod list; +mod util; -const SCRIPT_TEMPLATE: &'static str = include_str!("script.template"); +#[cfg(not(feature = "switch-go-lang"))] +const SCRIPT_TEMPLATE: &'static str = include_str!("script.template.rs"); +#[cfg(feature = "switch-go-lang")] +const SCRIPT_TEMPLATE: &'static str = include_str!("script.template.go"); + +#[cfg(not(feature = "switch-go-lang"))] +const CMD_NAME: &str = "runrs"; +#[cfg(feature = "switch-go-lang")] +const CMD_NAME: &str = "rungo"; fn main() { - let user_home = get_user_home().unwrap_or_else(|| failure_and_exit!("$HOME not found!")); - let rust_script = get_run_script_bin_name(&user_home); - let args = env::args().skip(1).collect::>(); if args.is_empty() { - failure_and_exit!("runrs v{}, need arguments, `runrs -h` or `runrs --help` for help", env!("CARGO_PKG_VERSION")); + failure_and_exit!( + "{} v{}, need arguments, `{} -h` or `{} --help` for help", + CMD_NAME, + env!("CARGO_PKG_VERSION"), + CMD_NAME, + CMD_NAME, + ); } - let first_argument = args.get(0).unwrap_or_else(|| failure_and_exit!("Must assign a script file name")); + let first_argument = args + .get(0) + .unwrap_or_else(|| failure_and_exit!("Must assign a script file name")); if first_argument == "--help" || first_argument == "-h" { print_help(); return; @@ -43,20 +64,42 @@ fn main() { return; } - let script_file = first_argument; + #[cfg(feature = "switch-go-lang")] + if true { + // rungo, and run .go file is not supported + failure_and_exit!("Go script should run by gorun, template for: rungo -t"); + } + let script_file = first_argument; let (_, script_sha256) = read_file_and_digest(script_file); debugging!("File {} -> sha256: {}", script_file, script_sha256); - #[cfg(target_os = "macos")] - let cache_script_bin_name = format!("{}/Library/Caches/rust-script/binaries/release/{}", user_home, script_sha256); - // #[cfg(target_os = "linux")] - #[cfg(not(target_os = "macos"))] - let cache_script_bin_name = format!("{}/.cache/rust-script/binaries/release/{}", user_home, script_sha256); - - let mut run_script_cmd = build_script_command(rust_script, script_file, &script_sha256, &cache_script_bin_name); + let user_home = get_user_home().unwrap_or_else(|| failure_and_exit!("$HOME not found!")); + let rust_script = get_run_script_bin_name(&user_home); + let cache_script_bin_name = get_cache_script_bin_name(&user_home, &script_sha256); + let mut run_script_cmd = build_script_command( + rust_script, + script_file, + &script_sha256, + &cache_script_bin_name, + ); for arg in args.iter().skip(1) { run_script_cmd.arg(arg); } run_script_command(script_file, &cache_script_bin_name, &mut run_script_cmd) } + +fn get_cache_script_bin_name(user_home: &str, script_sha256: &str) -> String { + #[cfg(target_os = "macos")] + let cache_script_bin_name = format!( + "{}/Library/Caches/rust-script/binaries/release/{}", + user_home, script_sha256 + ); + // #[cfg(target_os = "linux")] + #[cfg(not(target_os = "macos"))] + let cache_script_bin_name = format!( + "{}/.cache/rust-script/binaries/release/{}", + user_home, script_sha256 + ); + cache_script_bin_name +} diff --git a/src/script.template.go b/src/script.template.go new file mode 100644 index 0000000..d597df6 --- /dev/null +++ b/src/script.template.go @@ -0,0 +1,40 @@ +/// 2>/dev/null ; gorun "$0" "$@" ; exit $? +// OR: #!/usr/bin/env gorun + +package main + +import ( + "encoding/json" + "fmt" + "io" + "net/http" + "os" +) + +const GetIpUrl = "https://hatter.ink/ip/ip.jsonp" + +type IpResponse struct { + Status int16 `json:"status"` + Message string `json:"message"` + IP string `json:"ip"` + UserAgent string `json:"userAgent"` +} + +func main() { + response, err := http.Get(GetIpUrl) + if err != nil { + fmt.Printf("[ERROR] Get IP failed: %s\n", err) + os.Exit(1) + } + body, err := io.ReadAll(response.Body) + if err != nil { + fmt.Printf("[ERROR] Get IP failed: %s\n", err) + os.Exit(2) + } + var ipReponse IpResponse + if err := json.Unmarshal(body, &ipReponse); err != nil { + fmt.Printf("[ERROR] Get IP failed: %s\n", err) + os.Exit(3) + } + fmt.Printf("[INFO] Your IP address: %s\n", ipReponse.IP) +} diff --git a/src/script.template b/src/script.template.rs similarity index 100% rename from src/script.template rename to src/script.template.rs diff --git a/src/util.rs b/src/util.rs index b875cef..63423cc 100644 --- a/src/util.rs +++ b/src/util.rs @@ -5,6 +5,16 @@ use std::process::Command; use std::time::SystemTime; use std::{env, fs, process}; +#[cfg(not(feature = "switch-go-lang"))] +pub const SCRIPT_HYPHEN_EXT: &str = "-rs"; +#[cfg(feature = "switch-go-lang")] +pub const SCRIPT_HYPHEN_EXT: &str = "-go"; + +#[cfg(not(feature = "switch-go-lang"))] +pub const SCRIPT_DOT_EXT: &str = ".rs"; +#[cfg(feature = "switch-go-lang")] +pub const SCRIPT_DOT_EXT: &str = ".go"; + 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");