From 9c17370df5a016256a03bd8f35a20d92a252b9d4 Mon Sep 17 00:00:00 2001 From: ityuany <519495771@qq.com> Date: Wed, 17 Apr 2024 16:34:27 +0800 Subject: [PATCH] add dlx command --- crates/cli/src/main.rs | 45 ++++++++++++++++------- crates/cli/src/ni/npm_args.rs | 13 +++++++ crates/cli/src/ni/pnpm_args.rs | 9 +++++ crates/cli/src/ni/trait_transform_args.rs | 8 ++++ crates/cli/src/ni/yarn_args.rs | 9 +++++ crates/cli/src/ni/yarnpkg_args.rs | 9 +++++ crates/cli/src/snm_command.rs | 6 ++- 7 files changed, 83 insertions(+), 16 deletions(-) diff --git a/crates/cli/src/main.rs b/crates/cli/src/main.rs index 2d1088c8..e1b83b81 100644 --- a/crates/cli/src/main.rs +++ b/crates/cli/src/main.rs @@ -15,8 +15,11 @@ use snm_command::SnmCommands; use snm_core::{ config::SnmConfig, model::{ - dispatch_manage::DispatchManage, package_json::PackageManager, snm_error::handle_snm_error, - trait_manage::ManageTrait, PackageJson, SnmError, + dispatch_manage::DispatchManage, + package_json::{self, PackageManager}, + snm_error::handle_snm_error, + trait_manage::ManageTrait, + PackageJson, SnmError, }, println_success, }; @@ -25,6 +28,7 @@ use snm_npm::snm_npm::SnmNpm; use snm_pnpm::snm_pnpm::SnmPnpm; use snm_yarn::{snm_yarn::SnmYarn, snm_yarnpkg::SnmYarnPkg}; use std::{ + env::current_dir, path::PathBuf, process::{Command, Stdio}, }; @@ -205,32 +209,45 @@ async fn execute_cli() -> Result<(), SnmError> { SnmCommands::Bump => { bump_impl()?; } - SnmCommands::Dlx => todo!(), + SnmCommands::Dlx(args) => { + execute_command(|creator| creator.get_dlx_command(args)).await?; + } SnmCommands::Exec => todo!(), } Ok(()) } -async fn get_bin() -> Result<(PackageManager, PathBuf), SnmError> { - let package_manager = PackageJson::from_dir_path(None)?.parse_package_manager()?; - let manager = get_manage(&package_manager).await?; - let dispatcher = DispatchManage::new(manager); - let (_, bin_path_buf) = dispatcher.ensure_strict_package_manager().await?; - Ok((package_manager, bin_path_buf)) +async fn get_bin() -> Result<((String, String), PathBuf), SnmError> { + let dir = current_dir()?; + let package_json_path_buf = dir.join("package.json"); + if package_json_path_buf.exists() { + let package_json: PackageJson = PackageJson::from_file_path(&package_json_path_buf)?; + let package_manager = package_json.parse_package_manager()?; + let manager = get_manage(&package_manager).await?; + let dispatcher = DispatchManage::new(manager); + let (_, bin_path_buf) = dispatcher.proxy_process().await?; + return Ok(( + (package_manager.name, package_manager.version), + bin_path_buf, + )); + } else { + let dispatcher = DispatchManage::new(Box::new(SnmPnpm::new())); + let (version, bin_path_buf) = dispatcher.proxy_process().await?; + return Ok((("pnpm".to_string(), version), bin_path_buf)); + } } async fn execute_command(get_command_args: F) -> Result<(), SnmError> where F: FnOnce(&dyn CommandArgsCreatorTrait) -> Result, SnmError>, { - let (package_manager, bin_path_buf) = get_bin().await?; + let ((name, version), bin_path_buf) = get_bin().await?; - let command_args_creator: Box = match package_manager.name.as_str() - { + let command_args_creator: Box = match name.as_str() { "npm" => Box::new(NpmArgsTransform {}), "pnpm" => Box::new(PnpmArgsTransform {}), "yarn" => { - if get_is_less_2(&package_manager.version)? { + if get_is_less_2(&version)? { Box::new(YarnArgsTransform {}) } else { Box::new(YarnPkgArgsTransform {}) @@ -243,7 +260,7 @@ where println_success!( "Use {}. {}", - format!("{:<8}", package_manager.version).bright_green(), + format!("{:<8}", &version).bright_green(), format!("by {}", bin_path_buf.display()).bright_black() ); diff --git a/crates/cli/src/ni/npm_args.rs b/crates/cli/src/ni/npm_args.rs index 89c01f17..ede21e0d 100644 --- a/crates/cli/src/ni/npm_args.rs +++ b/crates/cli/src/ni/npm_args.rs @@ -40,4 +40,17 @@ impl CommandArgsCreatorTrait for NpmArgsTransform { let process_args = vec!["uninstall".to_string(), args.package_spec]; Ok(process_args) } + + fn get_dlx_command( + &self, + args: super::trait_transform_args::DlxCommandArgs, + ) -> Result, SnmError> { + let mut process_args = vec!["exec".to_string()]; + + process_args.append(&mut args.package_spec.clone()); + + process_args.append(&mut vec!["-n".to_string()]); + + Ok(process_args) + } } diff --git a/crates/cli/src/ni/pnpm_args.rs b/crates/cli/src/ni/pnpm_args.rs index 4695a465..c59b05c9 100644 --- a/crates/cli/src/ni/pnpm_args.rs +++ b/crates/cli/src/ni/pnpm_args.rs @@ -39,4 +39,13 @@ impl CommandArgsCreatorTrait for PnpmArgsTransform { let process_args = vec!["remove".to_string(), args.package_spec]; Ok(process_args) } + + fn get_dlx_command( + &self, + args: super::trait_transform_args::DlxCommandArgs, + ) -> Result, SnmError> { + let mut process_args = vec!["dlx".to_string()]; + process_args.append(&mut args.package_spec.clone()); + Ok(process_args) + } } diff --git a/crates/cli/src/ni/trait_transform_args.rs b/crates/cli/src/ni/trait_transform_args.rs index f4163329..d6f261e0 100644 --- a/crates/cli/src/ni/trait_transform_args.rs +++ b/crates/cli/src/ni/trait_transform_args.rs @@ -36,10 +36,18 @@ pub struct DeleteCommandArgs { pub package_spec: String, } +#[derive(Parser, Debug)] +pub struct DlxCommandArgs { + #[arg(help = "The package spec to install.")] + pub package_spec: Vec, +} + pub trait CommandArgsCreatorTrait { fn get_install_command(&self, args: InstallCommandArgs) -> Result, SnmError>; fn get_add_command<'a>(&self, args: AddCommandArgs) -> Result, SnmError>; fn get_delete_command(&self, args: DeleteCommandArgs) -> Result, SnmError>; + + fn get_dlx_command(&self, args: DlxCommandArgs) -> Result, SnmError>; } diff --git a/crates/cli/src/ni/yarn_args.rs b/crates/cli/src/ni/yarn_args.rs index 38f077ca..5ed38096 100644 --- a/crates/cli/src/ni/yarn_args.rs +++ b/crates/cli/src/ni/yarn_args.rs @@ -39,4 +39,13 @@ impl CommandArgsCreatorTrait for YarnArgsTransform { let process_args = vec!["remove".to_string(), args.package_spec]; Ok(process_args) } + + fn get_dlx_command( + &self, + args: super::trait_transform_args::DlxCommandArgs, + ) -> Result, SnmError> { + let mut process_args = vec!["dlx".to_string()]; + process_args.append(&mut args.package_spec.clone()); + Ok(process_args) + } } diff --git a/crates/cli/src/ni/yarnpkg_args.rs b/crates/cli/src/ni/yarnpkg_args.rs index f61aa26a..bef345ed 100644 --- a/crates/cli/src/ni/yarnpkg_args.rs +++ b/crates/cli/src/ni/yarnpkg_args.rs @@ -39,4 +39,13 @@ impl CommandArgsCreatorTrait for YarnPkgArgsTransform { let process_args = vec!["remove".to_string(), args.package_spec]; Ok(process_args) } + + fn get_dlx_command( + &self, + args: super::trait_transform_args::DlxCommandArgs, + ) -> Result, SnmError> { + let mut process_args = vec!["dlx".to_string()]; + process_args.append(&mut args.package_spec.clone()); + Ok(process_args) + } } diff --git a/crates/cli/src/snm_command.rs b/crates/cli/src/snm_command.rs index 9aee4199..d077cca2 100644 --- a/crates/cli/src/snm_command.rs +++ b/crates/cli/src/snm_command.rs @@ -2,7 +2,9 @@ use clap::Subcommand; use crate::{ manage_command::ManageCommands, - ni::trait_transform_args::{AddCommandArgs, DeleteCommandArgs, InstallCommandArgs}, + ni::trait_transform_args::{ + AddCommandArgs, DeleteCommandArgs, DlxCommandArgs, InstallCommandArgs, + }, }; #[derive(Subcommand, Debug)] @@ -40,7 +42,7 @@ pub enum SnmCommands { #[command( about = "Fetches a package from the registry without installing it as a dependency, hotloads it, and runs whatever default command binary it exposes.." )] - Dlx, + Dlx(DlxCommandArgs), #[command(about = "Run a command from a local package.")] Exec,