just icon indicating copy to clipboard operation
just copied to clipboard

just_executable() and other functions return the native path, not the cygpath, when in Windows

Open john-cd opened this issue 10 months ago • 5 comments

  1. 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()}}'

  1. Not clear: does just require cygpath.exe in the system $PATH while on Windows? does it fail if it does not find it?

  2. The sentence above also conflicts with https://just.systems/man/en/paths-on-windows.html

  3. There should be a function to normalize Windows path to Unix / POSIX paths and vice-versa.

john-cd avatar Jan 27 '25 21:01 john-cd

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.

casey avatar Jan 27 '25 22:01 casey

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

john-cd avatar Jan 28 '25 00:01 john-cd

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.

casey avatar Jan 28 '25 16:01 casey

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.

nyurik avatar Nov 02 '25 16:11 nyurik

P.S. @casey take a look at path-slash crate for the internal translation, but that might not fix my issue above

nyurik avatar Nov 02 '25 16:11 nyurik