feat(sterni/lv): interim gopher page

This adds an interim placeholder page for gopher://sterni.lv and
additionally my preexisting Nix-based static site generator for
gophermap supporting servers. It is based on building a nested Nix data
structure representing the directory structure of the resulting site
which then resolves to a bunch of fine grained derivations.

Change-Id: Id6c0b60cfe8d9d4df6a3700d96ed48b7df02ce58
Reviewed-on: https://cl.tvl.fyi/c/depot/+/7292
Tested-by: BuildkiteCI
Reviewed-by: sterni <sternenseemann@systemli.org>
This commit is contained in:
sterni 2022-06-06 12:33:34 +02:00
parent 6ef6e9c97f
commit 7b4a545699
2 changed files with 117 additions and 0 deletions

View file

@ -0,0 +1,8 @@
{ depot, ... }:
depot.users.sterni.nix.build.buildGopherHole {
name = "gopher-sterni.lv";
dir = [
"🚧 closed for construction 🚧"
];
}

View file

@ -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;
}