Make settings.lang_packages append instead of replace

Downstream modules assign settings.lang_packages.<lang> plainly, which
out-priorities mkOptionDefault and silently dropped the built-in
defaults (e.g. lintr, breaking R linting in downstream wrappers like the
project-template ed flake).

Move the built-in defaults into a separate settings.langPackageDefaults
option and compose defaults ++ lang_packages at the consumption sites
(catPkgs r/python/julia, quarto extraRPackages, neovide R host). A new
append-semantics check fails if defaults migrate back into lang_packages.

Also fix pre-existing inverted assertions in downstream-overrides check:
the override module sets cats.r = true, so assert presence, not absence.
This commit is contained in:
Daniel Winkler 2026-08-25 11:25:05 +10:00
commit 9a6e20110e
6 changed files with 206 additions and 113 deletions

View file

@ -29,7 +29,6 @@
url = "github:jmbuhr/cmp-pandoc-references";
flake = false;
};
"plugins-bloocky" = {
url = "github:atiladefreitas/bloocky";
flake = false;
@ -39,6 +38,7 @@
url = "github:atiladefreitas/dooing";
flake = false;
};
};
outputs = {
@ -216,10 +216,10 @@
(builtins.length (self.lib.devShellPackages defaultConfig) > 0)
];
overrideAssertions = [
(!(overrideConfig.cats.r or false))
(overrideConfig.cats.r or false)
(builtins.length overrideNix == 1)
((builtins.head overrideNix) == "alejandra")
(builtins.match ".*R RHOME.*" overrideShellHook == null)
(builtins.match ".*R RHOME.*" overrideShellHook != null)
];
in
pkgs.runCommand "check-downstream-overrides" {
@ -241,6 +241,36 @@
touch $out
'';
# Downstream modules assign settings.lang_packages.<lang> plainly. The
# module system replaces same-option defaults, so built-in defaults must
# live in langPackageDefaults and be composed at the consumption sites.
# This check fails if someone moves defaults back into lang_packages:
# then a downstream assignment would silently drop lintr etc.
append-semantics = let
downstreamCfg = (self.lib.eval {
inherit pkgs;
modules = [
{
cats.r = true;
settings.lang_packages.r = [ pkgs.rpkgs.rPackages.fixest ];
}
];
}).config;
rWrapperPkg = builtins.head downstreamCfg.catPkgs.r;
in
pkgs.runCommand "check-lang-packages-append" { } ''
script=$(readlink -f "${rWrapperPkg}/bin/R")
grep -q "r-lintr-" "$script" || {
echo "default R packages were dropped by a downstream lang_packages assignment" >&2
exit 1
}
grep -q "r-fixest-" "$script" || {
echo "downstream lang_packages.r additions were not appended" >&2
exit 1
}
echo "lang_packages append semantics OK" > $out
'';
smoke-test = pkgs.runCommand "smoke-test" {} ''
# The Nix build sandbox has a read-only HOME; point XDG dirs at a
# writable location so vim.lsp/shaDa can write state headlessly.