tazjin/nix-1p

overrideAttrs only works if the attribute is already populated

nixinator opened this issue · 2 comments

if you try

someProgram.overrideAttrs(old: {
    configureFlags = old.configureFlags ++ ["--mimic-threaten-tag"];
})

configureFlags has to be populated, if it's empty overriderAttrs can't append to an empty list

nix repl
:l <nixpkgs>

nix-repl> cowsay.configureFlags
[ ]

cowsay.overrideAttrs(old: { configureFlags = old.configureFlags ++  ["--dummy"]; })


error: attribute 'configureFlags' missing

       at «string»:1:45:

            1| cow.overrideAttrs(old: { configureFlags = old.configureFlags ++  ["--dummy"]; })
             |                                             ^
            2|

however

nix-repl> cowsay.outputs                                                           
[ "out" "man" ]

cowsay.overrideAttrs(old: { outputs = old.outputs ++  ["--dummy"]; })
«derivation /nix/store/0fva8szi6s2cz838l9ag9xayd583mxay-cowsay-3.04.drv»

so i think this is a quirk with overrideAttrs

however is easily fixed with

:b  hello.overrideAttrs(old: { configureFlags = ["--dummy"]; }) 

error: builder for '/nix/store/k5y89y29rgkrwapvak19giwbhkpncabv-hello-2.10.drv' failed with exit code 1;
       last 9 log lines:
       > unpacking sources
       > unpacking source archive /nix/store/3x7dwzq014bblazs7kq20p9hyzz0qh8g-hello-2.10.tar.gz
       > source root is hello-2.10
       > setting SOURCE_DATE_EPOCH to timestamp 1416139241 of file hello-2.10/ChangeLog
       > patching sources
       > configuring
       > configure flags: --disable-dependency-tracking --prefix=/nix/store/133si7nj0lpg8bf0hwgpi7wbq8nmzbla-hello-2.10 --dummyaaa
       > configure: error: unrecognized option: `--dummyaaa'
       > Try `./configure --help' for more information
       For full logs, run 'nix log /nix/store/k5y89y29rgkrwapvak19giwbhkpncabv-hello-2.10.drv'.

bizzare huh! i presume the there is no 'old.configureFlags', because it's empty :-) .... quirky?

I think what's going on is that the attributes passed at the point where overrides are enabled do not contain configureFlags (hence the error), but some function call further down defaults it to [ ] (haven't taken a look at what that is).

You can guard against this using the or statement:

nix-repl> cowsay.overrideAttrs(old: { configureFlags = old.configureFlags ++ [ "--new-flag" ]; })
error: attribute 'configureFlags' missing, at (string):1:46
«derivation 

nix-repl> cowsay.overrideAttrs(old: { configureFlags = old.configureFlags or [] ++ [ "--new-flag" ]; })
«derivation /nix/store/znjs9q7k6rhdi131wspqz4xks3wshdxw-cowsay-3.04.drv»

I'll update the override docs to add a note about this, since it's often difficult to predict this situation when writing override code :)

Actually I was slightly incorrect about the cause here, what's going on is this:

nix-repl> ({ a ? 1 }@args: args) {}
{ }

What this means is that captures of attribute set parameters (using @) do not capture defaulted variables. This is actually surprising to me, so thanks for pointing out something new about the language! I'll update the docs accordingly.