From 078b938606cc5273002ac97bb47b711ccd0f6e4d Mon Sep 17 00:00:00 2001 From: cinereal Date: Sat, 21 Jun 2025 11:03:18 +0200 Subject: [PATCH] add toml flesh out toml move function restore translations for ini source escaping rules tests pass --- flake.nix | 1 + lib.nix | 40 +++++++++++++++++++++++++++++++++------- tests/toml.nix | 41 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 75 insertions(+), 7 deletions(-) create mode 100644 tests/toml.nix diff --git a/flake.nix b/flake.nix index 3ead877..3da1f9a 100644 --- a/flake.nix +++ b/flake.nix @@ -21,6 +21,7 @@ checks = nixpkgs.lib.genAttrs supportedArchitectures (system: { template = import ./tests/template.nix { inherit legacyPackages system nixpkgs; }; json = import ./tests/json.nix { inherit legacyPackages system nixpkgs; }; + toml = import ./tests/toml.nix { inherit legacyPackages system nixpkgs; }; }); }; } diff --git a/lib.nix b/lib.nix index 9f73a0a..946c920 100644 --- a/lib.nix +++ b/lib.nix @@ -16,7 +16,7 @@ rec { file = file; }; - # make a template with placeholders + # make a template with placeholders from a text templateText = { name, text, outPath, translations ? {} }: pkgs.runCommand name { textBeforeTemplate = text; @@ -32,15 +32,41 @@ rec { chmod +x $out/bin/${name} ''; - templateGenerator = translations: generator: { name, value, outPath }: templateText { + # make a template with placeholders from a file + templateFromFile = { name, templateFile, outPath, translations ? {} }: + pkgs.runCommand name { + inherit templateFile; + script = '' + #!/bin/sh + ${nix_templater}/bin/nix_templater ${builtins.placeholder "out"}/template ${builtins.placeholder "nix_template"} "${outPath}" '${lib.strings.toJSON translations}' + ''; + passAsFile = [ "script" ]; + } '' + mkdir -p $out/bin + cp $templateFile $out/template + cp $scriptPath $out/bin/${name} + chmod +x $out/bin/${name} + ''; + + translateFile = translations: generator: { name, value, outPath }: templateFromFile { + inherit name outPath translations; + templateFile = generator value; + }; + + translateText = translations: generator: { name, value, outPath }: templateText { inherit name outPath translations; text = generator value; }; - templateJsonWith = options: templateGenerator escapeJson (lib.generators.toJSON options); - templateYamlWith = options: templateGenerator escapeJson (lib.generators.toYAML options); # just json - templateIniWith = options: templateGenerator escapeJson (lib.generators.toINI options); - templateJson = templateJsonWith { }; - templateYaml = templateYamlWith { }; + # escaping: https://www.json.org/json-en.html + templateJson = translateFile escapeJson (pkgs.writers.writeJSON "template.json"); + # just json + templateYaml = translateFile escapeJson (pkgs.writers.writeYAML "template.yaml"); + # escaping: technically also control characters (U+0000 to U+001F): https://toml.io/en/v0.3.0#string + templateToml = translateFile escapeJson (pkgs.writers.writeTOML "template.toml"); + + # escaping: https://git.kernel.org/pub/scm/git/git.git/tree/Documentation/config.txt?id=a54a84b333adbecf7bc4483c0e36ed5878cac17b#n47 + templateIniWith = options: translateText escapeJson (lib.generators.toINI options); + templateIni = templateIniWith { }; } diff --git a/tests/toml.nix b/tests/toml.nix new file mode 100644 index 0000000..b8edc6c --- /dev/null +++ b/tests/toml.nix @@ -0,0 +1,41 @@ +# test injecting a secret into a toml template +{ legacyPackages, system, nixpkgs }: +let + hostPkgs = nixpkgs.legacyPackages.${system}; + secret_file = hostPkgs.writeText "secret" "secret\\needing\"escaping"; +in (nixpkgs.lib.nixos.runTest { + inherit hostPkgs; + name = "nix_templates"; + + nodes.machine = {pkgs, ...}: { + config = { + systemd.services.testservice = { + wantedBy = [ "multi-user.target" ]; + serviceConfig = { + Type = "oneshot"; + ExecStartPre = "${legacyPackages.${system}.templateToml { + name = "test"; + value = { + foo = "text"; + bar = legacyPackages.${system}.fileContents secret_file; + }; + outPath = "./test"; + }}/bin/test"; + ExecStart = pkgs.writeScript "test_file_got_templates" '' + #!/bin/sh + cat ./test | grep -q 'secret' + ''; + }; + }; + }; + }; + + testScript = '' + start_all() + print(machine.execute("uname -a")) + machine.wait_for_unit("multi-user.target") + print(machine.succeed("cat /test")) + print(machine.succeed("cat /test | grep -q secret")) + # print(machine.succeed("cat /test | ${hostPkgs.jq}/bin/jq")) + ''; + })