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

adding support for a nix.fish script along side $HOME/.nix-profile/etc/profile.d/nix.sh #440

Closed
cartazio opened this issue Jan 11, 2015 · 57 comments
Assignees
Labels
installer stale UX The way in which users interact with Nix. Higher level than UI.

Comments

@cartazio
Copy link

hey all,
to complement the nix.sh script, because I use fish as my root shell,
i had to write a nix.fish

https://gist.github.com/cartazio/21523fb72db0227611ac is that file

and inline here too

#! /usr/local/bin/fish
if test  -n "$HOME" ;
    set -xg NIX_LINK "$HOME/.nix-profile"

    # Set the default profile.
    if not test -L "$NIX_LINK" ;
        echo "creating $NIX_LINK" >&2
        set -l _NIX_DEF_LINK /nix/var/nix/profiles/default
        /nix/store/cdybb3hbbxf6k84c165075y7vkv24vm2-coreutils-8.23/bin/ln -s "$_NIX_DEF_LINK" "$NIX_LINK"
    end

    set -xg PATH $NIX_LINK/bin $NIX_LINK/sbin $PATH

    # Subscribe the user to the Nixpkgs channel by default.
    if not test -e $HOME/.nix-channels ;
        echo "https://nixos.org/channels/nixpkgs-unstable nixpkgs" > $HOME/.nix-channels
    end

    # Append ~/.nix-defexpr/channels/nixpkgs to $NIX_PATH so that
    # <nixpkgs> paths work when the user has fetched the Nixpkgs
    # channel.
    # set -xg  NIX_PATH ${NIX_PATH:+$NIX_PATH:}nixpkgs=$HOME/.nix-defexpr/channels/nixpkgs
    set -xg  NIX_PATH $NIX_PATH $HOME/.nix-defexpr/channels/nixpkgs

    # Set $SSL_CERT_FILE so that Nixpkgs applications like curl work.
    if test  -e /etc/ssl/certs/ca-bundle.crt ;  # Fedora, NixOS
        set -xg SSL_CERT_FILE /etc/ssl/certs/ca-bundle.crt ;
    else if test -e /etc/ssl/certs/ca-certificates.crt ;  # Ubuntu, Debian
        set -xg SSL_CERT_FILE /etc/ssl/certs/ca-certificates.crt
    else if test -e "$NIX_LINK/etc/ca-bundle.crt" ;  # fall back to Nix profile
        set -xg SSL_CERT_FILE "$NIX_LINK/etc/ca-bundle.crt"
    end
end

How would I go about upstreaming this and (future) fish scripting support?
I understand some of this stuff is generated from various templates?

thanks!

@cartazio
Copy link
Author

mind you, i'm still debugging/tweaking this to work right : )

@wmertens
Copy link
Contributor

I'm thinking it would be better to split the script in a setup part and an
environment loading part, and have the setup part be a bash script that
gets called.

It would also be nice if the environment loading part just read a
cross-shell file so the shell environment is only defined in one place.

See also #452

On Sun Jan 11 2015 at 3:16:18 AM Carter Tazio Schonwald <
notifications@github.com> wrote:

mind you, i'm still debugging/tweaking this to work right : )


Reply to this email directly or view it on GitHub
#440 (comment).

@elasticdog
Copy link

I can't yet vouch for the script itself, but I'm a fish shell user as well and would love to have an officially supported version of the environment setup script.

@cspickert
Copy link

I wrote a bash script that sources the existing nix.sh script and dumps the environment setup as a sequence of fish commands. It would need to be modified if the original script changed, but it's enough to get things up and running.

#!/usr/bin/env bash

# Usage from fish: "eval (./nix_fish_env) 2>/dev/null"

# Abort if nix isn't installed
if ! [ -f ~/.nix-profile/etc/profile.d/nix.sh ]; then
    exit
fi

# Unset variables that will be loaded from nix init
unset PATH
unset SSL_CERT_FILE

# Load environment from nix init
source ~/.nix-profile/etc/profile.d/nix.sh

# Remove trailing `:` from PATH
PATH="${PATH%:}"

# Read PATH and NIX_PATH into arrays
IFS=: read -a PATH_ARRAY <<< "$PATH"
IFS=: read -a NIX_PATH_ARRAY <<< "$NIX_PATH"

# Echo fish commands to export environment variables
echo set -x PATH ${PATH_ARRAY[@]} \$PATH \;
echo set -x NIX_PATH ${NIX_PATH_ARRAY[@]} \;

if [ -f "$SSL_CERT_FILE" ]; then
    echo set -x SSL_CERT_FILE \'$SSL_CERT_FILE\' \;
fi

@wmertens
Copy link
Contributor

wmertens commented May 6, 2015

So what's the next action on this? I presume your problem is solved, but
other fish users might want this. Should this be distributed alongside Nix?

On Fri, Apr 24, 2015 at 11:45 PM Cameron Spickert notifications@github.com
wrote:

I wrote a bash script
https://github.com/cspickert/fish/blob/master/misc/nix_fish_env.sh that
sources the existing nix.sh script and dumps the results as a sequence of
fish commands. It would need to be modified if the original script changed,
but it's enough to get things up and running.


Reply to this email directly or view it on GitHub
#440 (comment).

@jc00ke
Copy link

jc00ke commented May 30, 2015

I would like to see this distributed by default.

@ryanartecona
Copy link

I don't know if anything's changed here, but I just ran into this. I'm looking to try out Nix in OS X, and I also use fish as my system shell. Is there anything preventing this fish profile script from being added?

@rened
Copy link

rened commented Aug 5, 2015

+1, would love to have this!

@edolstra
Copy link
Member

edolstra commented Aug 6, 2015

Well, merging this would create a bit of a maintainability problem, since any future change to the bash profile script would have to be propagated to the fish script, and I don't know fish...

@Globegitter
Copy link

@edolstra just running into this as well and would love to see fish support.

I can see the issue with maintainability but most of fish syntax is quite easy to translate from bash, especially if you already have an example as above. (e.g. you have set -x instead of export, if end etc.) Creating a nix.fish from the original nix.sh took me about half an hour with barely any fish knowledge.

But you could also add it with the caveat that it is not fully tested and if any change breaks the existing fish script I am sure a fish user would step up to fix it.

@edolstra
Copy link
Member

Okay, if somebody wants to make a PR, I'll merge it.

@rasendubi
Copy link
Member

Any update on this? I can make a PR if it wasn't done yet and still needed.

@donut
Copy link

donut commented Jun 13, 2016

Just FYI, @cspickert's script still works. Maybe something like that would be easier to maintain as compared to completely duplicating everything in fish.

@domenkozar
Copy link
Member

Doesn't #626 fix this?

@rasendubi
Copy link
Member

Yeah, it does.

However, there was an idea to auto-generate nix.fish from the run of nix.sh. Not sure what way is better.

@Ericson2314
Copy link
Member

fish is able to convert bash's PATH to an array, I believe. Perhaps it can/will convert NIX_PATH too? Maybe something like @cspickert's script that just starts fish at the end instead of expecting to be called by fish would to the trick.

@rasendubi
Copy link
Member

rasendubi commented Jun 15, 2016

@cspickert's script produces fish's config. It doesn't expect to be called by fish.

But I got your idea. Just tried and this works:

#!/usr/bin/env bash
source ~/.nix-profile/etc/profile.d/nix.sh
fish

The big downside is that it starts a new shell.

@rasendubi
Copy link
Member

Whoa! Sourcing the next script from fish sets all needed variables:

eval (bash -c "source ~/.nix-profile/etc/profile.d/nix.sh; fish --command 'echo set -x NIX_PATH \"\$NIX_PATH\"\;; echo set -x PATH \"\$PATH\"\;; echo set -x SSL_CERT_FILE \"\$SSL_CERT_FILE\"'")

It's a bit convoluted, but what it does is simply:
source nix.sh from bash and run fish with all environment variables set. Fish then prints instructions to be evaluated by external fish.

Now I realize it's not too different from @cspickert's script and has many drawbacks (doesn't handle whitespaces, is influenced by .bashrc, etc)

@asymmetric
Copy link
Contributor

asymmetric commented Oct 6, 2016

@rasendubi running your command almost crashed my machine (the shell must've gotten in some infinite loop presumably), I had to force kill the fish process from outside the X session :).

@cvogt
Copy link

cvogt commented May 21, 2017

To avoid No manual entry for nix-env when calling nix-env --help, an addition to @cspickert's solution to set the MANPATH correctly: echo set -x MANPATH $NIX_LINK/share/man:$MANPATH

( cspickert/fish#1 )

@lilyball
Copy link
Member

@cvogt You actually should just unset MANPATH entirely. If you don't have it set, man will search for manpages based on $PATH.

@sebastien
Copy link

I finished writing a Python script that automatically converts the nix profile to a Fish script. See https://gist.github.com/sebastien/18a7eb71fdd34f6a0f825e69f9461d01

Run the script and you'll have ~/.config/fish/nix.fish. This is what I have in my fish config to load it:

if test -d $HOME/.nix-profile; and test -d /nix
   source ~/.config/fish/nix.fish
end

@princed
Copy link

princed commented Jul 16, 2018

For those who are using multi-user setup and need to convert "/nix/var/nix/profiles/default/etc/profile.d/nix-daemon.sh instead:

  1. Use modified version of @sebastien's script: https://gist.github.com/princed/8ed52eeb8d665b00f6f8330132863157 to get ~/.config/fish/nix-daemon.fish

  2. Loading snippet would look a bit differently:

if test -d /nix
   source ~/.config/fish/nix-daemon.fish
end

@mikeplus64
Copy link

mikeplus64 commented Aug 6, 2018

I made an alternate fish script that runs the original nix.sh, looks at env after it finishes, and re-exports stuff from that. It also only re-exports vars that are found (with just grep '^ *export', lol) in the input script. Should work for both nix.sh and nix-daemon.sh.

https://gist.github.com/mikeplus64/ef220937525e473f1769147c68ffddeb

@jtojnar
Copy link
Member

jtojnar commented Oct 13, 2018

Here is @rasendubi’s snippet modified to not run fish in order to prevent loop in ~/.config/fish/config.fish:

eval (bash -c "source ~/.nix-profile/etc/profile.d/nix.sh; echo export NIX_PATH=\"\$NIX_PATH\"; echo export PATH=\"\$PATH\"; echo export SSL_CERT_FILE=\"\$SSL_CERT_FILE\"")

@PyroLagus
Copy link
Contributor

In order to save other people the pain, I'd like to point out that the SSL_CERT_FILE variables in the above one-liners should actually be NIX_SSL_CERT_FILE as set in nix.sh. Using them as is will break things. At the very least, it'll break rustup and cargo.

So eval (bash -c "source ~/.nix-profile/etc/profile.d/nix.sh; echo export NIX_PATH=\"\$NIX_PATH\"; echo export PATH=\"\$PATH\"; echo export SSL_CERT_FILE=\"\$SSL_CERT_FILE\"") should actually be eval (bash -c "source ~/.nix-profile/etc/profile.d/nix.sh; echo export NIX_PATH=\"\$NIX_PATH\"; echo export PATH=\"\$PATH\"; echo export NIX_SSL_CERT_FILE=\"\$NIX_SSL_CERT_FILE\"")

Whether that actually is the best approach or whether using @sebastien's script or something like https://github.com/edc/bass is better, I don't know. It would be nice if we could have a standard fish script, and I think it would be great to come to an agreement over whether nix should be bundled with a generated fish script, a handwritten fish script, or whether using something like bass should be recommended.

@cartazio
Copy link
Author

so whats the current state of play for this?

@douglascamata
Copy link

@lilyball your Fish plugin saved me, thanks! ❤️

@analyticd
Copy link

@lilyball This works for me with nix installed fish too despite what the readme for it says, at least with everything I have tried so far.

@lilyball
Copy link
Member

@analyticd You're right, the README is slightly misleading. What I was trying to say is that Nix-installed Fish on NixOS doesn't need this, but it does everywhere else, including Nix-installed Fish on systems other than NixOS. I'll tweak the wording.

@workflow
Copy link

@analyticd You're right, the README is slightly misleading. What I was trying to say is that Nix-installed Fish on NixOS doesn't need this, but it does everywhere else, including Nix-installed Fish on systems other than NixOS. I'll tweak the wording.

To be precise, I think non-NixOS systems that install nix with --daemon (multi-user mode) might not need this either?

@lilyball
Copy link
Member

To be precise, I think non-NixOS systems that install nix with --daemon (multi-user mode) might not need this either?

They do. The mechanism that means this isn't necessary is the presence of /etc/fish/nixos-env-preinit.fish, a file that sources the Nix environment (and in particular sets up the $NIX_PROFILES env var).

This file is set up by the nixos fish module, not by the fish package (which makes sense because the fish package can't write to the system /etc dir).

@lilyball
Copy link
Member

Actually one caveat: If the $NIX_PROFILES env var is somehow already set by the time the shell starts, it isn't necessary. I don't run with multi-user nix myself so I don't know all the details of it, but I assume it doesn't have a way to set up the environment prior to the shell's execution.

@golddranks
Copy link

Is there still no official support for initing the nix environment for fish? How should I as a noob evaluate which of the scripts provided in this thread fits the bill for me? (MacOS, fish, single user, nix)

@lilyball
Copy link
Member

@golddranks AFAIK the other approaches just get you the nix environment and don't get you the rest of the fish stuff (e.g. completions, vendor scripts, etc). My plugin was designed for precisely your setup: https://github.com/lilyball/nix-env.fish

@lilyball
Copy link
Member

(If you don't use a fish plugin manager you can just copy the script into your own ~/.config/fish/conf.d folder as well

@golddranks
Copy link

Thank you! Seems to work well!

@yonkeltron
Copy link

I can confirm that this is still an issue. I'm on macOS and tried to install Nix directly as per the website's instructions. It failed until I dropped to ZSH and now I can't use anything Nix-related in Fish.

@mofahead
Copy link

mofahead commented May 24, 2020

@yonkeltron Once you had nix installed for ZSH, did you try installing the fish script linked by @lilyball above? Seems to work for me (single or multi user install). I’m running Linux not macOS though.

@jdelStrother
Copy link

jdelStrother commented May 25, 2020

I've just upgraded to Catalina and ran the multiuser install. @lilyball's fisher plugin works, though for me it needs tweaking since I don't have a ~/.nix-profile/etc directory (lilyball/nix-env.fish#1)

@cartazio
Copy link
Author

So ... the whole issue still stands. What is needed to get fish support for nix /Nixpkgs etc into upstream? Or is this being actively addressed? Thx

@lilyball
Copy link
Member

I just pushed a new commit to my plugin that should make it work on multi-user installs. I don't have a (non-NixOS) multi-user install to test with though.

@jdelStrother
Copy link

I just pushed a new commit to my plugin that should make it work on multi-user installs. I don't have a (non-NixOS) multi-user install to test with though.

Thanks @lilyball - works well for me on a multiuser macOS Catalina install.

@stale
Copy link

stale bot commented Feb 13, 2021

I marked this as stale due to inactivity. → More info

@stale stale bot added the stale label Feb 13, 2021
@lilyball
Copy link
Member

Not sure if it’s hit nixpkgs-unstable yet, but NixOS/nixpkgs#111978 was merged recently that adds a fishEnvPreInit option to fish that can be used to source stuff during init, including using fish-foreign-env to do so, and so can be written to source ${nix}/etc/profile.d/nix-daemon.sh. This isn’t very discoverable though, and I’m not sure the right way to handle that.

@thufschmitt
Copy link
Member

Should be fixed by #7014. Do reopen if it's not the case :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
installer stale UX The way in which users interact with Nix. Higher level than UI.
Projects
None yet
Development

No branches or pull requests