aboutsummaryrefslogtreecommitdiff
path: root/compiler
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2019-10-07 16:38:46 +0200
committerIgor Pashev <pashev.igor@gmail.com>2019-10-07 17:29:21 +0200
commit7ae181e09835a38d88990f18b8f0ed42835959ee (patch)
treec39d1c51c70f0b3a5f274e2fa489d8c7a92117e8 /compiler
downloadhakyll-template-7ae181e09835a38d88990f18b8f0ed42835959ee.tar.gz
Initial commit
Diffstat (limited to 'compiler')
-rw-r--r--compiler/cabal.project2
-rw-r--r--compiler/default.nix96
-rw-r--r--compiler/site/Main.hs86
-rw-r--r--compiler/site/Rules.hs54
-rw-r--r--compiler/site/site.cabal16
5 files changed, 254 insertions, 0 deletions
diff --git a/compiler/cabal.project b/compiler/cabal.project
new file mode 100644
index 0000000..37b8053
--- /dev/null
+++ b/compiler/cabal.project
@@ -0,0 +1,2 @@
+packages: ./*/*.cabal
+
diff --git a/compiler/default.nix b/compiler/default.nix
new file mode 100644
index 0000000..b9bd640
--- /dev/null
+++ b/compiler/default.nix
@@ -0,0 +1,96 @@
+{ boot ? import <nixpkgs> {} }:
+
+let
+
+ filtFn = root: path: type:
+ let
+ name = baseNameOf path;
+ hidden = builtins.match "\\..+" name != null;
+ nix = builtins.match ".*\\.nix" name != null;
+ r = !hidden && !nix ;
+ in builtins.trace (path + ": " + (if r then "yes" else "no")) r;
+
+ fltsrc = builtins.filterSource (filtFn (builtins.toPath ./. + "/"));
+
+ nixpkgs = boot.pkgs.fetchFromGitHub {
+ owner = "NixOS";
+ repo = "nixpkgs";
+ rev = "897ec814c9c234f3ed9d60a1a713025d2f9fab2d";
+ sha256 = "0alg5h5zmxdrnfdj94fa4yr5g7j7z3424k78aq44r0a0aqm20iy5";
+ };
+
+ config = {
+ allowUnfree = true; # for local packages
+ allowBroken = true; # some nixpkgs' nonsense
+ };
+
+ inherit (import nixpkgs { inherit config; }) pkgs;
+ inherit (pkgs) lib;
+
+ nixHaskellPackages =
+ let
+ isnix = n: _: null != builtins.match ".*\\.nix" n && n != "default.nix";
+ files = lib.filterAttrs isnix (builtins.readDir ./.);
+ in lib.mapAttrs' (n: _:
+ { name = lib.removeSuffix ".nix" n;
+ value = ./. + "/${n}";
+ }) files;
+
+ localHaskellPackages =
+ let
+ islocal = n: t: !lib.hasPrefix "." n && t == "directory";
+ files = lib.filterAttrs islocal (builtins.readDir ./.);
+ in lib.mapAttrs (n: _: fltsrc (./. + "/${n}")) files;
+
+ haskellPackages =
+ let
+
+ hlib = pkgs.haskell.lib;
+
+ set0 = pkgs.haskell.packages.ghc865;
+
+ set1 = set0.extend (
+ self: super:
+ lib.mapAttrs (_: f: super.callPackage f {}) nixHaskellPackages
+ );
+
+ set2 = set1.extend (
+ self: super:
+ lib.mapAttrs (n: d: super.callCabal2nix n d {}) localHaskellPackages
+ );
+
+ set3 = set2.extend (
+ self: super: {
+ mkDerivation = drv: super.mkDerivation (drv // {
+ buildTools = (drv.buildTools or []);
+
+ # XXX a lot of troubles are cause by tests which require fancy packages of features.
+ # XXX Enable tests for critical packages when unsure.
+ doCheck = false;
+
+ doHaddock = false;
+
+ enableExecutableProfiling = false;
+ enableLibraryProfiling = false;
+ });
+
+ primitive = self.primitive_0_7_0_0;
+ primitive-extras = self.primitive-extras_0_8;
+
+ });
+
+ set = set3.extend (
+ self: super:
+ lib.mapAttrs (n: _:
+ hlib.overrideCabal super.${n} (drv:
+ {
+ doCheck = true;
+ configureFlags = (drv.configureFlags or []) ++ [
+ "--ghc-option=-Werror"
+ ];
+ })
+ ) localHaskellPackages);
+
+ in set;
+
+in haskellPackages
diff --git a/compiler/site/Main.hs b/compiler/site/Main.hs
new file mode 100644
index 0000000..e7fb92f
--- /dev/null
+++ b/compiler/site/Main.hs
@@ -0,0 +1,86 @@
+module Main
+ ( main
+ ) where
+
+import Control.Applicative ((<**>))
+import System.Exit (exitWith)
+
+import qualified Options.Applicative as O
+import System.FilePath ((</>))
+
+import qualified Hakyll.Commands as Cmd
+import qualified Hakyll.Core.Configuration as Conf
+import qualified Hakyll.Core.Logger as Logger
+
+import Rules (rules)
+
+data Command
+ = Build
+ | Clean
+ | Check Cmd.Check
+
+parseCheck :: O.Parser Cmd.Check
+parseCheck =
+ O.flag
+ Cmd.InternalLinks
+ Cmd.All
+ (O.long "all" <> O.short 'a' <> O.help "Check external links as well")
+
+parseCommand :: O.Parser Command
+parseCommand =
+ O.subparser $
+ O.command "build" (O.info (pure Build) (O.progDesc "Build the site")) <>
+ O.command "clean" (O.info (pure Clean) (O.progDesc "Clean")) <>
+ O.command
+ "check"
+ (O.info ((Check <$> parseCheck) <**> O.helper) (O.progDesc "Check links"))
+
+data Options = Options
+ { verbose :: Bool
+ , outDir :: FilePath
+ , srcDir :: FilePath
+ , cacheDir :: FilePath
+ , command :: Command
+ }
+
+parseOptions :: O.Parser Options
+parseOptions =
+ Options <$>
+ O.switch (O.long "verbose" <> O.short 'v' <> O.help "Run in verbose mode") <*>
+ O.strOption
+ (O.long "output" <> O.short 'o' <> O.metavar "DIR" <> O.showDefault <>
+ O.value (Conf.destinationDirectory Conf.defaultConfiguration) <>
+ O.help "Output directory") <*>
+ O.strOption
+ (O.long "source" <> O.short 's' <> O.metavar "DIR" <> O.showDefault <>
+ O.value ("." </> "src") <>
+ O.help "Source directory") <*>
+ O.strOption
+ (O.long "cache" <> O.short 'c' <> O.metavar "DIR" <> O.showDefault <>
+ O.value (Conf.storeDirectory Conf.defaultConfiguration) <>
+ O.help "Cache directory") <*>
+ parseCommand
+
+main :: IO ()
+main = do
+ opts <-
+ O.execParser
+ (O.info
+ (parseOptions <**> O.helper)
+ (O.fullDesc <> O.header "Static site compiler"))
+ let conf =
+ Conf.defaultConfiguration
+ { Conf.destinationDirectory = outDir opts
+ , Conf.providerDirectory = srcDir opts
+ , Conf.storeDirectory = cacheDir opts
+ , Conf.tmpDirectory = cacheDir opts </> "tmp"
+ }
+ log <-
+ Logger.new
+ (if verbose opts
+ then Logger.Debug
+ else Logger.Message)
+ case command opts of
+ Build -> Cmd.build conf log rules >>= exitWith
+ Clean -> Cmd.clean conf log
+ Check chk -> Cmd.check conf log chk >>= exitWith
diff --git a/compiler/site/Rules.hs b/compiler/site/Rules.hs
new file mode 100644
index 0000000..0cbf772
--- /dev/null
+++ b/compiler/site/Rules.hs
@@ -0,0 +1,54 @@
+{-# LANGUAGE OverloadedStrings #-}
+
+module Rules
+ ( rules
+ ) where
+
+import Hakyll
+
+postCtx :: Context String
+postCtx = dateField "date" "%B %e, %Y" <> defaultContext
+
+rules :: Rules ()
+rules = do
+ match "images/*" $ do
+ route idRoute
+ compile copyFileCompiler
+ match "css/*" $ do
+ route idRoute
+ compile compressCssCompiler
+ match (fromList ["about.rst", "contact.markdown"]) $ do
+ route $ setExtension "html"
+ compile $
+ pandocCompiler >>=
+ loadAndApplyTemplate "templates/default.html" defaultContext >>=
+ relativizeUrls
+ match "posts/*" $ do
+ route $ setExtension "html"
+ compile $
+ pandocCompiler >>= loadAndApplyTemplate "templates/post.html" postCtx >>=
+ loadAndApplyTemplate "templates/default.html" postCtx >>=
+ relativizeUrls
+ create ["archive.html"] $ do
+ route idRoute
+ compile $ do
+ posts <- recentFirst =<< loadAll "posts/*"
+ let archiveCtx =
+ listField "posts" postCtx (return posts) <>
+ constField "title" "Archives" <>
+ defaultContext
+ makeItem "" >>= loadAndApplyTemplate "templates/archive.html" archiveCtx >>=
+ loadAndApplyTemplate "templates/default.html" archiveCtx >>=
+ relativizeUrls
+ match "index.html" $ do
+ route idRoute
+ compile $ do
+ posts <- recentFirst =<< loadAll "posts/*"
+ let indexCtx =
+ listField "posts" postCtx (return posts) <>
+ constField "title" "Home" <>
+ defaultContext
+ getResourceBody >>= applyAsTemplate indexCtx >>=
+ loadAndApplyTemplate "templates/default.html" indexCtx >>=
+ relativizeUrls
+ match "templates/*" $ compile templateBodyCompiler
diff --git a/compiler/site/site.cabal b/compiler/site/site.cabal
new file mode 100644
index 0000000..072e8f2
--- /dev/null
+++ b/compiler/site/site.cabal
@@ -0,0 +1,16 @@
+cabal-version: >=1.10
+name: site
+version: 0.1.0.0
+build-type: Simple
+
+executable site
+ main-is: Main.hs
+ other-modules:
+ Rules
+ default-language: Haskell2010
+ ghc-options: -threaded
+ build-depends:
+ base -any,
+ filepath -any,
+ hakyll >=4.10,
+ optparse-applicative -any