just_executable() and other functions return the native path, not the cygpath, when in Windows
- I am confused by the following sentence in the just doc:
On Windows, invocation_directory() uses cygpath to convert the invocation directory to a Cygwin-compatible /-separated path. Use invocation_directory_native() to return the verbatim invocation directory on all platforms.
Running the following on Windows, I still get Windows-native paths e.g. D:\some\thing\
@test: echo '{{just_executable()}}' echo '{{justfile()}}' echo '{{justfile_directory()}}' echo '{{source_directory()}}' echo '{{invocation_directory()}}'
-
Not clear: does
justrequirecygpath.exein the system $PATH while on Windows? does it fail if it does not find it? -
The sentence above also conflicts with https://just.systems/man/en/paths-on-windows.html
-
There should be a function to normalize Windows path to Unix / POSIX paths and vice-versa.
You're not alone in being confused 😅
The dependency on cygpath.exe is because cygwin is maybe the most common way to get a sh available so you could use just.
I believe that Git Bash uses cygwin and provides cygpath.exe.
The two places where cygpath is requires is shebang recipes, where it translates the shebang style from unix style, invocation_directory() which translates the path to unix-style. These are documented as needing cygpath, let me know if you think it isn't clear enough.
The Paths on Windows section should definitely be updated to note the two dependencies on cygpath.
You can translate paths manually cygpath with:
shell(`cygpath --windows "$1"`, path)
shell(`cygpath --unix "$1"`, path)
I think we could consider providing helper functions for these, ideally without depending on cygpath, but I'm not sure how complex the translation is, and how environment-specific it is.
a) It is indeed not clear in the manual. You may want to add to it.
I would also add a "how to" page on how to use cygwin with just on Windows, especially since the cygwin installation does not include /bin , where cygpath lives, in his $PATH (at least when I tried)
(or is just looking for cygpath.exe in c:\cygwin64\bin specifically??)
b) Another complication: WSL adds a bash.exe to directories in the Windows PATH:
C:\Users\xyz>where bash C:\Windows\System32\bash.exe C:\Users\xyz\AppData\Local\Microsoft\WindowsApps\bash.exe
That means one has to write the full path for Cygwin Bash on Windows:
set windows-shell := [ "C:\cygwin64\bin\bash.exe", "-uc"] with double \
c) If cygpath is not in the path, should just fail instead of returning Windows-style paths, as it does currently (at least on my machine - see the test above)? Or is returning Windows-style path a bug in that case?
At least there should be a set option to fail or warn if cygpath.exe cannot be located.
d) The transformation of Windows paths into POSIX depends on the shell
- Cygwin converts e.g. from C:\ to /cygdrive/c/
- Git bash to /c/
- WSL bash to /mnt/c/
AFAIK
so you may need a setting for "conversion style"
https://users.rust-lang.org/t/how-to-normalize-windowss-to-when-display-or-convert-path-to-string/103919/6
e) See also the crates:
https://docs.rs/typed-path/latest/typed_path/ https://github.com/pratikpc/wsl-path-rust/tree/develop
I opened #2602 to document in one place how cygpath.exe is used.
Returning Windows paths for all functions except invocation_directory() (invocation_directory_native() will return the Windows path) is the intended behavior. It's not ideal, but I'm not sure the dependency on cygpath.exe, which is specific to only certain kinds of installations of sh, is a good idea.
I'm not sure we can provide facilities to convert between paths. We would either have to depend on cygpath.exe, or try to guess the environment and convert based on that guess, which seems very tricky to get right and not run into edge cases.
This behavior is confusing in GitHub CI, which seems to always use bash by default, including on Windows. As a result, this command does not work consistently in CI. I have not figured out a way for the justfile to "just work" regardless of how it was executed.
env-info:
{{just_executable()}} --version
Run just env-info
just env-info
shell: C:\Program Files\PowerShell\7\pwsh.EXE -command ". '{0}'"
C:\Users\runneradmin\.cargo\bin\just.exe --version
/usr/bin/bash: line 1: C:Usersrunneradmin.cargobinjust.exe: command not found
error: Recipe `env-info` failed on line 80 with exit code 127
Error: Process completed with exit code 1.
P.S. @casey take a look at path-slash crate for the internal translation, but that might not fix my issue above