How to use `nix-env --set` without losing access to `nix-env`? - nix

If I create a derivation using nix and then run nix-env --set <derivation name>, then commands like nix-env and nix are now missing from my nix profile and so I get the error Command 'nix-env' not found. I then have to mess around with symlinks in my nix profile to get it back.
This of course makes sense, because the nix package itself is not part of my derivation. Is there a way that I can use nix-env --set without losing access to nix itself?

Related

How can I create home-nix file from my current configuration

What I think that I've understood about home-manager.
Instead of using
nix-env iA packageToBeInstalled
you write a list of package in a file (/home/nixos/.config/nixpkgs/home.nix that I from now on call just home.nix)
you run
home-manager switch
and the package are installed.
But I have already installed some packages with nix-env. (home-manager for instance)
I would like to have my configuration save just in home.nix in order to just have to import it and execute home-manager switch to import the exact same configuration in a other OS.
Therefore I need a command replicating my configuration in home.nix.
I am not aware of a tool that fully automates this.
The nix-env list of installed packages is maintained in ~/.nix-profile/manifest.nix, but does not contain the attribute path, which is the "name" you need to use in such configuration files.
To find the attribute paths for the things you've installed, you may first create an index of sorts based on your current nixpkgs (NIX_PATH etc):
nix-env -qaP >packages.tmp
and then use it to look up each package.
Here's a one-liner that doesn't work for all packages.
nix-env -q | while read name; do grep "$name" <packages.tmp; done
So make sure to read through nix-env -q yourself and look up anything that's missing using for example https://search.nixos.org/packages.
To finalize, remove the imperatively installed packages with nix-env -e, check nix-env -q, and rm packages.tmp.

Why does my NixOS installation not have `~/.nix-profile/etc/profile.d/nix.sh`?

A NixOS user, I am studying the Nix Pills. They frequently reference ~/.nix-profile/etc/profile.d/nix.sh as a means of "entering the Nix environment". E.g. quoting from chapter 5:
I remind you how to enter the Nix environment: source
~/.nix-profile/etc/profile.d/nix.sh
However, my NixOS machine does not even have a ~/.nix-profile/etc directory, let alone a ~/.nix-profile/etc/profile.d/nix.sh file. My questions:
Why might my machine not have ~/.nix-profile/etc?
Is there an ordinary way to generate ~/.nix-profile/etc/profile.d/nix.sh?
Is there straightforward alternative way to "enter the Nix environment" in NixOS?
I do not yet have answers to (1) and (2), but do have an answer to (3). That is:
$ nix repl
works to enter the nix environment.
According to the official documentation, profile could be automatically generated when you've switched to it by command:
$ nix-env --switch-profile /nix/var/nix/profiles/default
So, you should try this command and it should create missed files and directories.
Here is the text copied from official doc:
You generally wouldn’t have /nix/var/nix/profiles/some-profile/bin in your PATH. Rather, there is a symlink ~/.nix-profile that points to your current profile. This means that you should put ~/.nix-profile/bin in your PATH (and indeed, that’s what the initialisation script /nix/etc/profile.d/nix.sh does). This makes it easier to switch to a different profile. You can do that using the command nix-env --switch-profile:
$ nix-env --switch-profile /nix/var/nix/profiles/my-profile
$ nix-env --switch-profile /nix/var/nix/profiles/default
These commands switch to the my-profile and default profile, respectively. If the profile doesn’t exist, it will be created automatically. You should be careful about storing a profile in another location than the profiles directory, since otherwise it might not be used as a root of the garbage collector.

How can I reset my nix environment to the original user profile?

I believe I ran nix-env -if example.nix which changed my nix environment.
How can I undo this action?
I'm trying to run a application that is specified in my nixos config (/etc/nixos/*), however it no longer seems available (within the $PATH).
Seems it might be nix-env --switch-profile /nix/var/nix/profiles/default (according to https://nixos.org/nix/manual/#sec-profiles) ?
I run nix-env -e '*' to remove all packages from my profile installed via nix-env regularly and move anything I want to use into environment.systemPackages so all my packages are tracked in my nixos configuration declaratively. As for debugging why the application specified in your configuration.nix isn't in your path, an application specified in your configuration.nix should be symlinked to /run/current-system/sw/bin, so the first thing would be to check that the binary you're looking for is listed in there and second that is in your $PATH.

How to know the build plan and store path without building a Nix expression?

nix-build ... --no-out-link gives a path in the Nix store.
Is it possible to find out that path without actually building the expression ?
Is it possible to find out the dependencies and the planned build operations without building the expression ?
How could I find the answer myself ?
The Nix manual, "Building and testing" section refers to nix-build documentation, which in the last "Description" paragraph mentions it is a combination of nix-instantiate and nix-store -r.
nix-instantiate does not build. It only calculates the plan, in the form of a derivation and its closure:
$ nix-instantiate '<nixpkgs>' -A hello
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
/nix/store/20bc2g6gfn44p9wk98s30pm346pmz0x9-hello-2.10.drv
However, I prefer to use nix repl to explore Nix expressions:
$ nix repl '<nixpkgs>'
Loading '<nixpkgs>'...
Added 8623 variables.
nix-repl> hello.outPath
"/nix/store/nic2bl8ry6vfyxr9717983d5b2l4sn1c-hello-2.10"
Its tab completion is very helpful when exploring expressions.
man nix-store has the answer, and in particular the --query section.
To know the output path:
nix-store -q --outputs $(nix-instanciate default.nix)
To know the build-time dependencies:
nix-store -qR --include-outputs $(nix-instanciate default.nix)
As for a build plan, the closer I get is to use the --tree flag.
Note that nix-shell exposes a $out variable too, so another possible solution to the first bullet point would be:
nix-shell --pure --run 'echo $out' some-file.nix

Inject runtime dependency into nix package

Adding a runtime dependency to a package through override buildInputs causes the package to rebuild. Is there a simple way to inject runtime dependencies into a package without recompiling?
So basically adding package/bin to PATH and package/lib to LD_LIBRARY_PATH
If I understand correctly that you want to tweak the environment used when a Nix-installed app is run, not the one used when it is built, then a method I know of is as follows below. By using it, you essentially create a wrapper script, which overrides the "default command". So, something similar like creating e.g. a custom ~/bin/vim script, which adds some options/env overrides to the default vim binary, which is called with a "hardcoded original path" inside the script.
One example of it in nixpkgs is how vimutils.vimWithRC overrides vim command with a custom script. For your own use, you could write more or less something like below:
with import <nixpkgs> {};
writeScriptBin "vim" ''
#!/usr/bin/env bash
export PATH=package/bin:$PATH # whatever you like; I've added what you asked for
export LD_LIBRARY_PATH=package/lib:$LD_LIBRARY_PATH
${vim}/bin/vim --my-options "$#"
'';
If you put it in my-vim.nix, you should be able to install it with:
$ nix-env -e vim # REMOVE NORMAL VIM. I think this should be done first to avoid conflict
$ nix-env -i -f my-vim.nix
And hopefully it'll work and "override" the default vim for you.
DISCLAIMER: I haven't actually tested it in this exact form, sorry. Don't have a Nix console handy at this moment, unfortunately.

Resources