lol

lib: `modules.sh` should check JSON output for predictability

Currently, the `lib/tests/modules.sh` test checks the output of
`nix-instantiate --eval` without `--json`, which outputs an unspecified
human-readable format.

This patch modifies `modules.sh` to use the `--json` output instead, to
be robust against future changes to `nix-instantiate` output.

+24 -17
+14 -14
lib/tests/modules.sh
··· 24 24 local attr=$1 25 25 shift 26 26 local script="import ./default.nix { modules = [ $* ];}" 27 - nix-instantiate --timeout 1 -E "$script" -A "$attr" --eval-only --show-trace --read-write-mode 27 + nix-instantiate --timeout 1 -E "$script" -A "$attr" --eval-only --show-trace --read-write-mode --json 28 28 } 29 29 30 30 reportFailure() { 31 31 local attr=$1 32 32 shift 33 33 local script="import ./default.nix { modules = [ $* ];}" 34 - echo 2>&1 "$ nix-instantiate -E '$script' -A '$attr' --eval-only" 34 + echo 2>&1 "$ nix-instantiate -E '$script' -A '$attr' --eval-only --json" 35 35 evalConfig "$attr" "$@" || true 36 36 ((++fail)) 37 37 } ··· 148 148 checkConfigOutput '^"24"$' config.value ./declare-either.nix ./define-value-string.nix 149 149 # types.oneOf 150 150 checkConfigOutput '^42$' config.value ./declare-oneOf.nix ./define-value-int-positive.nix 151 - checkConfigOutput '^\[ \]$' config.value ./declare-oneOf.nix ./define-value-list.nix 151 + checkConfigOutput '^\[\]$' config.value ./declare-oneOf.nix ./define-value-list.nix 152 152 checkConfigOutput '^"24"$' config.value ./declare-oneOf.nix ./define-value-string.nix 153 153 154 154 # Check mkForce without submodules. ··· 328 328 # Shorthand modules interpret `meta` and `class` as config items 329 329 checkConfigOutput '^true$' options._module.args.value.result ./freeform-attrsOf.nix ./define-freeform-keywords-shorthand.nix 330 330 # No freeform assignments shouldn't make it error 331 - checkConfigOutput '^{ }$' config ./freeform-attrsOf.nix 331 + checkConfigOutput '^{}$' config ./freeform-attrsOf.nix 332 332 # but only if the type matches 333 333 checkConfigError 'A definition for option .* is not of type .*' config.value ./freeform-attrsOf.nix ./define-value-list.nix 334 334 # and properties should be applied ··· 366 366 checkConfigOutput '^0$' config.value.int ./types-anything/equal-atoms.nix 367 367 checkConfigOutput '^false$' config.value.bool ./types-anything/equal-atoms.nix 368 368 checkConfigOutput '^""$' config.value.string ./types-anything/equal-atoms.nix 369 - checkConfigOutput '^/$' config.value.path ./types-anything/equal-atoms.nix 369 + checkConfigOutput '^"/[^"]+"$' config.value.path ./types-anything/equal-atoms.nix 370 370 checkConfigOutput '^null$' config.value.null ./types-anything/equal-atoms.nix 371 371 checkConfigOutput '^0.1$' config.value.float ./types-anything/equal-atoms.nix 372 372 # Functions can't be merged together 373 373 checkConfigError "The option .value.multiple-lambdas.<function body>. has conflicting option types" config.applied.multiple-lambdas ./types-anything/functions.nix 374 - checkConfigOutput '^<LAMBDA>$' config.value.single-lambda ./types-anything/functions.nix 374 + checkConfigOutput '^true$' config.valueIsFunction.single-lambda ./types-anything/functions.nix 375 375 checkConfigOutput '^null$' config.applied.merging-lambdas.x ./types-anything/functions.nix 376 376 checkConfigOutput '^null$' config.applied.merging-lambdas.y ./types-anything/functions.nix 377 377 # Check that all mk* modifiers are applied 378 378 checkConfigError 'attribute .* not found' config.value.mkiffalse ./types-anything/mk-mods.nix 379 - checkConfigOutput '^{ }$' config.value.mkiftrue ./types-anything/mk-mods.nix 379 + checkConfigOutput '^{}$' config.value.mkiftrue ./types-anything/mk-mods.nix 380 380 checkConfigOutput '^1$' config.value.mkdefault ./types-anything/mk-mods.nix 381 - checkConfigOutput '^{ }$' config.value.mkmerge ./types-anything/mk-mods.nix 381 + checkConfigOutput '^{}$' config.value.mkmerge ./types-anything/mk-mods.nix 382 382 checkConfigOutput '^true$' config.value.mkbefore ./types-anything/mk-mods.nix 383 383 checkConfigOutput '^1$' config.value.nested.foo ./types-anything/mk-mods.nix 384 384 checkConfigOutput '^"baz"$' config.value.nested.bar.baz ./types-anything/mk-mods.nix ··· 398 398 checkConfigOutput '^"a b c"$' config.resultFooFoo ./declare-variants.nix ./define-variant.nix 399 399 400 400 ## emptyValue's 401 - checkConfigOutput "[ ]" config.list.a ./emptyValues.nix 402 - checkConfigOutput "{ }" config.attrs.a ./emptyValues.nix 401 + checkConfigOutput "\[\]" config.list.a ./emptyValues.nix 402 + checkConfigOutput "{}" config.attrs.a ./emptyValues.nix 403 403 checkConfigOutput "null" config.null.a ./emptyValues.nix 404 - checkConfigOutput "{ }" config.submodule.a ./emptyValues.nix 404 + checkConfigOutput "{}" config.submodule.a ./emptyValues.nix 405 405 # These types don't have empty values 406 406 checkConfigError 'The option .int.a. is used but not defined' config.int.a ./emptyValues.nix 407 407 checkConfigError 'The option .nonEmptyList.a. is used but not defined' config.nonEmptyList.a ./emptyValues.nix 408 408 409 409 ## types.raw 410 - checkConfigOutput "{ foo = <CODE>; }" config.unprocessedNesting ./raw.nix 410 + checkConfigOutput '^true$' config.unprocessedNestingEvaluates.success ./raw.nix 411 411 checkConfigOutput "10" config.processedToplevel ./raw.nix 412 412 checkConfigError "The option .multiple. is defined multiple times" config.multiple ./raw.nix 413 413 checkConfigOutput "bar" config.priorities ./raw.nix ··· 441 441 checkConfigOutput '^1$' config.sub.specialisation.value ./extendModules-168767-imports.nix 442 442 443 443 # Class checks, evalModules 444 - checkConfigOutput '^{ }$' config.ok.config ./class-check.nix 444 + checkConfigOutput '^{}$' config.ok.config ./class-check.nix 445 445 checkConfigOutput '"nixos"' config.ok.class ./class-check.nix 446 446 checkConfigError 'The module .*/module-class-is-darwin.nix was imported into nixos instead of darwin.' config.fail.config ./class-check.nix 447 447 checkConfigError 'The module foo.nix#darwinModules.default was imported into nixos instead of darwin.' config.fail-anon.config ./class-check.nix 448 448 449 449 # Class checks, submoduleWith 450 - checkConfigOutput '^{ }$' config.sub.nixosOk ./class-check.nix 450 + checkConfigOutput '^{}$' config.sub.nixosOk ./class-check.nix 451 451 checkConfigError 'The module .*/module-class-is-darwin.nix was imported into nixos instead of darwin.' config.sub.nixosFail.config ./class-check.nix 452 452 453 453 # submoduleWith type merge with different class
+4 -1
lib/tests/modules/raw.nix
··· 1 - { lib, ... }: { 1 + { lib, config, ... }: { 2 2 3 3 options = { 4 4 processedToplevel = lib.mkOption { ··· 12 12 }; 13 13 priorities = lib.mkOption { 14 14 type = lib.types.raw; 15 + }; 16 + unprocessedNestingEvaluates = lib.mkOption { 17 + default = builtins.tryEval config.unprocessedNesting; 15 18 }; 16 19 }; 17 20
+2 -2
lib/tests/modules/types-anything/equal-atoms.nix
··· 9 9 value.int = 0; 10 10 value.bool = false; 11 11 value.string = ""; 12 - value.path = /.; 12 + value.path = ./.; 13 13 value.null = null; 14 14 value.float = 0.1; 15 15 } ··· 17 17 value.int = 0; 18 18 value.bool = false; 19 19 value.string = ""; 20 - value.path = /.; 20 + value.path = ./.; 21 21 value.null = null; 22 22 value.float = 0.1; 23 23 }
+4
lib/tests/modules/types-anything/functions.nix
··· 1 1 { lib, config, ... }: { 2 2 3 + options.valueIsFunction = lib.mkOption { 4 + default = lib.mapAttrs (name: lib.isFunction) config.value; 5 + }; 6 + 3 7 options.value = lib.mkOption { 4 8 type = lib.types.anything; 5 9 };