Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

pkgs/formats: add generator for PHP config files #311299

Merged
merged 1 commit into from
May 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions nixos/doc/manual/development/settings-options.section.md
Original file line number Diff line number Diff line change
Expand Up @@ -146,6 +146,27 @@ have a predefined type and string generator already declared under
: Outputs the given attribute set as an Elixir map, instead of the
default Elixir keyword list

`pkgs.formats.php { finalVariable }` []{#pkgs-formats-php}

: A function taking an attribute set with values

`finalVariable`

: The variable that will store generated expression (usually `config`). If set to `null`, generated expression will contain `return`.

It returns a set with PHP-Config-specific attributes `type`, `lib`, and
`generate` as specified [below](#pkgs-formats-result).

The `lib` attribute contains functions to be used in settings, for
generating special PHP values:

`mkRaw phpCode`

: Outputs the given string as raw PHP code

`mkMixedArray list set`
thenhnn marked this conversation as resolved.
Show resolved Hide resolved

: Creates PHP array that contains both indexed and associative values. For example, `lib.mkMixedArray [ "hello" "world" ] { "nix" = "is-great"; }` returns `['hello', 'world', 'nix' => 'is-great']`

[]{#pkgs-formats-result}
These functions all return an attribute set with these values:
Expand Down
2 changes: 2 additions & 0 deletions pkgs/pkgs-lib/formats.nix
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ rec {

hocon = (import ./formats/hocon/default.nix { inherit lib pkgs; }).format;

php = (import ./formats/php/default.nix { inherit lib pkgs; }).format;

json = {}: {

type = with lib.types; let
Expand Down
69 changes: 69 additions & 0 deletions pkgs/pkgs-lib/formats/php/default.nix
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
{pkgs, lib}: {
# Format for defining configuration of some PHP services, that use "include 'config.php';" approach.
format = {finalVariable ? null}: let
toPHP = value: {
"null" = "null";
"bool" = if value then "true" else "false";
"int" = toString value;
"float" = toString value;
"string" = string value;
"set" = attrs value;
"list" = list value;
}
.${builtins.typeOf value} or
(abort "should never happen: unknown value type ${builtins.typeOf value}");

# https://www.php.net/manual/en/language.types.string.php#language.types.string.syntax.single
escapeSingleQuotedString = lib.escape [ "'" "\\" ];
string = value: "'${escapeSingleQuotedString value}'";
thenhnn marked this conversation as resolved.
Show resolved Hide resolved

listContent = values: lib.concatStringsSep ", " (map toPHP values);
list = values: "[" + (listContent values) + "]";

attrsContent = values: lib.pipe values [
(lib.mapAttrsToList (k: v: "${toPHP k} => ${toPHP v}"))
(lib.concatStringsSep ", ")
];
attrs = set:
if set ? _phpType then specialType set
else
"[" + attrsContent set + "]";

mixedArray = {list, set}: if list == [] then attrs set else "[${listContent list}, ${attrsContent set}]";

specialType = {value, _phpType}: {
"mixed_array" = mixedArray value;
"raw" = value;
}.${_phpType};

type = with lib.types;
nullOr (oneOf [
bool
int
float
str
(attrsOf type)
(listOf type)
])
// {
description = "PHP value";
};
in {

inherit type;

lib = {
mkMixedArray = list: set: {_phpType = "mixed_array"; value = { inherit list set;}; };
mkRaw = raw: {_phpType = "raw"; value = raw;};
};

generate = name: value: pkgs.writeTextFile {
inherit name;
text = let
# strict_types enabled here to easily debug problems when calling functions of incorrect type using `mkRaw`.
phpHeader = "<?php\ndeclare(strict_types=1);\n";
thenhnn marked this conversation as resolved.
Show resolved Hide resolved
in if finalVariable == null then phpHeader + "return ${toPHP value};\n" else phpHeader + "\$${finalVariable} = ${toPHP value};\n";
};

};
}
44 changes: 44 additions & 0 deletions pkgs/pkgs-lib/tests/formats.nix
Original file line number Diff line number Diff line change
Expand Up @@ -425,4 +425,48 @@ in runBuildTests {
\u0627\u0644\u062c\u0628\u0631 = \u0623\u0643\u062b\u0631 \u0645\u0646 \u0645\u062c\u0631\u062f \u0623\u0631\u0642\u0627\u0645
'';
};

phpAtoms = shouldPass rec {
format = formats.php { finalVariable = "config"; };
input = {
null = null;
false = false;
true = true;
int = 10;
float = 3.141;
str = "foo";
str_special = "foo\ntesthello'''";
attrs.foo = null;
thenhnn marked this conversation as resolved.
Show resolved Hide resolved
list = [ null null ];
mixed = format.lib.mkMixedArray [ 10 3.141 ] {
str = "foo";
attrs.foo = null;
};
raw = format.lib.mkRaw "random_function()";
};
expected = ''
<?php
declare(strict_types=1);
$config = ['attrs' => ['foo' => null], 'false' => false, 'float' => 3.141000, 'int' => 10, 'list' => [null, null], 'mixed' => [10, 3.141000, 'attrs' => ['foo' => null], 'str' => 'foo'], 'null' => null, 'raw' => random_function(), 'str' => 'foo', 'str_special' => 'foo
testhello\'\'\'${"'"}, 'true' => true];
'';
};

phpReturn = shouldPass {
format = formats.php { };
input = {
int = 10;
float = 3.141;
str = "foo";
str_special = "foo\ntesthello'''";
attrs.foo = null;
};
expected = ''
<?php
declare(strict_types=1);
return ['attrs' => ['foo' => null], 'float' => 3.141000, 'int' => 10, 'str' => 'foo', 'str_special' => 'foo
testhello\'\'\'${"'"}];
'';
};

}