diff --git a/.vscode/settings.json b/.vscode/settings.json index b6cac696..cb852cc0 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -15,6 +15,7 @@ "crossterm", "dialoguer", "flate", + "fmtln", "hasher", "indicatif", "outpath", diff --git a/crates/snm_download_builder/src/lib.rs b/crates/snm_download_builder/src/lib.rs index 30ed445a..8758686c 100644 --- a/crates/snm_download_builder/src/lib.rs +++ b/crates/snm_download_builder/src/lib.rs @@ -1,7 +1,7 @@ use colored::*; use futures_util::StreamExt; use indicatif::{ProgressBar, ProgressDrawTarget}; -use reqwest::{Client, StatusCode}; +use reqwest::Client; use snm_utils::snm_error::SnmError; use std::path::Path; use std::time::Duration; @@ -50,12 +50,6 @@ impl DownloadBuilder { download_url: &str, abs_path: P, ) -> Result { - // let response = Client::new().head(download_url).send().await?; - - // if response.status() == StatusCode::NOT_FOUND { - // return Err(SnmError::NotFoundResourceError(download_url.to_string())); - // } - let mut attempts = 0; while attempts < (self.retries + 1) { @@ -91,7 +85,9 @@ impl DownloadBuilder { if abs_path_ref.exists() { match self.write_strategy { WriteStrategy::Error => { - return Err(SnmError::FileAlreadyExists(abs_path_ref.to_path_buf())); + return Err(SnmError::FileAlreadyExists { + file_path: abs_path_ref.to_path_buf(), + }); } WriteStrategy::WriteAfterDelete => { std::fs::remove_file(&abs_path_ref)?; @@ -113,10 +109,6 @@ impl DownloadBuilder { .send() .await?; - if response.status() == StatusCode::NOT_FOUND { - return Err(SnmError::NotFoundResourceError(download_url.to_string())); - } - if !response.status().is_success() { return Err(SnmError::HttpStatusCodeUnOk); } diff --git a/crates/snm_package_json/src/package_json.rs b/crates/snm_package_json/src/package_json.rs index 974721d3..68e0c015 100644 --- a/crates/snm_package_json/src/package_json.rs +++ b/crates/snm_package_json/src/package_json.rs @@ -2,7 +2,7 @@ use std::{collections::HashMap, fs::File, io::BufReader, ops::Not, path::PathBuf use regex::{Match, Regex}; use serde::Deserialize; -use snm_utils::snm_error::SnmError; +use snm_utils::{constant::PACKAGE_MANAGER, snm_error::SnmError}; use crate::{ package_manager_meta::{PackageManager, PackageManagerDownloadHash}, @@ -107,13 +107,11 @@ fn parse_package_manager(raw_package_manager: &str) -> Result Result { let dir = current_dir()?; - let snm_config = parse_snm_config(&dir)?; let snm_node = NodeAtom::new(snm_config.clone()); @@ -83,7 +82,5 @@ pub async fn get_node_bin_dir() -> Result { } let binary = snm_node.get_runtime_binary_dir_string(version.as_str())?; - // let binary_dir_string = ensure_binary_path(&snm_node, &version).await?; - Ok(binary) } diff --git a/crates/snm_shim/src/package_manager_shim.rs b/crates/snm_shim/src/package_manager_shim.rs index d46d5f1f..32f1e195 100644 --- a/crates/snm_shim/src/package_manager_shim.rs +++ b/crates/snm_shim/src/package_manager_shim.rs @@ -8,7 +8,7 @@ use std::{ use snm_atom::{atom::AtomTrait as _, package_manager_atom::PackageManagerAtom}; use snm_config::parse_snm_config; use snm_download_builder::{DownloadBuilder, WriteStrategy}; -use snm_utils::{exec::exec_cli, snm_error::SnmError}; +use snm_utils::{constant::RESTRICTED_LIST, exec::exec_cli, snm_error::SnmError}; use crate::get_node_bin_dir::get_node_bin_dir; @@ -31,8 +31,6 @@ pub async fn package_manager(prefix: &str, bin_name: &str) -> Result<(), SnmErro let snm_package_manage = PackageManagerAtom::new(prefix, snm_config.clone()); - let restricted_list = vec!["install", "i", "run"]; - let bin_dirs = if let Some(package_manager) = snm_config.get_runtime_package_manager() { tracing::trace!( "There is a package manager in the entry process that is currently in use." @@ -74,7 +72,7 @@ pub async fn package_manager(prefix: &str, bin_name: &str) -> Result<(), SnmErro let binary = snm_package_manage.get_runtime_binary_dir_string(version.as_str())?; vec![node_dir.clone(), binary] - } else if restricted_list.contains(&command.as_str()) { + } else if RESTRICTED_LIST.contains(&command.as_str()) { return Err(SnmError::NotMatchPackageManagerError { raw_command: args_all.join(" ").to_string(), expect: package_manager.name, diff --git a/crates/snm_utils/src/constant.rs b/crates/snm_utils/src/constant.rs new file mode 100644 index 00000000..9c294fdf --- /dev/null +++ b/crates/snm_utils/src/constant.rs @@ -0,0 +1,3 @@ +pub const PACKAGE_MANAGER: [&str; 3] = ["npm", "pnpm", "yarn"]; + +pub const RESTRICTED_LIST: [&str; 3] = ["install", "i", "run"]; diff --git a/crates/snm_utils/src/exec.rs b/crates/snm_utils/src/exec.rs index 39d47b91..fb9a1bff 100644 --- a/crates/snm_utils/src/exec.rs +++ b/crates/snm_utils/src/exec.rs @@ -1,7 +1,7 @@ use std::{ env, ffi::OsStr, - process::{Command, Stdio}, + process::{exit, Command, Stdio}, }; use crate::snm_error::SnmError; @@ -32,6 +32,8 @@ where return Err(SnmError::SNMBinaryProxyFail { stderr: String::from_utf8_lossy(&output.stderr).to_string(), }); + // TODO + // exit(1); } print!("{}", String::from_utf8_lossy(&output.stdout).to_string()); diff --git a/crates/snm_utils/src/fmtln.rs b/crates/snm_utils/src/fmtln.rs new file mode 100644 index 00000000..b48c8bd7 --- /dev/null +++ b/crates/snm_utils/src/fmtln.rs @@ -0,0 +1,7 @@ +#[macro_export] +macro_rules! fmtln { + ($fmt:expr, $($arg:tt)*) => { + format!($fmt, $($arg)*) + r#" +"# + }; +} diff --git a/crates/snm_utils/src/lib.rs b/crates/snm_utils/src/lib.rs index f83baea8..e770647d 100644 --- a/crates/snm_utils/src/lib.rs +++ b/crates/snm_utils/src/lib.rs @@ -1,3 +1,5 @@ +pub mod constant; pub mod exec; +pub mod fmtln; pub mod snm_error; pub mod to_ok; diff --git a/crates/snm_utils/src/snm_error.rs b/crates/snm_utils/src/snm_error.rs index 13c5556d..1ac6f4ee 100644 --- a/crates/snm_utils/src/snm_error.rs +++ b/crates/snm_utils/src/snm_error.rs @@ -2,6 +2,8 @@ use colored::*; use std::{path::PathBuf, process::exit}; use thiserror::Error; +use crate::fmtln; + #[derive(Error, Debug)] pub enum SnmError { #[error("Build config error: {0}")] @@ -25,9 +27,6 @@ pub enum SnmError { #[error("Deserialize error: {0}")] DeserializeError(#[from] serde_json::Error), - #[error("Not found: {0}")] - NotFoundResourceError(String), - #[error("Http status code not ok")] HttpStatusCodeUnOk, @@ -37,14 +36,11 @@ pub enum SnmError { #[error("Get workspace dir error")] GetWorkspaceError, - #[error("Not found valid version")] - NotFoundValidNodeVersionDeclaration, - #[error("No default node binary")] NoDefaultNodeBinary, - #[error("File already exists {0}")] - FileAlreadyExists(PathBuf), + #[error("File already exists {file_path}")] + FileAlreadyExists { file_path: PathBuf }, #[error("Exceeded maximum retry attempts: {0}")] ExceededMaxRetries(String), @@ -97,7 +93,7 @@ pub fn create_error_message(message: String, descriptions: Vec) -> Strin .iter() .map(|value| format!("{:<4}{}", "", value)) .collect::>() - .join("\r\n".repeat(2).as_str()); + .join("\r\n".repeat(1).as_str()); format!( r##" @@ -106,13 +102,26 @@ pub fn create_error_message(message: String, descriptions: Vec) -> Strin {:<3}{} {} - "##, +"##, "👹", message, "📋", "Explain", description ) } pub fn friendly_error_message(error: SnmError) { match error { + SnmError::SNMBinaryProxyFail { stderr } => { + eprintln!( + r##" + 👹 SNM proxy error info: + + {} + "##, + stderr + ) + } + SnmError::NoDefaultNodeBinary => { + eprintln!(r##"[error]: No default node binary"##); + } SnmError::ParsePackageManagerError { raw_package_manager, } => { @@ -135,23 +144,14 @@ pub fn friendly_error_message(error: SnmError) { SnmError::ExceededMaxRetries(url) => { let message = create_error_message( "Exceeded max retries".to_string(), - vec![format!( - "The download failed after {} retries.", - url.to_string().bold().red() - )], + vec![ + fmtln!("URL {}", url.to_string().bold().red()), + fmtln!("The download failed after 3 retries.",), + fmtln!("Please check the network connection and the download URL",), + ], ); eprintln!("{}", message); } - SnmError::NotFoundResourceError(url) => { - eprintln!( - r##" - 👹 Not found resource - - The resource {} was not found. - "##, - url.to_string().bold().red() - ); - } SnmError::GetHomeDirError => { eprintln!( r##" @@ -181,22 +181,17 @@ pub fn friendly_error_message(error: SnmError) { "## ); } - SnmError::FileAlreadyExists(path_buf) => { - eprintln!( - r##" - 👹 File already exists - - The file {} already exists. - "##, - path_buf.to_string_lossy().bold().red() + SnmError::FileAlreadyExists { file_path } => { + let message = create_error_message( + "File already exists".to_string(), + vec![format!( + "The file {} already exists.", + file_path.to_string_lossy().bold().red() + )], ); + eprintln!("{}", message); } - SnmError::NotFoundValidNodeVersionDeclaration => { - eprintln!(r##"[error]: Not found valid node version declaration"##); - } - SnmError::NoDefaultNodeBinary => { - eprintln!(r##"[error]: No default node binary"##); - } + SnmError::NotFoundCommandError { bin_name } => { let message = create_error_message( format!("Not found command {}", bin_name.bold().red()), @@ -222,16 +217,6 @@ pub fn friendly_error_message(error: SnmError) { ); eprintln!("{}", message); } - SnmError::SNMBinaryProxyFail { stderr } => { - eprintln!( - r##" - 👹 SNM proxy error info: - - {} - "##, - stderr - ) - } SnmError::ShasumError { file_path, expect, @@ -272,7 +257,7 @@ pub fn friendly_error_message(error: SnmError) { let message = create_error_message( format!("Unsupported node {}", version.bold().bright_red()), vec![ - vec!["Only the following list is supported:".to_string()], + vec![fmtln!("{}", "Only the following list is supported:")], node_white_list .iter() .map(|item| format!("- {}", item).to_string()) @@ -291,10 +276,7 @@ pub fn friendly_error_message(error: SnmError) { format!("Unsupported packageManager {}", name.bold().bright_red()), vec![ vec![ - format!( - "The raw package manager configuration is {}, Only the following list is supported:", - raw.bold().bright_red() - ), + fmtln!("The raw package manager configuration is {}, Only the following list is supported:", raw.bold().bright_red()), ], supported .iter()