mirror of
https://github.com/NixOS/nix
synced 2025-06-24 22:11:15 +02:00
WIP: Allow for null packages and formatters
This is useful for frameworks (such as flake-parts) to avoid unnecessary evaluation. See discussion here: https://github.com/hercules-ci/flake-parts/issues/288#issuecomment-2912459614 While digging into this, I discovered that `nix fmt` already handles `null` formatters identically to undefined formatters. I added a couple of tests to demonstrate this behavior. `nix flake show` needs some reworking to avoid crashing with a "error: expected a derivation" when it encounters a `null` formatter or package. My changes here avoid the crash, but has some cosmetic issues, which is why I've labeled this PR as a draft. Cosmetic issues =============== With the following `flake.nix`: ```nix { outputs = _: { packages.x86_64-linux.default = null; }; } ``` `nix flake show` shows a weird empty system: ``` $ nix flake show path:/tmp/tmp.uL0iGuNwXB?lastModified=1748472558&narHash=sha256-tC%2BhdXAyoeFvWHNllJbois8X%2B7wpZ6CJzEzbcaGQxtM%3D └───packages └───x86_64-linux ``` Similarly, `nix flake show --json` includes an empty object: ``` $ nix flake show --json { "packages": { "x86_64-linux": { "default": null } } } ``` `nix build` crashes: ``` $ nix build .#default error: expected flake output attribute 'packages.x86_64-linux.default' to be a derivation or path but found null: null ```
This commit is contained in:
parent
ba96067535
commit
929423476e
6 changed files with 59 additions and 6 deletions
|
@ -1,3 +1,4 @@
|
||||||
|
#include "nix/expr/value.hh"
|
||||||
#include "nix/util/users.hh"
|
#include "nix/util/users.hh"
|
||||||
#include "nix/expr/eval-cache.hh"
|
#include "nix/expr/eval-cache.hh"
|
||||||
#include "nix/store/sqlite.hh"
|
#include "nix/store/sqlite.hh"
|
||||||
|
@ -762,6 +763,14 @@ std::vector<Symbol> AttrCursor::getAttrs()
|
||||||
return attrs;
|
return attrs;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool AttrCursor::isNull()
|
||||||
|
{
|
||||||
|
// <<< TODO: caching? >>>
|
||||||
|
auto & v = forceValue();
|
||||||
|
|
||||||
|
return v.type() == nNull;
|
||||||
|
}
|
||||||
|
|
||||||
bool AttrCursor::isDerivation()
|
bool AttrCursor::isDerivation()
|
||||||
{
|
{
|
||||||
auto aType = maybeGetAttr("type");
|
auto aType = maybeGetAttr("type");
|
||||||
|
|
|
@ -153,6 +153,8 @@ public:
|
||||||
|
|
||||||
bool isDerivation();
|
bool isDerivation();
|
||||||
|
|
||||||
|
bool isNull();
|
||||||
|
|
||||||
Value & forceValue();
|
Value & forceValue();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1340,10 +1340,14 @@ struct CmdFlakeShow : FlakeCommand, MixJSON
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
if (visitor.isDerivation())
|
if (visitor.isNull()) {
|
||||||
showDerivation();
|
j = nullptr;
|
||||||
else
|
} else{
|
||||||
throw Error("expected a derivation");
|
if (visitor.isDerivation())
|
||||||
|
showDerivation();
|
||||||
|
else
|
||||||
|
throw Error("expected a derivation");
|
||||||
|
}
|
||||||
} catch (IFDError & e) {
|
} catch (IFDError & e) {
|
||||||
if (!json) {
|
if (!json) {
|
||||||
logger->cout(fmt("%s " ANSI_WARNING "omitted due to use of import from derivation" ANSI_NORMAL, headerPrefix));
|
logger->cout(fmt("%s " ANSI_WARNING "omitted due to use of import from derivation" ANSI_NORMAL, headerPrefix));
|
||||||
|
|
|
@ -16,6 +16,7 @@ writeSimpleFlake() {
|
||||||
foo = import ./simple.nix;
|
foo = import ./simple.nix;
|
||||||
fooScript = (import ./shell.nix {}).foo;
|
fooScript = (import ./shell.nix {}).foo;
|
||||||
default = foo;
|
default = foo;
|
||||||
|
noPackage = null;
|
||||||
};
|
};
|
||||||
packages.someOtherSystem = rec {
|
packages.someOtherSystem = rec {
|
||||||
foo = import ./simple.nix;
|
foo = import ./simple.nix;
|
||||||
|
|
|
@ -53,7 +53,7 @@ cat >flake.nix <<EOF
|
||||||
packages.$system = { };
|
packages.$system = { };
|
||||||
packages.someOtherSystem = { };
|
packages.someOtherSystem = { };
|
||||||
|
|
||||||
formatter = { };
|
formatter.x86_64-linux = null;
|
||||||
nixosConfigurations = { };
|
nixosConfigurations = { };
|
||||||
nixosModules = { };
|
nixosModules = { };
|
||||||
};
|
};
|
||||||
|
@ -63,7 +63,7 @@ nix flake show --json --all-systems > show-output.json
|
||||||
nix eval --impure --expr '
|
nix eval --impure --expr '
|
||||||
let show_output = builtins.fromJSON (builtins.readFile ./show-output.json);
|
let show_output = builtins.fromJSON (builtins.readFile ./show-output.json);
|
||||||
in
|
in
|
||||||
assert show_output == { };
|
assert show_output == { formatter = { x86_64-linux = null; }; };
|
||||||
true
|
true
|
||||||
'
|
'
|
||||||
|
|
||||||
|
|
|
@ -85,3 +85,40 @@ rm ./my-result
|
||||||
# Flake outputs check.
|
# Flake outputs check.
|
||||||
nix flake check
|
nix flake check
|
||||||
nix flake show | grep -P "package 'formatter'"
|
nix flake show | grep -P "package 'formatter'"
|
||||||
|
|
||||||
|
function expectFailWithOutputMatching() {
|
||||||
|
outputMustMatch=$1
|
||||||
|
|
||||||
|
if output=$(nix fmt 2>&1); then
|
||||||
|
echo >&2 "nix fmt unexpectedly succeeded"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
if ! echo "$output" | grep "$outputMustMatch"; then
|
||||||
|
echo >&2 "Expected nix fmt output to match:"
|
||||||
|
echo >&2 "$outputMustMatch"
|
||||||
|
echo >&2 "However, the actual output was:"
|
||||||
|
echo >&2 "$output"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
# Try a flake with no formatter.
|
||||||
|
cat << EOF > flake.nix
|
||||||
|
{
|
||||||
|
outputs = _: {};
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
expectFailWithOutputMatching "does not provide attribute 'formatter.$system'"
|
||||||
|
# Confirm that a null formatter is treated as if there is no formatter.
|
||||||
|
cat << EOF > flake.nix
|
||||||
|
{
|
||||||
|
outputs = _: {
|
||||||
|
formatter.$system = null;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
EOF
|
||||||
|
if nix fmt | grep "does not provide attribute 'formatter.$system'"; then
|
||||||
|
echo >&2 "nix fmt unexpectedly succeeded"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue