chriswarbo-net: dd4ce41242c3e46b4dded6f8b7c07e4e04b81538

     1: { commands, emptyDirectory, fail, lib, metadata, newScope, nix-helpers
     2: , nixpkgs-lib, pageTests, relTo, runCommand, warbo-packages, withArgs
     3: , writeScript }:
     4: 
     5: with rec {
     6:   inherit (builtins) attrValues elem getAttr hasAttr hashFile map readFile;
     7:   inherit (lib)
     8:     concatMapStringsSep concatStringsSep escapeShellArg hasSuffix mapAttrs
     9:     optionalAttrs;
    10: 
    11:   test = { file, name }:
    12:     runCommand name { inherit file; } (concatStringsSep "\n" (attrValues
    13:       (mapAttrs (testName: t:
    14:         if elem testName [ "override" "overrideDerivation" ] then
    15:           ""
    16:         else
    17:           ''${t} "$file"'') pageTests) ++ [ ''ln -s "$file" "$out"'' ]));
    18: };
    19: { file, inputs ? [ ], name, SOURCE_PATH, TO_ROOT ? "", unfinished ? false
    20: , vars ? { }, }:
    21: with rec {
    22:   md = metadata.of file;
    23:   extraPkgs = map (n:
    24:     if hasAttr n commands then
    25:       getAttr n commands
    26:     else
    27:       newScope (nix-helpers // warbo-packages) (withArgs [ n ] (getAttr n)) { })
    28:     (md.packages or [ ]);
    29: 
    30:   dir = if md ? dependencies then
    31:     nixpkgs-lib.fileset.toSource {
    32:       root = ../..;
    33:       fileset =
    34:         nixpkgs-lib.fileset.unions (map (p: ../.. + "/${p}") md.dependencies);
    35:     }
    36:   else
    37:     emptyDirectory;
    38: 
    39:   # If the page specifies a 'sha256' in its metadata, its renderer will be a
    40:   # fixed-output derivation (hence allowing network access)
    41:   hash = if md ? sha256 then {
    42:     outputHashMode = "flat";
    43:     outputHashAlgo = "sha256";
    44:     outputHash = md.sha256;
    45:   } else
    46:     { };
    47: 
    48:   # If we're using a fixed-output derivation, its hash will be looked up in the
    49:   # cache, even if we've changed the page. We would prefer such pages to be
    50:   # rebuilt when changed, just in case their hash is out of date. To make this
    51:   # happen, we append a hash of the page's content to its derivation name, so
    52:   # when the content changes, so does the name (and hence the store path).
    53:   prefix = with {
    54:     # When we hash the file, we need to strip out the `sha256:` line, so that
    55:     # when we plug in the correct hash, that won't cause the file's hash to
    56:     # change!
    57:     # We also add the paths to our processing commands, so any changes to those
    58:     # will cause rebuilds too.
    59:     # See https://stackoverflow.com/a/23696995/884682 for the awk command
    60:     stripHash = runCommand "strip-hash-${name}" { inherit file; } ''
    61:       {
    62:         echo ${commands.render_page}
    63:         awk '!/^sha256:/ || f++' < "$file"
    64:       } > "$out"
    65:     '';
    66:   };
    67:     if md ? sha256 then "${hashFile "sha256" "${stripHash}"}-" else "";
    68: 
    69:   # A "raw" page has been rendered, but not postprocessed or checked. We do that
    70:   # in separate derivations, to prevent tweaks from triggering the whole site to
    71:   # re-render (note that, due to Panpipe, each page can take arbitrarily long!)
    72:   raw = runCommand "raw-${prefix + name}" ({
    73:     inherit dir file SOURCE_PATH;
    74:     buildInputs = inputs ++ extraPkgs ++ [ commands.render_page fail ];
    75: 
    76:   } // optionalAttrs (hasAttr "parseArgs" md) {
    77:     parseArgF = writeScript "${name}-parseArgs.sh" ''
    78:       parseArgs=()
    79:       ${concatMapStringsSep "\n" (arg: "parseArgs+=(${escapeShellArg arg})")
    80:       md.parseArgs}
    81:     '';
    82:   } // optionalAttrs (hasAttr "renderArgs" md) {
    83:     renderArgF = writeScript "${name}-renderArgs.sh" ''
    84:       renderArgs=()
    85:       ${concatMapStringsSep "\n" (arg: "renderArgs+=(${escapeShellArg arg})")
    86:       md.renderArgs}
    87:     '';
    88:   } // hash // vars) ''
    89:     export DEST="$PWD/out.html"
    90: 
    91:     cd "$dir"
    92:     SOURCE="$file" render_page
    93:     grep '^.' < "$DEST" > /dev/null || fail "Error: No output when rendering"
    94:     mv "$DEST" "$out"
    95:   '';
    96: 
    97:   untested = runCommand "untested-${name}" {
    98:     inherit raw TO_ROOT;
    99:     buildInputs = [
   100:       commands.cleanup
   101:       commands.relativise
   102:     ]
   103:     # If postprocessor is given, it will usually refer to a commands element
   104:       ++ (if md ? postprocessor && hasAttr md.postprocessor commands then
   105:         [ (getAttr md.postprocessor commands) ]
   106:       else
   107:         [ ]);
   108:     postprocessor = md.postprocessor or "cat";
   109:   } ''
   110:     # Perform some post-processing steps: we always run cleanup and relativise,
   111:     # and pages are free to set another postprocessor in their YAML (defaults
   112:     # to 'cat', which passes its stdio along unchanged)
   113:     < "$raw" cleanup | "$postprocessor" | relativise > "$out"
   114:   '';
   115: 
   116:   rendered = if unfinished then
   117:     untested
   118:   else
   119:     test {
   120:       inherit name;
   121:       file = untested;
   122:     };
   123: };
   124: if hasSuffix ".html" file then
   125:   with { data = writeScript name (readFile file); };
   126:   if TO_ROOT == "" then data else relTo TO_ROOT data
   127: else
   128:   rendered

Generated by git2html.