Repository navigation
Closed
Description
Found while fixing #1186 on the Windows CI job (PR #1190, run https://github.com/thekevinscott/dirsql/actions/runs/36432881839).
command::run_command spawns argv through Rust's Command::args. On Windows, Rust wraps an argument in quotes only when it contains a space or tab. An MSYS/Cygwin child (Git for Windows' sh, printf, echo, cat, ...) re-parses its command line and runs glob and brace expansion on every unquoted word, with \ as the escape character. That breaks the contract in command.rs ("no globbing", "a substituted value is always exactly one argv element") when the child is an MSYS program:
on-file = "printf '[{}]'": printf receives[]after brace expansion, so every file yields zero rows.printf '[{"n":1}]'andprintf ... {abspath}are mangled the same way.- A
{path}in verbatim form (\\?\C:\Users\..., whichfs::canonicalizeand a canonical cwd produce on Windows, and which the watcher reports) contains?, so it is globbed, and its backslashes are eaten as escapes: the hook sees\?C:Usersrunneradmin...in_cwd.txt.
Tests red for this reason on Windows (after #1190):
internal_tests::build_tables_from_config_creates_on_file_tables,run_on_file_parses_command_json_output,run_on_file_does_not_substitute_abspathasync_sdk::from_config_path_loads_config_with_explicit_rootsdk::builder_config_loads_tables_with_explicit_root,builder_appends_programmatic_tables_to_config_tablescli_repeatable_config_e2e::query_subcommand_accepts_repeated_config_flags,server_serves_tables_from_two_config_flagscli_e2e::config_elsewhere_indexes_invocation_cwd_not_config_parentconfig_root_derivation::config_without_root_indexes_process_cwd_not_config_parent(verbatim cwd)cli_e2e::get_events_emits_insert_event_when_file_created,cli_integration::get_events_streams_mutation_events, and probablycli_e2e::server_indexes_a_directory_moved_into_the_root(watcher paths are verbatim)
Options, not mutually exclusive:
- On Windows, force-quote every argument (
CommandExt::raw_argwith MS quoting). MSYS does not glob a quoted word, and MSVCRT children parse it the same as today. Caveat: inside quotes MSYS collapses\\to\, which MS rules keep, so a\\?\or UNC value still differs between the two runtimes. - Hand hooks a non-verbatim path (
C:\...instead of\\?\C:\...). This removes the?and the doubled backslash, and helps any Windows tool that rejects verbatim paths. - Declare MSYS children unsupported and rewrite the fixtures. Users on Windows would still hit this.
Metadata
Metadata
Assignees
Labels
No labels
Activity
thekevinbot commentedon Oct 2, 2026
Resolved on main by #1209 (force-quote every argv element on Windows, MS quoting rules) and #1211 (hand hooks non-verbatim paths), options 1 and 2 above. The Windows CI job added in #1178 runs the tests listed here and is green on main at efee3e9 (run 37058064986, job "Windows tests"). Closing.