diff options
-rw-r--r-- | TODOs.org | 3 | ||||
-rw-r--r-- | default.nix | 112 | ||||
-rwxr-xr-x | spelling/check-spelling.sh | 29 | ||||
-rw-r--r-- | utils.nix | 101 |
4 files changed, 155 insertions, 90 deletions
@@ -18,5 +18,6 @@ CLOSED: [2019-05-21 Tue 08:09] CLOSED: [2019-05-20 Mon 21:02] *** Use NixOS instead of Debian? * Misc -** TODO Always update existing published files +** DONE Always update existing published files +CLOSED: [2019-05-31 Fri 19:51] =rsync= isn't sending new versions of existing files to the server. diff --git a/default.nix b/default.nix index 3f814b9..de75f93 100644 --- a/default.nix +++ b/default.nix @@ -5,10 +5,7 @@ let sha256 = "0hk4y2vkgm1qadpsm4b0q1vxq889jhxzjx3ragybrlwwg54mzp4f"; }) { }; pkgs = pkgsUnstable; - rootSrc = pkgs.nix-gitignore.gitignoreSource [] ./.; - nixfmt = import (builtins.fetchTarball - "https://github.com/serokell/nixfmt/archive/master.tar.gz") { }; # Taken from: # http://www.cs.yale.edu/homes/lucas.paul/posts/2017-04-10-hakyll-on-nix.html @@ -23,94 +20,53 @@ let ghc -O2 -dynamic --make Main.hs -o $out/bin/build-site ''; }; - baseTask = pkgs.stdenv.mkDerivation { - name = "website-task"; +in rec { + utils = import ./utils.nix { + pkgs = pkgs; src = rootSrc; - buildInputs = [pkgs.perl]; - phases = "unpackPhase buildPhase"; - buildPhase = '' - echo "ERROR: base task buildPhase not overriden." - exit 1 - ''; + baseName = "website"; }; -in with pkgs; -with pkgs.stdenv; rec { subtasks = rec { - fixme = baseTask.overrideAttrs (baseAttrs: { - name = "${baseAttrs.name}-fixme"; - buildInputs = baseAttrs.buildInputs ++ [ag]; - buildPhase = '' - ag FIXME --ignore default.nix --ignore pastebin/skeleton.org || { - touch $out - } - ''; - }); - perlPodCheck = baseTask.overrideAttrs (baseAttrs: { + perlPodCheck = utils.baseTask.overrideAttrs (baseAttrs: { name = "${baseAttrs.name}-perl-podcheck"; + buildInputs = baseAttrs.buildInputs ++ [pkgs.perl]; buildPhase = '' podchecker website pastebin/website-pastebin slides/website-slides touch $out ''; }); - batsTest = baseTask.overrideAttrs (baseAttrs: { + batsTest = utils.baseTask.overrideAttrs (baseAttrs: { name = "${baseAttrs.name}-bats-test"; - buildInputs = baseAttrs.buildInputs ++ [bats]; + buildInputs = baseAttrs.buildInputs ++ [pkgs.bats pkgs.perl]; buildPhase = '' patchShebangs . ./t/website.bats touch $out ''; }); - perlInternalTest = baseTask.overrideAttrs (baseAttrs: { + perlInternalTest = utils.baseTask.overrideAttrs (baseAttrs: { name = "${baseAttrs.name}-perl-test"; + buildInputs = baseAttrs.buildInputs ++ [pkgs.perl]; buildPhase = '' patchShebangs . ./website test touch $out ''; }); - formatNix = baseTask.overrideAttrs (baseAttrs: { - name = "${baseAttrs.name}-nixfmt"; - buildInputs = baseAttrs.buildInputs ++ [nixfmt]; - buildPhase = '' - diff <(nixfmt < default.nix) default.nix || { - echo "The default.nix is unformatted. To fix it, run:" - echo " nixfmt default.nix" - exit 1 - } - touch $out - ''; - }); - hunspellCheck = baseTask.overrideAttrs (baseAttrs: { + hunspellCheck = utils.baseTask.overrideAttrs (baseAttrs: { name = "${baseAttrs.name}-hunspell"; buildInputs = baseAttrs.buildInputs - ++ [(hunspellWithDicts (with hunspellDicts; [en-us]))]; + ++ [(pkgs.hunspellWithDicts (with pkgs.hunspellDicts; [en-us]))]; buildPhase = '' - # Required by =sort= and =hunspell= - export LANG=C.UTF-8 - - for DICT in spelling/*.txt; do - diff <(sort $DICT) $DICT || { - echo "The $DICT dictionary is unsorted. To fix it, run:" - echo " LANG=C.UTF-8 sort $DICT | sponge $DICT" - exit 1 - } - done - - HTML_DIR="${subtasks.docs}" - hunspell -l -p <(cat spelling/international.dic.txt spelling/en_US.dic.txt spelling/en_US.aff.txt) -d en_US -i utf-8 $(find "$HTML_DIR" -type f -name '*.html') | tee spelling.txt - [[ -s spelling.txt ]] && { - echo "Mispelled words detected by hunspell." - exit 1 - } - + patchShebangs . + ./spelling/check-spelling.sh "${subtasks.docs}" touch $out ''; }); - docs = baseTask.overrideAttrs (baseAttrs: { + docs = utils.baseTask.overrideAttrs (baseAttrs: { name = "${baseAttrs.name}-docs"; src = ./site; - buildInputs = [ websiteBuilder pandoc ]; + buildInputs = [ websiteBuilder pkgs.pandoc ]; buildPhase = '' export LOCALE_ARCHIVE="${pkgs.glibcLocales}/lib/locale/locale-archive"; export LANG=en_US.UTF-8 @@ -124,44 +80,22 @@ with pkgs.stdenv; rec { ''; }); }; - test = baseTask.overrideAttrs (baseAttrs: rec { - name = "${baseAttrs.name}-test"; - buildInputs = [ - subtasks.fixme + test = utils.test [ + utils.formatNix + (utils.shellcheck null) + (utils.fixme ["pastebin/skeleton.org" "utils.nix"]) subtasks.perlPodCheck subtasks.batsTest subtasks.perlInternalTest - subtasks.formatNix subtasks.hunspellCheck ]; - buildPhase = '' - echo "Ran tests for:" - for d in ${builtins.toString buildInputs}; do - echo " $d" - done - echo "All tests passed!" - touch $out - ''; - }); - shell = mkShell rec { + shell = pkgs.mkShell rec { name = "website-shell"; buildInputs = [ websiteBuilder (pkgs.haskellPackages.ghcWithPackages (p: with p; [hakyll])) - nixfmt - (hunspellWithDicts (with hunspellDicts; [en-us])) + (pkgs.hunspellWithDicts (with pkgs.hunspellDicts; [en-us])) ]; }; - publishScript = pkgs.writeShellScriptBin "publish.sh" '' - set -euo pipefail - ${pkgs.rsync}/bin/rsync --verbose \ - --copy-links \ - --progress \ - --stats \ - --update \ - --recursive \ - --rsh="ssh -o StrictHostKeyChecking=no" \ - ${subtasks.docs}/ \ - "$SERVER_URL:$DOCS_SERVER_PATH" - ''; + publishScript = utils.publishScript subtasks.docs; } diff --git a/spelling/check-spelling.sh b/spelling/check-spelling.sh new file mode 100755 index 0000000..7656dc4 --- /dev/null +++ b/spelling/check-spelling.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash +set -Eeuo pipefail + +HTML_DIR="${1:-}" +[[ -z "${HTML_DIR}" ]] && { + echo 'Undefined HTML_DIR.' + exit 2 +} + +# Required by =sort= and =hunspell= +export LANG=C.UTF-8 + +for DICT in spelling/*.txt; do + diff <(sort $DICT) $DICT || { + echo "The $DICT dictionary is unsorted. To fix it, run:" + echo " LANG=C.UTF-8 sort $DICT | sponge $DICT" + exit 1 + } +done + +hunspell -l -p <(cat spelling/international.dic.txt spelling/en_US.dic.txt spelling/en_US.aff.txt) -d en_US -i utf-8 $(find "$HTML_DIR" -type f -name '*.html') | tee spelling.txt +cat spelling.txt +[[ -s spelling.txt ]] && { + echo "Mispelled words detected by hunspell." + cat spelling.txt + exit 1 +} || { + echo "No words mispelled" +} diff --git a/utils.nix b/utils.nix new file mode 100644 index 0000000..b41e9f5 --- /dev/null +++ b/utils.nix @@ -0,0 +1,101 @@ +{ pkgs, src, baseName }: +let + nixfmt = import (builtins.fetchTarball + "https://github.com/serokell/nixfmt/archive/master.tar.gz") { }; +in rec { + baseTask = pkgs.stdenv.mkDerivation { + name = "${baseName}-task"; + src = src; + buildInputs = [ ]; + phases = "unpackPhase buildPhase"; + buildPhase = '' + echo "ERROR: base task buildPhase not overriden." + exit 1 + ''; + }; + shellcheck = ignoredFindPattern: + baseTask.overrideAttrs (baseAttrs: rec { + name = "${baseAttrs.name}-shellcheck"; + buildInputs = baseAttrs.buildInputs ++ [ pkgs.shellcheck ]; + ignoredPattern = if ignoredFindPattern == null then "" else ignoredFindPattern; + buildPhase = '' + find . -type f \( -name '*.sh' -and -regextype egrep ! -regex '${ignoredPattern}' \) -print0 | xargs -0 shellcheck + touch $out + ''; + }); + formatNix = baseTask.overrideAttrs (baseAttrs: { + name = "${baseAttrs.name}-nixfmt"; + buildInputs = baseAttrs.buildInputs ++ [ nixfmt ]; + buildPhase = '' + format() { + nix_file="$1" + diff <(nixfmt < "$nix_file") "$nix_file" || { + echo "The $nix_file is unformatted. To fix it, run:" + echo " nixfmt $nix_file" + exit 1 + } + } + export -f format + find . -type f -name '*.nix' -print0 | xargs -0 -I{} bash -c "format {}" \; + touch $out + ''; + }); + fixme = ignoredFiles: + baseTask.overrideAttrs (baseAttrs: rec { + name = "${baseAttrs.name}-fixme"; + buildInputs = baseAttrs.buildInputs ++ [ pkgs.ag ]; + ignoredPattern = pkgs.lib.fold (a: b: " --ignore ${a} ${b}") "" + (if ignoredFiles == null then [ + "default.nix" + "TODOs.org" + ] else + ignoredFiles); + buildPhase = '' + ag FIXME ${ignoredPattern} || { + touch $out + exit 0 + } + echo " Found dangling FIXME markers on the project." + echo " You should write them down properly on TODOs.org." + exit 1 + ''; + }); + orgMkDocs = title: + baseTask.overrideAttrs (baseAttrs: { + name = "${baseAttrs.name}-docs"; + buildInputs = [ pkgs.pandoc pkgs.mkdocs ]; + buildPhase = '' + # Convert from org-mode to markdown with pandoc + find docs/ -type f -name '*.org' -print0 | xargs -0 -I{} pandoc -o {}.md {}.org + + # Give the generated markdown files to MkDocs + mkdocs build + + # Build remaining one-off files + pandoc README.org -o site/index.html --css docs/README.css --to=html5 --self-contained --metadata title="${title}" + + mv site/ $out/ + ''; + }); + test = testDerivations: + baseTask.overrideAttrs (baseAttrs: { + name = "${baseAttrs.name}-test"; + buildPhase = '' + echo "Ran tests for:" + for d in ${builtins.toString testDerivations}; do + echo " $d" + done + echo "All tests passed!" + touch $out + ''; + }); + publishScript = docsDerivation: + pkgs.writeShellScriptBin "publish.sh" '' + set -euo pipefail + OUT_DOCS="${docsDerivation}" + ${pkgs.rsync}/bin/rsync -avzP \ + --rsh="ssh -o StrictHostKeyChecking=no" \ + "$OUT_DOCS/" \ + "$SERVER_URL:$DOCS_SERVER_PATH" + ''; +} |