All approaches @Mic92 described are indeed declarative, however you have to edit file to add new package.
Would you give up imperative nix-env --install
behavior for this? If not, then read next.
I’ve written a small (50 lines) bash script, that replaces 50% of nix-env
. Here it is Imperative nix-env rewrite (so it becomes declarative) · GitHub. Add an alias (declaratively in NixOS or in ~/.profile)
alias nix-env=/path/to/script
It replaces nix-env
with a thing, that supports 3 commands: install
, uninstall
and list
.
$ nix-env list
nixpkgs.htop
$ nix-env uninstall calibre
Not installed
$ nix-env install calibre
scheduled install'n'update
error: undefined variable 'calibre' at /home/danbst/.config/nixpkgs/declarative-env.nix:7:1
$ nix-env install nixpkgs.calibre
scheduled install'n'update
replacing old 'declarative-collection'
installing 'declarative-collection'
building '/nix/store/2cnhxqwxl79qj81mfkrqpl7xr361i3z1-user-environment.drv'...
created 5054 symlinks in user environment
Success
$ nix-env install '(nixpkgs.htop.overrideAttrs (_: { name = "my-override"; }))'
scheduled install'n'update
replacing old 'declarative-collection'
installing 'declarative-collection'
these derivations will be built:
/nix/store/fbggzpbs91ryysmdzc131vvkg8vm14yz-declarative-collection.drv
building '/nix/store/fbggzpbs91ryysmdzc131vvkg8vm14yz-declarative-collection.drv'...
building '/nix/store/wpb2w7vj3cq4lsl1syac7lhndahqc64r-user-environment.drv'...
created 5054 symlinks in user environment
Success
$ nix-env list
nixpkgs.calibre
(nixpkgs.htop.overrideAttrs (_: { name = "my-override"; }))
# Original nix-env is available as \nix-env
There are 3 distinctions from nix-env
here (besides completely new CLI):
- packages are identified by their attribute, instead of “name”. Just like in nix 2.0
- it saves it’s installed packages state in simple format: line per package (original nix-env builds a
maniphest.nix
with lots of metadata, but most importantly, it doesn’t save attribute name in maniphest) - as a buildEnv wrapper, it maintains consistency among all installed pacakges (can upgrade/downgrade some unrelated package). Same behavior as for
nixos-rebuild
In fact, nix-env list
is an alias to cat ~/.config/nixpkgs/declarative
. This list is used to build env:
$ cat /home/danbst/.config/nixpkgs/declarative-env.nix
───────┬─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
│ File: /home/danbst/.config/nixpkgs/declarative-env.nix
───────┼─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
1 │ let nixos = import <nixos> { }; in
2 │ let nixpkgs = import <nixpkgs> { }; in
3 │ let _pkgs = import <nixpkgs> { }; in
4 │ rec { _paths = [
5 │ nixpkgs.calibre
6 │ (nixpkgs.htop.overrideAttrs (_: { name = "my-override"; }))
7 │ ];
8 │ env = _pkgs.buildEnv {
9 │ name = ''declarative-collection'';
10 │ paths = _paths;
11 │ }; }
12 │ # Updated successfully!
───────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────────
And installed atomically with original nix-env
. Pretty much declarative’n’imperative now! (I have a feeling that people have done this before…)