Raku / App-Rakubrew

Raku environment manager
https://rakubrew.org/
Other
26 stars 13 forks source link

init Fish doesn't add bin directories to path #69

Closed masukomi closed 1 year ago

masukomi commented 1 year ago

the core problem is that the bin directories aren't in my path even when i have rakubrew init Fish | source in my fish config.

However it's important to note that it's not handling the path stuff in a very fishy way anyway.

the appropriate way to add a folder to fish's path is not to override PATH like Bash. Instead you say fish_add_path -g <path>

you can optionally specify -a (append) or -p (prepend) if you want to control if it gets added to the start or end of the path. fish_add_path docs here

To me this implies that the path handling code can be dramatically simplified and just be iterating over get_bin_paths and adding a fish_add_path line for each.

Separately but related: To me it also seems very weird to create a function with the same name of an executable that you want to execute. The fact that you then have to override the function name you've just created by using the command to execute the rakubrew executable but not the function seems like a code smell and points to the debugging problems inherent in this. AFAIK neither rbenv, rvm, or ASDF do this.


rakubrew v33 Build type: macos OS: darwin

shim

/Users/masukomi/.rakubrew

patrickbkr commented 1 year ago

I can't reproduce this locally. Can you post the output of rakubrew init Fish? Also, which paths do you expect to be in PATH which aren't?

Backgound of the shell function with the name 'rakubrew':

Rakubrew can work in two different modes: shim and env.

Rakubrew in env mode works by changing the PATH variable in the currently running shell. That's generally impossible for a subprocess to do. The trick is to have code run in the context of the users shell itself. That's what this shell function is for. I am unaware of any other *env managers that have found a way around this. Do note that some are programmed in Bash / Shell and thus can run in the users shell in the first place and thus don't need a separate hook. Also some only work via shims (just like rakubrew in shim mode) which doesn't require such a shell hook as the PATH stays untouched.

Rakubrew uses the shell hook for one other thing as well: Injecting autocompletion code into the shell. So when running rakubrew in shim mode and abstaining from autocompletion it is possible to use rakubrew without that hook. That's what the section Bare bones installation on the Rakubrew website describes.

masukomi commented 1 year ago

I can't reproduce this locally. Can you post the output of rakubrew init Fish?

❯ rakubrew init Fish
set -x PATH '/Users/masukomi/.rakubrew/shims' '/Library/Frameworks/Python.framework/Versions/3.11/bin' '/Users/masukomi/.asdf/shims' '/opt/homebrew/opt/asdf/libexec/bin' '/Users/masukomi/.rbenv/shims' '/opt/homebrew/opt/libxslt/bin' '/opt/homebrew/opt/llvm/bin' '/opt/homebrew/opt/openssl@3/bin' '/Applications/Racket v8.4/bin' '/opt/homebrew/opt/bash/bin' '/Users/masukomi/.rakubrew/bin' '/Users/masukomi' '/Users/masukomi/bin/git-scripts' '/Users/masukomi/bin/git-scripts/hooks' '/usr/local/bin' '/System/Cryptexes/App/usr/bin' '/usr/bin' '/bin' '/usr/sbin' '/sbin' '/opt/X11/bin' '/Applications/Little Snitch.app/Contents/Components' '/Library/TeX/texbin' '/opt/homebrew/sbin' '/opt/homebrew/bin' '/Users/masukomi/bin' '/Applications' '/Users/masukomi/.iterm2' '/Users/masukomi/Applications' '/Users/masukomi/workspace/git_accessories' '/Users/masukomi/go/bin' '/Users/masukomi/.cargo/bin' '/Users/masukomi/bin/work' '/Users/masukomi/Library/Python/3.9/bin' '/usr/local/opt/python/libexec/bin' '/Library/Apple/usr/bin'

function rakubrew
    command /Users/masukomi/bin/rakubrew internal_hooked Fish $argv
    and eval (command /Users/masukomi/bin/rakubrew internal_shell_hook Fish post_call_eval $argv)
end

function _rakubrew_is_not_register
    set args (commandline -poc)
    if [ (count $args) -eq 3 -a $args[1] = 'register' ]
        return 1
    else
        return 0
    end
end

complete -c rakubrew -f -n _rakubrew_is_not_register -a '(command /Users/masukomi/bin/rakubrew internal_shell_hook Fish completions (commandline -poc) (commandline -ct) | string split " ")'

Also, which paths do you expect to be in PATH which aren't?

/Users/masukomi/.rakubrew/versions/moar-2022.12/bin
/Users/masukomi/.rakubrew/versions/moar-2022.12/share/perl6/core/bin
/Users/masukomi/.rakubrew/versions/moar-2022.12/share/perl6/site/bin
/Users/masukomi/.rakubrew/versions/moar-2022.12/share/perl6/vendor/bin

found via find $(rakubrew home) -type d -name 'bin' (in bash)

the site one is the one that's most directly affecting me at the moment because i installed the Hey package which has an executable, which ended up there, but that wasn't in my path so i couldn't run it.

patrickbkr commented 1 year ago

Ah, then I think there is a misunderstanding. You are running rakubrew in shim mode. In that mode rakubrew dies not add the different bin folders to PATH. Instead only the /shim folder is in PATH. That folder contains shims for all the executables found in the different versions. If you installed a module that provides an executable, then you need to run rakubrew rehash to make rakubrew rescan the bin dirs and add any missing shims.

masukomi commented 1 year ago

If you installed a module that provides an executable, then you need to run rakubrew rehash to make rakubrew rescan the bin dirs and add any missing shims.

So, to sanity check: that means that every time i zef install something with an executable i need to follow that up with a rakubrew rehash. Correct?

Either way, I'm thinking maybe this ticket should be closed an a new ticket opened to alter the code to use fish_add_path -g <path> instead of redefining the PATH variable

patrickbkr commented 1 year ago

So, to sanity check: that means that every time i zef install something with an executable i need to follow that up with a rakubrew rehash. Correct?

Yes, exactly.

Either way, I'm thinking maybe this ticket should be closed an a new ticket opened to alter the code to use fish_add_path -g <path> instead of redefining the PATH variable

I briefly looked into the code. The reason it works by overwriting PATH, is that's how the API is designed. The individual shell hook implementations only provide a function to set a full PATH variable. The new PATH possibly misses previously existing paths and guarantees to not add duplicates. So to use fish_add_path one would either have to redesign the API and adapt the code of all the other shell hooks, or do an awkward dance of diffing the current PATH against the given PATH string and turning all missing paths into fish_add_path and remove all excessive paths. See Fish.pm:99-10 for the respective function. If you have a good idea of how to factor this better, I'm open to pull requests. Otherwise I think it's better to leave it as is.

patrickbkr commented 1 year ago

Closing as I think this works as intended. Please reopen if you disagree.