Skip to content

fix(rust): slash-separate root-relative paths on Windows - #1189

Open
thekevinbot wants to merge 9 commits into
claude/1175-windows-cifrom
claude/1184-win-rel-paths
Open

thekevinbot wants to merge 9 commits into
claude/1175-windows-cifrom
claude/1184-win-rel-paths

Conversation

@thekevinbot

@thekevinbot thekevinbot commented Sep 28, 2026 •

Copy link
Copy Markdown
Collaborator

Fixes #1184

Root-relative paths are built with scanner::to_slash, so they are /-separated on every platform. Applied where they are produced: the initial scan (relative_path), the watcher (process_file_event, index_subtree), the path-table vtab (reported_path) and the parsed-vtab cache key and skip messages. Db::files_under now matches on a / prefix, since stored paths no longer use the native separator.

reported_path joins a path prefix with / and leaves the prefix as given, so an absolute path-table reads <prefix>/docs/a.md, as path_table_globs.rs expects.

tests/watch_scan_correctness.rs fixture change, justified: its on-file closure computed path by stripping the canonicalized root and keeping native separators. On Windows the scan hands it paths under the root as given (C:\Users\RUNNER~1\...) while canonicalize returns \\?\C:\Users\runneradmin\..., so the strip failed and rows held full paths. The fixture now strips either spelling and slash-separates, which is what it meant.

Glob matching needed no change: globset already normalizes \ to / on Windows before matching.

to_slash delegates to with_slashes(path, native_separator). The separator is a parameter so a Linux unit test covers the Windows case. On Unix it is a no-op, because \ is a legal file-name character there.

Windows failures

Before (run 35995035941): 99 failing. After (run 36436772830): 51 failing, none of them #1184. The comment below lists the issue that owns each one.

E2E Verification

  • Ran e2e suites locally for every affected SDK
  • Python SDK e2e: pass (38 passed)
  • TypeScript SDK e2e: pass
  • Rust core e2e: pass (cargo test -p dirsql --features cli, 0 failures)
  • packages/python/e2e-attestations/claude-1184-win-rel-paths.json receipt written (just e2e-attest-python)
  • packages/ts/e2e-attestations/claude-1184-win-rel-paths.json receipt written (just e2e-attest-ts)
  • Command(s) run: just e2e-attest-python, just e2e-attest-ts, cargo test -p dirsql --features cli, just preflight
  • Result summary: all green on Linux. Manual run: dirsql "SELECT path, dir FROM '/tmp/claude/win1184-demo/docs'" returned /tmp/claude/win1184-demo/docs/nested/a.md and dir /tmp/claude/win1184-demo/docs/nested, unchanged on Linux.

Changelog / Migrations

  • Changelog fragment added under packages/rust/changelog.d/
  • Migration fragment added under packages/rust/migrations.d/ (Windows-only behavior change; Unix output is unchanged)

@thekevinbot

Copy link
Copy Markdown
Collaborator Author

Windows tests: 99 failing on run 35995035941, 51 failing on this PR (run 36436772830). All the failures #1184 names now pass: db::tests::files_under_*, internal_tests::process_file_event_*, vtab::tests::*, vtab.rs, path_table_query.rs, path_table_gitignore.rs, most of path_table_globs.rs, watch_scan_correctness.rs, and several cli_e2e.rs tests.

The 51 still failing, by owning issue:

#1185, absolute / ~/ / ../ path-tables (11): path_table::tests::{a_home_relative_*, a_parent_relative_path_folds_*, a_parent_relative_path_past_*, an_absolute_glob_*, an_absolute_single_file_*}, path_table_cli_e2e::an_absolute_path_table_resolves_outside_the_index_root, and path_table_globs::{a_parent_relative_*, an_absolute_*} (5). a_parent_relative_path_table_resolves_against_the_index_root now differs only in the prefix, which normalize rewrote to \: it produces ...\.tmpX\docs/a.md where the test expects ...\.tmpX/docs/a.md.

#1186, test harness (38):

  • On-file fixtures produce invalid JSON: they put a native {path} into the JSON or strip "$2"/ from it. This affects internal_tests::{build_tables_from_config_*, run_on_file_*} (4), from_config.rs (7), config_root_derivation.rs (2), declared_table_name.rs (2), and cli_e2e::{get_events_emits_*, query_subcommand_fans_out_*, server_indexes_a_directory_moved_*}, plus cli_integration::get_events_streams_mutation_events.
  • on-file = "printf '[{}]'" indexes 0 rows with no error. This hits sdk::builder_* (3), async_sdk::from_config_path_*, cli_repeatable_config_e2e.rs (2), cli_e2e::config_elsewhere_*, and repeatable_config.rs (2). I have not confirmed the cause. The likeliest one is MSYS argv globbing brace-expanding [{}] to []. Windows: Rust test fixtures assume Unix paths and file handles #1186 does not list this yet.
  • persist_parsed_path_table.rs (8): two tests hit set_modified PermissionDenied, which Windows: Rust test fixtures assume Unix paths and file handles #1186 lists. The other six interpolate a native script path into the command template, and shlex eats the backslashes (C:UsersRUNNER~1...parse.sh). Windows: Rust test fixtures assume Unix paths and file handles #1186 does not list that yet.
  • extensions.rs TOML escape (1). parsed_vtab::run_parser_* cwd os error 267 (1).

Unowned, Unix absolute paths in unit fixtures (2): internal_tests::relative_root_canonicalizes_watch_root_only (/ws/canonical is not absolute on Windows) and extension_resolution::tests::select_loadable_rejects_an_ambiguous_package_in_sorted_order (/pkg joined natively as /pkg\a.so). Neither is root-relative. Both fit #1186 best.

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant