Fix npm error when spawned in Windows

Issue #277 - Affects running login, pack, and publish on Windows.

`Command::new("npm")` launched `npm` with quotes, `"npm"`, causing a
run-time error on Windows. Now, `Command::new` is wrapped by
`child::new_command(program: &str)`. This prepends `cmd /c` to the
program name if `cfg!(windows)`.

See rustc: #42436, #42791, #44542
master
Dan Wilhelm 6 years ago committed by Ashley Williams
parent 3088e790a0
commit 92d24ff298
  1. 30
      src/child.rs
  2. 7
      src/npm.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<u8>),
}
/// Return a new Command object
pub fn new_command(program: &str) -> Command {
// On Windows, initializes launching <program> as `cmd /c <program>`.
// 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<R, F>(
@ -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<String, Error> {
pub fn run(logger: &Logger, mut command: Command, command_name: &str) -> Result<String, Error> {
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();

@ -4,14 +4,13 @@ use child;
use command::publish::access::Access;
use failure::{self, ResultExt};
use slog::Logger;
use std::process::Command;
/// 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,7 +18,7 @@ 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<Access>) -> Result<(), failure::Error> {
let mut cmd = Command::new("npm");
let mut cmd = child::new_command("npm");
match access {
Some(a) => cmd
.current_dir(path)
@ -56,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);

Loading…
Cancel
Save