diff options
-rw-r--r-- | users/sterni/lv/gopher/default.nix | 8 | ||||
-rw-r--r-- | users/sterni/nix/build/buildGopherHole/default.nix | 109 |
2 files changed, 117 insertions, 0 deletions
diff --git a/users/sterni/lv/gopher/default.nix b/users/sterni/lv/gopher/default.nix new file mode 100644 index 000000000000..f8f42c82d56f --- /dev/null +++ b/users/sterni/lv/gopher/default.nix @@ -0,0 +1,8 @@ +{ depot, ... }: + +depot.users.sterni.nix.build.buildGopherHole { + name = "gopher-sterni.lv"; + dir = [ + "🚧 closed for construction 🚧" + ]; +} diff --git a/users/sterni/nix/build/buildGopherHole/default.nix b/users/sterni/nix/build/buildGopherHole/default.nix new file mode 100644 index 000000000000..eec13a865421 --- /dev/null +++ b/users/sterni/nix/build/buildGopherHole/default.nix @@ -0,0 +1,109 @@ +{ depot, pkgs, lib, ... }: + +let + inherit (pkgs) + runCommand + writeText + ; + + inherit (depot.users.sterni.nix.build) + buildGopherHole + ; + + fileTypes = { + # RFC1436 + text = "0"; + menu = "1"; + cso = "2"; + error = "3"; + binhex = "4"; + dos = "5"; + uuencoded = "6"; + index-server = "7"; + telnet = "8"; + binary = "9"; + mirror = "+"; + gif = "g"; + image = "I"; + tn3270 = "T"; + # non-standard + info = "i"; + html = "h"; + }; + + buildFile = { file, name, fileType ? fileTypes.text }: + runCommand name + { + passthru = { + # respect the file type the file derivation passes + # through. otherwise use explicitly set type or + # default value. + fileType = file.fileType or fileType; + }; + } '' + ln -s ${file} "$out" + ''; + + buildGopherMap = dir: + let + /* strings constitute an info line or an empty line + if their length is zero. sets that contain a menu + value have that added to the gophermap as-is. + + all other entries should be a set which can be built using + buildGopherHole and is linked by their name. The resulting + derivation is expected to passthru a fileType containing the + gopher file type char of themselves. + */ + gopherMapLine = e: + if builtins.isString e + then e + else if e ? menu + then e.menu + else + let + drv = buildGopherHole e; + title = e.title or e.name; + in + "${drv.fileType}${title}\t${drv.name}"; + in + writeText ".gophermap" (lib.concatMapStringsSep "\n" gopherMapLine dir); + + buildDir = + { dir, name, ... }: + + let + # filter all entries out that have to be symlinked: + # sets with the file or dir attribute + drvOnly = builtins.map buildGopherHole (builtins.filter + (x: !(builtins.isString x) && (x ? dir || x ? file)) + dir); + gopherMap = buildGopherMap dir; + in + runCommand name + { + passthru = { + fileType = fileTypes.dir; + }; + } + ('' + mkdir -p "$out" + ln -s "${gopherMap}" "$out/.gophermap" + '' + lib.concatMapStrings + (drv: '' + ln -s "${drv}" "$out/${drv.name}" + '') + drvOnly); +in + +{ + # Dispatch into different file / dir handling code + # which is mutually recursive with this function. + __functor = _: args: + if args ? file then buildFile args + else if args ? dir then buildDir args + else builtins.throw "Unrecognized gopher hole item type: " + + lib.generators.toPretty { } args; + + inherit fileTypes; +} |