Skip to content

Commit 2bbe81f

Browse files
YOMXXXkylehgc
authored andcommitted
fix(pnpm): preserve install failure output
1 parent 921e027 commit 2bbe81f

2 files changed

Lines changed: 87 additions & 0 deletions

File tree

‎src/cmds/js/pnpm_cmd.rs‎

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -487,6 +487,7 @@ fn run_install(args: &[String], verbose: u8) -> Result<i32> {
487487
let result = exec_capture(&mut cmd).context("Failed to run pnpm install")?;
488488

489489
if !result.success() {
490+
print!("{}", result.stdout);
490491
eprint!("{}", result.stderr);
491492
return Ok(result.exit_code);
492493
}

‎tests/pnpm_install_failure_test.rs‎

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
use std::env;
2+
use std::fs;
3+
use std::path::{Path, PathBuf};
4+
use std::process::Command;
5+
6+
#[cfg(unix)]
7+
use std::os::unix::fs::PermissionsExt;
8+
9+
fn write_fake_pnpm(dir: &Path) -> PathBuf {
10+
#[cfg(windows)]
11+
{
12+
let path = dir.join("pnpm.cmd");
13+
fs::write(
14+
&path,
15+
"@echo off\r\n\
16+
if \"%1\"==\"install\" (\r\n\
17+
echo Scope: all 3 workspace projects\r\n\
18+
echo ERR_PNPM_FETCH_404 GET https://registry.npmjs.org/@missing/pkg: Not Found - 404\r\n\
19+
echo This error happened while installing a direct dependency of /tmp/app\r\n\
20+
exit /B 1\r\n\
21+
)\r\n\
22+
echo unexpected args %* 1>&2\r\n\
23+
exit /B 2\r\n",
24+
)
25+
.expect("write fake pnpm");
26+
path
27+
}
28+
29+
#[cfg(unix)]
30+
{
31+
let path = dir.join("pnpm");
32+
fs::write(
33+
&path,
34+
"#!/bin/sh\n\
35+
if [ \"$1\" = \"install\" ]; then\n\
36+
printf '%s\\n' 'Scope: all 3 workspace projects'\n\
37+
printf '%s\\n' 'ERR_PNPM_FETCH_404 GET https://registry.npmjs.org/@missing/pkg: Not Found - 404'\n\
38+
printf '%s\\n' 'This error happened while installing a direct dependency of /tmp/app'\n\
39+
exit 1\n\
40+
fi\n\
41+
printf '%s\\n' \"unexpected args $*\" >&2\n\
42+
exit 2\n",
43+
)
44+
.expect("write fake pnpm");
45+
let mut permissions = fs::metadata(&path)
46+
.expect("fake pnpm metadata")
47+
.permissions();
48+
permissions.set_mode(0o755);
49+
fs::set_permissions(&path, permissions).expect("chmod fake pnpm");
50+
path
51+
}
52+
}
53+
54+
fn path_with_front(front: &Path) -> std::ffi::OsString {
55+
let current = env::var_os("PATH").unwrap_or_default();
56+
let paths = std::iter::once(front.to_path_buf()).chain(env::split_paths(&current));
57+
env::join_paths(paths).expect("join PATH")
58+
}
59+
60+
#[test]
61+
fn pnpm_install_failure_preserves_stdout_error_output() {
62+
let temp = tempfile::tempdir().expect("tempdir");
63+
let _fake = write_fake_pnpm(temp.path());
64+
65+
let output = Command::new(env!("CARGO_BIN_EXE_rtk"))
66+
.args(["pnpm", "install"])
67+
.env("PATH", path_with_front(temp.path()))
68+
.output()
69+
.expect("run rtk");
70+
71+
assert!(!output.status.success(), "pnpm failure must propagate");
72+
73+
let combined = format!(
74+
"{}{}",
75+
String::from_utf8_lossy(&output.stdout),
76+
String::from_utf8_lossy(&output.stderr)
77+
);
78+
assert!(
79+
combined.contains("ERR_PNPM_FETCH_404"),
80+
"pnpm stdout error must be preserved, got: {combined:?}"
81+
);
82+
assert!(
83+
combined.contains("direct dependency"),
84+
"pnpm failure context must be preserved, got: {combined:?}"
85+
);
86+
}

0 commit comments

Comments
 (0)