buildLuaPackage: enable __structuredAttrs rocks

it makes overriding easier, instead of having to know internals to
decide which of `sqlite = prev.luaLib.overrideLuarocks prev.sqlite (drv: {` or
`sqlite = prev.sqlite.overrideAttrs (drv: {` just use the latter
This commit is contained in:
Matthieu Coudron 2023-03-30 15:43:19 +02:00
parent fc95204368
commit 30a70671f4
3 changed files with 134 additions and 139 deletions

View File

@ -2,7 +2,7 @@
{ lib
, lua
, wrapLua
, luarocks
# Whether the derivation provides a lua module or not.
, luarocksCheckHook
, luaLib
@ -38,13 +38,7 @@
# Skip wrapping of lua programs altogether
, dontWrapLuaPrograms ? false
, meta ? {}
, passthru ? {}
, doCheck ? false
, doInstallCheck ? false
# Non-Lua / system (e.g. C library) dependencies. Is a list of deps, where
# each dep is either a derivation, or an attribute set like
# { name = "rockspec external_dependencies key"; dep = derivation; }
@ -73,7 +67,6 @@
# Keep extra attributes from `attrs`, e.g., `patchPhase', etc.
let
generatedRockspecFilename = "${rockspecDir}/${pname}-${rockspecVersion}.rockspec";
# TODO fix warnings "Couldn't load rockspec for ..." during manifest
# construction -- from initial investigation, appears it will require
@ -82,43 +75,33 @@ let
# configured trees)
luarocks_config = "luarocks-config.lua";
# Filter out the lua derivation itself from the Lua module dependency
# closure, as it doesn't have a rock tree :)
requiredLuaRocks = lib.filter (d: d ? luaModule)
(lua.pkgs.requiredLuaModules (luarocksDrv.nativeBuildInputs ++ luarocksDrv.propagatedBuildInputs));
luarocksDrv = luaLib.toLuaModule ( lua.stdenv.mkDerivation (self: attrs // {
# example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ]
externalDepsGenerated = lib.unique (lib.filter (drv: !drv ? luaModule) (
luarocksDrv.nativeBuildInputs ++ luarocksDrv.propagatedBuildInputs ++ luarocksDrv.buildInputs)
);
externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps;
luarocksDrv = luaLib.toLuaModule ( lua.stdenv.mkDerivation (finalAttrs: let
rocksSubdir = "${finalAttrs.pname}-${finalAttrs.version}-rocks";
luarocks_content = let
generatedConfig = luaLib.generateLuarocksConfig {
externalDeps = externalDeps ++ externalDepsGenerated;
inherit extraVariables rocksSubdir requiredLuaRocks;
};
in
''
${generatedConfig}
${extraConfig}
'';
in builtins.removeAttrs attrs ["disabled" "externalDeps" "extraVariables"] // {
name = namePrefix + pname + "-" + finalAttrs.version;
name = namePrefix + pname + "-" + self.version;
inherit rockspecVersion;
__structuredAttrs = true;
env = {
LUAROCKS_CONFIG="$PWD/${luarocks_config}";
};
generatedRockspecFilename = "${rockspecDir}/${pname}-${rockspecVersion}.rockspec";
nativeBuildInputs = [
wrapLua
luarocks
] ++ lib.optionals doCheck ([ luarocksCheckHook ] ++ finalAttrs.nativeCheckInputs);
lua.pkgs.luarocks
];
buildInputs = buildInputs
++ (map (d: d.dep) externalDeps');
inherit doCheck extraVariables rockspecFilename knownRockspec externalDeps nativeCheckInputs;
buildInputs = let
# example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ]
externalDeps' = lib.filter (dep: !lib.isDerivation dep) self.externalDeps;
in [ lua.pkgs.luarocks ]
++ lib.optionals self.doCheck ([ luarocksCheckHook ] ++ self.nativeCheckInputs)
++ (map (d: d.dep) externalDeps')
;
# propagate lua to active setup-hook in nix-shell
propagatedBuildInputs = propagatedBuildInputs ++ [ lua ];
@ -126,25 +109,42 @@ let
# @-patterns do not capture formal argument default values, so we need to
# explicitly inherit this for it to be available as a shell variable in the
# builder
inherit rocksSubdir;
rocksSubdir = "${self.pname}-${self.version}-rocks";
luarocks_content = let
externalDepsGenerated = lib.filter (drv: !drv ? luaModule)
(self.nativeBuildInputs ++ self.propagatedBuildInputs ++ self.buildInputs);
generatedConfig = luaLib.generateLuarocksConfig {
externalDeps = lib.unique (self.externalDeps ++ externalDepsGenerated);
# Filter out the lua derivation itself from the Lua module dependency
# closure, as it doesn't have a rock tree :)
# luaLib.hasLuaModule
requiredLuaRocks = lib.filter luaLib.hasLuaModule
(lua.pkgs.requiredLuaModules (self.nativeBuildInputs ++ self.propagatedBuildInputs));
inherit (self) extraVariables rocksSubdir;
};
in
''
${generatedConfig}
${extraConfig}
'';
configurePhase = ''
runHook preConfigure
cat > ${luarocks_config} <<EOF
${luarocks_content}
${self.luarocks_content}
EOF
export LUAROCKS_CONFIG="$PWD/${luarocks_config}";
cat "$LUAROCKS_CONFIG"
''
+ lib.optionalString (rockspecFilename == null) ''
rockspecFilename="${generatedRockspecFilename}"
+ lib.optionalString (self.rockspecFilename == null) ''
rockspecFilename="${self.generatedRockspecFilename}"
''
+ lib.optionalString (knownRockspec != null) ''
+ lib.optionalString (self.knownRockspec != null) ''
# prevents the following type of error:
# Inconsistency between rockspec filename (42fm1b3d7iv6fcbhgm9674as3jh6y2sh-luv-1.22.0-1.rockspec) and its contents (luv-1.22.0-1.rockspec)
rockspecFilename="$TMP/$(stripHash ''${knownRockspec})"
cp ''${knownRockspec} "$rockspecFilename"
rockspecFilename="$TMP/$(stripHash ${self.knownRockspec})"
cp ${self.knownRockspec} "$rockspecFilename"
''
+ ''
runHook postConfigure
@ -155,9 +155,9 @@ let
nix_debug "Using LUAROCKS_CONFIG=$LUAROCKS_CONFIG"
LUAROCKS=luarocks
LUAROCKS_EXTRA_ARGS=""
if (( ''${NIX_DEBUG:-0} >= 1 )); then
LUAROCKS="$LUAROCKS --verbose"
LUAROCKS_EXTRA_ARGS=" --verbose"
fi
runHook postBuild
@ -167,7 +167,7 @@ let
wrapLuaPrograms
'' + attrs.postFixup or "";
installPhase = attrs.installPhase or ''
installPhase = ''
runHook preInstall
# work around failing luarocks test for Write access
@ -182,21 +182,17 @@ let
# maybe we could reestablish dependency checking via passing --rock-trees
nix_debug "ROCKSPEC $rockspecFilename"
nix_debug "cwd: $PWD"
$LUAROCKS make --deps-mode=all --tree=$out ''${rockspecFilename}
luarocks $LUAROCKS_EXTRA_ARGS make --deps-mode=all --tree=$out ''${rockspecFilename}
runHook postInstall
'';
checkPhase = attrs.checkPhase or ''
checkPhase = ''
runHook preCheck
$LUAROCKS test
luarocks test
runHook postCheck
'';
LUAROCKS_CONFIG="$PWD/${luarocks_config}";
shellHook = ''
runHook preShell
export LUAROCKS_CONFIG="$PWD/${luarocks_config}";
@ -205,16 +201,14 @@ let
passthru = {
inherit lua; # The lua interpreter
inherit externalDeps;
inherit luarocks_content;
} // passthru;
};
meta = {
platforms = lua.meta.platforms;
# add extra maintainer(s) to every package
maintainers = (meta.maintainers or []) ++ [ ];
maintainers = (attrs.meta.maintainers or []) ++ [ ];
broken = disabled;
} // meta;
} // attrs.meta;
}));
in
luarocksDrv

View File

@ -65,7 +65,7 @@ rec {
so that luaRequireModules can be run later
*/
toLuaModule = drv:
drv.overrideAttrs( oldAttrs: {
drv.overrideAttrs(oldAttrs: {
# Use passthru in order to prevent rebuilds when possible.
passthru = (oldAttrs.passthru or {}) // {
luaModule = lua;
@ -81,8 +81,7 @@ rec {
};
*/
generateLuarocksConfig = {
externalDeps
externalDeps
# a list of lua derivations
, requiredLuaRocks
, extraVariables ? {}

View File

@ -73,13 +73,7 @@ with prev;
'';
});
cqueues = (prev.luaLib.overrideLuarocks prev.cqueues (drv: {
externalDeps = [
{ name = "CRYPTO"; dep = openssl; }
{ name = "OPENSSL"; dep = openssl; }
];
disabled = luaOlder "5.1" || luaAtLeast "5.4";
})).overrideAttrs (oa: rec {
cqueues = prev.cqueues.overrideAttrs (oa: rec {
# Parse out a version number without the Lua version inserted
version = with lib; let
version' = prev.cqueues.version;
@ -89,10 +83,17 @@ with prev;
in
"${date}-${rev}";
meta.broken = luaOlder "5.1" || luaAtLeast "5.4";
nativeBuildInputs = oa.nativeBuildInputs ++ [
gnum4
];
externalDeps = [
{ name = "CRYPTO"; dep = openssl; }
{ name = "OPENSSL"; dep = openssl; }
];
# Upstream rockspec is pointlessly broken into separate rockspecs, per Lua
# version, which doesn't work well for us, so modify it
postConfigure = let inherit (prev.cqueues) pname; in
@ -109,7 +110,7 @@ with prev;
'';
});
cyrussasl = prev.luaLib.overrideLuarocks prev.cyrussasl (drv: {
cyrussasl = prev.cyrussasl.overrideAttrs (drv: {
externalDeps = [
{ name = "LIBSASL"; dep = cyrus_sasl; }
];
@ -138,7 +139,11 @@ with prev;
*/
});
ldbus = prev.luaLib.overrideLuarocks prev.ldbus (drv: {
lpty = prev.lpty.overrideAttrs (oa: {
meta.broken = luaOlder "5.1" || luaAtLeast "5.3";
});
ldbus = prev.ldbus.overrideAttrs (oa: {
extraVariables = {
DBUS_DIR = "${dbus.lib}";
DBUS_ARCH_INCDIR = "${dbus.lib}/lib/dbus-1.0/include";
@ -149,7 +154,7 @@ with prev;
];
});
ljsyscall = prev.luaLib.overrideLuarocks prev.ljsyscall (drv: rec {
ljsyscall = prev.ljsyscall.overrideAttrs (oa: rec {
version = "unstable-20180515";
# package hasn't seen any release for a long time
src = fetchFromGitHub {
@ -163,9 +168,9 @@ with prev;
preConfigure = ''
sed -i 's/lua == 5.1/lua >= 5.1, < 5.3/' ${knownRockspec}
'';
disabled = luaOlder "5.1" || luaAtLeast "5.3";
meta.broken = luaOlder "5.1" || luaAtLeast "5.3";
propagatedBuildInputs = with lib; optional (!isLuaJIT) luaffi;
propagatedBuildInputs = with lib; oa.propagatedBuildInputs ++ optional (!isLuaJIT) luaffi;
});
lgi = prev.lgi.overrideAttrs (oa: {
@ -228,7 +233,7 @@ with prev;
'';
});
lmpfrlib = prev.luaLib.overrideLuarocks prev.lmpfrlib (drv: {
lmpfrlib = prev.lmpfrlib.overrideAttrs (oa: {
externalDeps = [
{ name = "GMP"; dep = gmp; }
{ name = "MPFR"; dep = mpfr; }
@ -238,32 +243,32 @@ with prev;
'';
});
lrexlib-gnu = prev.luaLib.overrideLuarocks prev.lrexlib-gnu (drv: {
buildInputs = [
lrexlib-gnu = prev.lrexlib-gnu.overrideAttrs (oa: {
buildInputs = oa.buildInputs ++ [
gnulib
];
});
lrexlib-pcre = prev.luaLib.overrideLuarocks prev.lrexlib-pcre (drv: {
lrexlib-pcre = prev.lrexlib-pcre.overrideAttrs (oa: {
externalDeps = [
{ name = "PCRE"; dep = pcre; }
];
});
lrexlib-posix = prev.luaLib.overrideLuarocks prev.lrexlib-posix (drv: {
buildInputs = [
lrexlib-posix = prev.lrexlib-posix.overrideAttrs (oa: {
buildInputs = oa.buildInputs ++ [
glibc.dev
];
});
lua-curl = prev.luaLib.overrideLuarocks prev.lua-curl (drv: {
buildInputs = [
curl
lua-curl = prev.lua-curl.overrideAttrs (oa: {
buildInputs = oa.buildInputs ++ [
curl.dev
];
});
lua-iconv = prev.luaLib.overrideLuarocks prev.lua-iconv (drv: {
buildInputs = [
lua-iconv = prev.lua-iconv.overrideAttrs (oa: {
buildInputs = oa.buildInputs ++ [
libiconv
];
});
@ -276,39 +281,39 @@ with prev;
'';
});
lua-zlib = prev.luaLib.overrideLuarocks prev.lua-zlib (drv: {
buildInputs = [
lua-zlib = prev.lua-zlib.overrideAttrs (oa: {
buildInputs = oa.buildInputs ++ [
zlib.dev
];
disabled = luaOlder "5.1" || luaAtLeast "5.4";
meta.broken = luaOlder "5.1" || luaAtLeast "5.4";
});
luadbi-mysql = prev.luaLib.overrideLuarocks prev.luadbi-mysql (drv: {
luadbi-mysql = prev.luadbi-mysql.overrideAttrs (oa: {
extraVariables = {
# Can't just be /include and /lib, unfortunately needs the trailing 'mysql'
MYSQL_INCDIR = "${libmysqlclient.dev}/include/mysql";
MYSQL_LIBDIR = "${libmysqlclient}/lib/mysql";
};
buildInputs = [
buildInputs = oa.buildInputs ++ [
mariadb.client
libmysqlclient
];
});
luadbi-postgresql = prev.luaLib.overrideLuarocks prev.luadbi-postgresql (drv: {
buildInputs = [
luadbi-postgresql = prev.luadbi-postgresql.overrideAttrs (oa: {
buildInputs = oa.buildInputs ++ [
postgresql
];
});
luadbi-sqlite3 = prev.luaLib.overrideLuarocks prev.luadbi-sqlite3 (drv: {
luadbi-sqlite3 = prev.luadbi-sqlite3.overrideAttrs (oa: {
externalDeps = [
{ name = "SQLITE"; dep = sqlite; }
];
});
luaevent = prev.luaLib.overrideLuarocks prev.luaevent (drv: {
propagatedBuildInputs = [
luaevent = prev.luaevent.overrideAttrs (oa: {
propagatedBuildInputs = oa.propagatedBuildInputs ++ [
luasocket
];
externalDeps = [
@ -317,7 +322,7 @@ with prev;
disabled = luaOlder "5.1" || luaAtLeast "5.4";
});
luaexpat = prev.luaLib.overrideLuarocks prev.luaexpat (drv: {
luaexpat = prev.luaexpat.overrideAttrs (_: {
externalDeps = [
{ name = "EXPAT"; dep = expat; }
];
@ -325,7 +330,7 @@ with prev;
# TODO Somehow automatically amend buildInputs for things that need luaffi
# but are in luajitPackages?
luaffi = prev.luaLib.overrideLuarocks prev.luaffi (drv: {
luaffi = prev.luaffi.overrideAttrs (oa: {
# The packaged .src.rock version is pretty old, and doesn't work with Lua 5.3
src = fetchFromGitHub {
owner = "facebook";
@ -334,75 +339,70 @@ with prev;
sha256 = "1nwx6sh56zfq99rcs7sph0296jf6a9z72mxknn0ysw9fd7m1r8ig";
};
knownRockspec = with prev.luaffi; "${pname}-${version}.rockspec";
disabled = luaOlder "5.1" || luaAtLeast "5.4" || isLuaJIT;
meta.broken = luaOlder "5.1" || luaAtLeast "5.4" || isLuaJIT;
});
lualdap = prev.luaLib.overrideLuarocks prev.lualdap (drv: {
lualdap = prev.lualdap.overrideAttrs (_: {
externalDeps = [
{ name = "LDAP"; dep = openldap; }
];
});
luaossl = prev.luaLib.overrideLuarocks prev.luaossl (drv: {
luaossl = prev.luaossl.overrideAttrs (_: {
externalDeps = [
{ name = "CRYPTO"; dep = openssl; }
{ name = "OPENSSL"; dep = openssl; }
];
});
luaposix = prev.luaLib.overrideLuarocks prev.luaposix (drv: {
luaposix = prev.luaposix.overrideAttrs (_: {
externalDeps = [
{ name = "CRYPT"; dep = libxcrypt; }
];
});
luasec = prev.luaLib.overrideLuarocks prev.luasec (drv: {
luasec = prev.luasec.overrideAttrs (oa: {
externalDeps = [
{ name = "OPENSSL"; dep = openssl; }
];
});
luasql-sqlite3 = prev.luaLib.overrideLuarocks prev.luasql-sqlite3 (drv: {
luasql-sqlite3 = prev.luasql-sqlite3.overrideAttrs (oa: {
externalDeps = [
{ name = "SQLITE"; dep = sqlite; }
];
});
luasystem = prev.luaLib.overrideLuarocks prev.luasystem (drv: lib.optionalAttrs stdenv.isLinux {
luasystem = prev.luasystem.overrideAttrs (oa: lib.optionalAttrs stdenv.isLinux {
buildInputs = [ glibc.out ];
});
luazip = prev.luaLib.overrideLuarocks prev.luazip (drv: {
buildInputs = [
luazip = prev.luazip.overrideAttrs (oa: {
buildInputs = oa.buildInputs ++ [
zziplib
];
});
lua-yajl = prev.luaLib.overrideLuarocks prev.lua-yajl (drv: {
buildInputs = [
lua-yajl = prev.lua-yajl.overrideAttrs (oa: {
buildInputs = oa.buildInputs ++ [
yajl
];
});
luaunbound = prev.luaLib.overrideLuarocks prev.luaunbound (drv: {
luaunbound = prev.luaunbound.overrideAttrs (oa: {
externalDeps = [
{ name = "libunbound"; dep = unbound; }
];
});
lush-nvim = prev.luaLib.overrideLuarocks prev.lush-nvim (drv: {
lush-nvim = prev.lush-nvim.overrideAttrs (drv: {
doCheck = false;
});
luuid = (prev.luaLib.overrideLuarocks prev.luuid (drv: {
luuid = prev.luuid.overrideAttrs (oa: {
externalDeps = [
{ name = "LIBUUID"; dep = libuuid; }
];
disabled = luaOlder "5.1" || (luaAtLeast "5.4");
})).overrideAttrs (oa: {
meta = oa.meta // {
platforms = lib.platforms.linux;
};
# Trivial patch to make it work in both 5.1 and 5.2. Basically just the
# tiny diff between the two upstream versions placed behind an #if.
# Upstreams:
@ -415,6 +415,10 @@ with prev;
postConfigure = ''
sed -Ei ''${rockspecFilename} -e 's|lua >= 5.2|lua >= 5.1,|'
'';
meta = oa.meta // {
broken = luaOlder "5.1" || (luaAtLeast "5.4");
platforms = lib.platforms.linux;
};
});
@ -444,14 +448,14 @@ with prev;
++ lib.optionals stdenv.isDarwin [ fixDarwinDylibNames ];
};
luv = prev.luaLib.overrideLuarocks prev.luv (drv: {
luv = prev.luv.overrideAttrs (oa: {
nativeBuildInputs = [ pkg-config ];
nativeBuildInputs = oa.nativeBuildInputs ++ [ pkg-config ];
buildInputs = [ libuv ];
# Use system libuv instead of building local and statically linking
extraVariables = {
"WITH_SHARED_LIBUV" = "ON";
WITH_SHARED_LIBUV = "ON";
};
# we unset the LUA_PATH since the hook erases the interpreter defaults (To fix)
@ -460,22 +464,21 @@ with prev;
unset LUA_PATH
rm tests/test-{dns,thread}.lua
'';
passthru.libluv = final.libluv;
});
lyaml = prev.luaLib.overrideLuarocks prev.lyaml (oa: {
lyaml = prev.lyaml.overrideAttrs (oa: {
buildInputs = [
libyaml
];
});
mpack = prev.luaLib.overrideLuarocks prev.mpack (drv: {
buildInputs = [ libmpack ];
# the rockspec doesn't use the makefile so you may need to export more flags
USE_SYSTEM_LUA = "yes";
USE_SYSTEM_MPACK = "yes";
mpack = prev.mpack.overrideAttrs (drv: {
buildInputs = (drv.buildInputs or []) ++ [ libmpack ];
env = {
# the rockspec doesn't use the makefile so you may need to export more flags
USE_SYSTEM_LUA = "yes";
USE_SYSTEM_MPACK = "yes";
};
});
rapidjson = prev.rapidjson.overrideAttrs (oa: {
@ -485,24 +488,23 @@ with prev;
'';
});
readline = (prev.luaLib.overrideLuarocks prev.readline (drv: {
unpackCmd = ''
unzip "$curSrc"
tar xf *.tar.gz
'';
propagatedBuildInputs = prev.readline.propagatedBuildInputs ++ [ readline.out ];
readline = prev.readline.overrideAttrs (oa: {
propagatedBuildInputs = oa.propagatedBuildInputs ++ [ readline.out ];
extraVariables = rec {
READLINE_INCDIR = "${readline.dev}/include";
HISTORY_INCDIR = READLINE_INCDIR;
};
})).overrideAttrs (old: {
unpackCmd = ''
unzip "$curSrc"
tar xf *.tar.gz
'';
# Without this, source root is wrongly set to ./readline-2.6/doc
setSourceRoot = ''
sourceRoot=./readline-${lib.versions.majorMinor old.version}
sourceRoot=./readline-${lib.versions.majorMinor oa.version}
'';
});
sqlite = prev.luaLib.overrideLuarocks prev.sqlite (drv: {
sqlite = prev.sqlite.overrideAttrs (drv: {
doCheck = true;
nativeCheckInputs = [ final.plenary-nvim neovim-unwrapped ];