1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-24 22:11:15 +02:00
nix/tests/functional/formatter.sh
Jeremy Fleischman 929423476e
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
```
2025-05-28 16:03:58 -07:00

124 lines
3.1 KiB
Bash
Executable file

#!/usr/bin/env bash
source common.sh
TODO_NixOS # Provide a `shell` variable. Try not to `export` it, perhaps.
clearStoreIfPossible
rm -rf "$TEST_HOME"/.cache "$TEST_HOME"/.config "$TEST_HOME"/.local
cp ./simple.nix ./simple.builder.sh ./formatter.simple.sh "${config_nix}" "$TEST_HOME"
cd "$TEST_HOME"
nix formatter --help | grep "build or run the formatter"
nix fmt --help | grep "reformat your code"
nix fmt run --help | grep "reformat your code"
nix fmt build --help | grep "build"
cat << EOF > flake.nix
{
outputs = _: {
formatter.$system =
with import ./config.nix;
mkDerivation {
name = "formatter";
buildCommand = ''
mkdir -p \$out/bin
echo "#! ${shell}" > \$out/bin/formatter
cat \${./formatter.simple.sh} >> \$out/bin/formatter
chmod +x \$out/bin/formatter
'';
};
};
}
EOF
mkdir subflake
cp ./simple.nix ./simple.builder.sh ./formatter.simple.sh "${config_nix}" "$TEST_HOME/subflake"
cat << EOF > subflake/flake.nix
{
outputs = _: {
formatter.$system =
with import ./config.nix;
mkDerivation {
name = "formatter";
buildCommand = ''
mkdir -p \$out/bin
echo "#! ${shell}" > \$out/bin/formatter
cat \${./formatter.simple.sh} >> \$out/bin/formatter
chmod +x \$out/bin/formatter
'';
};
};
}
EOF
# No arguments check
[[ "$(nix fmt)" = "PRJ_ROOT=$TEST_HOME Formatting(0):" ]]
[[ "$(nix formatter run)" = "PRJ_ROOT=$TEST_HOME Formatting(0):" ]]
# Argument forwarding check
nix fmt ./file ./folder | grep "PRJ_ROOT=$TEST_HOME Formatting(2): ./file ./folder"
nix formatter run ./file ./folder | grep "PRJ_ROOT=$TEST_HOME Formatting(2): ./file ./folder"
# test subflake
cd subflake
nix fmt ./file | grep "PRJ_ROOT=$TEST_HOME/subflake Formatting(1): ./file"
# Build checks
## Defaults to a ./result.
nix formatter build | grep ".\+/bin/formatter"
[[ -L ./result ]]
rm result
## Can prevent the symlink.
nix formatter build --no-link
[[ ! -e ./result ]]
## Can change the symlink name.
nix formatter build --out-link my-result | grep ".\+/bin/formatter"
[[ -L ./my-result ]]
rm ./my-result
# Flake outputs check.
nix flake check
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