From 3d765d6805329dbc9f76c6c4bf3395562a299492 Mon Sep 17 00:00:00 2001 From: "Robert W. Pearce" Date: Sun, 13 Jun 2021 00:02:29 -0400 Subject: [PATCH] The great Flakes refactor --- .envrc | 6 - .ghci | 5 +- .github/workflows/main.yml | 15 +- .gitignore | 4 +- README.md | 233 +++++++++++++----- default.nix | 26 -- flake.lock | 42 ++++ flake.nix | 50 ++++ generator/LICENSE | 30 --- generator/default.nix | 3 - generator/hpkgs.nix | 32 --- generator/shell.nix | 21 -- generator/hakyll.patch => hakyll.patch | 0 haskell-overlay.nix | 66 +++++ nix/default.nix | 44 ---- nix/sources.json | 38 --- nix/sources.nix | 148 ----------- shell.nix | 14 -- src/css/article.css | 44 ---- src/css/default.css | 38 ++- src/index.html | 8 +- src/posts/2020-09-21-hello-world.md | 9 +- src/posts/2020-09-22-hola-mundo.md | 9 +- src/templates/default.html | 4 +- ssg/LICENSE | 29 +++ {generator => ssg}/src/Main.hs | 42 +++- {generator => ssg}/src/Slug.hs | 0 .../ssg.cabal | 10 +- 28 files changed, 463 insertions(+), 507 deletions(-) delete mode 100644 .envrc delete mode 100644 default.nix create mode 100644 flake.lock create mode 100644 flake.nix delete mode 100644 generator/LICENSE delete mode 100644 generator/default.nix delete mode 100644 generator/hpkgs.nix delete mode 100644 generator/shell.nix rename generator/hakyll.patch => hakyll.patch (100%) create mode 100644 haskell-overlay.nix delete mode 100644 nix/default.nix delete mode 100644 nix/sources.json delete mode 100644 nix/sources.nix delete mode 100644 shell.nix delete mode 100644 src/css/article.css create mode 100644 ssg/LICENSE rename {generator => ssg}/src/Main.hs (87%) rename {generator => ssg}/src/Slug.hs (100%) rename generator/hakyll-nix-template.cabal => ssg/ssg.cabal (62%) diff --git a/.envrc b/.envrc deleted file mode 100644 index 87ef84a..0000000 --- a/.envrc +++ /dev/null @@ -1,6 +0,0 @@ -use nix - -eval "$(lorri direnv)" - -# Install pre-commit hooks -eval "$shellHook" diff --git a/.ghci b/.ghci index 992189d..c0fa0bb 100644 --- a/.ghci +++ b/.ghci @@ -1,4 +1,7 @@ :def hoogle \x -> return $ ":!hoogle --count=15 \"" ++ x ++ "\"" :def doc \x -> return $ ":!hoogle --info \"" ++ x ++ "\"" :set -Wall -:set -fno-warn-type-defaults +:set -fno-warn-type-defaults -ferror-spans -freverse-errors -fprint-expanded-synonyms +:set prompt "\ESC[0;32m%s\n\ESC[m[ghci]\ESC[38;5;172mλ \ESC[m" +:set prompt-cont " \ESC[38;5;172m> \ESC[m" +:load ssg/src/Slug.hs ssg/src/Main.hs diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index a02a320..239a5d6 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -9,22 +9,25 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v2.3.4 - name: Install Nix - uses: cachix/install-nix-action@v12 + uses: cachix/install-nix-action@v13 with: skip_adding_nixpkgs_channel: true + install_url: https://nixos-nix-install-tests.cachix.org/serve/lb41az54kzk6j12p81br4bczary7m145/install + install_options: '--tarball-url-prefix https://nixos-nix-install-tests.cachix.org/serve' + extra_nix_config: | + experimental-features = nix-command flakes - name: Build with cachix - uses: cachix/cachix-action@v8 + uses: cachix/cachix-action@v10 with: name: hakyll-nix-template signingKey: ${{ secrets.CACHIX_SIGNING_KEY }} #authToken: ${{ secrets.CACHIX_AUTH_TOKEN }} - - run: nix-build - - run: nix-shell --run "echo OK" + - run: nix build - name: Artifact pages uses: actions/upload-artifact@v2 @@ -46,7 +49,7 @@ jobs: - name: GitHub Pages if: success() - uses: crazy-max/ghaction-github-pages@v2 + uses: crazy-max/ghaction-github-pages@v2.3.0 with: build_dir: result target_branch: gh-pages diff --git a/.gitignore b/.gitignore index e6d56f2..57917e5 100644 --- a/.gitignore +++ b/.gitignore @@ -1,7 +1,7 @@ .ghc.environment.* -.pre-commit-config.yaml +_cache +_tmp dist dist-newstyle -hakyll-cache node_modules result diff --git a/README.md b/README.md index 4145ed0..b1df82b 100644 --- a/README.md +++ b/README.md @@ -2,72 +2,175 @@ [![built with nix](https://builtwithnix.org/badge.svg)](https://builtwithnix.org) -[Hakyll](https://jaspervdj.be/hakyll/) + [Nix](https://nixos.org/) template - -## Usage - -1. Click the "Use this template" button and create your repository -1. Renaming - 1. Rename all instances of `hakyll-nix-template` with the name of your project - 1. Rename `generator/hakyll-nix-template.cabal` to reflect your project name -1. Cachix - 1. Create a cachix cache for your project on https://app.cachix.org - 1. Follow the cachix instructions to generate a signing keypair - 1. Copy the signing keypair value to a new `CACHIX_SIGNING_KEY` secret on - https://github.com///settings/secrets -1. Run `nix-build` to build the project and `nix-shell` to open the nix shell -1. If you want to update `niv` and the other pinned dependencies, then in the - `nix-shell` run `niv init` and then `niv update` and then `exit` to leave the - nix shell -1. To start an environment for running hakyll commands like `hakyll-site watch` - (the dev server) and `hakyll-site build`: `cd generator && nix-shell`. You'll - then have access to the `hakyll-site` executable defined in - `generator/hakyll-nix-template.cabal`. While you can do `nix-shell` in the - root and then `cd generator && hakyll-site watch`, you get some more tools if - you `nix-shell` from within the `generator/` folder. -1. Once you're satisfied, create a branch, push your project up there, and check - that the GitHub Actions successfully build. If so, you're good to merge your - project with your main branch. -1. Once you have a successful build on your main branch, open - https://github.com///settings and set the GitHub Pages - branch to be the `gh-pages` branch +[Hakyll](https://jaspervdj.be/hakyll/) + [Nix](https://nixos.org) template ## Features -tl;dr: `nix-build` will collect all your pinned dependencies, build your hakyll -site, and output the built site in a `result/` directory. If you set up the -[main GitHub Action](./.github/workflows/main.yml) with what it needs (your -[cachix](https://cachix.org) cache, and your app needs a `CACHIX_SIGNING_KEY` -secret), it will deploy your built site to a `gh-pages` branch. +### nix flakes -* Hakyll (see [the generator folder](./generator)) - * Haskell `nix-shell` environment inside the `generator` folder through which - you can run `hakyll-site watch` and all other hakyll commands, including - the ability to run `ghci` and load haskell modules for testing - * Ability to patch hakyll via `hakyll.patch` - * Ability to provide nixpkgs overrides for packages whose versions need to - come from [hackage](https://hackage.haskell.org) - * RSS & Atom XML feed generation - * Sitemap generation - * Reasonable pandoc markdown customization to make it as close to GitHub's - style as possible - * `Slug.hs` module that makes nice URIs - * Many other opinionated general website setup features that should be very - helpful -* Nix - * Pinned [nixpkgs](https://github.com/NixOS/nixpkgs), [niv](https://github.com/nmattia/niv), - and [pre-commit-hooks.nix](https://github.com/cachix/pre-commit-hooks.nix) - * `nix-build` will build your site into a `result/` directory - * `nix-shell` in the root will give you a shell with the `tools` dependencies - in [./nix/default.nix](./nix/default.nix) - * `nix-shell` in [./generator](./generator) will give you a haskell shell with - your `hakyll-site` available, as well as `ghci` -* Dev linting via [pre-commit-hooks.nix](https://github.com/cachix/pre-commit-hooks.nix) - * [nix-linter](https://github.com/Synthetica9/nix-linter) - * [nixpkgs-fmt](https://github.com/nix-community/nixpkgs-fmt) - * [ormolu](https://github.com/tweag/ormolu) - * [shellcheck](https://github.com/koalaman/shellcheck) -* Encourages dev use of [lorri](https://github.com/target/lorri) -* Deployment through a [GitHub Actions](https://github.com/features/actions) - build with [cachix](https://cachix.org) and deploying to - [GitHub Pages](https://pages.github.com/) via a `gh-pages` branch +* Build your site into the `./result/dist` folder: + ```sh + λ nix build + ``` +* Start hakyll's dev server that reloads when changes are made: + ```sh + λ nix run . watch + Listening on http://127.0.0.1:8000 + ...more logs + ``` +* Run any hakyll command through `nix run .`! + ```sh + λ nix run . clean + Removing dist... + Removing ssg/_cache... + Removing ssg/_tmp... + ``` +* Start a development environment that + * has your shell environment + * has `hakyll-site` (for building/watching/cleaning hakyll projects) + * has `hakyll-init` (for generating new projects) + * can have anything else you put in the `buildInputs` of the `devShell` in + `flake.nix`; for example: `haskell-language-server`, `hlint`, and `ormolu` + * is set up to run `ghci` with some defaults and the modules loaded so you can + make your own changes and test them out in the ghci REPL + + ```sh + λ nix develop + + [hakyll]λ hakyll-site build + ... + Success + + [hakyll]λ ghci + ... + [1 of 2] Compiling Slug ( ssg/src/Slug.hs, interpreted ) + [2 of 2] Compiling Main ( ssg/src/Main.hs, interpreted ) + ... + + λ > :type toSlug + toSlug :: T.Text -> T.Text + + λ > import Data.Text (pack) + λ > toSlug (pack "What If I Told You...") + "what-if-i-told-you" + ``` +* Easily unbreak hakyll's nixpkgs distribution or change hakyll's compile flags +via the `./haskell-overlay.nix` and `hakyll.patch` files + +### hakyll + +All of this is custmomizable, and here are some things that are already done for +you: + +* [pandoc](https://github.com/jgm/pandoc/) markdown customization to make it as + close to GitHub's markdown style as possible +* `Slug.hs` module that makes nice link URIs based on post titles +* RSS & Atom XML feed generation +* Sitemap generation +* Code syntax highlighting customization +* ...other reasonable defaults + +Configure the dev server, cache & tmp directories, and more in +`./ssg/src/Main.hs`. + +### Deployment + +Deployment is set up through a [GitHub +Action](https://github.com/features/actions) with [cachix](https://cachix.org), +and it deploys to a [GitHub Pages](https://pages.github.com/) branch, +`gh-pages`, when you merge code into your main branch. + +Setup information can be found below in the "Cachix" section. + +Note: If your main branch's name isn't `main`, ensure `'refs/heads/main'` gets +updated to `'refs/heads/my-main-branch'` in `./github/workflows/main.yml`. + +## Setup + +### Nix Flakes + +If you don't have [nix](https://nixos.org) _and are not running macOS_, follow +[the nix installation instructions](https://nixos.org/download.html). + +At the time of writing, the macOS installation is in a weird place. You should +use this: + +```sh +λ sh <(curl https://abathur-nix-install-tests.cachix.org/serve/yihf8zbs0jwph2rs9qfh80dnilijxdi2/install) --tarball-url-prefix https://abathur-nix-install-tests.cachix.org/serve +``` + +Once you have nix installed, follow the instructions here to get access to +flakes: https://nixos.wiki/wiki/Flakes. + +### Cachix + +The `./.github/workflows/main.yml` file builds with help from +[cachix](https://app.cachix.org), so you'll to generate a signing key to be able +to do this. + +1. Create a cache on cachix for your project +1. Follow cachix's instructions to generate a signing keypair +1. Copy the signing keypair value to a new `CACHIX_SIGNING_KEY` secret on + https://github.com/settings/secrets + +## Enable Content-Addressible Derivation (experimental) + +Given you have your nix conf `experimental-features` set to something like + +``` +experimental-features = "nix-command flakes ca-derivations ca-references" +``` + +Uncomment the `__contentAddressed = true;` line in `haskell-ovelray.nix`, and +then run + +```sh +λ nix build --experimental-features "ca-derivations flakes nix-command" +``` + +## Alternatives to the haskell overlay + +### Overriding `legacyPackages`' haskell compiler packages + +```nix +pkgs = nixpkgs.legacyPackages.${system}; +myHaskellPackages = pkgs.haskell.packages.${haskellCompiler}.override { + overrides = hpFinal: hpPrev: + let + hakyll-src = hpPrev.callHackage "hakyll" "4.14.0.0" {}; + pandoc-src = hpPrev.callHackage "pandoc" "2.11.4" {}; + in { + hakyll = pipe hakyll-src [ + doJailbreak + dontCheck + (withPatch ./hakyll.patch) + (withFlags [ "-f" "watchServer" "-f" "previewServer" ]) + ]; + + pandoc = pipe pandoc-src [ + doJailbreak + dontCheck + ]; + }; +}; +``` + +## Pulling `hakyll-src` from GitHub + +`hakyll-src`, used in the `haskell-overlay.nix` and in the prior example, +doesn't have to come from hackage; it could come from what your pinned nixpkgs +version has via `hakyll-src = hpPrev.hakyll`, or it could come from the hakyll +repo pinned as a nix flake input: + +```nix +hakyll-src = { + url = "github:jaspervdj/hakyll/v4.14.0.0"; + flake = false; +}; +``` + +...and then: + +```nix +hakyll-src = hpPrev.callCabal2nix "hakyll" hakyll-src {}; +``` diff --git a/default.nix b/default.nix deleted file mode 100644 index 3ffa4ca..0000000 --- a/default.nix +++ /dev/null @@ -1,26 +0,0 @@ -let - cfg = import ./nix/default.nix { }; -in -{ pkgs ? cfg.pkgs }: - -pkgs.stdenv.mkDerivation { - name = "hakyll-nix-template"; - buildInputs = [ - cfg.generator - ]; - src = cfg.src; - - # https://github.com/jaspervdj/hakyll/issues/614 - # https://github.com/NixOS/nix/issues/318#issuecomment-52986702 - # https://github.com/MaxDaten/brutal-recipes/blob/source/default.nix#L24 - LOCALE_ARCHIVE = pkgs.lib.optionalString (pkgs.buildPlatform.libc == "glibc") "${pkgs.glibcLocales}/lib/locale/locale-archive"; - LANG = "en_US.UTF-8"; - - buildPhase = '' - hakyll-site build - ''; - installPhase = '' - mkdir -p "$out/dist" - cp -r ../dist/* "$out/dist" - ''; -} diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..f1cf1fa --- /dev/null +++ b/flake.lock @@ -0,0 +1,42 @@ +{ + "nodes": { + "flake-utils": { + "locked": { + "lastModified": 1623660459, + "narHash": "sha256-OTmOsh43po7r5F9s9H6lVCBQ2b0FikWbmiwLbMAGRdw=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "98c8d36b1828009b20f12544214683c7489935a1", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1623576761, + "narHash": "sha256-krXZQ0lObduC95f40K3JwIT//VIBpXBwVNclqh5njtE=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "1f91fd1040667e9265a760b0347f8bc416249da7", + "type": "github" + }, + "original": { + "id": "nixpkgs", + "ref": "nixos-21.05", + "type": "indirect" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + } + }, + "root": "root", + "version": 7 +} diff --git a/flake.nix b/flake.nix new file mode 100644 index 0000000..a4ea75f --- /dev/null +++ b/flake.nix @@ -0,0 +1,50 @@ +{ + description = "hakyll-nix-template"; + + nixConfig.bash-prompt = "[nix]\\e\[38;5;172mλ \\e\[m"; + + inputs = { + nixpkgs.url = "nixpkgs/nixos-21.05"; + + flake-utils = { + url = "github:numtide/flake-utils"; + inputs.nixpkgs.follows = "nixpkgs"; + }; + }; + + outputs = { flake-utils, nixpkgs, self }: + flake-utils.lib.eachDefaultSystem (system: + let + config = {}; + overlays = [ (import ./haskell-overlay.nix) ]; + pkgs = import nixpkgs { inherit config overlays system; }; + in rec { + defaultPackage = packages.website; + defaultApp = apps.hakyll-site; + + packages = with pkgs.myHaskellPackages; { inherit ssg website; }; + + apps.hakyll-site = flake-utils.lib.mkApp { + drv = packages.ssg; + exePath = "/bin/hakyll-site"; + }; + + devShell = pkgs.myHaskellPackages.shellFor { + packages = p: [ p.ssg ]; + + buildInputs = with pkgs.myHaskellPackages; [ + ssg + + # Helpful tools for `nix develop` shells + # + #ghcid # https://github.com/ndmitchell/ghcid + #haskell-language-server # https://github.com/haskell/haskell-language-server + #hlint # https://github.com/ndmitchell/hlint + #ormolu # https://github.com/tweag/ormolu + ]; + + withHoogle = true; + }; + } + ); +} diff --git a/generator/LICENSE b/generator/LICENSE deleted file mode 100644 index 56fa0c3..0000000 --- a/generator/LICENSE +++ /dev/null @@ -1,30 +0,0 @@ -Copyright (c) 2019, Robert Pearce - -All rights reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - - * Redistributions of source code must retain the above copyright - notice, this list of conditions and the following disclaimer. - - * Redistributions in binary form must reproduce the above - copyright notice, this list of conditions and the following - disclaimer in the documentation and/or other materials provided - with the distribution. - - * Neither the name of Robert Pearce nor the names of other - contributors may be used to endorse or promote products derived - from this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS -"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT -LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR -A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT -OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, -SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT -LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, -DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY -THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT -(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/generator/default.nix b/generator/default.nix deleted file mode 100644 index b5449a4..0000000 --- a/generator/default.nix +++ /dev/null @@ -1,3 +0,0 @@ -{ pkgs }: - -(pkgs.callPackage ./hpkgs.nix { }).hakyll-nix-template diff --git a/generator/hpkgs.nix b/generator/hpkgs.nix deleted file mode 100644 index 002e4ca..0000000 --- a/generator/hpkgs.nix +++ /dev/null @@ -1,32 +0,0 @@ -{ compiler ? "ghc884" -, pkgs -}: -let - inherit (pkgs.lib.trivial) flip pipe; - inherit (pkgs.haskell.lib) appendPatch appendConfigureFlags dontCheck; - - hakyllFlags = [ "-f" "watchServer" "-f" "previewServer" ]; - - haskellPackages = pkgs.haskell.packages.${compiler}.override { - overrides = hpNew: hpOld: { - hakyll = - pipe - hpOld.hakyll - [ - (flip appendPatch ./hakyll.patch) - (flip appendConfigureFlags hakyllFlags) - ]; - - hakyll-nix-template = hpNew.callCabal2nix "hakyll-nix-template" ./. { }; - - # when hakyll is marked as broken in nixpkgs - # because of version issues, fix them here: - - hslua = dontCheck (hpNew.callHackage "hslua" "1.0.3.2" { }); - jira-wiki-markup = dontCheck (hpNew.callHackage "jira-wiki-markup" "1.1.4" { }); - pandoc = dontCheck (hpNew.callHackage "pandoc" "2.9.2.1" { }); - pandoc-types = dontCheck (hpNew.callHackage "pandoc-types" "1.20" { }); - }; - }; -in -haskellPackages diff --git a/generator/shell.nix b/generator/shell.nix deleted file mode 100644 index 8ae2168..0000000 --- a/generator/shell.nix +++ /dev/null @@ -1,21 +0,0 @@ -let - cfg = import ../nix/default.nix { }; - hp = cfg.haskellPackages; -in -{}: - -hp.shellFor { - packages = p: [ - p.hakyll-nix-template - ]; - - buildInputs = with hp; [ - cabal-install - ghcid - hlint - hp.hakyll-nix-template - ormolu - ]; - - withHoogle = true; -} diff --git a/generator/hakyll.patch b/hakyll.patch similarity index 100% rename from generator/hakyll.patch rename to hakyll.patch diff --git a/haskell-overlay.nix b/haskell-overlay.nix new file mode 100644 index 0000000..c146220 --- /dev/null +++ b/haskell-overlay.nix @@ -0,0 +1,66 @@ +final: prev: + let + inherit (prev.stdenv) mkDerivation; + inherit (prev.lib.trivial) flip pipe; + inherit (prev.haskell.lib) + appendPatch + appendConfigureFlags + dontCheck + doJailbreak; + + withPatch = flip appendPatch; + withFlags = flip appendConfigureFlags; + + haskellCompiler = "ghc884"; + in { + myHaskellPackages = prev.haskell.packages.${haskellCompiler}.override { + overrides = hpFinal: hpPrev: + let + hakyll-src = hpPrev.callHackage "hakyll" "4.14.0.0" {}; + pandoc-src = hpPrev.callHackage "pandoc" "2.11.4" {}; # version specified by hayll 4.14.0.0 + in rec { + hakyll = pipe hakyll-src [ + doJailbreak + dontCheck + (withPatch ./hakyll.patch) + (withFlags [ "-f" "watchServer" "-f" "previewServer" ]) + ]; + + pandoc = pipe pandoc-src [ + doJailbreak + dontCheck + ]; + + ssg = hpPrev.callCabal2nix "ssg" ./ssg {}; + + website = prev.stdenv.mkDerivation { + #__contentAddressed = true; # uncomment if using cas: https://www.tweag.io/blog/2020-09-10-nix-cas/ + name = "website"; + buildInputs = [ ssg ]; + src = prev.nix-gitignore.gitignoreSourcePure [ + ./.gitignore + ".git" + ".github" + ] ./.; + + # LANG and LOCALE_ARCHIVE are fixes pulled from the community: + # https://github.com/jaspervdj/hakyll/issues/614#issuecomment-411520691 + # https://github.com/NixOS/nix/issues/318#issuecomment-52986702 + # https://github.com/MaxDaten/brutal-recipes/blob/source/default.nix#L24 + LANG = "en_US.UTF-8"; + LOCALE_ARCHIVE = prev.lib.optionalString + (prev.buildPlatform.libc == "glibc") + "${prev.glibcLocales}/lib/locale/locale-archive"; + + buildPhase = '' + hakyll-site build --verbose + ''; + + installPhase = '' + mkdir -p "$out/dist" + cp -r dist/* "$out/dist" + ''; + }; + }; + }; +} diff --git a/nix/default.nix b/nix/default.nix deleted file mode 100644 index ebb18c3..0000000 --- a/nix/default.nix +++ /dev/null @@ -1,44 +0,0 @@ -let - sources = import ./sources.nix; - config = { allowBroken = true; }; -in -{ pkgs ? import sources.nixpkgs { inherit config; } }: - - let - pre-commit-hooks = import sources."pre-commit-hooks.nix"; - haskellPackages = pkgs.callPackage ../generator/hpkgs.nix {}; - generator = haskellPackages.callPackage ../generator/default.nix {}; - src = ../src; - in - { - inherit generator haskellPackages pkgs src; - - tools = [ - # uncomment pkgs.cacert & pkgs.nix if nix-shell --pure - # (https://github.com/nmattia/niv/issues/222) - - #pkgs.cacert - #pkgs.nix - generator - pkgs.niv - pkgs.pre-commit - pre-commit-hooks.hlint - pre-commit-hooks.nixpkgs-fmt - pre-commit-hooks.ormolu - ]; - - ci = { - pre-commit-check = pre-commit-hooks.run { - inherit src; - - hooks = { - hlint.enable = true; - nix-linter.enable = true; - nixpkgs-fmt.enable = true; - ormolu.enable = true; - shellcheck.enable = true; - }; - excludes = [ "^nix/sources\.nix$" ]; - }; - }; - } diff --git a/nix/sources.json b/nix/sources.json deleted file mode 100644 index 0ec4488..0000000 --- a/nix/sources.json +++ /dev/null @@ -1,38 +0,0 @@ -{ - "niv": { - "branch": "master", - "description": "Easy dependency management for Nix projects", - "homepage": "https://github.com/nmattia/niv", - "owner": "nmattia", - "repo": "niv", - "rev": "20c899271f288d33114760bc298838575fc6c7f9", - "sha256": "07zswk6dhlydihl9g6skmy52grjvqpra8r98f2dmbgwzc1yhjhxq", - "type": "tarball", - "url": "https://github.com/nmattia/niv/archive/20c899271f288d33114760bc298838575fc6c7f9.tar.gz", - "url_template": "https://github.com///archive/.tar.gz" - }, - "nixpkgs": { - "branch": "nixos-20.09", - "description": "A read-only mirror of NixOS/nixpkgs tracking the released channels. Send issues and PRs to", - "homepage": "https://github.com/NixOS/nixpkgs", - "owner": "nixos", - "repo": "nixpkgs", - "rev": "edb26126d98bc696f4f3e206583faa65d3d6e818", - "sha256": "1cl4ka4kk7kh3bl78g06dhiidazf65q8miyzaxi9930d6gwyzkci", - "type": "tarball", - "url": "https://github.com/nixos/nixpkgs/archive/edb26126d98bc696f4f3e206583faa65d3d6e818.tar.gz", - "url_template": "https://github.com///archive/.tar.gz" - }, - "pre-commit-hooks.nix": { - "branch": "master", - "description": "Seamless integration of https://pre-commit.com git hooks with Nix.", - "homepage": "", - "owner": "cachix", - "repo": "pre-commit-hooks.nix", - "rev": "117579f3cfe4c0abeff70631fa31261d5ea99cfd", - "sha256": "1bjvadx76rlf54b43agfx1w35wqpagzihdv2yy0jsrk1glxc15ax", - "type": "tarball", - "url": "https://github.com/cachix/pre-commit-hooks.nix/archive/117579f3cfe4c0abeff70631fa31261d5ea99cfd.tar.gz", - "url_template": "https://github.com///archive/.tar.gz" - } -} diff --git a/nix/sources.nix b/nix/sources.nix deleted file mode 100644 index b64b8f8..0000000 --- a/nix/sources.nix +++ /dev/null @@ -1,148 +0,0 @@ -# This file has been generated by Niv. - -let - - # - # The fetchers. fetch_ fetches specs of type . - # - - fetch_file = pkgs: spec: - if spec.builtin or true then - builtins_fetchurl { inherit (spec) url sha256; } - else - pkgs.fetchurl { inherit (spec) url sha256; }; - - fetch_tarball = pkgs: name: spec: - let - ok = str: ! builtins.isNull (builtins.match "[a-zA-Z0-9+-._?=]" str); - # sanitize the name, though nix will still fail if name starts with period - name' = stringAsChars (x: if ! ok x then "-" else x) "${name}-src"; - in - if spec.builtin or true then - builtins_fetchTarball { name = name'; inherit (spec) url sha256; } - else - pkgs.fetchzip { name = name'; inherit (spec) url sha256; }; - - fetch_git = spec: - builtins.fetchGit { url = spec.repo; inherit (spec) rev ref; }; - - fetch_local = spec: spec.path; - - fetch_builtin-tarball = name: throw - ''[${name}] The niv type "builtin-tarball" is deprecated. You should instead use `builtin = true`. - $ niv modify ${name} -a type=tarball -a builtin=true''; - - fetch_builtin-url = name: throw - ''[${name}] The niv type "builtin-url" will soon be deprecated. You should instead use `builtin = true`. - $ niv modify ${name} -a type=file -a builtin=true''; - - # - # Various helpers - # - - # The set of packages used when specs are fetched using non-builtins. - mkPkgs = sources: - let - sourcesNixpkgs = - import (builtins_fetchTarball { inherit (sources.nixpkgs) url sha256; }) {}; - hasNixpkgsPath = builtins.any (x: x.prefix == "nixpkgs") builtins.nixPath; - hasThisAsNixpkgsPath = == ./.; - in - if builtins.hasAttr "nixpkgs" sources - then sourcesNixpkgs - else if hasNixpkgsPath && ! hasThisAsNixpkgsPath then - import {} - else - abort - '' - Please specify either (through -I or NIX_PATH=nixpkgs=...) or - add a package called "nixpkgs" to your sources.json. - ''; - - # The actual fetching function. - fetch = pkgs: name: spec: - - if ! builtins.hasAttr "type" spec then - abort "ERROR: niv spec ${name} does not have a 'type' attribute" - else if spec.type == "file" then fetch_file pkgs spec - else if spec.type == "tarball" then fetch_tarball pkgs name spec - else if spec.type == "git" then fetch_git spec - else if spec.type == "local" then fetch_local spec - else if spec.type == "builtin-tarball" then fetch_builtin-tarball name - else if spec.type == "builtin-url" then fetch_builtin-url name - else - abort "ERROR: niv spec ${name} has unknown type ${builtins.toJSON spec.type}"; - - # If the environment variable NIV_OVERRIDE_${name} is set, then use - # the path directly as opposed to the fetched source. - replace = name: drv: - let - saneName = stringAsChars (c: if isNull (builtins.match "[a-zA-Z0-9]" c) then "_" else c) name; - ersatz = builtins.getEnv "NIV_OVERRIDE_${saneName}"; - in - if ersatz == "" then drv else ersatz; - - # Ports of functions for older nix versions - - # a Nix version of mapAttrs if the built-in doesn't exist - mapAttrs = builtins.mapAttrs or ( - f: set: with builtins; - listToAttrs (map (attr: { name = attr; value = f attr set.${attr}; }) (attrNames set)) - ); - - # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/lists.nix#L295 - range = first: last: if first > last then [] else builtins.genList (n: first + n) (last - first + 1); - - # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L257 - stringToCharacters = s: map (p: builtins.substring p 1 s) (range 0 (builtins.stringLength s - 1)); - - # https://github.com/NixOS/nixpkgs/blob/0258808f5744ca980b9a1f24fe0b1e6f0fecee9c/lib/strings.nix#L269 - stringAsChars = f: s: concatStrings (map f (stringToCharacters s)); - concatStrings = builtins.concatStringsSep ""; - - # fetchTarball version that is compatible between all the versions of Nix - builtins_fetchTarball = { url, name, sha256 }@attrs: - let - inherit (builtins) lessThan nixVersion fetchTarball; - in - if lessThan nixVersion "1.12" then - fetchTarball { inherit name url; } - else - fetchTarball attrs; - - # fetchurl version that is compatible between all the versions of Nix - builtins_fetchurl = { url, sha256 }@attrs: - let - inherit (builtins) lessThan nixVersion fetchurl; - in - if lessThan nixVersion "1.12" then - fetchurl { inherit url; } - else - fetchurl attrs; - - # Create the final "sources" from the config - mkSources = config: - mapAttrs ( - name: spec: - if builtins.hasAttr "outPath" spec - then abort - "The values in sources.json should not have an 'outPath' attribute" - else - spec // { outPath = replace name (fetch config.pkgs name spec); } - ) config.sources; - - # The "config" used by the fetchers - mkConfig = - { sourcesFile ? if builtins.pathExists ./sources.json then ./sources.json else null - , sources ? if isNull sourcesFile then {} else builtins.fromJSON (builtins.readFile sourcesFile) - , pkgs ? mkPkgs sources - }: rec { - # The sources, i.e. the attribute set of spec name to spec - inherit sources; - - # The "pkgs" (evaluated nixpkgs) to use for e.g. non-builtin fetchers - inherit pkgs; - }; - -in -mkSources (mkConfig {}) // { __functor = _: settings: mkSources (mkConfig settings); } diff --git a/shell.nix b/shell.nix deleted file mode 100644 index 80355bd..0000000 --- a/shell.nix +++ /dev/null @@ -1,14 +0,0 @@ -let - sources = import ./nix/sources.nix; -in -{ pkgs ? import sources.nixpkgs {} }: - - let - cfg = import ./nix/default.nix {}; - in - pkgs.mkShell { - buildInputs = cfg.tools; - shellHook = '' - ${cfg.ci.pre-commit-check.shellHook} - ''; - } diff --git a/src/css/article.css b/src/css/article.css deleted file mode 100644 index 86fa71a..0000000 --- a/src/css/article.css +++ /dev/null @@ -1,44 +0,0 @@ -:root { - font-size: 62.5%; - box-sizing: border-box; - -ms-text-size-adjust: 100%; - -webkit-text-size-adjust: 100%; -} -*, -*:before, -*:after { - box-sizing: inherit; -} -html, -body { - min-height: 100vh; -} -body { - font-kerning: normal; - -moz-font-feature-settings: "kern", "liga", "clig", "calt"; - -ms-font-feature-settings: "kern", "liga", "clig", "calt"; - -webkit-font-feature-settings: "kern", "liga", "clig", "calt"; - font-feature-settings: "kern", "liga", "clig", "calt"; - scroll-behavior: smooth; -} -article h1, -article small, -article p { - -webkit-font-smoothing: antialiased; - -moz-osx-font-smoothing: grayscale; -} -article h1 { - font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif; - font-size: 4.0rem; -} -article small, -article p { - font-family: Tahoma, Arial, sans-serif; -} -article small { - font-size: 1.6rem; - font-style: italic; -} -article p { - font-size: 1.8rem; -} diff --git a/src/css/default.css b/src/css/default.css index 7a3a707..23bb11d 100644 --- a/src/css/default.css +++ b/src/css/default.css @@ -20,11 +20,35 @@ body { -webkit-font-feature-settings: "kern", "liga", "clig", "calt"; font-feature-settings: "kern", "liga", "clig", "calt"; scroll-behavior: smooth; + font-size: 2rem; +} +body, +input, +button { + -webkit-font-smoothing: antialiased; + -moz-osx-font-smoothing: grayscale; +} +h1, +h2 { + font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif; +} +h1 { + font-size: 4.0rem; +} +h2 { + font-size: 2.6rem; +} +small, +p { + font-family: Tahoma, Arial, sans-serif; +} +small { + font-size: 1.6rem; + font-style: italic; +} +p { + font-size: 1.8rem; +} +pre.sourceCode { + padding: 2rem 1.5rem; } -.ffs { font-family: "Palatino Linotype", "Book Antiqua", Palatino, serif; } -.ffss { font-family: Tahoma, Arial, sans-serif; } -.fs { -webkit-font-smoothing: antialiased; -moz-osx-font-smoothing: grayscale; } -.fs14 { font-size: 1.4rem; } -.fs18 { font-size: 1.8rem; } -.fs32 { font-size: 3.2rem; } -.fs40 { font-size: 4.0rem; } diff --git a/src/index.html b/src/index.html index 6fc847e..30f5fb6 100644 --- a/src/index.html +++ b/src/index.html @@ -7,7 +7,7 @@ title: "Hello, world!" ---
-

Hello, world!

+

Hello, world!

A woman sitting on a bench amongst trees at the end of a boardwalk leading to a pond with mountains in the background
-

Blog Posts

+

Blog Posts

diff --git a/src/posts/2020-09-21-hello-world.md b/src/posts/2020-09-21-hello-world.md index c8d2e2b..6fb6b67 100644 --- a/src/posts/2020-09-21-hello-world.md +++ b/src/posts/2020-09-21-hello-world.md @@ -5,7 +5,6 @@ desc: "I announce myself to the world" image: "./images/waiheke-stony-batter.jpg" keywords: "hello, announcement" lang: "en" -stylesheet: "article" title: "Hello, world!" updated: "2020-09-22T12:00:00Z" --- @@ -17,3 +16,11 @@ Hello, world! I am here! src="./images/waiheke-stony-batter.jpg" style="max-width:500px;" /> + +Haskell, for example: + +```haskell +toSlug :: T.Text -> T.Text +toSlug = + T.intercalate (T.singleton '-') . T.words . T.toLower . clean +``` diff --git a/src/posts/2020-09-22-hola-mundo.md b/src/posts/2020-09-22-hola-mundo.md index 11b9109..2bb0db9 100644 --- a/src/posts/2020-09-22-hola-mundo.md +++ b/src/posts/2020-09-22-hola-mundo.md @@ -5,7 +5,6 @@ desc: "Me anuncio al mundo" image: "./images/waiheke-stony-batter.jpg" keywords: "hola, anuncio" lang: "es" -stylesheet: "article" title: "¡Hola Mundo!" updated: "2020-09-23T12:00:00Z" --- @@ -17,3 +16,11 @@ updated: "2020-09-23T12:00:00Z" src="./images/waiheke-stony-batter.jpg" style="max-width:500px;" /> + +Haskell, por ejemplo: + +```haskell +toSlug :: T.Text -> T.Text +toSlug = + T.intercalate (T.singleton '-') . T.words . T.toLower . clean +``` diff --git a/src/templates/default.html b/src/templates/default.html index 264fdc0..b099c14 100644 --- a/src/templates/default.html +++ b/src/templates/default.html @@ -40,9 +40,7 @@ - $if(stylesheet)$ - - $endif$ + $body$ diff --git a/ssg/LICENSE b/ssg/LICENSE new file mode 100644 index 0000000..1009f96 --- /dev/null +++ b/ssg/LICENSE @@ -0,0 +1,29 @@ +BSD 3-Clause License + +Copyright (c) 2020, Robert Pearce +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this + list of conditions and the following disclaimer. + +2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation + and/or other materials provided with the distribution. + +3. Neither the name of the copyright holder nor the names of its + contributors may be used to endorse or promote products derived from + this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/generator/src/Main.hs b/ssg/src/Main.hs similarity index 87% rename from generator/src/Main.hs rename to ssg/src/Main.hs index f610117..0ff0a3f 100644 --- a/generator/src/Main.hs +++ b/ssg/src/Main.hs @@ -9,18 +9,19 @@ import Text.Pandoc ( Extension (Ext_fenced_code_attributes, Ext_footnotes, Ext_gfm_auto_identifiers, Ext_implicit_header_references, Ext_smart), Extensions, ReaderOptions, - WriterOptions, + WriterOptions (writerHighlightStyle), extensionsFromList, githubMarkdownExtensions, readerExtensions, writerExtensions, ) +import Text.Pandoc.Highlighting (Style, breezeDark, styleToCss) -- CONFIG root :: String root = - "https://rpearce.github.io/hakyll-nix-template" + "https://my-site.com" siteName :: String siteName = @@ -29,13 +30,13 @@ siteName = config :: Configuration config = defaultConfiguration - { destinationDirectory = "../dist", + { destinationDirectory = "dist", ignoreFile = const False, previewHost = "127.0.0.1", previewPort = 8000, - providerDirectory = "../src", - storeDirectory = "../hakyll-cache", - tmpDirectory = "../hakyll-cache/tmp" + providerDirectory = "src", + storeDirectory = "ssg/_cache", + tmpDirectory = "ssg/_tmp" } -- BUILD @@ -56,51 +57,75 @@ main = hakyllWith config $ do $ \f -> match f $ do route idRoute compile copyFileCompiler + match "css/*" $ do route idRoute compile compressCssCompiler + match "posts/*" $ do let ctx = constField "type" "article" <> postCtx + route $ metadataRoute titleRoute compile $ pandocCompilerCustom >>= loadAndApplyTemplate "templates/post.html" ctx >>= saveSnapshot "content" >>= loadAndApplyTemplate "templates/default.html" ctx + match "index.html" $ do route idRoute compile $ do posts <- recentFirst =<< loadAll "posts/*" + let indexCtx = listField "posts" postCtx (return posts) <> constField "root" root <> constField "siteName" siteName <> defaultContext + getResourceBody >>= applyAsTemplate indexCtx >>= loadAndApplyTemplate "templates/default.html" indexCtx + match "templates/*" $ compile templateBodyCompiler + create ["sitemap.xml"] $ do route idRoute compile $ do posts <- recentFirst =<< loadAll "posts/*" + let pages = posts sitemapCtx = constField "root" root <> constField "siteName" siteName <> listField "pages" postCtx (return pages) + makeItem ("" :: String) >>= loadAndApplyTemplate "templates/sitemap.xml" sitemapCtx + create ["rss.xml"] $ do route idRoute compile (feedCompiler renderRss) + create ["atom.xml"] $ do route idRoute compile (feedCompiler renderAtom) + create ["css/code.css"] $ do + route idRoute + compile (makeStyle pandocHighlightStyle) + + {- ORMOLU_ENABLE -} + +-- COMPILER HELPERS + +makeStyle :: Style -> Compiler (Item String) +makeStyle = + makeItem . compressCss . styleToCss + -- CONTEXT feedCtx :: Context String @@ -165,8 +190,13 @@ pandocWriterOpts :: WriterOptions pandocWriterOpts = defaultHakyllWriterOptions { writerExtensions = pandocExtensionsCustom + , writerHighlightStyle = Just pandocHighlightStyle } +pandocHighlightStyle :: Style +pandocHighlightStyle = + breezeDark -- https://hackage.haskell.org/package/pandoc/docs/Text-Pandoc-Highlighting.html + -- FEEDS type FeedRenderer = diff --git a/generator/src/Slug.hs b/ssg/src/Slug.hs similarity index 100% rename from generator/src/Slug.hs rename to ssg/src/Slug.hs diff --git a/generator/hakyll-nix-template.cabal b/ssg/ssg.cabal similarity index 62% rename from generator/hakyll-nix-template.cabal rename to ssg/ssg.cabal index fbb6db5..cbc48d9 100644 --- a/generator/hakyll-nix-template.cabal +++ b/ssg/ssg.cabal @@ -1,6 +1,6 @@ cabal-version: 2.4 -name: hakyll-nix-template +name: ssg version: 0.1.0.0 build-type: Simple license: BSD-3-Clause @@ -10,10 +10,10 @@ executable hakyll-site main-is: Main.hs hs-source-dirs: src build-depends: base == 4.* - , hakyll ^>= 4.13.3.0 - , pandoc >= 2.0.5 && < 2.10 - , text ^>= 1.2.4 - , time >= 1.8 && < 1.10 + , hakyll ^>= 4.14 + , pandoc + , text + , time other-modules: Slug ghc-options: -Wall -threaded default-language: Haskell2010