From de41b3aaae2f13e5ae8cacca5c59ae95110e4f31 Mon Sep 17 00:00:00 2001 From: Martin Kuntz Jacobsen Date: Wed, 4 Nov 2026 20:32:42 +0100 Subject: [PATCH] plan/changed: read backslash local_path_override paths (closes #6212) On Windows, MODULE.bazel can say path = "..\\lib". The override filter split only on '/', so the outside-repo override was dropped and an affected-scoped run selected nothing that depends on it. Normalize backslashes to '/' before the '..' filter and the repo-relative resolution. Absolute paths are still skipped on the original string. Co-Authored-By: Claude Haiku 5.5 Claude-Session: https://claude.ai/code/session_011u9TXHDZrfmzFQ2WT8QAKK --- cli/plan/src/resolve/changed.rs | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/cli/plan/src/resolve/changed.rs b/cli/plan/src/resolve/changed.rs index fcc0a3b9fd..b33e4f09f2 100644 --- a/cli/plan/src/resolve/changed.rs +++ b/cli/plan/src/resolve/changed.rs @@ -261,7 +261,9 @@ pub fn local_override_changes( let text = std::fs::read_to_string(workspace.join("MODULE.bazel")).unwrap_or_default(); let overrides: Vec = dx_adopt::local_path_overrides(&text) .into_iter() - .filter(|path| !Path::new(path).is_absolute() && path.split('/').any(|part| part == "..")) + .filter(|path| !Path::new(path).is_absolute()) + .map(|path| path.replace('\\', "/")) + .filter(|path| path.split('/').any(|part| part == "..")) .collect(); if overrides.is_empty() { return Ok(Vec::new()); @@ -3327,6 +3329,28 @@ mod tests { assert!(calls[2].0.contains(&"--full-name".to_owned()), "{calls:?}"); } + #[test] + fn override_changes_read_backslash_override_paths_like_slash_paths() { + let scratch = dx_test_scratch::scratch("dx-changed-override-backslash-"); + let workspace = scratch.path().to_path_buf(); + write( + &workspace, + "MODULE.bazel", + "local_path_override(module_name = \"lib\", path = \"..\\\\lib\")\n", + ); + let query = FakeQuery::new(vec![ + FakeQuery::raw(b"sub/\n".to_vec()), + FakeQuery::raw(b"lib/x.rs\0".to_vec()), + FakeQuery::raw(b"lib/new.rs\0".to_vec()), + ]); + let changes = + local_override_changes(Path::new("/hermetic/git"), &workspace, &query, "base-sha") + .expect("override changes"); + assert_eq!(changes, strings(&["../lib/new.rs", "../lib/x.rs"])); + let calls = query.calls(); + assert!(calls[1].0.ends_with(&[":(top)lib".to_owned()]), "{calls:?}"); + } + #[test] fn override_changes_skip_the_override_modules_dx_state() { let scratch = dx_test_scratch::scratch("dx-changed-override-dx-");