modules/performance: ensure all lua dependencies are byte-compiled

This commit replaces custom lua plugins in tests with shared stub
plugins from utils module.
After this change the test has started to fail. Debugging this issue
I found out that dependencies of plugins weren't processed.
This commit improves the test assertion to detect duplicated
dependencies in this case and fixes the underlying issue by also
processing dependencies.
This commit is contained in:
Stanislav Asunkin 2025-05-10 22:07:02 +03:00
parent 2210d7bb10
commit 9474ce916a
2 changed files with 65 additions and 55 deletions

View file

@ -9,20 +9,35 @@ let
builders = lib.nixvim.builders.withPkgs pkgs; builders = lib.nixvim.builders.withPkgs pkgs;
inherit (import ./utils.nix lib) mapNormalizedPlugins; inherit (import ./utils.nix lib) mapNormalizedPlugins;
luaPackages = pkgs.neovim-unwrapped.lua.pkgs;
# Applies a function to the derivation, but only if it's a lua module,
# otherwise returns it as is
mapLuaModule = f: drv: if luaPackages.luaLib.hasLuaModule drv then f drv else drv;
# Byte-compile only lua dependencies # Byte-compile only lua dependencies
byteCompileDeps = byteCompileDeps =
drv: drv:
drv.overrideAttrs ( lib.pipe drv [
prev: (
lib.optionalAttrs (prev ? propagatedBuildInputs) { drv:
propagatedBuildInputs = map byteCompile prev.propagatedBuildInputs; if drv.dependencies or [ ] != [ ] then
} drv.overrideAttrs { dependencies = map byteCompileDeps drv.dependencies; }
); else
drv
)
(
drv:
if drv.propagatedBuildInputs or [ ] != [ ] then
drv.overrideAttrs { propagatedBuildInputs = map byteCompile drv.propagatedBuildInputs; }
else
drv
)
# 'toLuaModule' updates requiredLuaModules attr
# It works without it, but update it anyway for consistency
(mapLuaModule luaPackages.toLuaModule)
];
# Byte-compile derivation (but only if it's a lua module) and its dependencies # Byte-compile derivation (but only if it's a lua module) and its dependencies
byteCompile = byteCompile = drv: byteCompileDeps (mapLuaModule builders.byteCompileLuaDrv drv);
drv:
byteCompileDeps (
if pkgs.luaPackages.luaLib.hasLuaModule drv then builders.byteCompileLuaDrv drv else drv
);
in in
mapNormalizedPlugins byteCompileDeps mapNormalizedPlugins byteCompileDeps

View file

@ -1,5 +1,7 @@
{ pkgs, ... }: { lib, pkgs, ... }:
let let
pluginStubs = pkgs.callPackage ../../../utils/plugin-stubs.nix { };
isByteCompiledFun = # lua isByteCompiledFun = # lua
'' ''
-- LuaJIT bytecode header is: ESC L J version -- LuaJIT bytecode header is: ESC L J version
@ -325,70 +327,63 @@ in
# performance.byteCompileLua.luaLib for propagatedBuildInputs # performance.byteCompileLua.luaLib for propagatedBuildInputs
lua-lib-propagated-build-inputs = lua-lib-propagated-build-inputs =
{ { config, ... }:
config,
lib,
pkgs,
...
}:
{ {
performance.byteCompileLua = { performance.byteCompileLua = {
enable = true; enable = true;
luaLib = true; luaLib = true;
}; };
extraPlugins = extraPlugins = pluginStubs.pluginPack;
let
inherit (config.package) lua;
setDeps =
drv: deps:
# 'toLuaModule' is used here for updating 'requiredLuaModules' attr
lua.pkgs.luaLib.toLuaModule (
drv.overrideAttrs {
propagatedBuildInputs = [ lua ] ++ deps;
}
);
# Add the 'argparse' dependency to the 'say' module
say = setDeps lua.pkgs.say [ lua.pkgs.argparse ];
in
[
# 'lz-n' depends on 'say' which itself depends on 'argparse'
(setDeps pkgs.vimPlugins.lz-n [ say ])
# 'nvim-cmp' depends on 'argparse'
(setDeps pkgs.vimPlugins.nvim-cmp [ lua.pkgs.argparse ])
];
extraConfigLuaPost = '' extraConfigLuaPost = ''
${pluginStubs.pluginChecks}
${isByteCompiledFun} ${isByteCompiledFun}
-- Plugins themselves are importable -- Lua modules are byte-compiled
require("lz.n") ${lib.concatMapStringsSep "\n" (
require("cmp") name: "test_lualib_file(require('${name}').name, true)"
) pluginStubs.libNames}
-- Lua modules are importable and byte compiled -- Plugins themselves are not byte-compiled
local say = require("say") ${lib.concatMapStringsSep "\n" (
test_lualib_file(say.set, true) name: "test_rtp_file('lua/${name}/init.lua', false)"
local argparse = require("argparse") ) pluginStubs.pluginNames}
test_lualib_file(argparse("test").parse, true)
''; '';
assertions = assertions =
let let
requiredLuaModules = lib.pipe config.extraPlugins [ # Get plugins with all dependencies
(builtins.catAttrs "requiredLuaModules") getDeps = drv: [ drv ] ++ builtins.concatMap getDeps drv.dependencies or [ ];
builtins.concatLists plugins = lib.pipe config.build.plugins [
(builtins.catAttrs "plugin")
(builtins.concatMap getDeps)
lib.unique lib.unique
]; ];
# Collect both propagatedBuildInputs and requiredLuaModules to one list
getAllRequiredLuaModules = lib.flip lib.pipe [
(
drvs: builtins.catAttrs "propagatedBuildInputs" drvs ++ builtins.catAttrs "requiredLuaModules" drvs
)
(builtins.concatMap (deps: deps ++ getAllRequiredLuaModules deps))
lib.unique
];
allRequiredLuaModules = getAllRequiredLuaModules plugins;
in in
[ [
# Ensure that propagatedBuildInputs are byte-compiled recursively # Ensure that lua dependencies are byte-compiled recursively
# by checking that every library is present only once # by checking that every library is present only once.
# If there are two different derivations with the same name,
# then one of them probably isn't byte-compiled.
{ {
assertion = lib.allUnique (map lib.getName requiredLuaModules); assertion = lib.allUnique (map lib.getName allRequiredLuaModules);
message = '' message = ''
Expected requiredLuaModules of all propagatedBuildInputs to have unique names. Expected propagatedBuildInputs and requiredLuaModules of all plugins to have unique names.
Got the following derivations: ${builtins.concatStringsSep ", " requiredLuaModules}. Got the following derivations:''\n${lib.concatLines allRequiredLuaModules}
One possible reason is that not all dependencies are overridden the same way. Possible reasons:
- not all dependencies are overridden the same way
- requiredLuaModules are not updated along with propagatedBuildInputs
''; '';
} }
]; ];