prefix-dev / pixi

Package management made easy
https://pixi.sh
BSD 3-Clause "New" or "Revised" License
3.1k stars 172 forks source link

Create alias for executables without `.bat` extension on windows #2249

Open plattenschieber opened 1 day ago

plattenschieber commented 1 day ago

Problem description

Hi, I'm enjoying using pixi as a package manager, but I have encountered a minor inconvenience when working in a bash environment (such as Git Bash) on Windows.

When globally (and also locally) installing packages, pixi appends .bat to the executable scripts, which requires explicitly calling app.bat rather than just app. I'm switching frequently between Windows and Unix-like systems and can't wrap my head around that but also don't want to creat aliases by hand 😅

Looking into your codebase, I noticed that this behavior is handled in the following section:

if cfg!(windows) {
    executable_script_path.set_extension("bat");
};
mappings.push(BinScriptMapping {
    original_executable: exec,
    global_binary_path: executable_script_path,
});

A possible solution is to extend this logic to create an alias without the .bat extension so that app can be called directly without needing to type app.bat.

The necessary changes could involve:

In the create_executable_scripts function, create a second version of the executable script without the .bat extension after generating the original.

In the map_executables_to_global_bin_scripts function, include mappings for both the original script and the new alias without the .bat extension.

This would make the usage for Windows users who prefer a more Unix-like command structure easier, while retaining compatibility with existing .bat scripts.

wolfv commented 1 day ago

Do you know if that "just works"? I am wondering why Git Bash isn't helping with this :)

As far as I know, the executable ending on Windows are something like .exe, .bat, .com, and maybe a few more.

We could think about adding a second "bin" folder that works better with git bash...e

plattenschieber commented 1 day ago

Do you know if that "just works"?

No, I haven't tried it out as I don't have any rust experience and no build tools at hand here. Could give it a try next week with a Codespace.

I am wondering why Git Bash isn't helping with this :)

You were guessing correctly. Just found out, that omitting .exe, e.g. app, leads to a correct call of app.exe in Git Bash. But this is not the case for .bat files.

At the same time, I'm not sure whether my suggestion is the right way: The .bat you are creating consists of several steps, like setting the path and a conda prefix before calling the executable itself (which is probably necessary to ensure correct environment setup for calling the exe?).

❯ pwd
/c/Users/xxx/.pixi/bin

❯ cat app.bat
@echo off
setlocal
@chcp 65001 > nul
@SET "Path=C:\Users\xxx\.pixi\envs\app;C:\Users\xxx\.pixi\envs\app\Library/mingw-w64/bin;C:\Users\xxx\.pixi\envs\app\Library/usr/bin;C:\Users\xxx\.pixi\envs\app\Library/bin;C:\Users\xxx\.pixi\envs\app\Scripts;C:\Users\xxx\.pixi\envs\app\bin;%Path%"
@SET "CONDA_PREFIX=C:\Users\xxx\.pixi\envs\app"
@CALL "C:\Users\xxx\.pixi\envs\app\etc/conda/activate.d\openssl_activate-win.bat"
@"C:\Users\xxx\.pixi\envs\app\Scripts/app.exe" %*

(btw weird setting of forward and backward slashes in one line ^^, probably string substitution instead of using something like pathlib?)

So, I don't know what's best. Creating an .exe out of the bat file? At least, that would make it executable and immediately callable.

wolfv commented 1 day ago

Yeah, I think the right thing to do would be to create a small "launcher-executable" that we can drop in the right place and that would essentially call the correct bat file under the hood.

plattenschieber commented 1 day ago

Don't your generated bat files already serve as a launcher executables? Maybe just replace them with a "real" executable?