Skip to content

Commit 9c8f7fe

Browse files
BoxingOctopusclaude
andcommitted
Never resolve extensionless scripts on Windows
Toolchains like groovy and kotlin ship an extensionless unix launcher next to the .bat; find_in_dir preferred the exact name, handing CreateProcess a shell script (error 193). On Windows only .exe/.cmd/ .bat/.com count, extension search order otherwise. Also restores a quote my earlier edit dropped in the Alpine groovy smoke line. Co-Authored-By: Claude Fable 5 <[email protected]>
1 parent 54549f7 commit 9c8f7fe

2 files changed

Lines changed: 14 additions & 10 deletions

File tree

.github/workflows/ci.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ jobs:
9595
linguo jvm run -- java -version
9696
linguo groovy install
9797
linguo groovy use 5
98-
linguo groovy run -- groovy -e "println \"groovy on musl ok\"
98+
linguo groovy run -- groovy -e "println \"groovy on musl ok\""
9999
100100
# node and go have no official musl builds: expect honest errors
101101
linguo node install 2>/dev/null && exit 1 || echo "node bails as expected"

src/exec.rs

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,22 +14,26 @@ pub fn exe(name: &str) -> String {
1414
}
1515
}
1616

17-
/// Locate an executable named `name` in `dir`, trying Windows executable
18-
/// extensions when `name` has none.
17+
/// Locate an executable named `name` in `dir`. On Windows only files with
18+
/// executable extensions count: toolchains often ship an extensionless unix
19+
/// script alongside a .bat (groovy, kotlin), and handing the script to
20+
/// CreateProcess fails with "not a valid Win32 application".
1921
pub fn find_in_dir(dir: &Path, name: &str) -> Option<PathBuf> {
20-
let direct = dir.join(name);
21-
if is_executable(&direct) {
22-
return Some(direct);
23-
}
24-
if cfg!(windows) && Path::new(name).extension().is_none() {
25-
for ext in ["exe", "cmd", "bat"] {
22+
if cfg!(windows) {
23+
if Path::new(name).extension().is_some() {
24+
let direct = dir.join(name);
25+
return direct.is_file().then_some(direct);
26+
}
27+
for ext in ["exe", "cmd", "bat", "com"] {
2628
let candidate = dir.join(format!("{name}.{ext}"));
2729
if candidate.is_file() {
2830
return Some(candidate);
2931
}
3032
}
33+
return None;
3134
}
32-
None
35+
let direct = dir.join(name);
36+
is_executable(&direct).then_some(direct)
3337
}
3438

3539
/// A Command for `program`, resolved against linguo-managed dirs first with

0 commit comments

Comments
 (0)