From 9014804e2c7778e1aaa61f983557680ac563b8a6 Mon Sep 17 00:00:00 2001 From: Profpatsch Date: Sun, 27 Feb 2022 12:32:23 +0100 Subject: feat(users/Profpatsch): add importDhall MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Makes it possible to import a dhall file as a nix expression (at IfD time), embedding dhall into nix. There’s some setup for adding dhall dependencies as well, but it hasn’t been really battle-tested yet. Change-Id: I3e5670f93c612f2eb530d7c65d6bb4b1bf7bd8bd Reviewed-on: https://cl.tvl.fyi/c/depot/+/5333 Reviewed-by: Profpatsch Tested-by: BuildkiteCI --- users/Profpatsch/importDhall.nix | 78 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 users/Profpatsch/importDhall.nix (limited to 'users/Profpatsch') diff --git a/users/Profpatsch/importDhall.nix b/users/Profpatsch/importDhall.nix new file mode 100644 index 000000000000..9713b2cfb8d3 --- /dev/null +++ b/users/Profpatsch/importDhall.nix @@ -0,0 +1,78 @@ +{ pkgs, depot, lib, ... }: +let + + # import the dhall file as nix expression via dhall-nix. + # Converts the normalized dhall expression to a nix file, + # puts it in the store and imports it. + # Types are erased, functions are converted to nix functions, + # unions values are nix functions that take a record of match + # functions for their alternatives. + # TODO: document better + importDhall = + { + # Root path of the dhall file tree to import (will be filtered by files) + root + , # A list of files which should be taken from `root` (relative paths). + # This is for minimizing the amount of things that have to be copied to the store. + # TODO: can you have directory prefixes? + files + , # The path of the dhall file which should be evaluated, relative to `root`, has to be in `files` + main + , # List of dependencies (TODO: what is a dependency?) + deps + , # dhall type of `main`, or `null` if anything should be possible. + type ? null + }: + let + src = + depot.users.Profpatsch.exactSource + root + # exactSource wants nix paths, but I think relative paths + # as strings are more intuitive. + ( + let abs = path: toString root + "/" + path; + in ([ (abs main) ] ++ (map abs files)) + ); + + cache = ".cache"; + cacheDhall = "${cache}/dhall"; + + typeAnnot = if type == null then "" else ": ${type}"; + + convert = pkgs.runCommandLocal "dhall-to-nix" { inherit deps; } '' + mkdir -p ${cacheDhall} + for dep in $deps; do + ${pkgs.xorg.lndir}/bin/lndir -silent $dep/${cacheDhall} ${cacheDhall} + done + + export XDG_CACHE_HOME=$(pwd)/${cache} + # go into the source directory, so that the type can import files. + # TODO: This is a bit of a hack hrm. + cd "${src}" + printf '%s' ${lib.escapeShellArg "${src}/${main} ${typeAnnot}"} \ + | ${pkgs.dhall-nix}/bin/dhall-to-nix \ + > $out + ''; + in + import convert; + + + # read dhall file in as JSON, then import as nix expression. + # The dhall file must not try to import from non-local URLs! + readDhallFileAsJson = dhallType: file: + let + convert = pkgs.runCommandLocal "dhall-to-json" { } '' + printf '%s' ${lib.escapeShellArg "${file} : ${dhallType}"} \ + | ${pkgs.dhall-json}/bin/dhall-to-json \ + > $out + ''; + in + builtins.fromJSON (builtins.readFile convert); + +in +{ + inherit + importDhall + readDhallFileAsJson + ; +} -- cgit 1.4.1