Avoid watchers for one-shot builds and preserve watcher errors (AI-assisted)

This commit is contained in:
CheckPickerUpper 2026-10-07 16:53:22 -04:00
parent 7e60406373
commit 691efad330
7 changed files with 160 additions and 14 deletions

View file

@ -108,3 +108,58 @@ fn run_build_test(test_name: &str) {
assert_snapshot!(test_name, contents);
});
}
#[cfg(target_os = "linux")]
#[test]
fn build_without_watch_does_not_create_inotify_instance() -> Result<(), Box<dyn std::error::Error>>
{
const CHILD_ENV: &str = "ROJO_TEST_BUILD_WITHOUT_WATCH_CHILD";
// Isolate descriptor inspection from other tests that create file watchers.
if std::env::var_os(CHILD_ENV).is_none() {
let output = Command::new(std::env::current_exe()?)
.args([
"--exact",
"tests::build::build_without_watch_does_not_create_inotify_instance",
"--nocapture",
])
.env(CHILD_ENV, "1")
.output()?;
assert!(
output.status.success(),
"{}\n{}",
String::from_utf8_lossy(&output.stdout),
String::from_utf8_lossy(&output.stderr)
);
return Ok(());
}
let project_dir = tempdir()?;
fs::write(
project_dir.path().join("default.project.json"),
r#"{"name":"WithoutWatcher","tree":{"$className":"Folder","$path":"src"}}"#,
)?;
fs::create_dir(project_dir.path().join("src"))?;
fs::write(project_dir.path().join("src/main.luau"), "return 42")?;
let output_path = project_dir.path().join("output.rbxmx");
librojo::cli::BuildCommand {
project: project_dir.path().to_path_buf(),
output: Some(output_path.clone()),
plugin: None,
watch: false,
}
.run()?;
assert!(fs::read_to_string(output_path)?.contains("return 42"));
// BuildCommand keeps its session alive until process exit, so an eagerly
// allocated watcher remains observable after the build completes.
for entry in fs::read_dir("/proc/self/fd")? {
match fs::read_link(entry?.path()) {
Ok(target) => assert_ne!(target, Path::new("anon_inode:inotify")),
Err(err) if err.kind() == std::io::ErrorKind::NotFound => {}
Err(err) => return Err(err.into()),
}
}
Ok(())
}