diff --git a/overlay/default.nix b/overlay/default.nix index a17b84b..6e3c4e0 100644 --- a/overlay/default.nix +++ b/overlay/default.nix @@ -168,6 +168,18 @@ in nullPkgs // { # Packages from the Nimble flake with adjustments. prev.nimPackages.overrideScope' (_: prev': { + dhall = with prev'; buildNimPackage rec { + name = "dhall"; + version = "0.1.0"; + src = prev.fetchFromSourcehut { + owner = "~ehmry"; + repo = "dhall-nim"; + rev = version; + hash = "sha256-AhGD/h61Yqiq80woD8bfrvwuTjqCPGYCmUFhK5xFur4="; + }; + buildInputs = [ bigints cbor ]; + }; + genode = prev'.genode.overrideAttrs (attrs: rec { version = "20.11.1"; src = fetchgit { diff --git a/overlay/eris-patch-hook/default.nix b/overlay/eris-patch-hook/default.nix index 00568bf..23e756d 100644 --- a/overlay/eris-patch-hook/default.nix +++ b/overlay/eris-patch-hook/default.nix @@ -1,10 +1,11 @@ -{ buildNimPackage, patchelf, base32, eris }: +{ buildNimPackage, patchelf, base32, bigints, cbor, dhall, eris }: buildNimPackage { name = "eris_patch"; - buildInputs = [ base32 eris ]; + buildInputs = [ base32 bigints cbor dhall eris ]; inherit patchelf; unpackPhase = "install -D ${./eris_patch.nim} ./src/eris_patch.nim"; + nimBinOnly = true; preConfigure = '' cat << EOF > eris_patch.nimble bin = @[ "src/eris_patch"] diff --git a/overlay/eris-patch-hook/eris_patch.nim b/overlay/eris-patch-hook/eris_patch.nim index 5bed28f..b714074 100644 --- a/overlay/eris-patch-hook/eris_patch.nim +++ b/overlay/eris-patch-hook/eris_patch.nim @@ -1,14 +1,25 @@ +import std/[asyncdispatch, deques, json, os, osproc, streams, strutils, tables] +import dhall/[render, terms] import eris -import std/asyncdispatch, std/deques, std/json, std/os, std/osproc, std/streams, - std/strutils, std/tables +proc toDhall(js: JsonNode): Value = + case js.kind + of JString: + result = newValue(js.str) + of JObject: + result = newRecordLiteral(js.fields.len) + for key, val in js.fields.pairs: + result.table[key] = val.toDhall + else: + raiseAssert "unhandled JSON value" if getEnv("dontErisPatch") != "": quit 0 let patchelf = getEnv("ERIS_PATCHELF", "patchelf") nixStore = getEnv("NIX_STORE", "/nix/store") - manifestSubPath = "nix-support" / "eris-manifest.json" + jsonManifestSubPath = "nix-support" / "eris-manifest.json" + dhallManifestSubPath = "nix-support" / "eris-manifest.dhall" proc isElf(path: string): bool = var magic: array[4, char] @@ -27,7 +38,7 @@ var failed = false for outputName in getEnv("outputs").splitWhitespace: let outputRoot = getEnv(outputName) - if fileExists(outputRoot / manifestSubPath): + if fileExists(outputRoot / jsonManifestSubPath): echo "Not running ERIS patch hook again" quit 0 outputManifests[outputRoot] = newJObject() @@ -103,7 +114,7 @@ proc fileClosure(filePath: string): TableRef[string, string] = storePath = p if storePath.startsWith nixStore: # read the closure manifest of the dependency - let manifestPath = storePath / manifestSubPath + let manifestPath = storePath / jsonManifestSubPath if fileExists(manifestPath): let manifest = parseFile(manifestPath) @@ -117,7 +128,7 @@ proc fileClosure(filePath: string): TableRef[string, string] = closureCache[filePath] = result for outputRoot in outputManifests.keys: - let manifestPath = outputRoot / manifestSubPath + let manifestPath = outputRoot / jsonManifestSubPath if fileExists manifestPath: continue for filePath in walkDirRec(outputRoot, relative = false): # Populate the queue of files to patch @@ -185,5 +196,8 @@ if failed: quit -1 for outputRoot, manifest in outputManifests: - createDir(outputRoot / "nix-support") - writeFile(outputRoot / manifestSubPath, $manifest) + let supportDir = outputRoot / "nix-support" + createDir(supportDir) + writeFile(outputRoot / jsonManifestSubPath, $manifest) + for path, attrs in manifest.pairs: + writeFile(supportDir / path.extractFilename & ".eris.dhall", $(attrs.toDhall))