Skip to content

Commit 30358ab

Browse files
authored
formats.lua: init; types.luaInline: init (#390120)
2 parents a84ebe2 + 2611d5b commit 30358ab

File tree

8 files changed

+184
-3
lines changed

8 files changed

+184
-3
lines changed

lib/default.nix

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -156,6 +156,7 @@ let
156156
makeScope makeScopeWithSplicing makeScopeWithSplicing'
157157
extendMkDerivation;
158158
inherit (self.derivations) lazyDerivation optionalDrvAttr warnOnInstantiate;
159+
inherit (self.generators) mkLuaInline;
159160
inherit (self.meta) addMetaAttrs dontDistribute setName updateName
160161
appendToName mapDerivationAttrset setPrio lowPrio lowPrioSet hiPrio
161162
hiPrioSet licensesSpdx getLicenseFromSpdxId getLicenseFromSpdxIdOr

lib/generators.nix

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -743,6 +743,8 @@ in rec {
743743
"nil"
744744
else if isInt v || isFloat v || isString v || isBool v then
745745
toJSON v
746+
else if isPath v || isDerivation v then
747+
toJSON "${v}"
746748
else if isList v then
747749
(if v == [ ] then "{}" else
748750
"{${introSpace}${concatItems (map (value: "${toLua innerArgs value}") v)}${outroSpace}}")
@@ -752,8 +754,6 @@ in rec {
752754
"(${v.expr})"
753755
else if v == { } then
754756
"{}"
755-
else if isDerivation v then
756-
''"${toString v}"''
757757
else
758758
"{${introSpace}${concatItems (
759759
mapAttrsToList (key: value: "[${toJSON key}] = ${toLua innerArgs value}") v

lib/types.nix

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,15 @@ rec {
834834
};
835835
};
836836

837+
# A value produced by `lib.mkLuaInline`
838+
luaInline = mkOptionType {
839+
name = "luaInline";
840+
description = "inline lua";
841+
descriptionClass = "noun";
842+
check = x: x._type or null == "lua-inline";
843+
merge = mergeEqualOption;
844+
};
845+
837846
uniq = unique { message = ""; };
838847

839848
unique = { message }: type: mkOptionType rec {

nixos/doc/manual/development/option-types.section.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -232,6 +232,13 @@ merging is handled.
232232
definitions cannot be merged. The regular expression is processed
233233
using `builtins.match`.
234234

235+
### Specialised types {#sec-option-types-specialised}
236+
237+
`types.luaInline`
238+
239+
: A string wrapped using `lib.mkLuaInline`. Allows embedding lua expressions
240+
inline within generated lua. Multiple definitions cannot be merged.
241+
235242
## Submodule types {#sec-option-types-submodule}
236243

237244
Submodules are detailed in [Submodule](#section-option-types-submodule).

nixos/doc/manual/development/settings-options.section.md

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -402,6 +402,31 @@ have a predefined type and string generator already declared under
402402
: Outputs the given attribute set as an Elixir map, instead of the
403403
default Elixir keyword list
404404

405+
`pkgs.formats.lua { asBindings ? false, multiline ? true, columnWidth ? 100, indentWidth ? 2, indentUsingTabs ? false }`
406+
407+
: A function taking an attribute set with values
408+
409+
`asBindings` (default `false`)
410+
411+
: Whether to treat attributes as variable bindings
412+
413+
`multiline` (default `true`)
414+
415+
: Whether to procude a multiline output. The output may still wrap across
416+
multiple lines if it would otherwise exceed `columnWidth`.
417+
418+
`columnWidth` (default `100`)
419+
420+
: The column width to use to attempt to wrap lines.
421+
422+
`indentWidth` (default `2`)
423+
424+
: The width of a single indentation level.
425+
426+
`indentUsingTabs` (default `false`)
427+
428+
: Whether the indentation should use tabs instead of spaces.
429+
405430
`pkgs.formats.php { finalVariable }` []{#pkgs-formats-php}
406431

407432
: A function taking an attribute set with values

nixos/doc/manual/redirects.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,9 @@
15921592
"sec-option-types-string": [
15931593
"index.html#sec-option-types-string"
15941594
],
1595+
"sec-option-types-specialised": [
1596+
"index.html#sec-option-types-specialised"
1597+
],
15951598
"sec-option-types-submodule": [
15961599
"index.html#sec-option-types-submodule"
15971600
],

pkgs/pkgs-lib/formats.nix

Lines changed: 61 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ rec {
4747

4848
inherit (lib) mkOptionType;
4949
inherit (lib.types) nullOr oneOf coercedTo listOf nonEmptyListOf attrsOf either;
50-
inherit (lib.types) bool int float str path;
50+
inherit (lib.types) bool int float str path luaInline;
5151

5252
json = {}: {
5353

@@ -541,6 +541,66 @@ rec {
541541
'';
542542
};
543543

544+
lua =
545+
{
546+
asBindings ? false,
547+
multiline ? true,
548+
columnWidth ? 100,
549+
indentWidth ? 2,
550+
indentUsingTabs ? false,
551+
}:
552+
{
553+
type =
554+
let
555+
valueType =
556+
nullOr (oneOf [
557+
bool
558+
float
559+
int
560+
path
561+
str
562+
luaInline
563+
(attrsOf valueType)
564+
(listOf valueType)
565+
])
566+
// {
567+
description = "lua value";
568+
descriptionClass = "noun";
569+
};
570+
in
571+
if asBindings then attrsOf valueType else valueType;
572+
generate =
573+
name: value:
574+
pkgs.callPackage (
575+
{ runCommand, stylua }:
576+
runCommand name
577+
{
578+
nativeBuildInputs = [ stylua ];
579+
inherit columnWidth;
580+
inherit indentWidth;
581+
indentType = if indentUsingTabs then "Tabs" else "Spaces";
582+
value = lib.generators.toLua { inherit asBindings multiline; } value;
583+
passAsFile = [ "value" ];
584+
preferLocalBuild = true;
585+
}
586+
''
587+
${lib.optionalString (!asBindings) ''
588+
echo -n 'return ' >> $out
589+
''}
590+
cat $valuePath >> $out
591+
stylua \
592+
--no-editorconfig \
593+
--line-endings Unix \
594+
--column-width $columnWidth \
595+
--indent-width $indentWidth \
596+
--indent-type $indentType \
597+
$out
598+
''
599+
) { };
600+
# Alias for mkLuaInline
601+
lib.mkRaw = lib.mkLuaInline;
602+
};
603+
544604
# Outputs a succession of Python variable assignments
545605
# Useful for many Django-based services
546606
pythonVars = {}: {

pkgs/pkgs-lib/tests/formats.nix

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -601,6 +601,82 @@ in runBuildTests {
601601
'';
602602
};
603603

604+
luaTable = shouldPass {
605+
format = formats.lua { };
606+
input = {
607+
null = null;
608+
false = false;
609+
true = true;
610+
int = 10;
611+
float = 3.141;
612+
str = "foo";
613+
attrs.foo = null;
614+
list = [
615+
null
616+
null
617+
];
618+
path = ./testfile;
619+
inline = lib.mkLuaInline "hello('world')";
620+
};
621+
expected = ''
622+
return {
623+
["attrs"] = {
624+
["foo"] = nil,
625+
},
626+
["false"] = false,
627+
["float"] = 3.141,
628+
["inline"] = (hello("world")),
629+
["int"] = 10,
630+
["list"] = {
631+
nil,
632+
nil,
633+
},
634+
["null"] = nil,
635+
["path"] = "${./testfile}",
636+
["str"] = "foo",
637+
["true"] = true,
638+
}
639+
'';
640+
};
641+
642+
luaBindings = shouldPass {
643+
format = formats.lua {
644+
asBindings = true;
645+
};
646+
input = {
647+
null = null;
648+
_false = false;
649+
_true = true;
650+
int = 10;
651+
float = 3.141;
652+
str = "foo";
653+
attrs.foo = null;
654+
list = [
655+
null
656+
null
657+
];
658+
path = ./testfile;
659+
inline = lib.mkLuaInline "hello('world')";
660+
};
661+
expected = ''
662+
_false = false
663+
_true = true
664+
attrs = {
665+
["foo"] = nil,
666+
}
667+
float = 3.141
668+
inline = (hello("world"))
669+
int = 10
670+
list = {
671+
nil,
672+
nil,
673+
}
674+
null = nil
675+
path = "${./testfile}"
676+
str = "foo"
677+
'';
678+
};
679+
604680
phpAtoms = shouldPass rec {
605681
format = formats.php { finalVariable = "config"; };
606682
input = {

0 commit comments

Comments
 (0)