Are spaces and dots supposed to be allowed in pname values?

I’m considering creating a pull request that adds Media Preservation Frontend Checker to Nixpkgs. In order to do that, I need to choose a pname value for the package. Here’s what the package naming guidelines say at the moment:

  • For the pname attribute:

    • It should be identical to the upstream package name.

    • It must not contain uppercase letters.

      Example: Use "mplayer" instead of "MPlayer"

Media Preservation Frontend Checker has two upstream package names:

  • Its long name is “Media Preservation Frontend Checker”. According to the above rules, I should change that name to "media preservation frontend checker" if I’m going to use it as a pname value.

  • Its short name is “MPF.Check”. According to the above rules, I should change that name to "mpf.check" if I’m going to use it as a pname value.

Both of those potential pname values look wrong to me. The first one contains spaces, and the second one contains a dot. The rules for pname attributes don’t disallow spaces or dots, but I feel like that might have been an accidental omission.

Are spaces and dots supposed to be allowed in pname values?

1 Like

The implicit rules, inherited from builtins.derivation disallow the usage of spaces.

Personally I’d go with the short name in lowercase, just removing the dot.

Dots even though they are allowed in a drv name might be confused with a nested set notation.

2 Likes

Could you elaborate? What do you mean by “the implicit rules”?

I agree, it would be easy to confuse them with nested set notation. That’s why I was surprised when I didn’t see any rules that prohibited the inclusion of dots in the pnames and attribute names of packages in Nixpkgs. Perhaps a rule that prohibits dots should be added.

Any builder uses builtins.derivation under the hood eventually. It is impossible to create a derivation without it, so we inherit all rules its usage implies. One of the rules is, that a derivation name must not contain spaces.

1 Like

The pname is used as part of the nix store path, so only strings that are valid in store path names can be used in practice.

This isn’t explicitly stated in those guidelines, so the rule is implicit.

Incidentally, I can’t find docs for this in the nix documentation either.

Probably, but note those are guidelines not rules. Many files written with writeTextFile use dots for extensions.

2 Likes

I agree that all all builders must use builtins.derivation (or builtins.derivationStrict, I guess) under the hood because that’s the only way to create a derivation, and I also agree that the value of the name attribute that gets passed to builtins.derivation must not contain spaces. I can verify that that’s the case by trying to build this Nix expression:

# This file is dedicated to the public domain using 🅭🄍1.0:
# <https://creativecommons.org/publicdomain/zero/1.0>.
let
  # At the moment, this commit is the tip of the nixos-unstable branch.
  nixpkgsCommit = "8110df5ad7abf5d4c0f6fb0f8f978390e77f9685";
  nixpkgsDirectory = builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/${nixpkgsCommit}.tar.gz";
    sha256 = "0y28hhfxx1w06qrvwdxiwpm7rzplmsm255y49nkn40y82vn38x0g";
  };
  pkgs = import nixpkgsDirectory { };
  inherit (pkgs.lib.strings) escapeShellArg escapeNixString;
  nameWithSpaces = builtins.derivation {
    name = "name with spaces";
    system = pkgs.stdenv.buildPlatform.system;
    builder = pkgs.lib.meta.getExe pkgs.bash;
    args = [
      "-c"
      "printf 'The value of name is %s.\\n' ${escapeShellArg (escapeNixString nameWithSpaces.name)} > \"$out\""
    ];
  };
in
nameWithSpaces

When I try to build that Nix expression, I get an error that clearly indicates that spaces are not allowed in name values:

$ nix-build 'name with spaces.nix'
error:
       … while calling the 'derivationStrict' builtin
         at <nix/derivation-internal.nix>:37:12:
           36|
           37|   strict = derivationStrict drvAttrs;
             |            ^
           38|

       … while evaluating derivation 'name with spaces'
         whose name attribute is located at /home/jayman/Documents/Home/local/tmp/name with spaces.nix:13:5

       error: invalid derivation name: name 'name with spaces' contains illegal character ' '. Please pass a different 'name'.
$ 

That being said, I don’t think that the rules for pname values inherit all of the rules for name values. I was able to verify that pname values can contain spaces by building this Nix expression:

# This file is dedicated to the public domain using 🅭🄍1.0:
# <https://creativecommons.org/publicdomain/zero/1.0>.
let
  # At the moment, this commit is the tip of the nixos-unstable branch.
  nixpkgsCommit = "8110df5ad7abf5d4c0f6fb0f8f978390e77f9685";
  nixpkgsDirectory = builtins.fetchTarball {
    url = "https://github.com/NixOS/nixpkgs/archive/${nixpkgsCommit}.tar.gz";
    sha256 = "0y28hhfxx1w06qrvwdxiwpm7rzplmsm255y49nkn40y82vn38x0g";
  };
  pkgs = import nixpkgsDirectory { };
  inherit (pkgs.lib.strings) escapeShellArg escapeNixString;
in
pkgs.stdenv.mkDerivation (finalAttrs: {
  pname = "pname with spaces";
  version = "0-unstable-2026-03-30";
  dontUnpack = true;
  buildPhase = ''
    printf 'The value of pname is %s.\n' ${escapeShellArg (escapeNixString finalAttrs.pname)} > "$out"
  '';
})

When I build that Nix expression, here’s what happens:

$ nix-build 'pname with spaces.nix'
/nix/store/y4s06kaipza4mny8jwl9nvv7m2g5ki4c-pname-with-spaces-0-unstable-2026-03-30
$ cat result 
The value of pname is "pname with spaces".
$ 

From you perspective, what is the difference between guidelines and rules?

Yeah, there are probably a bunch of different corner cases where it does make sense to include dots in pname values. If a guideline about dots gets added, it should probably use an RFC 2119 should instead of an RFC 2119 must.

Interesting, this normalisation/slugification must be new… I was not aware that this happens, last time I tried this (mostly by accident) is years ago…

1 Like

Guidelines do not have to be observed if there is sufficient reasoning to do so. It’s supposed to “guide” you, not “rule” you, like a rule.

That’s the dictionary definition, also.

That is a less ambiguous way to define “guideline”, yes.

Personally, I find the term “guideline” pretty unambiguous, it’s quite self-explanatory, but well, you finding it ambiguous proves your point.

From the same guidelines you linked:

  • For the package attribute name:

    • It must be a valid identifier in Nix.

    • If the pname starts with a digit, the attribute name should be prefixed with an underscore. Otherwise the attribute name should not be prefixed with an underscore.

      Example: The corresponding attribute name for 0ad should be _0ad.

    • New attribute names should be the same as the value in pname.

      Hyphenated names should not be converted to snake case or camel case. This was done historically, but is not necessary any more. The Nix language allows dashes in identifiers since 2012.

    • If there are multiple versions of a package, this should be reflected in the attribute names in all-packages.nix.

      Example: json-c_0_9 and json-c_0_11

      If there is an obvious “default” version, make an extra attribute.

      Example: json-c = json-c_0_9;

This answers your questions: since new packages should have pname equal to their attribute name modulo starting with a digit or not, and attribute names must be valid identifiers, pname should match [A-Za-z0-9_][A-Za-z0-9_'-]*. A preference for hyphenation over camel case is stated explicitly, and a preference for hyphenation over underscores is implied by the versioned example and common practice. (Single quotes aren’t explicitly addressed anywhere, but would be pretty awful for CLI UX and pkgs/by-name directory names, so presumably nobody has ever thought about wanting to try using them in the first place.)

Therefore the characters you are unsure about are explicitly advised against for new packages and your options look like mpf-check, mpfcheck, media-preservation-frontend-checker. I’d prefer the first one.

1 Like

I prefer your interpretation, but attribute names have to be valid names, not valid identifiers (according to the page you link), which does include arbitrary string literals.

1 Like

“It must be a valid identifier in Nix.” seems pretty unambiguous to me?

1 Like

I agree that in general attribute names can be arbitrary string literals. I can verify that that is the case by evaluating this Nix expression:

{
  "attribute name that contains spaces" = null;
}

That Nix expression validates successfully on my system which indicates that you are indeed right that attribute names can be arbitrary string literals. That being said, I think that there are extra guidelines that apply to the attribute names of packages in Nixpkgs that don’t necessarily apply to other attribute names. The part of the guidelines that emily quoted says:

What makes you say that it must be a valid name instead of a valid identifier?

1 Like

I created a Nixpkgs pull request that was inspired by the discussions in this thread. The goal of the pull request is to make Nixpkgs’s package naming guidelines simpler and easier to follow so that questions like this one don’t crop up in the future.

1 Like