NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.37k stars 13.6k forks source link

Nixpkgs-provided Fish shell breaks Fish's support for software distribution #190229

Open grahamc opened 2 years ago

grahamc commented 2 years ago

Describe the bug

Our Fish has a Nix store path set as its sysconfig dir:

grahamc@hyperchicken ~ [121]> echo $__fish_sysconf_dir
/nix/store/l5kr8p1ijqa9l9lciv15hc370rnynsz5-fish-3.2.2/etc/fish

this directory has a config.fish which loads /etc/fish/config.fish. However, Fish has conf.d support to allow other vendors to ship snippets that also get loaded: https://fishshell.com/docs/current/language.html?highlight=__fish_sysconf_dir#configuration-files

Because we set the sysconf dir to the Nix store, this behavior is broken.

Furthermore, software may run fish to ask where its sysconf directory is, which is also broken since that location is read only:

[nix-shell:~]$ fish -c 'echo $__fish_sysconf_dir'
/nix/store/l5kr8p1ijqa9l9lciv15hc370rnynsz5-fish-3.2.2/etc/fish

I'm looking at supporting Fish in the Nix installer, and it appears that using a Nix-provided Fish shell breaks the Nix installation. The part about querying where the sysconf dir is especially painful, because basically every packaging for Fish on a Mac puts it somewhere else:

    "/etc/fish/conf.d/nix.fish" # standard $__fish_sysconf_dir
    "/usr/local/etc/fish/conf.d/nix.fish" # their installer .pkg for macos's $__fish_sysconf_dir
    "/opt/homebrew/etc/fish/conf.d/nix.fish" # homebrew's $__fish_sysconf_dir
    "/opt/local/etc/fish/conf.d/nix.fish" # macports' $__fish_sysconf_dir

Expected behavior

Fish's conf.d support loads.

Notify maintainers

@cole-h @rapenne-s @winterqt

cole-h commented 2 years ago

Graham and I talked about this a little bit, and one potential solution (just brainstorming, really; functionality or lack thereof may make it a nonstarter) might be to make $__fish_sysconf_dir/conf.d a symlink to /etc/fish/conf.d EDIT: whether it exists or not.

winterqt commented 2 years ago

So this may be a totally... bad idea, but something I came up with is dynamically setting the sysconf dir based on what exists. What this would look like in practice is a wrapper that goes through a list of potential sysconf dirs (sorted by priority), and when one exists, setting the environment variable to that (and caching using a separate environment variable) -- or just setting it if it's unset.

This isn't currently possible since Fish would override the sysconf directory on startup, but with a one line patch we can disable this.

Thoughts welcome, I'd be happy to implement this if we agree to move forward with it :)

winterqt commented 2 years ago

Graham and I talked about this a little bit, and one potential solution (just brainstorming, really; functionality or lack thereof may make it a nonstarter) might be to make $__fish_sysconf_dir/conf.d a symlink to /etc/fish/conf.d.

Do you mean just setting the sysconf directory to /etc/fish? (Don't see how symlinks would come into play.) Oh, I see what you mean -- making the store path a symlink.

Wouldn't this break "backwards" compatibility (moving from a non-Nixpkgs Fish to Nixpkgs Fish without having to move stuff around), though? Furthermore, how would /etc/fish be created -- wouldn't it have to be created and owned by root? Maybe Fish handles this already, I'll look into it.