forked from Fediversity/Fediversity
generate-module-options-rebase #1
2 changed files with 97 additions and 0 deletions
53
panel/src/panel/configuration/to_module.py
Normal file
53
panel/src/panel/configuration/to_module.py
Normal file
|
@ -0,0 +1,53 @@
|
||||||
|
import json
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
# TODO(@fricklerhandwerk): mix this in as a method on the Pydantic Schema itself
|
||||||
|
def generate_module(schema, service_name):
|
||||||
|
properties = schema.get("properties", {})
|
||||||
|
required = schema.get("required", [])
|
||||||
|
|
||||||
|
options = []
|
||||||
|
for name, prop in properties.items():
|
||||||
|
nix_type = {
|
||||||
|
"string": "types.str",
|
||||||
|
"integer": "types.int",
|
||||||
|
"boolean": "types.bool"
|
||||||
|
}[prop["type"]]
|
||||||
|
|
||||||
|
desc = prop.get("description")
|
||||||
|
|
||||||
|
default = None
|
||||||
|
if name not in required and "default" in prop:
|
||||||
|
to_nix_value = {
|
||||||
|
"string": lambda v: f'"{v}"',
|
||||||
|
"boolean": lambda v: str(v).lower(),
|
||||||
|
"integer": lambda v: str(v),
|
||||||
|
"number": lambda v: str(v)
|
||||||
|
}
|
||||||
|
default = to_nix_value[prop["type"]](prop["default"])
|
||||||
|
|
||||||
|
option = textwrap.dedent(f"""
|
||||||
|
{name} = mkOption {{{f'''
|
||||||
|
description = "{desc}";''' if desc else ''}
|
||||||
|
type = {nix_type};{f'''
|
||||||
|
default = {default};''' if default is not None else ''}
|
||||||
|
}};
|
||||||
|
""")
|
||||||
|
|
||||||
|
options.append(option.strip())
|
||||||
|
|
||||||
|
module = textwrap.dedent(f"""
|
||||||
|
{{ lib, ... }}:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.{service_name};
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
in
|
||||||
|
{{
|
||||||
|
options.services.{service_name} = {{
|
||||||
|
{textwrap.indent("\n\n".join(options), ' ').strip()}
|
||||||
|
}};
|
||||||
|
}}
|
||||||
|
""")
|
||||||
|
|
||||||
|
return module
|
44
panel/src/panel/tests/test_to_module.py
Normal file
44
panel/src/panel/tests/test_to_module.py
Normal file
|
@ -0,0 +1,44 @@
|
||||||
|
from django.test import TestCase
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
import textwrap
|
||||||
|
|
||||||
|
from panel.configuration import to_module
|
||||||
|
|
||||||
|
|
||||||
|
class ConvertToModule(TestCase):
|
||||||
|
def test_minimal_module(self):
|
||||||
|
class Example(BaseModel):
|
||||||
|
name: str = Field(..., description="Service name")
|
||||||
|
port: int = Field(8080)
|
||||||
|
enable: bool = Field(True, description="Enable service")
|
||||||
|
|
||||||
|
expected = textwrap.dedent("""
|
||||||
|
{ lib, ... }:
|
||||||
|
|
||||||
|
let
|
||||||
|
cfg = config.services.myservice;
|
||||||
|
inherit (lib) mkOption types;
|
||||||
|
in
|
||||||
|
{
|
||||||
|
options.services.myservice = {
|
||||||
|
name = mkOption {
|
||||||
|
description = "Service name";
|
||||||
|
type = types.str;
|
||||||
|
};
|
||||||
|
|
||||||
|
port = mkOption {
|
||||||
|
type = types.int;
|
||||||
|
default = 8080;
|
||||||
|
};
|
||||||
|
|
||||||
|
enable = mkOption {
|
||||||
|
description = "Enable service";
|
||||||
|
type = types.bool;
|
||||||
|
default = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
|
""")
|
||||||
|
|
||||||
|
actual = to_module.generate_module(Example.schema(), "myservice")
|
||||||
|
self.assertEqual(actual, expected)
|
Loading…
Add table
Reference in a new issue