From 9e3a95ba24dab59ad471629d887bfb2d0e2ff027 Mon Sep 17 00:00:00 2001 From: Gabriel Arazas Date: Sun, 9 Jun 2024 23:03:26 +0800 Subject: [PATCH] lib/data: init --- lib/data.nix | 47 ++++++++++++++++++++++++++++ lib/default.nix | 7 ++++- tests/lib/data/data/sample.json | 9 ++++++ tests/lib/data/data/sample.yaml | 6 ++++ tests/lib/data/default.nix | 33 +++++++++++++++++++ tests/lib/data/fixtures/sample.tera | 1 + tests/lib/data/templates/sample.tera | 1 + tests/lib/default.nix | 1 + 8 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 lib/data.nix create mode 100644 tests/lib/data/data/sample.json create mode 100644 tests/lib/data/data/sample.yaml create mode 100644 tests/lib/data/default.nix create mode 100644 tests/lib/data/fixtures/sample.tera create mode 100644 tests/lib/data/templates/sample.tera diff --git a/lib/data.nix b/lib/data.nix new file mode 100644 index 00000000..74688f28 --- /dev/null +++ b/lib/data.nix @@ -0,0 +1,47 @@ +# Anything that has to do with interacting with data especially with external +# ones (that is, anything that is not represented as a Nix object). +# Unfortunately, most of these functions are surely going to use packages found +# in nixpkgs so expect a lot of them are used as an IFD. +{ pkgs, lib, self }: + +{ + /* Import the YAML file and return it as a Nix object. Unfortunately, this is + implemented as an import-from-derivation (IFD) so it will not be pretty. + + Type: importYAML :: Path -> Attrs + + Example: + importYAML ./your-mom.yaml + => { name = "Yor Mum"; age = 56; world = "Herown"; } + */ + importYAML = path: + let + dataDrv = pkgs.runCommand "convert-yaml-to-json" { } '' + ${lib.getExe' pkgs.yaml2json "yaml2json"} < "${path}" > "$out" + ''; + in lib.importJSON dataDrv; + + /* Render a Tera template given a parameter set powered by `tera-cli`. Also + typically used as an IFD. + + Type: renderTeraTemplate :: Attrs -> Path + + Example: + renderTeraTemplate { path = ./template.tera; context = { hello = 34; }; } + => /nix/store/HASH-tera-render-template + */ + renderTeraTemplate = { template, context, extraArgs ? { } }: + let + extraArgs' = lib.cli.toGNUCommandLineShell { } extraArgs; + + # Take note we're generating the context file in this way since tera-cli + # can only detect them through its file extension and doesn't have a way + # of explicitly reading files as JSON, YAML, etc. + settingsFormat = pkgs.formats.json { }; + contextFile = settingsFormat.generate "tera-context.json" context; + in pkgs.runCommand "tera-render-template" { + nativeBuildInputs = with pkgs; [ tera-cli ]; + } '' + tera --out "$out" ${extraArgs'} --template "${template}" "${contextFile}" + ''; +} diff --git a/lib/default.nix b/lib/default.nix index 2c42167b..04613909 100644 --- a/lib/default.nix +++ b/lib/default.nix @@ -1,4 +1,7 @@ -# The entrypoint for our custom library set. +# The entrypoint for our custom library set. Take note, this is modularly +# included as part of the environment so we cannot have any functions or +# references that could make the evaluation go in an infinite recursion such as +# a function that generates a valid nixpkgs module. { pkgs }: pkgs.lib.makeExtensible @@ -8,6 +11,8 @@ pkgs.lib.makeExtensible callLib = file: import file { inherit pkgs lib self; }; in { trivial = callLib ./trivial.nix; + data = callLib ./data.nix; inherit (self.trivial) countAttrs getConfig getUser; + inherit (self.data) importYAML renderTeraTemplate; }) diff --git a/tests/lib/data/data/sample.json b/tests/lib/data/data/sample.json new file mode 100644 index 00000000..742222ae --- /dev/null +++ b/tests/lib/data/data/sample.json @@ -0,0 +1,9 @@ +{ + "hello": "world", + "whoa": 4566, + "list-of-names": [ + "Cheesy", + "Angry", + "Ash" + ] +} diff --git a/tests/lib/data/data/sample.yaml b/tests/lib/data/data/sample.yaml new file mode 100644 index 00000000..25c95e60 --- /dev/null +++ b/tests/lib/data/data/sample.yaml @@ -0,0 +1,6 @@ +hello: world +whoa: 4566 +list-of-names: + - Cheesy + - Angry + - Ash diff --git a/tests/lib/data/default.nix b/tests/lib/data/default.nix new file mode 100644 index 00000000..d647a9a4 --- /dev/null +++ b/tests/lib/data/default.nix @@ -0,0 +1,33 @@ +{ pkgs, lib, self }: + +lib.runTests { + testImportYAML = { + expr = self.data.importYAML ./data/sample.yaml; + expected = { + hello = "world"; + whoa = 4566; + list-of-names = [ + "Cheesy" "Angry" "Ash" + ]; + }; + }; + + testImportYAMLAsJSON = { + expr = self.data.importYAML ./data/sample.json; + expected = { + hello = "world"; + whoa = 4566; + list-of-names = [ + "Cheesy" "Angry" "Ash" + ]; + }; + }; + + testRenderTeraTemplate = { + expr = builtins.readFile (self.data.renderTeraTemplate { + template = ./templates/sample.tera; + context = lib.importJSON ./data/sample.json; + }); + expected = builtins.readFile ./fixtures/sample.tera; + }; +} diff --git a/tests/lib/data/fixtures/sample.tera b/tests/lib/data/fixtures/sample.tera new file mode 100644 index 00000000..cc628ccd --- /dev/null +++ b/tests/lib/data/fixtures/sample.tera @@ -0,0 +1 @@ +world diff --git a/tests/lib/data/templates/sample.tera b/tests/lib/data/templates/sample.tera new file mode 100644 index 00000000..8fe25f99 --- /dev/null +++ b/tests/lib/data/templates/sample.tera @@ -0,0 +1 @@ +{{ hello }} diff --git a/tests/lib/default.nix b/tests/lib/default.nix index 0e8a3a35..1d966475 100644 --- a/tests/lib/default.nix +++ b/tests/lib/default.nix @@ -18,6 +18,7 @@ let in { trivial = callLib ./trivial.nix; + data = callLib ./data; # Environment-specific subset. home-manager = callLib ./home-manager.nix;