diff --git a/CHANGELOG.md b/CHANGELOG.md index 3126ba3d18..7fe1734c0b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -29,12 +29,14 @@ - Fix `null` and array values incorrectly matching the `Object` branch when pattern matching on `JSON.t` (or other untagged variants with an `Object` case) in statement position. https://github.com/rescript-lang/rescript/pull/8279 - Fix rewatch panic when `package.json` has no `name` field. https://github.com/rescript-lang/rescript/pull/8291 - Fix unpacking first-class module in default argument of react component. https://github.com/rescript-lang/rescript/pull/8296 +- Fix exception record field regression. https://github.com/rescript-lang/rescript/pull/8319 +- Rewatch: ignore stale lock for unrelated process name. https://github.com/rescript-lang/rescript/pull/8316 #### :memo: Documentation #### :nail_care: Polish -- Improve error message for dependency without `rescript.json`. https://github.com/rescript-lang/rescript/issues/8265 +- Improve error message for dependency without `rescript.json`. https://github.com/rescript-lang/rescript/pull/8292 #### :house: Internal diff --git a/rewatch/src/lock.rs b/rewatch/src/lock.rs index d722a3714e..7d5528053b 100644 --- a/rewatch/src/lock.rs +++ b/rewatch/src/lock.rs @@ -3,7 +3,7 @@ use std::fs::File; use std::io::Write; use std::path::Path; use std::process; -use sysinfo::{PidExt, System, SystemExt}; +use sysinfo::{PidExt, ProcessExt, System, SystemExt}; /* This locking mechanism is meant to never be deleted. Instead, it stores the PID of the process * that's running, when trying to aquire a lock, it checks wether that process is still running. If @@ -46,11 +46,30 @@ pub enum Lock { Error(Error), } -fn pid_exists(to_check_pid: u32) -> bool { - System::new_all() - .processes() - .iter() - .any(|(pid, _process)| pid.as_u32() == to_check_pid) +fn matching_process_name() -> Option { + std::env::current_exe() + .ok() + .and_then(|path| path.file_name().map(|name| name.to_string_lossy().into_owned())) +} + +fn pid_matches_current_process(to_check_pid: u32) -> bool { + let system = System::new_all(); + let current_process_name = matching_process_name(); + + system.processes().iter().any(|(pid, process)| { + if pid.as_u32() != to_check_pid { + return false; + } + + match ¤t_process_name { + Some(current_process_name) => process + .exe() + .file_name() + .map(|name| name.to_string_lossy() == current_process_name.as_str()) + .unwrap_or_else(|| process.name() == current_process_name.as_str()), + None => true, + } + }) } pub fn get(folder: &str) -> Lock { @@ -67,7 +86,9 @@ pub fn get(folder: &str) -> Lock { // proceed, otherwise we will overwrite the stale lock with our own PID. match fs::read_to_string(&location) { Ok(contents) => match contents.parse::() { - Ok(parsed_pid) if pid_exists(parsed_pid) => return Lock::Error(Error::Locked(parsed_pid)), + Ok(parsed_pid) if pid_matches_current_process(parsed_pid) => { + return Lock::Error(Error::Locked(parsed_pid)); + } Ok(_) => (), Err(e) => return Lock::Error(Error::ParsingLockfile(e)), }, @@ -133,4 +154,18 @@ mod tests { "lockfile should be created" ); } + + #[test] + fn ignores_stale_lock_for_unrelated_process_name() { + let temp_dir = TempDir::new().expect("temp dir should be created"); + let project_folder = temp_dir.path().join("project"); + let lib_dir = project_folder.join("lib"); + fs::create_dir_all(&lib_dir).expect("lib directory should be created"); + fs::write(lib_dir.join(LOCKFILE), "1").expect("lockfile should be written"); + + match get(project_folder.to_str().expect("path should be valid")) { + Lock::Aquired(_) => {} + _ => panic!("expected stale lock from unrelated process to be ignored"), + } + } }