The papercut thread - post your small annoyances/confusions here

A similar relatively common situation may happen when setting nix.nixPath (such as when you are setting up building from a local checkout of nixpkgs). You actually have to rebuild twice - the first time will update the environment variables, the second time will actually build from the new location.

(I hope I got this right.)

I think all of those options can be set using the --option flag… but they’re not documented in nixos-rebuild and some have no example of useful values…

2 Likes

I’m late to the party, but haven’t seen this one mentioned yet:

  • Deprecate ‘let/in’, since ‘with’ is objectively superior

From reading others, it seems like this is controversial; hence why I’ve
never opened a GitHub issue (although I did mention the reasoning at
Language feature proposal: exclusive 'with' · Issue #1361 · NixOS/nix · GitHub )

Just an observation: I think recursive lets are redundant with recursive attrsets?
I’m mildly annoyed by the lack of nonrecursive let.
Also, that’s a strange atypical opinion, thanks for posting it and providing some interesting points!

It was mentioned by me at the beginning of this thread :slight_smile: But I argue the exact opposite. Deprecate the with syntax for let inherit as it’s obviously superior :slight_smile:

5 Likes

(Several posts talk about deprecating with in favor of let, but the point was that warbo has precisely the antipodal argument?)

  • Getting PHP-FPM to work with nginx - a pretty common setup - involves unnecessarily much work. Much of this could be abstracted away by a module configuration option.
  • Copy-pastability of configuration examples is low, which can make it challenging to understand how to configure something correctly without making a mess of your existing configuration - because the same configuration can be represented in many ways and often examples are dependent on context and abstractions that live in other people’s repositories. Nix flakes would probably alleviate this a lot, by reducing the need to copy-paste examples, instead lowering the bar for publishing and consuming third-party abstractions/presets.

When you do this:

pkgs.stdenv.mkDerivation {
	name = "foo";
	src = ./some/folder;

	installPhase = ''
		cp -r $src/ $out/
		cp ${../elsewhere/extra-file.txt} $out/extra-file.txt
	'';
}

… the copying of extra-file.txt will fail with a cryptic permission error. This occurs because the permissions from the source directory (which is read-only, being in the Nix store) are copied over to the new $out directory that is implicitly being created, which prevents any later copying of files into it.

You need to explicitly mkdir -p $out first, instead, to create the folder with the default permissions, so that the cp after it merely copies over the contents:

pkgs.stdenv.mkDerivation {
	name = "foo";
	src = ./some/folder;

	installPhase = ''
		mkdir -p $out/
		cp -r $src/ $out/
		cp ${../elsewhere/extra-file.txt} $out/extra-file.txt
	'';
}

No idea how this could be made more usable (on an implementation level), but I’d imagine that it might be a pretty common thing to forget a mkdir. There should probably be at least a warning of some sort.

2 Likes

When package sets are written like gitAndTools:

/* All git-relates tools live here, in a separate attribute set so that users
 * can get a fast overview over what's available.
 */
args @ {config, lib, pkgs}: with args; with pkgs;
let
  gitBase = callPackage ./git { ... };

  self = rec {
    git = appendToName "minimal" gitBase;
    gitFull = gitBase.override { ... };
  };
in
  self

…it becomes really annoying to try and override the definition of gitBase or whatever local bindings are defined, because you have to do so for every attribute in the set that uses the binding; and there’s really no reason not to expose the binding so it can be overridden. It doesn’t reduce closure sizes, and we’re already in a scope so it’s not polluting the top level.

In general, I wish for a convention that any binding made with callPackage should be exposed to the top level of the scope in which it’s used. emacs-packages.nix is an egregious offender.

5 Likes

I’m not sure if I’m your reading your point correctly, but fundamentally I agree and I’m massively annoyed by these kinds of problems.
(WIP)(RFC) A new nixpkgs frontend for language infrastructures - #2 by deliciouslytyped is intended to address this kind of structure.

However, a much simpler thing to do at least in this case - if a simple rec set is acceptable - is to make the self attr take an argument and pass gitBase as a parameter - if I’m following correctly.

I see two issues here; one is that let expressions are horrible for overridability, the other is whether what is consuming your inputs is parametrized over it’s scope (bad for overriding), or over explicit arguments (good for overriding). I use “horrible” to emphasize my strong feelings towards this, but I’m always open to being convinced otherwise.

Hey, I have a paper cut.

nix-env without absolute paths is unbearably slow.

In my experience, nix-env -i foo is much slower than even nix search foo && nix-env -iA nixos.foo

In my experience, nix-env -i foo is much slower than even nix search foo && nix-env -iA nixos.foo

Doesn’t nix search cache something? I guess nix-env -i is unlikely to ever become fast enough again…

Doesn’t nix search cache something? I guess nix-env -i is unlikely to ever become fast enough again…

If that’s the case (i.e. nix-env not caching), then why are absolute paths (e.g. nixos.git) so fast?

Either way, could nix-env not try the prefix nixos etc first before doing an uncached search for possible absolute paths?

I’m sure there’s a reason. I’m just not seeing it :-/

If that’s the case (i.e. nix-env not caching), then why are absolute paths (e.g. nixos.git) so fast?

Either way, could nix-env not try the prefix nixos etc first before doing an uncached search for possible absolute paths?

nix-env -i evaluates all packages to find all packages with the specified name and then choose by priority and version. Heuristics allowing to find some of the packages with the chosen name quickly are not enough there.

nix-env -iA uses lazy evaluation etc. to evaluate only the part of Nixpkgs that is necessary for the single package specified via attribute path. It doesn’t have any reason to check if, say, tig has name “git” and higher version than git (the definition of nix-env -i implies doing this check and many many similar ones).

1 Like

What we really should do is ship a database of package names with each channel to speed up nix-env -i. If you stick a nixpkgs checkout in your NIX_PATH that wouldn’t help, but as long as you’re using channels, there’s no reason nix-env really should be evaluating the entire package set each time.

Of course, it would still need to evaluate overlays, but I’m sure we can do some magic where we intercept overlays, evaluate just those, and ignore the overridden paths from the database.

1 Like

The idea was to stop using nix-env -i altogether. Except we don’t have a replacement yet. Right now the best option is to find the attribute with nix search and then use nix-env -iA.

Related to that there is also the programs.sqlite DB that is generated for the nixos channels. This DB is currently only used by the command-not-found program. The schema looks like this:

It would be nice to also generate that DB for the other channels so command-not-found and other tools can be built on top.

5 Likes

The confusion around overlapping phase variable/functions in nix-shell.
The explanation was quite hard to find:
https://github.com/NixOS/nix/issues/456
Only reason I bothered fighting through finding this is because a newbie asked the very sane question “but then how do I test my phases…”
I’m not proud of the fact that I’ve been copy-pasting phases out of nix show-derivation.

I sometimes get annoyed by the way derivations are named. Right now I’m looking for programs to manage my photo collection and I’ve found a list online that I’m trying. Of course I use nix-shell, so I enter…

$ nix-shell -p digik<tabtab>
digikam   digikam5

meh… are these the same? is “digikam” version 4 or version 6? I don’t want to dig into nixpkgs to figure that out, I just want the most recent packaged version.

Use nix search digikam to find the attribute name. Then, use the attribute name with nix run, e.g. nix run nixpkgs.digikam. Don’t use nix-shell -p, it’s not meant for what you’re doing.

nix run has the same problem, when I don’t want to run a search:

$ nix run nixpkgs.digikam<tabtab>
nixpkgs.digikam   nixpkgs.digikam5

Having to run a search just because the attribute names are unclear is what I consider to be the papercut here.

1 Like