1{ pkgs, lib, lua }:
2let
3 requiredLuaModules = drvs: with lib; let
4 modules = filter hasLuaModule drvs;
5 in unique ([lua] ++ modules ++ concatLists (catAttrs "requiredLuaModules" modules));
6 # Check whether a derivation provides a lua module.
7 hasLuaModule = drv: drv ? luaModule;
8
9
10 /*
11 Use this to override the arguments passed to buildLuarocksPackage
12 */
13 overrideLuarocks = drv: f: (drv.override (args: args // {
14 buildLuarocksPackage = drv: (args.buildLuarocksPackage drv).override f;
15 })) // {
16 overrideScope = scope: overrideLuarocks (drv.overrideScope scope) f;
17 };
18
19in
20rec {
21 inherit overrideLuarocks;
22 inherit hasLuaModule requiredLuaModules;
23
24 luaPathList = [
25 "share/lua/${lua.luaversion}/?.lua"
26 "share/lua/${lua.luaversion}/?/init.lua"
27 ];
28 luaCPathList = [
29 "lib/lua/${lua.luaversion}/?.so"
30 ];
31
32 /* generate paths without a prefix
33 */
34 luaPathRelStr = lib.concatStringsSep ";" luaPathList;
35 luaCPathRelStr = lib.concatStringsSep ";" luaCPathList;
36
37 /* generate LUA_(C)PATH value for a specific derivation, i.e., with absolute paths
38 */
39 genLuaPathAbsStr = drv: lib.concatMapStringsSep ";" (x: "${drv}/${x}") luaPathList;
40 genLuaCPathAbsStr = drv: lib.concatMapStringsSep ";" (x: "${drv}/${x}") luaCPathList;
41
42 /* Generate a LUA_PATH with absolute paths
43 */
44 # genLuaPathAbs = drv:
45 # lib.concatStringsSep ";" (map (x: "${drv}/x") luaPathList);
46
47 luaAtLeast = lib.versionAtLeast lua.luaversion;
48 luaOlder = lib.versionOlder lua.luaversion;
49 isLua51 = (lib.versions.majorMinor lua.version) == "5.1";
50 isLua52 = (lib.versions.majorMinor lua.version) == "5.2";
51 isLua53 = lua.luaversion == "5.3";
52 isLuaJIT = lib.getName lua == "luajit";
53
54 /* generates the relative path towards the folder where
55 seems stable even when using lua_modules_path = ""
56
57 Example:
58 getDataFolder luaPackages.stdlib
59 => stdlib-41.2.2-1-rocks/stdlib/41.2.2-1/doc
60 */
61 getDataFolder = drv:
62 "${drv.pname}-${drv.version}-rocks/${drv.pname}/${drv.version}";
63
64 /* Convert derivation to a lua module.
65 so that luaRequireModules can be run later
66 */
67 toLuaModule = drv:
68 drv.overrideAttrs( oldAttrs: {
69 # Use passthru in order to prevent rebuilds when possible.
70 passthru = (oldAttrs.passthru or {}) // {
71 luaModule = lua;
72 requiredLuaModules = requiredLuaModules drv.propagatedBuildInputs;
73 };
74 });
75
76 /* generate luarocks config
77
78 generateLuarocksConfig {
79 externalDeps = [ { name = "CRYPTO"; dep = pkgs.openssl; } ];
80 rocksSubdir = "subdir";
81 };
82 */
83 generateLuarocksConfig = {
84 externalDeps
85 , requiredLuaRocks
86 , extraVariables ? {}
87 , rocksSubdir
88 }: let
89 rocksTrees = lib.imap0
90 (i: dep: "{ name = [[dep-${toString i}]], root = '${dep}', rocks_dir = '${dep}/${dep.rocksSubdir}' }")
91 requiredLuaRocks;
92
93 # Explicitly point luarocks to the relevant locations for multiple-output
94 # derivations that are external dependencies, to work around an issue it has
95 # (https://github.com/luarocks/luarocks/issues/766)
96 depVariables = lib.concatMap ({name, dep}: [
97 "${name}_INCDIR='${lib.getDev dep}/include';"
98 "${name}_LIBDIR='${lib.getLib dep}/lib';"
99 "${name}_BINDIR='${lib.getBin dep}/bin';"
100 ]) externalDeps';
101
102 # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ]
103 externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps;
104
105 externalDepsDirs = map
106 (x: "'${builtins.toString x}'")
107 (lib.filter (lib.isDerivation) externalDeps);
108
109 extraVariablesStr = lib.concatStringsSep "\n "
110 (lib.mapAttrsToList (k: v: "${k}='${v}';") extraVariables);
111 in ''
112 local_cache = ""
113 -- To prevent collisions when creating environments, we install the rock
114 -- files into per-package subdirectories
115 rocks_subdir = '${rocksSubdir}'
116 -- Then we need to tell luarocks where to find the rock files per
117 -- dependency
118 rocks_trees = {
119 ${lib.concatStringsSep "\n, " rocksTrees}
120 }
121 '' + lib.optionalString lua.pkgs.isLuaJIT ''
122 -- Luajit provides some additional functionality built-in; this exposes
123 -- that to luarock's dependency system
124 rocks_provided = {
125 jit='${lua.luaversion}-1';
126 ffi='${lua.luaversion}-1';
127 luaffi='${lua.luaversion}-1';
128 bit='${lua.luaversion}-1';
129 }
130 '' + ''
131 -- For single-output external dependencies
132 external_deps_dirs = {
133 ${lib.concatStringsSep "\n, " externalDepsDirs}
134 }
135 variables = {
136 -- Some needed machinery to handle multiple-output external dependencies,
137 -- as per https://github.com/luarocks/luarocks/issues/766
138 ${lib.optionalString (lib.length depVariables > 0) ''
139 ${lib.concatStringsSep "\n " depVariables}''}
140 ${extraVariablesStr}
141 }
142 '';
143}