Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
# Changelog

- **Fixed** The bundled shell that runs cached task commands on macOS no longer intermittently dies with exit 2 (`oils I/O error (main): No such process`) when a fast command finishes before the shell gets scheduled — the bundled osh now carries the upstream fix for its post-fork `getpgid` race ([#702](https://github.com/voidzero-dev/vite-task/issues/702), [oils#2689](https://github.com/oils-for-unix/oils/pull/2689)).
- **Fixed** `vp run` no longer hangs or fails when a task leaves a process running behind it, such as a dev server or a background helper, or when one of a task's processes is killed. The run finishes as soon as the task itself does, and the files the task used are still recorded ([#544](https://github.com/voidzero-dev/vite-task/issues/544), [#675](https://github.com/voidzero-dev/vite-task/pull/675)).
- **Fixed** A task that reads or writes an unusually large number of files now runs to the end instead of being killed partway through. Vite+ reports the run as not cached, because it could not record every file the task used ([#533](https://github.com/voidzero-dev/vite-task/issues/533), [#675](https://github.com/voidzero-dev/vite-task/pull/675)).
- **Fixed** Vite+ diagnostics now display individual paths and working directories without Rust debug formatting such as quoted paths or escaped Windows backslashes ([#534](https://github.com/voidzero-dev/vite-task/pull/534)).
Expand Down
14 changes: 10 additions & 4 deletions crates/fspy/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,13 +72,16 @@ const MACOS_BINARY_DOWNLOADS: &[(&str, &[BinaryDownload])] = &[
(
"aarch64",
&[
// Carries the Process::RunProcess getpgid ESRCH fix on top of stock
// 0.37.0 until an upstream release includes it
// (https://github.com/oils-for-unix/oils/pull/2689). Stock builds:
// https://github.com/wan9chi/oils-for-unix-build/releases/tag/oils-for-unix-0.37.0
BinaryDownload {
name: "oils_for_unix",
env_var: "FSPY_MACOS_ARTIFACT_OILS_FOR_UNIX",
url: "https://github.com/wan9chi/oils-for-unix-build/releases/download/oils-for-unix-0.37.0/oils-for-unix-0.37.0-darwin-arm64.tar.gz",
url: "https://github.com/lifeiscontent/oils-for-unix-build/releases/download/oils-for-unix-0.37.0-fspy.1/oils-for-unix-0.37.0-fspy.1-darwin-arm64.tar.gz",
path_in_targz: "oils-for-unix",
expected_sha256: "ce4bb80b15f0a0371af08b19b65bfa5ea17d30429ebb911f487de3d2bcc7a07d",
expected_sha256: "b61c45ee8c240d58fc75d6d2ae20f6a89790036362c30aa5f2c21c8f328643f7",
},
// https://github.com/uutils/coreutils/releases/tag/0.4.0
BinaryDownload {
Expand All @@ -93,13 +96,16 @@ const MACOS_BINARY_DOWNLOADS: &[(&str, &[BinaryDownload])] = &[
(
"x86_64",
&[
// Carries the Process::RunProcess getpgid ESRCH fix on top of stock
// 0.37.0 until an upstream release includes it
// (https://github.com/oils-for-unix/oils/pull/2689). Stock builds:
// https://github.com/wan9chi/oils-for-unix-build/releases/tag/oils-for-unix-0.37.0
BinaryDownload {
name: "oils_for_unix",
env_var: "FSPY_MACOS_ARTIFACT_OILS_FOR_UNIX",
url: "https://github.com/wan9chi/oils-for-unix-build/releases/download/oils-for-unix-0.37.0/oils-for-unix-0.37.0-darwin-x86_64.tar.gz",
url: "https://github.com/lifeiscontent/oils-for-unix-build/releases/download/oils-for-unix-0.37.0-fspy.1/oils-for-unix-0.37.0-fspy.1-darwin-x86_64.tar.gz",
path_in_targz: "oils-for-unix",
expected_sha256: "cf1a95993127770e2a5fff277cd256a2bb28cf97d7f83ae42fdccc172cdb540d",
expected_sha256: "bf570d54a78dbe0a55712620f746c2b90bbc2aedc633c80d41ca9bbd934424d3",
},
// https://github.com/uutils/coreutils/releases/tag/0.4.0
BinaryDownload {
Expand Down
45 changes: 45 additions & 0 deletions crates/fspy/tests/oils_esrch.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//! The bundled osh substitute must not lose the getpgid race against a fast
//! child: stock oils 0.37.0 calls getpgid(child) after fork even when job
//! control is disabled, and on macOS getpgid of an already-exited child fails
//! with ESRCH, killing the shell with "oils I/O error (main)" and exit 2
//! (oils-for-unix/oils#2689). Under CPU contention a few percent of runs died.
//!
//! The race is gone (not just rarer) with a fixed osh, so this fails
//! deterministically if the bundled artifact regresses to a stock build.
#![cfg(target_os = "macos")]

use std::{fs, path::Path};

use test_log::test;

#[test(tokio::test(flavor = "multi_thread", worker_threads = 8))]
async fn fast_external_commands_under_contention() -> anyhow::Result<()> {
let input = Path::new(env!("CARGO_TARGET_TMPDIR")).join("fspy-oils-esrch-input.txt");
fs::write(&input, "hello\n")?;

let mut failures = Vec::new();
for _round in 0..25 {
let mut handles = Vec::new();
for _ in 0..8 {
handles.push(tokio::spawn({
let input = input.clone();
async move {
let mut cmd = fspy::Command::new("/bin/sh");
cmd.arg("-c").arg(format!("cat {}", input.display()));
cmd.env("PATH", "/usr/bin:/bin");
let child = cmd.spawn(tokio_util::sync::CancellationToken::new()).await?;
let termination = child.wait_handle.await?;
anyhow::Ok(termination.status.code())
}
}));
}
for h in handles {
let code = h.await??;
if code != Some(0) {
failures.push(code);
}
}
}
assert!(failures.is_empty(), "osh exited non-zero {} times: {failures:?}", failures.len());
Ok(())
}