From c915fb87431b46bcfcbe525a08cf1aafd7fc2731 Mon Sep 17 00:00:00 2001 From: Yakiyo Date: Fri, 4 Aug 2023 13:51:00 +0000 Subject: [PATCH] feat: use shell-quote --- src/cli.rs | 5 +++-- src/main.rs | 24 +++++++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 7251d2f..899f80e 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,4 +1,5 @@ use clap::*; +use std::ffi::OsString; #[derive(Debug, Parser)] #[clap(author, version, about, rename_all = "kebab-case")] @@ -19,7 +20,7 @@ pub enum Command { Run(RunArgs), /// Execute a shell command in scope of a project. #[clap(external_subcommand)] - Other(Vec), + Other(Vec), } /// Runs a defined package script. @@ -30,5 +31,5 @@ pub struct RunArgs { pub script: Option, // Not OsString because it would be compared against package.json#scripts /// Arguments to pass to the package script. - pub args: Vec, + pub args: Vec, } diff --git a/src/main.rs b/src/main.rs index 469cbc2..cd79db6 100644 --- a/src/main.rs +++ b/src/main.rs @@ -5,6 +5,7 @@ use indexmap::IndexMap; use itertools::Itertools; use pipe_trait::Pipe; use serde::{Deserialize, Serialize}; +use shell_quote::sh; use std::{ env, ffi::OsString, @@ -73,20 +74,20 @@ fn run() -> Result<(), MainError> { eprintln!("> {command}\n"); run_script(name, command, cwd) }; - let command_string = |name: &str, args: &[String]| { - let mut string = name.to_string(); + let command_string = |name: &str, args: &[OsString]| { + let mut out: Vec = name.as_bytes().to_owned(); for arg in args { - string += " "; - string += arg; + out.push(b' '); + sh::escape_into(arg, &mut out); } - string + std::str::from_utf8(&out).map(str::to_string) }; match cli.command { cli::Command::Run(args) => { let (cwd, manifest) = cwd_and_manifest()?; if let Some(name) = args.script { if let Some(command) = manifest.scripts.get(&name) { - let command = command_string(command, &args.args); + let command = command_string(command, &args.args).unwrap(); print_and_run_script(&manifest, &name, &command, &cwd) } else { PnError::MissingScript { name } @@ -105,14 +106,23 @@ fn run() -> Result<(), MainError> { cli::Command::Other(args) => { let (cwd, manifest) = cwd_and_manifest()?; if let Some(name) = args.first() { + let name = name.to_str().unwrap(); if passed_through::PASSED_THROUGH_COMMANDS.contains(name) { + let args = args + .into_iter() + .map(|f| f.into_string().unwrap()) + .collect::>(); return pass_to_pnpm(&args); // args already contain name, no need to prepend } if let Some(command) = manifest.scripts.get(name) { - let command = command_string(command, &args[1..]); + let command = command_string(command, &args[1..]).unwrap(); return print_and_run_script(&manifest, name, &command, &cwd); } } + let args = args + .into_iter() + .map(|f| f.into_string().unwrap()) + .collect::>(); pass_to_sub(args.join(" ")) } }