(npm: &str, args: &[&str], dir: &Path)
| 61 | } |
| 62 | |
| 63 | fn run_npm(npm: &str, args: &[&str], dir: &Path) -> Result<(), String> { |
| 64 | println!( |
| 65 | "cargo::warning=dashboard assets: running `{npm} {}` in {} (this can take a minute on first build)", |
| 66 | args.join(" "), |
| 67 | dir.display() |
| 68 | ); |
| 69 | let output = Command::new(npm) |
| 70 | .args(args) |
| 71 | .current_dir(dir) |
| 72 | .stdin(Stdio::null()) |
| 73 | .output() |
| 74 | .map_err(|e| format!("failed to spawn `{npm} {}`: {e}", args.join(" ")))?; |
| 75 | if output.status.success() { |
| 76 | return Ok(()); |
| 77 | } |
| 78 | let mut combined = String::from_utf8_lossy(&output.stdout).into_owned(); |
| 79 | combined.push_str(&String::from_utf8_lossy(&output.stderr)); |
| 80 | let tail = combined |
| 81 | .lines() |
| 82 | .rev() |
| 83 | .take(40) |
| 84 | .collect::<Vec<_>>() |
| 85 | .into_iter() |
| 86 | .rev() |
| 87 | .collect::<Vec<_>>() |
| 88 | .join("\n"); |
| 89 | Err(format!( |
| 90 | "`{npm} {}` failed with {} in {}:\n{tail}", |
| 91 | args.join(" "), |
| 92 | output.status, |
| 93 | dir.display() |
| 94 | )) |
| 95 | } |
| 96 | |
| 97 | /// Builds the dashboard frontend (`cd dashboard && npm ci/install && npm run |
| 98 | /// build`) when dist assets are missing or stale, so plain `cargo build` / `cargo |
no test coverage detected