Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Open
john-cd opened this issue Jan 27, 2025 · 3 comments

Comments

@john-cd
Copy link

john-cd commented Jan 27, 2025

  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.

@casey
Copy link
Owner

casey commented Jan 27, 2025

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.

@john-cd
Copy link
Author

john-cd commented Jan 28, 2025

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

@casey
Copy link
Owner

casey commented Jan 28, 2025

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.

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

No branches or pull requests

2 participants