diff --git a/src/child.rs b/src/child.rs index e312c205..72c8e870 100644 --- a/src/child.rs +++ b/src/child.rs @@ -7,7 +7,9 @@ use failure::Error; use slog::Logger; use std::{ io::{self, Read}, - mem, process, string, + mem, + process::{Command, Stdio}, + string, sync::mpsc, thread, }; @@ -19,6 +21,22 @@ enum OutputFragment { Stderr(Vec), } +/// Return a new Command object +pub fn new_command(program: &str) -> Command { + // On Windows, initializes launching as `cmd /c `. + // Initializing only with `Command::new("npm")` will launch + // `npm` with quotes, `"npm"`, causing a run-time error on Windows. + // See rustc: #42436, #42791, #44542 + + if cfg!(windows) { + let mut cmd = Command::new("cmd"); + cmd.arg("/c").arg(program); + cmd + } else { + Command::new(program) + } +} + /// Read data from the give reader and send it as an `OutputFragment` over the /// given sender. fn read_and_send( @@ -115,16 +133,12 @@ where } /// Run the given command and return its stdout. -pub fn run( - logger: &Logger, - mut command: process::Command, - command_name: &str, -) -> Result { +pub fn run(logger: &Logger, mut command: Command, command_name: &str) -> Result { info!(logger, "Running {:?}", command); let mut child = command - .stdout(process::Stdio::piped()) - .stderr(process::Stdio::piped()) + .stdout(Stdio::piped()) + .stderr(Stdio::piped()) .spawn()?; let stdout = child.stdout.take().unwrap(); diff --git a/src/npm.rs b/src/npm.rs index 6b09e63a..74a02508 100644 --- a/src/npm.rs +++ b/src/npm.rs @@ -4,14 +4,13 @@ use child; use command::publish::access::Access; use failure::{self, ResultExt}; use slog::Logger; -use std::process::{Command, Stdio}; /// The default npm registry used when we aren't working with a custom registry. pub const DEFAULT_NPM_REGISTRY: &'static str = "https://registry.npmjs.org/"; /// Run the `npm pack` command. pub fn npm_pack(log: &Logger, path: &str) -> Result<(), failure::Error> { - let mut cmd = Command::new("npm"); + let mut cmd = child::new_command("npm"); cmd.current_dir(path).arg("pack"); child::run(log, cmd, "npm pack").context("Packaging up your code failed")?; Ok(()) @@ -19,19 +18,13 @@ pub fn npm_pack(log: &Logger, path: &str) -> Result<(), failure::Error> { /// Run the `npm publish` command. pub fn npm_publish(log: &Logger, path: &str, access: Option) -> Result<(), failure::Error> { - let mut cmd = Command::new("npm"); + let mut cmd = child::new_command("npm"); match access { Some(a) => cmd .current_dir(path) .arg("publish") - .arg(&format!("{}", a.to_string())) - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()), - None => cmd - .current_dir(path) - .arg("publish") - .stdin(Stdio::inherit()) - .stdout(Stdio::inherit()), + .arg(&format!("{}", a.to_string())), + None => cmd.current_dir(path).arg("publish"), }; child::run(log, cmd, "npm publish").context("Publishing to npm failed")?; @@ -52,7 +45,7 @@ pub fn npm_login( args.push(format!("--scope={}", scope)); } - if always_auth == true { + if always_auth { args.push(format!("--always_auth")); } @@ -62,7 +55,7 @@ pub fn npm_login( // Interactively ask user for npm login info. // (child::run does not support interactive input) - let mut cmd = Command::new("npm"); + let mut cmd = child::new_command("npm"); cmd.args(args); info!(log, "Running {:?}", cmd);