Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Installing NPM package with Rust std::process::Command

I am trying to programmatically install an NPM package as part of a Rust program.

I am using the std::process::Command struct, and can successfully run Node with:

pub fn check_for_node(&mut self) -> Result<(), Box<dyn Error>> {
    println!("Node Version: ");
    let node = process::Command::new("node")
        .arg("-v")
        .status()?;

    self.node_is_installed = node.success();
    Ok(())
}

The code above returns:

Node Version:
v10.15.1

with no error.

However, when I run:

pub fn install_puppeteer(&mut self) -> Result<(), Box<dyn Error>> {
    if self.node_is_installed {
        let npm = process::Command::new("npm")
            .arg("install")
            .arg("puppeteer")
            .status()?;
        self.puppeteer_is_installed = npm.success();
    }
    Ok(())
}

I get the error:

thread 'main' panicked at 'called Result::unwrap() on an Err value: Os { code: 2, kind: NotFound, message: "The system cannot find the file specified." }', src\libcore\result.rs:999:5

If I run npm -v manually, I get 6.4.1 printed, so I know that NPM is installed.

Is there any reason that std::process::Command would work for Node and not for NPM, and is there any way to fix it?

like image 617
Jared Forth Avatar asked Jan 20 '26 18:01

Jared Forth


1 Answers

I was able to fix the issue by changing the working directory to C:\Program Files\nodejs prior to to running the command with:

let npm = Path::new("C:\Program Files\nodejs");
assert!(env::set_current_dir(&npm).is_ok());

After changing the working directory to my Node install path, I was able to successfully run:

 let npm = process::Command::new("npm.cmd")
      .arg("install")
      .arg("-g")
      .arg("puppeteer")
      .status()?;

I am on Windows, but to make this answer cross platform the following code could be used:

#[cfg(windows)]
pub const NPM: &'static str = "npm.cmd";

#[cfg(not(windows))]
pub const NPM: &'static str = "npm";

...

 let npm = process::Command::new(NPM)
      .arg("install")
      .arg("-g")
      .arg("puppeteer")
      .status()?;
like image 131
Jared Forth Avatar answered Jan 23 '26 20:01

Jared Forth



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!