Loading lib/generators.nix +21 −3 Original line number Diff line number Diff line Loading @@ -434,6 +434,7 @@ ${expr "" v} Configuration: * multiline - by default is true which results in indented block-like view. * indent - initial indent. * asBindings - by default generate single value, but with this use attrset to set global vars. Attention: Regardless of multiline parameter there is no trailing newline. Loading Loading @@ -464,18 +465,35 @@ ${expr "" v} /* If this option is true, the output is indented with newlines for attribute sets and lists */ multiline ? true, /* Initial indentation level */ indent ? "" indent ? "", /* Interpret as variable bindings */ asBindings ? false, }@args: v: with builtins; let innerIndent = "${indent} "; introSpace = if multiline then "\n${innerIndent}" else " "; outroSpace = if multiline then "\n${indent}" else " "; innerArgs = args // { indent = innerIndent; }; innerArgs = args // { indent = if asBindings then indent else innerIndent; asBindings = false; }; concatItems = concatStringsSep ",${introSpace}"; isLuaInline = { _type ? null, ... }: _type == "lua-inline"; generatedBindings = assert lib.assertMsg (badVarNames == []) "Bad Lua var names: ${toPretty {} badVarNames}"; libStr.concatStrings ( lib.attrsets.mapAttrsToList (key: value: "${indent}${key} = ${toLua innerArgs value}\n") v ); # https://en.wikibooks.org/wiki/Lua_Programming/variable#Variable_names matchVarName = match "[[:alpha:]_][[:alnum:]_]*(\\.[[:alpha:]_][[:alnum:]_]*)*"; badVarNames = filter (name: matchVarName name == null) (attrNames v); in if v == null then if asBindings then generatedBindings else if v == null then "nil" else if isInt v || isFloat v || isString v || isBool v then builtins.toJSON v Loading lib/tests/misc.nix +40 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,11 @@ with import ../default.nix; let testingThrow = expr: { expr = (builtins.tryEval (builtins.seq expr "didn't throw")); expected = { success = false; value = false; }; }; testingDeepThrow = expr: testingThrow (builtins.deepSeq expr expr); testSanitizeDerivationName = { name, expected }: let Loading Loading @@ -962,6 +967,41 @@ runTests { expected = ''{ 41, 43 }''; }; testToLuaEmptyBindings = { expr = generators.toLua { asBindings = true; } {}; expected = ""; }; testToLuaBindings = { expr = generators.toLua { asBindings = true; } { x1 = 41; _y = { a = 43; }; }; expected = '' _y = { ["a"] = 43 } x1 = 41 ''; }; testToLuaPartialTableBindings = { expr = generators.toLua { asBindings = true; } { "x.y" = 42; }; expected = '' x.y = 42 ''; }; testToLuaIndentedBindings = { expr = generators.toLua { asBindings = true; indent = " "; } { x = { y = 42; }; }; expected = " x = {\n [\"y\"] = 42\n }\n"; }; testToLuaBindingsWithSpace = testingThrow ( generators.toLua { asBindings = true; } { "with space" = 42; } ); testToLuaBindingsWithLeadingDigit = testingThrow ( generators.toLua { asBindings = true; } { "11eleven" = 42; } ); testToLuaBasicExample = { expr = generators.toLua {} { cmd = [ "typescript-language-server" "--stdio" ]; Loading pkgs/development/lua-modules/lib.nix +35 −42 Original line number Diff line number Diff line { pkgs, lib, lua }: let inherit (lib.generators) toLua; requiredLuaModules = drvs: with lib; let modules = filter hasLuaModule drvs; in unique ([lua] ++ modules ++ concatLists (catAttrs "requiredLuaModules" modules)); Loading Loading @@ -88,58 +89,50 @@ rec { , rocksSubdir }: let rocksTrees = lib.imap0 (i: dep: "{ name = [[dep-${toString i}]], root = '${dep}', rocks_dir = '${dep}/${dep.rocksSubdir}' }") (i: dep: { name = "dep-${toString i}"; root = "${dep}"; rocks_dir = "${dep}/${dep.rocksSubdir}"; }) requiredLuaRocks; # Explicitly point luarocks to the relevant locations for multiple-output # derivations that are external dependencies, to work around an issue it has # (https://github.com/luarocks/luarocks/issues/766) depVariables = lib.concatMap ({name, dep}: [ "${name}_INCDIR='${lib.getDev dep}/include';" "${name}_LIBDIR='${lib.getLib dep}/lib';" "${name}_BINDIR='${lib.getBin dep}/bin';" ]) externalDeps'; depVariables = zipAttrsWithLast (lib.lists.map ({name, dep}: { "${name}_INCDIR" = "${lib.getDev dep}/include"; "${name}_LIBDIR" = "${lib.getLib dep}/lib"; "${name}_BINDIR" = "${lib.getBin dep}/bin"; }) externalDeps'); zipAttrsWithLast = lib.attrsets.zipAttrsWith (name: lib.lists.last); # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ] externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps; externalDepsDirs = map (x: "'${builtins.toString x}'") (x: builtins.toString x) (lib.filter (lib.isDerivation) externalDeps); extraVariablesStr = lib.concatStringsSep "\n " (lib.mapAttrsToList (k: v: "${k}='${v}';") extraVariables); in '' local_cache = "" -- To prevent collisions when creating environments, we install the rock -- files into per-package subdirectories rocks_subdir = '${rocksSubdir}' -- first tree is the default target where new rocks are installed, -- any other trees in the list are treated as additional sources of installed rocks for matching dependencies. rocks_trees = { {name = "current", root = '${placeholder "out"}', rocks_dir = "current" }, ${lib.concatStringsSep "\n, " rocksTrees} } '' + lib.optionalString lua.pkgs.isLuaJIT '' -- Luajit provides some additional functionality built-in; this exposes -- that to luarock's dependency system in toLua { asBindings = true; } ({ local_cache = ""; # To prevent collisions when creating environments, we install the rock # files into per-package subdirectories rocks_subdir = rocksSubdir; # first tree is the default target where new rocks are installed, # any other trees in the list are treated as additional sources of installed rocks for matching dependencies. rocks_trees = ( [{name = "current"; root = "${placeholder "out"}"; rocks_dir = "current"; }] ++ rocksTrees ); } // lib.optionalAttrs lua.pkgs.isLuaJIT { # Luajit provides some additional functionality built-in; this exposes # that to luarock's dependency system rocks_provided = { jit='${lua.luaversion}-1'; ffi='${lua.luaversion}-1'; luaffi='${lua.luaversion}-1'; bit='${lua.luaversion}-1'; } '' + '' -- For single-output external dependencies external_deps_dirs = { ${lib.concatStringsSep "\n, " externalDepsDirs} } variables = { -- Some needed machinery to handle multiple-output external dependencies, -- as per https://github.com/luarocks/luarocks/issues/766 ${lib.optionalString (lib.length depVariables > 0) '' ${lib.concatStringsSep "\n " depVariables}''} ${extraVariablesStr} } ''; jit = "${lua.luaversion}-1"; ffi = "${lua.luaversion}-1"; luaffi = "${lua.luaversion}-1"; bit = "${lua.luaversion}-1"; }; } // { # For single-output external dependencies external_deps_dirs = externalDepsDirs; # Some needed machinery to handle multiple-output external dependencies, # as per https://github.com/luarocks/luarocks/issues/766 variables = (depVariables // extraVariables); }); } Loading
lib/generators.nix +21 −3 Original line number Diff line number Diff line Loading @@ -434,6 +434,7 @@ ${expr "" v} Configuration: * multiline - by default is true which results in indented block-like view. * indent - initial indent. * asBindings - by default generate single value, but with this use attrset to set global vars. Attention: Regardless of multiline parameter there is no trailing newline. Loading Loading @@ -464,18 +465,35 @@ ${expr "" v} /* If this option is true, the output is indented with newlines for attribute sets and lists */ multiline ? true, /* Initial indentation level */ indent ? "" indent ? "", /* Interpret as variable bindings */ asBindings ? false, }@args: v: with builtins; let innerIndent = "${indent} "; introSpace = if multiline then "\n${innerIndent}" else " "; outroSpace = if multiline then "\n${indent}" else " "; innerArgs = args // { indent = innerIndent; }; innerArgs = args // { indent = if asBindings then indent else innerIndent; asBindings = false; }; concatItems = concatStringsSep ",${introSpace}"; isLuaInline = { _type ? null, ... }: _type == "lua-inline"; generatedBindings = assert lib.assertMsg (badVarNames == []) "Bad Lua var names: ${toPretty {} badVarNames}"; libStr.concatStrings ( lib.attrsets.mapAttrsToList (key: value: "${indent}${key} = ${toLua innerArgs value}\n") v ); # https://en.wikibooks.org/wiki/Lua_Programming/variable#Variable_names matchVarName = match "[[:alpha:]_][[:alnum:]_]*(\\.[[:alpha:]_][[:alnum:]_]*)*"; badVarNames = filter (name: matchVarName name == null) (attrNames v); in if v == null then if asBindings then generatedBindings else if v == null then "nil" else if isInt v || isFloat v || isString v || isBool v then builtins.toJSON v Loading
lib/tests/misc.nix +40 −0 Original line number Diff line number Diff line Loading @@ -4,6 +4,11 @@ with import ../default.nix; let testingThrow = expr: { expr = (builtins.tryEval (builtins.seq expr "didn't throw")); expected = { success = false; value = false; }; }; testingDeepThrow = expr: testingThrow (builtins.deepSeq expr expr); testSanitizeDerivationName = { name, expected }: let Loading Loading @@ -962,6 +967,41 @@ runTests { expected = ''{ 41, 43 }''; }; testToLuaEmptyBindings = { expr = generators.toLua { asBindings = true; } {}; expected = ""; }; testToLuaBindings = { expr = generators.toLua { asBindings = true; } { x1 = 41; _y = { a = 43; }; }; expected = '' _y = { ["a"] = 43 } x1 = 41 ''; }; testToLuaPartialTableBindings = { expr = generators.toLua { asBindings = true; } { "x.y" = 42; }; expected = '' x.y = 42 ''; }; testToLuaIndentedBindings = { expr = generators.toLua { asBindings = true; indent = " "; } { x = { y = 42; }; }; expected = " x = {\n [\"y\"] = 42\n }\n"; }; testToLuaBindingsWithSpace = testingThrow ( generators.toLua { asBindings = true; } { "with space" = 42; } ); testToLuaBindingsWithLeadingDigit = testingThrow ( generators.toLua { asBindings = true; } { "11eleven" = 42; } ); testToLuaBasicExample = { expr = generators.toLua {} { cmd = [ "typescript-language-server" "--stdio" ]; Loading
pkgs/development/lua-modules/lib.nix +35 −42 Original line number Diff line number Diff line { pkgs, lib, lua }: let inherit (lib.generators) toLua; requiredLuaModules = drvs: with lib; let modules = filter hasLuaModule drvs; in unique ([lua] ++ modules ++ concatLists (catAttrs "requiredLuaModules" modules)); Loading Loading @@ -88,58 +89,50 @@ rec { , rocksSubdir }: let rocksTrees = lib.imap0 (i: dep: "{ name = [[dep-${toString i}]], root = '${dep}', rocks_dir = '${dep}/${dep.rocksSubdir}' }") (i: dep: { name = "dep-${toString i}"; root = "${dep}"; rocks_dir = "${dep}/${dep.rocksSubdir}"; }) requiredLuaRocks; # Explicitly point luarocks to the relevant locations for multiple-output # derivations that are external dependencies, to work around an issue it has # (https://github.com/luarocks/luarocks/issues/766) depVariables = lib.concatMap ({name, dep}: [ "${name}_INCDIR='${lib.getDev dep}/include';" "${name}_LIBDIR='${lib.getLib dep}/lib';" "${name}_BINDIR='${lib.getBin dep}/bin';" ]) externalDeps'; depVariables = zipAttrsWithLast (lib.lists.map ({name, dep}: { "${name}_INCDIR" = "${lib.getDev dep}/include"; "${name}_LIBDIR" = "${lib.getLib dep}/lib"; "${name}_BINDIR" = "${lib.getBin dep}/bin"; }) externalDeps'); zipAttrsWithLast = lib.attrsets.zipAttrsWith (name: lib.lists.last); # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ] externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps; externalDepsDirs = map (x: "'${builtins.toString x}'") (x: builtins.toString x) (lib.filter (lib.isDerivation) externalDeps); extraVariablesStr = lib.concatStringsSep "\n " (lib.mapAttrsToList (k: v: "${k}='${v}';") extraVariables); in '' local_cache = "" -- To prevent collisions when creating environments, we install the rock -- files into per-package subdirectories rocks_subdir = '${rocksSubdir}' -- first tree is the default target where new rocks are installed, -- any other trees in the list are treated as additional sources of installed rocks for matching dependencies. rocks_trees = { {name = "current", root = '${placeholder "out"}', rocks_dir = "current" }, ${lib.concatStringsSep "\n, " rocksTrees} } '' + lib.optionalString lua.pkgs.isLuaJIT '' -- Luajit provides some additional functionality built-in; this exposes -- that to luarock's dependency system in toLua { asBindings = true; } ({ local_cache = ""; # To prevent collisions when creating environments, we install the rock # files into per-package subdirectories rocks_subdir = rocksSubdir; # first tree is the default target where new rocks are installed, # any other trees in the list are treated as additional sources of installed rocks for matching dependencies. rocks_trees = ( [{name = "current"; root = "${placeholder "out"}"; rocks_dir = "current"; }] ++ rocksTrees ); } // lib.optionalAttrs lua.pkgs.isLuaJIT { # Luajit provides some additional functionality built-in; this exposes # that to luarock's dependency system rocks_provided = { jit='${lua.luaversion}-1'; ffi='${lua.luaversion}-1'; luaffi='${lua.luaversion}-1'; bit='${lua.luaversion}-1'; } '' + '' -- For single-output external dependencies external_deps_dirs = { ${lib.concatStringsSep "\n, " externalDepsDirs} } variables = { -- Some needed machinery to handle multiple-output external dependencies, -- as per https://github.com/luarocks/luarocks/issues/766 ${lib.optionalString (lib.length depVariables > 0) '' ${lib.concatStringsSep "\n " depVariables}''} ${extraVariablesStr} } ''; jit = "${lua.luaversion}-1"; ffi = "${lua.luaversion}-1"; luaffi = "${lua.luaversion}-1"; bit = "${lua.luaversion}-1"; }; } // { # For single-output external dependencies external_deps_dirs = externalDepsDirs; # Some needed machinery to handle multiple-output external dependencies, # as per https://github.com/luarocks/luarocks/issues/766 variables = (depVariables // extraVariables); }); }