So a sort of crazy thing happened to the Nix UI between Nix 2.3 and 2.4.
nix shell
, the command that opens a shell, was renamed to nix develop
.
nix develop
is not only more to type (no, nix dev
does not work), but it’s also a… misleading name for this command. I publish and preview my blog from a Nix shell, which has dependencies like my static site generator and CSS prefixer and such. I do not think of this as “developing” my blog. I think of it as writing my blog within a Nix shell. Shells are more broadly useful than “just” software development, even if that is the main use case.
Anyway. Coming from the classic commands: nix-shell
is now called nix develop
, and nix-shell -p
is now called nix shell
.
I don’t know why.
Maybe there’s some reason why nix shell
and nix develop
are separate now. It always made sense to me that nix-shell -p
was just a specific, simple case of nix-shell
, since they do basically the same thing. But maybe nix develop
does something more? Something different? I don’t know.
Let’s find out.
In fact, let’s use this blog as an example. Its shell.nix
looks like this:
$ cat shell.nix
with import <nixpkgs> {}; mkShellNoCC {
nativeBuildInputs = [
fswatch
hugo
nodePackages.autoprefixer
nodePackages.postcss-cli
];
}
One of the things I’m excited about with the new nix shell
– er, nix develop
– is dependency locking. I currently have a janky little hand-rolled pinning scheme for my blog, because nodePackages.postcss-cli
broke at some point in the past and I haven’t had time to look into why. So I keep this pinned to the last known good revision of Nixpkgs.
It basically just runs:
$ nix-shell -I nixpkgs=https://api.github.com/repos/NixOS/nixpkgs/tarball/fc39a32aa1322d8eec8f7224261c005cbf33954
Er, except that it also does the fancy garbage collection dance that I’ve talked about earlier. Which is another thing that nix develop
can do automatically, or so I’ve heard. Let’s try it out.
How do I migrate a shell.nix
file to a flake?
Let’s start with the obvious one:
$ nix develop
error: path '/Users/ian/src/ianthehenry.com' is not a flake (because it doesn't contain a 'flake.nix' file)
Alas. That is what I expected, but there was a small chance that nix develop
was backwards compatible.
So let’s learn how to write the equivalent flake.nix
file. I expect I should be able to import my shell.nix
file from a flake.nix
file…?
Let’s start by reading nix develop --help
:
nix develop
- run abash
shell that provides the build environment of a derivation
Oh gosh oh no. That documentation is not promising. I expected that I would have to rediscover how to run zsh
, but… well, if it’s not possible, I guess I’m sticking with nix-shell
.
Let’s see… it shows some usage commands. It shows this:
- Record a build environment in a profile:
# nix develop --profile /tmp/my-build-env nixpkgs#hello
Presumably that’s how I save things from the garbage collector. I’ll have to come back to that.
- Replace all occurences of the store path corresponding to
glibc.dev
with a writable directory:# nix develop --redirect nixpkgs#glibc.dev ~/my-glibc/outputs/dev
Note that this is useful if you’re running a
nix develop
shell fornixpkgs#glibc
in~/my-glibc
and want to compile another package against it.
Whoa. Weird. Okay. I’ll have to come back to that too.
Then it describes some stuff about the shell environment; okay…
nix develop
starts abash
shell that provides an interactive build environment nearly identical to what Nix would use to build installable. Inside this shell, environment variables and shell functions are set up so that you can interactively and incrementally build your package.Nix determines the build environment by building a modified version of the derivation installable that just records the environment initialised by
stdenv
and exits. This build environment can be recorded into a profile using--profile
.
Sounds a bit like the inputDerivation
scheme that I use. I wonder how this works if you aren’t using stdenv
?
The prompt used by the
bash
shell can be customised by setting thebash-prompt
andbash-prompt-suffix
settings innix.conf
or in the flake’snixConfig
attribute.
Not encouraging for zsh
users. Which is, you may recall, the default login shell for macOS users as of Catalina – which came out in October 2019.
Alright. So now it talks about what it actually does:
If no flake output attribute is given,
nix develop
tries the following flake output attributes:
devShell.<system>
defaultPackage.<system>
If a flake output name is given,
nix develop
tries the following flake output attributes:
devShells.<system>.<name>
packages.<system>.<name>
Okay. Well. Let’s try this:
$ cat shell.nix
{ nixpkgs ? import <nixpkgs> {} }:
with nixpkgs; mkShellNoCC {
nativeBuildInputs = [
fswatch
hugo
nodePackages.autoprefixer
nodePackages.postcss-cli
];
}
$ cat flake.nix
{
outputs = { nixpkgs }: {
devShell.${builtins.currentSystem} =
import ./shell.nix { inherit nixpkgs };
};
}
$ nix develop
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
error: source tree referenced by 'git+file:///Users/ian/src/ianthehenry.com' does not contain a '/flake.nix' file
Ah. Sigh. Because this is a Git repository, it’s assuming that I mean to treat it like a Git repository, and it’s upset that I haven’t added flake.nix
yet? But I just want it to be a local path:
$ time nix develop path:.
copying '/Users/ian/src/ianthehenry.com'
error: syntax error, unexpected '}'
at /nix/store/7nk5xzhpmfq6g5ldzwf4cf1433pndhb6-source/flake.nix:4:44:
3| devShell.${builtins.currentSystem} =
4| import ./shell.nix { inherit nixpkgs };
| ^
5| };
1.34s user 2.18s system 83% cpu 4.198 total
Okay, no, because it spends 4 seconds copying this folder for some reason.
$ git add flake.nix
$ time nix develop
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
error: syntax error, unexpected '}'
at /nix/store/58r3rydwwni2mym0bnwjx1i9x8snpcmn-source/flake.nix:4:44:
3| devShell.${builtins.currentSystem} =
4| import ./shell.nix { inherit nixpkgs };
| ^
5| };
0.25s user 0.15s system 84% cpu 0.480 total
That’s better. And we can see that, as always, I forgot a semicolon on a singleton attribute set…
I fix that, and try again:
$ nix develop
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
warning: creating lock file '/Users/ian/src/ianthehenry.com/flake.lock'
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
error: 'outputs' at /nix/store/rawzl90y6d1mvk8qcfqshk5x6j0gvx9b-source/flake.nix:2:13 called with unexpected argument 'self'
at «string»:45:21:
44|
45| outputs = flake.outputs (inputs // { self = result; });
| ^
46|
Okay. I forgot how flakes work. Let’s try that again:
$ cat flake.nix
{
outputs = { self, nixpkgs }: {
devShell.${builtins.currentSystem} =
import ./shell.nix { inherit nixpkgs; };
};
}
Better?
$ nix develop
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
error: attribute 'currentSystem' missing
at /nix/store/k5vy4d9l72isk2mbqw0slbc4hbcj0q0n-source/flake.nix:3:16:
2| outputs = { self, nixpkgs }: {
3| devShell.${builtins.currentSystem} =
| ^
4| import ./shell.nix { inherit nixpkgs; };
Ugh. Obviously builtins.currentSystem
does exist, normally, but apparently it’s forbidden when evaluating a flake? Just to be annoying? So I have to actually type out x86_64-darwin
. Which is like a Mavis Beacon boss level. One more try:
$ nix develop
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
error: undefined variable 'mkShellNoCC'
at /nix/store/w1m5vcxihca30mj0wm1yyijl0lqzcmv6-source/shell.nix:2:15:
1| { nixpkgs ? import <nixpkgs> {} }:
2| with nixpkgs; mkShellNoCC {
| ^
3| nativeBuildInputs = [
Ah, okay, right, because nixpkgs
is a flake now, not an attribute set. I have to do…
$ cat flake.nix
{
outputs = { self, nixpkgs }: {
devShell.x86_64-darwin =
import ./shell.nix {
nixpkgs = nixpkgs.outputs.legacyPackages.x86_64-darwin;
};
};
}
And I finally got it:
$ nix develop
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
[0/5 built, 1/2/14 copied (19.8/177.0 MiB), 5.5/51.5 MiB DL] fetching hugo-0.90.0 from https://cac
Whoooo. I don’t know where it was copying from, because the Nix CLI once again assumes that my terminal spans the full length of a widescreen monitor, and it chops off at my paltry 98 columns.
Ians-MBP:ianthehenry.com ian$ hugo version
hugo v0.90.0+extended darwin/amd64 BuildDate=unknown
But it did drop me into a bash shell! Wow. Ians-MBP
. Is that the name of this computer? This poor computer. It deserves something a little more personalized. I honestly don’t know what that string is or how I would change it, though. And hopefully I will never see it again, so I choose to ignore it.
Okay. I eventually wrote a flake. I only had to type x86_64-darwin
twice to do it, and my fingers are only barely cramping from the effort.
nix develop
did in fact ignore my NIX_BUILD_SHELL
that I’ve set to run zsh
, so I once again find myself plunged into a land free from tab completion and shell aliases. Wonderful.
Now let’s lock it to the correct version… nix flake lock --help
gets me here:
$ nix flake lock --update-input nixpkgs --override-flake nixpkgs https://api.github.com/repos/NixOS/nixpkgs/tarball/fc39a32aa1322d8eec8f7224261c005cbf339549
error: input 'https://api.github.com/repos/NixOS/nixpkgs/tarball/fc39a32aa1322d8eec8f7224261c005cbf339549' is unsupported
Er, darn. That’s the URL I was using before. But I guess the flaky version is:
$ nix flake lock --update-input nixpkgs --override-flake nixpkgs github:nixos/nixpkgs/fc39a32aa1322d8eec8f7224261c005cbf339549
[24.7 MiB DL] downloading 'https://api.github.com/repos/nixos/nixpkgs/tarball/fc39a32aa1322d8eec8f
Nice. It’s downloading something and spending the traditional full minute unpacking or copying or whatever it’s doing with it. I expected that it would just… update the lock file for me. But nope, it’s also gotta download and cache this. I dunno.
$ nix flake lock --update-input nixpkgs --override-flake nixpkgs github:nixos/nixpkgs/fc39a32aa1322d8eec8f7224261c005cbf339549
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
warning: updating lock file '/Users/ian/src/ianthehenry.com/flake.lock':
• Updated input 'nixpkgs':
'github:NixOS/nixpkgs/2beba9a23a8381eb95187f46b10c3677d8f63ca1' (2021-12-19)
→ 'github:nixos/nixpkgs/fc39a32aa1322d8eec8f7224261c005cbf339549' (2021-10-01)
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
Hey, that’s neat! I love that it shows the date.
I don’t know why it keeps telling me that my Git tree is dirty. I don’t know what I would possibly do with that information. I know that my worktree is dirty. You don’t have to tell me, twice, in the same command.
Let’s take a look:
$ cat flake.lock
{
"nodes": {
"nixpkgs": {
"locked": {
"lastModified": 1633070184,
"narHash": "sha256-B0G23rPFBhiBsM/OU7WsFXL2dDaLdgRUU7onC/CCyiA=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "fc39a32aa1322d8eec8f7224261c005cbf339549",
"type": "github"
},
"original": {
"id": "nixpkgs",
"type": "indirect"
}
},
"root": {
"inputs": {
"nixpkgs": "nixpkgs"
}
}
},
"root": "root",
"version": 7
}
Okay, neat. Looks great. It did the thing. And now:
$ nix develop
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
Ians-MBP:ianthehenry.com ian$ hugo version
hugo v0.88.1+extended darwin/amd64 BuildDate=unknown
So it worked! Nice.
And now let’s try the profile thingy…
$ nix develop --profile ~/scratch/test-profile
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
Ians-MBP:ianthehenry.com ian$
Okay. Did that do anything?
$ nix profile list --profile ~/scratch/test-profile
Umm… no. It did not do anything, in fact. Did I… do something wrong?
The example from the --help
is:
- Record a build environment in a profile:
# nix develop --profile /tmp/my-build-env nixpkgs#hello
Let’s try exactly that, minus the sudo
…
$ nix develop --profile /tmp/my-build-env nixpkgs#hello
zsh: no matches found: nixpkgs#hello
Sigh. Of course.
$ nix develop --profile /tmp/my-build-env 'nixpkgs#hello'
Ians-MBP:ianthehenry.com ian$
Did that do anything?
$ ll /tmp/my-build-env
/tmp/my-build-env -> my-build-env-1-link
$ ll /tmp/my-build-env-1-link
/tmp/my-build-env-1-link -> /nix/store/2cxr6dr0vpihcidc1b3h0vp0xvzxf8v4-hello-2.10-env
$ ll /nix/store/2cxr6dr0vpihcidc1b3h0vp0xvzxf8v4-hello-2.10-env
56K /nix/store/2cxr6dr0vpihcidc1b3h0vp0xvzxf8v4-hello-2.10-env
Okay. It produced a 56 kilobyte file. It seems to contain… all of the stdenv? I guess? Like the source code of the stdenv/setup
script? The file looks like this:
{
"bashFunctions": {
"_activatePkgs":" \n local hostOffset targetOffset;\n local pkg;\n for hostOffset in \"${allPlatOffsets[@]}\";\n do\n local pkgsVar=\"${pkgAccumVarVars[hostOffset + 1]}\";\n for targetOffset in \"${allPlatOffsets[@]}\";\n do\n (( hostOffset <= targetOffset )) || continue;\n local pkgsRef=\"${pkgsVar}[$targetOffset - $hostOffset]\";\n local pkgsSlice=\"${!pkgsRef}[@]\";\n for pkg in ${!pkgsSlice+\"${!pkgsSlice}\"};\n do\n activatePackage \"$pkg\" \"$hostOffset\" \"$targetOffset\";\n done;\n done;\n done\n",
"_addRpathPrefix":" \n if [ \"${NIX_NO_SELF_RPATH:-0}\" != 1 ]; then\n export NIX_LDFLAGS=\"-rpath $1/lib ${NIX_LDFLAGS-}\";\n if [ -n \"${NIX_LIB64_IN_SELF_RPATH:-}\" ]; then\n export NIX_LDFLAGS=\"-rpath $1/lib64 ${NIX_LDFLAGS-}\";\n fi;\n if [ -n \"${NIX_LIB32_IN_SELF_RPATH:-}\" ]; then\n export NIX_LDFLAGS=\"-rpath $1/lib32 ${NIX_LDFLAGS-}\";\n fi;\n fi\n",
... dozens more bash functions ...
},
"variables": {
"AR": {"type": "exported", "value": "ar"},
"AS": {"type": "exported", "value": "as"},
"BASH": {"type": "var", "value": "/nix/store/3npg6a8nc5vpcyw98v085cmlz7f78kgs-bash-5.1-p12/bin/bash"},
"BASHOPTS": {"type": "unknown"},
... dozens more environment variables ...
}
}
I have no idea. I mean, it created a thing. And when I manually inspect my ~/scratch/test-profile
, I can see that it is also a symlink to a thing that is kind of like this. But… that’s not what a profile is…?
$ nix profile install 'nixpkgs#hello' --profile ~/scratch/test-profile
$ nix profile list --profile ~/scratch/test-profile
0 flake:nixpkgs#legacyPackages.x86_64-darwin.hello github:NixOS/nixpkgs/2beba9a23a8381eb95187f46b10c3677d8f63ca1#legacyPackages.x86_64-darwin.hello /nix/store/6sv1isax4axkxfnmg4gxg1pzr4417r6v-hello-2.10
Okay. So theoretically now this profile contains nixpkgs#hello
and my weird shell thing?
$ tree ~/scratch/test-profile
/Users/ian/scratch/test-profile
├── bin -> /nix/store/6sv1isax4axkxfnmg4gxg1pzr4417r6v-hello-2.10/bin
├── manifest.json
└── share -> /nix/store/6sv1isax4axkxfnmg4gxg1pzr4417r6v-hello-2.10/share
$ jq . /nix/store/s5ms489y3rsxbf8qijrqixc2qzyw8py2-profile/manifest.json
{
"elements": [
{
"active": true,
"attrPath": "legacyPackages.x86_64-darwin.hello",
"originalUri": "flake:nixpkgs",
"storePaths": [
"/nix/store/6sv1isax4axkxfnmg4gxg1pzr4417r6v-hello-2.10"
],
"uri": "github:NixOS/nixpkgs/2beba9a23a8381eb95187f46b10c3677d8f63ca1"
}
],
"version": 1
}
Nope! Running nix profile
blew away whatever nix develop --profile
was doing. I guess… those are like… supposed to be separate…? Or… what?
I don’t know.
Bizarre.
I had suspected that this “adding devShells
to profiles” was one of the reasons that nix profile list
output was so crazy. Because your profile doesn’t just consist of simple outputs-of-flakes anymore, instead they consist of these weird computed expressions.
But I guess… that was wrong.
So I suppose the intended usage here, to prevent shells from being garbage-collected, is to like…?
$ nix develop --profile ~/scratch/my-dev-profile
$ ln -s ~/scratch/my-dev-profile /nix/var/nix/gcroots/per-user/ian/my-dev-profile
Make a separate “profile” for each “devShell
” and manually add them as gcroots…?
This is, once again, not exactly the API I was hoping for. But perhaps I can wrap this into something friendly.
All of this is moot, of course, if I can’t get nix develop
to run zsh
. So let’s try that now…
There’s nothing in nix develop --help
about changing the shell.
nix --help
teaches me nix print-dev-env
. It says:
print shell code that can be sourced by
bash
to reproduce the build environment of a derivation
Which… yep.
$ nix print-dev-env
unset shellHook
nix_saved_PATH="$PATH"
BASH='/nix/store/lr6i6xpcmy46bd75gzziwbviy1pl4gq9-bash-5.1-p8/bin/bash'
CONFIG_SHELL='/nix/store/lr6i6xpcmy46bd75gzziwbviy1pl4gq9-bash-5.1-p8/bin/bash'
export CONFIG_SHELL
EPOCHREALTIME='1640635264.449310'
EPOCHSECONDS='1640635264'
HOSTTYPE='x86_64'
HOST_PATH='/nix/store/yf7fdgv8lad2xwxh579lk607sy09kzph-coreutils-8.32/bin:/nix/store/3z69mjjcq29jg8j64msxd16nw5pi8r1g-findutils-4.8.0/bin:/nix/store/l1gbwf4qcmiryiw7phjq9ida65k73akk-diffutils-3.8/bin:/nix/store/s86czlnc3dcfng4gzi1jvlg2zy92nih8-gnused-4.8/bin:/nix/store/356m58q4iqyd33px2k10rn0x4c85dszj-gnugrep-3.6/bin:/nix/store/gvvl9z2aq6wc0x8jcxpva1x3m3fy095d-gawk-5.1.0/bin:/nix/store/5qxxdkq73kg2i3vi8fxb09ifz3g1ardp-gnutar-1.34/bin:/nix/store/w1hhgcgjrnaq2wnm6nx8s2h4ddqzaa1s-gzip-1.10/bin:/nix/store/lvn1gbp8v47vp78splg7v99zyjvp249q-bzip2-1.0.6.0.2-bin/bin:/nix/store/2jfpbzvma5j6pkjk6g0lv8dk38cpdws5-gnumake-4.3/bin:/nix/store/lr6i6xpcmy46bd75gzziwbviy1pl4gq9-bash-5.1-p8/bin:/nix/store/v9ihxmjwilqmgnqwndz60zq1zlwnjvg6-patch-2.7.6/bin:/nix/store/m0jph60y81z6rp53xg5lvsvsqxy797fx-xz-5.2.5-bin/bin'
export HOST_PATH
# ...dozens of lines of environment variables...
_activatePkgs ()
{
local hostOffset targetOffset;
local pkg;
for hostOffset in "${allPlatOffsets[@]}";
do
local pkgsVar="${pkgAccumVarVars[hostOffset + 1]}";
for targetOffset in "${allPlatOffsets[@]}";
do
(( hostOffset <= targetOffset )) || continue;
local pkgsRef="${pkgsVar}[$targetOffset - $hostOffset]";
local pkgsSlice="${!pkgsRef}[@]";
for pkg in ${!pkgsSlice+"${!pkgsSlice}"};
do
activatePackage "$pkg" "$hostOffset" "$targetOffset";
done;
done;
done
}
# ... hundreds of lines of shell functions...
PATH="$PATH:$nix_saved_PATH"
export NIX_BUILD_TOP="$(mktemp -d -t nix-shell.XXXXXX)"
export TMP="$NIX_BUILD_TOP"
export TMPDIR="$NIX_BUILD_TOP"
export TEMP="$NIX_BUILD_TOP"
export TEMPDIR="$NIX_BUILD_TOP"
eval "$shellHook"
Okay. Not exactly useful.
All I really care about are the environment variables, in my typical usage. I don’t care about the ability to run buildPhase
interactively. I have never actually written something that uses Nix’s build infrastructure to build itself. I write shell.nix
files as a way to document my dependencies, and I invoke my normal interactive build tools from within the shell.
So nix develop
does not seem like it’s useful to me.
Perhaps I can get nix shell
to do what I want?
Returning to my original shell.nix
:
with import <nixpkgs> {}; mkShellNoCC {
nativeBuildInputs = [
fswatch
hugo
nodePackages.autoprefixer
nodePackages.postcss-cli
];
}
I can run nix shell
with all of these at the command line and, you know, it works:
nix shell 'nixpkgs#fswatch' 'nixpkgs#hugo' 'nixpkgs#nodePackages.autoprefixer' 'nixpkgs#nodePackages.postcss-cli'
Ians-MBP:ianthehenry.com ian$
But it’s still bash. I can manually invoke zsh
, though:
$ nix shell 'nixpkgs#fswatch' 'nixpkgs#hugo' 'nixpkgs#nodePackages.autoprefixer' 'nixpkgs#nodePackages.postcss-cli' 'nixpkgs#zsh' -c zsh
nix-shell:shell ~/src/ianthehenry.com ➜ hugo version
hugo v0.90.0+extended darwin/amd64 BuildDate=unknown
Ah, a rare glimpse at my actual prompt. Except… huh, it sets the name
environment variable to shell
instead of nix-shell
, so it’s showing up in the long form nix-shell:shell
. Although nix-shell -p
does the same thing, apparently. I should maybe special-case that in my prompt.
Can I do this same thing with nix develop
?
$ nix develop -c zsh
nix-shell ~/src/ianthehenry.com ➜ lsof -p $$ | grep /bin/zsh
zsh 45836 ian txt REG 1,4 1348368 1152921500312807015 /bin/zsh
Yeah that’s sort of convoluted but macOS doesn’t have /proc
so this is the best I can do here.
Note that $name
is nix-shell
again, which renders as just nix-shell
instead of nix-shell:nix-shell
. This is a property of my own prompt and not really interesting to anyone else.
Hmmmm. So this is starting the zsh
on my PATH
which is, for some reason, /bin/zsh
. That’s not really what I want, though. I want to start nixpkgs#zsh
.
The obvious thing doesn’t work…
$ nix develop -c 'nixpkgs#zsh'
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
/tmp/nix-shell.G4K12z/nix-shell.fozDix: line 1452: exec: nixpkgs#zsh: not found
Which, whatever. But maybe I can do something weird…
$ nix develop -c 'nix run nixpkgs#zsh'
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
/tmp/nix-shell.pnLUvj: line 1452: exec: nix run nixpkgs#zsh: not found
Okay fair enough. But apparently…
$ nix develop -c nix run 'nixpkgs#zsh'
warning: Git tree '/Users/ian/src/ianthehenry.com' is dirty
nix-shell ~/src/ianthehenry.com ➜ lsof -p $$ | grep bin/zsh
zsh 46402 ian txt REG 1,6 770048 6523002 /nix/store/90f8r5pc7w5bbdslxcq18hyn6rdx5vb5-zsh-5.8/bin/zsh
Okay. That’s… something, I guess. This is a usable nix develop
setup. There’s no way to make this the default, as far as I can tell, but I could at least make an alias to invoke it with zsh
.
In fact it’s almost as usable as nix-shell
. The disadvantage is the annoying flake.nix
boilerplate, and adding GC roots is… a weird new puzzle that I don’t want to solve right now. So… I dunno. It doesn’t seem like flake.lock
is sufficiently more useful than my hand-rolled pinning scheme – to me – to justify the boilerplate. And I’m sure third-party tools like niv
work even better.
Which means that, once again, the only reason to use flakes is because nix search
forces me to.
Perhaps the correct next move is to fork Nix 2.4 and add a nix-search
binary that searches through my channel again, and pretend like this whole flakes thing was just a bad dream.
- How can I suppress all the “
warning: Git tree '...' is dirty
” messages? - How am I supposed to use
nix develop --profile
? - What’s up with that
nix develop --redirect
thing?