lol

Merge pull request #227714 from ony/feature/generateLuarocksConfig-toLua

lua.lib: use toLua in generateLuarocksConfig

authored by

Matthieu Coudron and committed by
GitHub
8670e496 68378870

+96 -45
+21 -3
lib/generators.nix
··· 434 434 Configuration: 435 435 * multiline - by default is true which results in indented block-like view. 436 436 * indent - initial indent. 437 + * asBindings - by default generate single value, but with this use attrset to set global vars. 437 438 438 439 Attention: 439 440 Regardless of multiline parameter there is no trailing newline. ··· 464 465 /* If this option is true, the output is indented with newlines for attribute sets and lists */ 465 466 multiline ? true, 466 467 /* Initial indentation level */ 467 - indent ? "" 468 + indent ? "", 469 + /* Interpret as variable bindings */ 470 + asBindings ? false, 468 471 }@args: v: 469 472 with builtins; 470 473 let 471 474 innerIndent = "${indent} "; 472 475 introSpace = if multiline then "\n${innerIndent}" else " "; 473 476 outroSpace = if multiline then "\n${indent}" else " "; 474 - innerArgs = args // { indent = innerIndent; }; 477 + innerArgs = args // { 478 + indent = if asBindings then indent else innerIndent; 479 + asBindings = false; 480 + }; 475 481 concatItems = concatStringsSep ",${introSpace}"; 476 482 isLuaInline = { _type ? null, ... }: _type == "lua-inline"; 483 + 484 + generatedBindings = 485 + assert lib.assertMsg (badVarNames == []) "Bad Lua var names: ${toPretty {} badVarNames}"; 486 + libStr.concatStrings ( 487 + lib.attrsets.mapAttrsToList (key: value: "${indent}${key} = ${toLua innerArgs value}\n") v 488 + ); 489 + 490 + # https://en.wikibooks.org/wiki/Lua_Programming/variable#Variable_names 491 + matchVarName = match "[[:alpha:]_][[:alnum:]_]*(\\.[[:alpha:]_][[:alnum:]_]*)*"; 492 + badVarNames = filter (name: matchVarName name == null) (attrNames v); 477 493 in 478 - if v == null then 494 + if asBindings then 495 + generatedBindings 496 + else if v == null then 479 497 "nil" 480 498 else if isInt v || isFloat v || isString v || isBool v then 481 499 builtins.toJSON v
+40
lib/tests/misc.nix
··· 4 4 with import ../default.nix; 5 5 6 6 let 7 + testingThrow = expr: { 8 + expr = (builtins.tryEval (builtins.seq expr "didn't throw")); 9 + expected = { success = false; value = false; }; 10 + }; 11 + testingDeepThrow = expr: testingThrow (builtins.deepSeq expr expr); 7 12 8 13 testSanitizeDerivationName = { name, expected }: 9 14 let ··· 961 966 expr = generators.toLua { multiline = false; } [ 41 43 ]; 962 967 expected = ''{ 41, 43 }''; 963 968 }; 969 + 970 + testToLuaEmptyBindings = { 971 + expr = generators.toLua { asBindings = true; } {}; 972 + expected = ""; 973 + }; 974 + 975 + testToLuaBindings = { 976 + expr = generators.toLua { asBindings = true; } { x1 = 41; _y = { a = 43; }; }; 977 + expected = '' 978 + _y = { 979 + ["a"] = 43 980 + } 981 + x1 = 41 982 + ''; 983 + }; 984 + 985 + testToLuaPartialTableBindings = { 986 + expr = generators.toLua { asBindings = true; } { "x.y" = 42; }; 987 + expected = '' 988 + x.y = 42 989 + ''; 990 + }; 991 + 992 + testToLuaIndentedBindings = { 993 + expr = generators.toLua { asBindings = true; indent = " "; } { x = { y = 42; }; }; 994 + expected = " x = {\n [\"y\"] = 42\n }\n"; 995 + }; 996 + 997 + testToLuaBindingsWithSpace = testingThrow ( 998 + generators.toLua { asBindings = true; } { "with space" = 42; } 999 + ); 1000 + 1001 + testToLuaBindingsWithLeadingDigit = testingThrow ( 1002 + generators.toLua { asBindings = true; } { "11eleven" = 42; } 1003 + ); 964 1004 965 1005 testToLuaBasicExample = { 966 1006 expr = generators.toLua {} {
+35 -42
pkgs/development/lua-modules/lib.nix
··· 1 1 { pkgs, lib, lua }: 2 2 let 3 + inherit (lib.generators) toLua; 3 4 requiredLuaModules = drvs: with lib; let 4 5 modules = filter hasLuaModule drvs; 5 6 in unique ([lua] ++ modules ++ concatLists (catAttrs "requiredLuaModules" modules)); ··· 88 89 , rocksSubdir 89 90 }: let 90 91 rocksTrees = lib.imap0 91 - (i: dep: "{ name = [[dep-${toString i}]], root = '${dep}', rocks_dir = '${dep}/${dep.rocksSubdir}' }") 92 + (i: dep: { name = "dep-${toString i}"; root = "${dep}"; rocks_dir = "${dep}/${dep.rocksSubdir}"; }) 92 93 requiredLuaRocks; 93 94 94 95 # Explicitly point luarocks to the relevant locations for multiple-output 95 96 # derivations that are external dependencies, to work around an issue it has 96 97 # (https://github.com/luarocks/luarocks/issues/766) 97 - depVariables = lib.concatMap ({name, dep}: [ 98 - "${name}_INCDIR='${lib.getDev dep}/include';" 99 - "${name}_LIBDIR='${lib.getLib dep}/lib';" 100 - "${name}_BINDIR='${lib.getBin dep}/bin';" 101 - ]) externalDeps'; 98 + depVariables = zipAttrsWithLast (lib.lists.map ({name, dep}: { 99 + "${name}_INCDIR" = "${lib.getDev dep}/include"; 100 + "${name}_LIBDIR" = "${lib.getLib dep}/lib"; 101 + "${name}_BINDIR" = "${lib.getBin dep}/bin"; 102 + }) externalDeps'); 103 + zipAttrsWithLast = lib.attrsets.zipAttrsWith (name: lib.lists.last); 102 104 103 105 # example externalDeps': [ { name = "CRYPTO"; dep = pkgs.openssl; } ] 104 106 externalDeps' = lib.filter (dep: !lib.isDerivation dep) externalDeps; 105 107 106 108 externalDepsDirs = map 107 - (x: "'${builtins.toString x}'") 109 + (x: builtins.toString x) 108 110 (lib.filter (lib.isDerivation) externalDeps); 109 - 110 - extraVariablesStr = lib.concatStringsSep "\n " 111 - (lib.mapAttrsToList (k: v: "${k}='${v}';") extraVariables); 112 - in '' 113 - local_cache = "" 114 - -- To prevent collisions when creating environments, we install the rock 115 - -- files into per-package subdirectories 116 - rocks_subdir = '${rocksSubdir}' 117 - -- first tree is the default target where new rocks are installed, 118 - -- any other trees in the list are treated as additional sources of installed rocks for matching dependencies. 119 - rocks_trees = { 120 - {name = "current", root = '${placeholder "out"}', rocks_dir = "current" }, 121 - ${lib.concatStringsSep "\n, " rocksTrees} 122 - } 123 - '' + lib.optionalString lua.pkgs.isLuaJIT '' 124 - -- Luajit provides some additional functionality built-in; this exposes 125 - -- that to luarock's dependency system 111 + in toLua { asBindings = true; } ({ 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 + # first tree is the default target where new rocks are installed, 117 + # any other trees in the list are treated as additional sources of installed rocks for matching dependencies. 118 + rocks_trees = ( 119 + [{name = "current"; root = "${placeholder "out"}"; rocks_dir = "current"; }] ++ 120 + rocksTrees 121 + ); 122 + } // lib.optionalAttrs lua.pkgs.isLuaJIT { 123 + # Luajit provides some additional functionality built-in; this exposes 124 + # that to luarock's dependency system 126 125 rocks_provided = { 127 - jit='${lua.luaversion}-1'; 128 - ffi='${lua.luaversion}-1'; 129 - luaffi='${lua.luaversion}-1'; 130 - bit='${lua.luaversion}-1'; 131 - } 132 - '' + '' 133 - -- For single-output external dependencies 134 - external_deps_dirs = { 135 - ${lib.concatStringsSep "\n, " externalDepsDirs} 136 - } 137 - variables = { 138 - -- Some needed machinery to handle multiple-output external dependencies, 139 - -- as per https://github.com/luarocks/luarocks/issues/766 140 - ${lib.optionalString (lib.length depVariables > 0) '' 141 - ${lib.concatStringsSep "\n " depVariables}''} 142 - ${extraVariablesStr} 143 - } 144 - ''; 126 + jit = "${lua.luaversion}-1"; 127 + ffi = "${lua.luaversion}-1"; 128 + luaffi = "${lua.luaversion}-1"; 129 + bit = "${lua.luaversion}-1"; 130 + }; 131 + } // { 132 + # For single-output external dependencies 133 + external_deps_dirs = externalDepsDirs; 134 + # Some needed machinery to handle multiple-output external dependencies, 135 + # as per https://github.com/luarocks/luarocks/issues/766 136 + variables = (depVariables // extraVariables); 137 + }); 145 138 }