diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -4,6 +4,18 @@
 
 # Releases
 
+## Hakyll 4.10.0.0
+
+- Bump Pandoc to 2.0 (contribution by Vaibhav Sagar)
+- Fix compression of calc() in CSS (contribution by Krzysztof Jurewicz)
+- Make unixFilter output stderr when failing (contribution by Nick Boultbee)
+- Export Check type from `Hakyll.Commands` (contribution by Futtetennista)
+- Add overwritten files check to `hakyll-init` (contribution by Ilya Murzinov)
+- Expose & document `hakyllWithExitCodeAndArgs`, `Options`, and `Command`
+  (contribution by Michael Walker)
+- Add check for non-overlapping redirects (contribution by gwern)
+- Fix early exit when calling check as a library
+
 ## Hakyll 4.9.8.0
 
 - Bump pandoc-citeproc to 0.10.5
diff --git a/data/example/css/default.css b/data/example/css/default.css
--- a/data/example/css/default.css
+++ b/data/example/css/default.css
@@ -1,56 +1,141 @@
+html {
+  font-size: 62.5%;
+}
+
 body {
-    color: black;
-    font-size: 16px;
-    margin: 0px auto 0px auto;
-    width: 600px;
+  font-size: 1.6rem;
+  color: #000;
 }
 
 header {
-    border-bottom: 2px solid black;
-    margin-bottom: 30px;
-    padding: 12px 0px 12px 0px;
+  border-bottom: 0.2rem solid #000;
 }
 
 nav {
-    text-align: right;
+  text-align: right;
 }
 
 nav a {
-    color: black;
-    font-size: 18px;
-    font-weight: bold;
-    margin-left: 12px;
-    text-decoration: none;
-    text-transform: uppercase;
+  font-size: 1.8rem;
+  font-weight: bold;
+  color: black;
+  text-decoration: none;
+  text-transform: uppercase;
 }
 
 footer {
-    border-top: solid 2px black;
-    color: #555;
-    font-size: 12px;
-    margin-top: 30px;
-    padding: 12px 0px 12px 0px;
-    text-align: right;
+  margin-top: 3rem;
+  padding: 1.2rem 0;
+  border-top: 0.2rem solid #000;
+  font-size: 1.2rem;
+  color: #555;
 }
 
 h1 {
-    font-size: 24px;
+  font-size: 2.4rem;
 }
 
 h2 {
-    font-size: 20px;
+  font-size: 2rem;
 }
 
 article .header {
-    color: #555;
-    font-size: 14px;
-    font-style: italic;
+  font-size: 1.4rem;
+  font-style: italic;
+  color: #555;
 }
 
 .logo a {
-    color: black;
+  font-weight: bold;
+  color: #000;
+  text-decoration: none;
+}
+
+@media (max-width: 319px) {
+  body {
+    width: 90%;
+    margin: 0;
+    padding: 0 5%;
+  }
+  header {
+    margin: 4.2rem 0;
+  }
+  nav {
+    margin: 0 auto 3rem;
+    text-align: center;
+  }
+  footer {
+    text-align: center;
+  }
+  .logo {
+    text-align: center;
+    margin: 1rem auto 3rem;
+  }
+  .logo a {
+    font-size: 2.4rem;
+  }
+  nav a {
+    display: block;
+    line-height: 1.6;
+  }
+}
+
+@media (min-width: 320px) {
+  body {
+    width: 90%;
+    margin: 0;
+    padding: 0 5%;
+  }
+  header {
+    margin: 4.2rem 0;
+  }
+  nav {
+    margin: 0 auto 3rem;
+    text-align: center;
+  }
+  footer {
+    text-align: center;
+  }
+  .logo {
+    text-align: center;
+    margin: 1rem auto 3rem;
+  }
+  .logo a {
+    font-size: 2.4rem;
+  }
+  nav a {
+    display: inline;
+    margin: 0 0.6rem;
+  }
+}
+
+@media (min-width: 640px) {
+  body {
+    width: 60rem;
+    margin: 0 auto;
+    padding: 0;
+  }
+  header {
+    margin: 0 0 3rem;
+    padding: 1.2rem 0;
+  }
+  nav {
+    margin: 0;
+    text-align: right;
+  }
+  nav a {
+    margin: 0 0 0 1.2rem;
+    display: inline;
+  }
+  footer {
+    text-align: right;
+  }
+  .logo {
+    margin: 0;
+    text-align: left;
+  }
+  .logo a {
     float: left;
-    font-size: 18px;
-    font-weight: bold;
-    text-decoration: none;
+    font-size: 1.8rem;
+  }
 }
diff --git a/hakyll.cabal b/hakyll.cabal
--- a/hakyll.cabal
+++ b/hakyll.cabal
@@ -1,5 +1,5 @@
 Name:    hakyll
-Version: 4.9.8.0
+Version: 4.10.0.0
 
 Synopsis: A static website compiler library
 Description:
@@ -153,38 +153,38 @@
     Paths_hakyll
 
   Build-Depends:
-    base                 >= 4.8    && < 5,
-    binary               >= 0.5    && < 0.9,
-    blaze-html           >= 0.5    && < 0.10,
-    blaze-markup         >= 0.5.1  && < 0.9,
-    bytestring           >= 0.9    && < 0.11,
-    containers           >= 0.3    && < 0.6,
-    cryptohash           >= 0.7    && < 0.12,
-    data-default         >= 0.4    && < 0.8,
-    deepseq              >= 1.3    && < 1.5,
-    directory            >= 1.0    && < 1.4,
-    filepath             >= 1.0    && < 1.5,
-    lrucache             >= 1.1.1  && < 1.3,
-    mtl                  >= 1      && < 2.3,
-    network              >= 2.6    && < 2.7,
-    network-uri          >= 2.6    && < 2.7,
-    pandoc               >= 1.14   && < 1.20,
-    pandoc-citeproc      >= 0.10.5 && < 0.11,
-    parsec               >= 3.0    && < 3.2,
-    process              >= 1.0    && < 1.6,
-    random               >= 1.0    && < 1.2,
-    regex-base           >= 0.93   && < 0.94,
-    regex-tdfa           >= 1.1    && < 1.3,
-    resourcet            >= 1.1    && < 1.2,
-    scientific           >= 0.3.4  && < 0.4,
-    tagsoup              >= 0.13.1 && < 0.15,
-    text                 >= 0.11   && < 1.3,
-    time                 >= 1.4    && < 1.8,
-    time-locale-compat   >= 0.1    && < 0.2,
-    unordered-containers >= 0.2    && < 0.3,
-    vector               >= 0.11   && < 0.13,
-    yaml                 >= 0.8.11 && < 0.9,
-    optparse-applicative >= 0.12   && < 0.15
+    base                 >= 4.8      && < 5,
+    binary               >= 0.5      && < 0.9,
+    blaze-html           >= 0.5      && < 0.10,
+    blaze-markup         >= 0.5.1    && < 0.9,
+    bytestring           >= 0.9      && < 0.11,
+    containers           >= 0.3      && < 0.6,
+    cryptohash           >= 0.7      && < 0.12,
+    data-default         >= 0.4      && < 0.8,
+    deepseq              >= 1.3      && < 1.5,
+    directory            >= 1.0      && < 1.4,
+    filepath             >= 1.0      && < 1.5,
+    lrucache             >= 1.1.1    && < 1.3,
+    mtl                  >= 1        && < 2.3,
+    network              >= 2.6      && < 2.7,
+    network-uri          >= 2.6      && < 2.7,
+    pandoc               >= 2.0.5    && < 2.1,
+    pandoc-citeproc      >= 0.12.1.1 && < 0.13,
+    parsec               >= 3.0      && < 3.2,
+    process              >= 1.6      && < 1.7,
+    random               >= 1.0      && < 1.2,
+    regex-base           >= 0.93     && < 0.94,
+    regex-tdfa           >= 1.1      && < 1.3,
+    resourcet            >= 1.1      && < 1.2,
+    scientific           >= 0.3.4    && < 0.4,
+    tagsoup              >= 0.13.1   && < 0.15,
+    text                 >= 0.11     && < 1.3,
+    time                 >= 1.8      && < 1.9,
+    time-locale-compat   >= 0.1      && < 0.2,
+    unordered-containers >= 0.2      && < 0.3,
+    vector               >= 0.11     && < 0.13,
+    yaml                 >= 0.8.11   && < 0.9,
+    optparse-applicative >= 0.12     && < 0.15
 
   If flag(previewServer)
     Build-depends:
@@ -248,38 +248,38 @@
     tasty-hunit                >= 0.9  && < 0.10,
     tasty-quickcheck           >= 0.8  && < 0.10,
     -- Copy pasted from hakyll dependencies:
-    base                 >= 4.8    && < 5,
-    binary               >= 0.5    && < 0.9,
-    blaze-html           >= 0.5    && < 0.10,
-    blaze-markup         >= 0.5.1  && < 0.9,
-    bytestring           >= 0.9    && < 0.11,
-    containers           >= 0.3    && < 0.6,
-    cryptohash           >= 0.7    && < 0.12,
-    data-default         >= 0.4    && < 0.8,
-    deepseq              >= 1.3    && < 1.5,
-    directory            >= 1.0    && < 1.4,
-    filepath             >= 1.0    && < 1.5,
-    lrucache             >= 1.1.1  && < 1.3,
-    mtl                  >= 1      && < 2.3,
-    network              >= 2.6    && < 2.7,
-    network-uri          >= 2.6    && < 2.7,
-    pandoc               >= 1.14   && < 1.20,
-    pandoc-citeproc      >= 0.10.5 && < 0.11,
-    parsec               >= 3.0    && < 3.2,
-    process              >= 1.0    && < 1.6,
-    random               >= 1.0    && < 1.2,
-    regex-base           >= 0.93   && < 0.94,
-    regex-tdfa           >= 1.1    && < 1.3,
-    resourcet            >= 1.1    && < 1.2,
-    scientific           >= 0.3.4  && < 0.4,
-    tagsoup              >= 0.13.1 && < 0.15,
-    text                 >= 0.11   && < 1.3,
-    time                 >= 1.4    && < 1.8,
-    time-locale-compat   >= 0.1    && < 0.2,
-    unordered-containers >= 0.2    && < 0.3,
-    vector               >= 0.11   && < 0.13,
-    yaml                 >= 0.8.11 && < 0.9,
-    optparse-applicative >= 0.12   && < 0.15
+    base                 >= 4.8      && < 5,
+    binary               >= 0.5      && < 0.9,
+    blaze-html           >= 0.5      && < 0.10,
+    blaze-markup         >= 0.5.1    && < 0.9,
+    bytestring           >= 0.9      && < 0.11,
+    containers           >= 0.3      && < 0.6,
+    cryptohash           >= 0.7      && < 0.12,
+    data-default         >= 0.4      && < 0.8,
+    deepseq              >= 1.3      && < 1.5,
+    directory            >= 1.0      && < 1.4,
+    filepath             >= 1.0      && < 1.5,
+    lrucache             >= 1.1.1    && < 1.3,
+    mtl                  >= 1        && < 2.3,
+    network              >= 2.6      && < 2.7,
+    network-uri          >= 2.6      && < 2.7,
+    pandoc               >= 2.0.5    && < 2.1,
+    pandoc-citeproc      >= 0.12.1.1 && < 0.13,
+    parsec               >= 3.0      && < 3.2,
+    process              >= 1.6      && < 1.7,
+    random               >= 1.0      && < 1.2,
+    regex-base           >= 0.93     && < 0.94,
+    regex-tdfa           >= 1.1      && < 1.3,
+    resourcet            >= 1.1      && < 1.2,
+    scientific           >= 0.3.4    && < 0.4,
+    tagsoup              >= 0.13.1   && < 0.15,
+    text                 >= 0.11     && < 1.3,
+    time                 >= 1.8      && < 1.9,
+    time-locale-compat   >= 0.1      && < 0.2,
+    unordered-containers >= 0.2      && < 0.3,
+    vector               >= 0.11     && < 0.13,
+    yaml                 >= 0.8.11   && < 0.9,
+    optparse-applicative >= 0.12     && < 0.15
 
   If flag(previewServer)
     Build-depends:
@@ -310,6 +310,9 @@
   Ghc-options:    -Wall
   Hs-source-dirs: src
   Main-is:        Init.hs
+
+  Other-modules:
+    Paths_hakyll
 
   Build-depends:
     hakyll,
diff --git a/lib/Hakyll/Check.hs b/lib/Hakyll/Check.hs
--- a/lib/Hakyll/Check.hs
+++ b/lib/Hakyll/Check.hs
@@ -17,7 +17,6 @@
 import           Control.Monad.State          (StateT, get, modify, runStateT)
 import           Control.Monad.Trans          (liftIO)
 import           Control.Monad.Trans.Resource (runResourceT)
-import           Data.ByteString.Char8        (unpack)
 import           Data.List                    (isPrefixOf)
 import qualified Data.Map.Lazy                as Map
 import           Network.URI                  (unEscapeString)
diff --git a/lib/Hakyll/Commands.hs b/lib/Hakyll/Commands.hs
--- a/lib/Hakyll/Commands.hs
+++ b/lib/Hakyll/Commands.hs
@@ -2,7 +2,8 @@
 -- | Implementation of Hakyll commands: build, preview...
 {-# LANGUAGE CPP #-}
 module Hakyll.Commands
-    ( build
+    ( Check(..)
+    , build
     , check
     , clean
     , preview
@@ -15,9 +16,11 @@
 
 --------------------------------------------------------------------------------
 import           Control.Concurrent
-import           System.Exit                (ExitCode, exitWith)
+import           System.Exit                (ExitCode)
 
+
 --------------------------------------------------------------------------------
+import           Hakyll.Check               (Check(..))
 import qualified Hakyll.Check               as Check
 import           Hakyll.Core.Configuration
 import           Hakyll.Core.Logger         (Logger)
@@ -26,6 +29,7 @@
 import           Hakyll.Core.Rules.Internal
 import           Hakyll.Core.Runtime
 import           Hakyll.Core.Util.File
+
 
 --------------------------------------------------------------------------------
 #ifdef WATCH_SERVER
diff --git a/lib/Hakyll/Core/UnixFilter.hs b/lib/Hakyll/Core/UnixFilter.hs
--- a/lib/Hakyll/Core/UnixFilter.hs
+++ b/lib/Hakyll/Core/UnixFilter.hs
@@ -92,7 +92,8 @@
         ExitSuccess   -> return output
         ExitFailure e -> fail $
             "Hakyll.Core.UnixFilter.unixFilterWith: " ++
-            unwords (programName : args) ++ " gave exit code " ++ show e
+            unwords (programName : args) ++ " gave exit code " ++ show e ++
+            ". (Error: " ++ err ++ ")"
 
 
 --------------------------------------------------------------------------------
diff --git a/lib/Hakyll/Main.hs b/lib/Hakyll/Main.hs
--- a/lib/Hakyll/Main.hs
+++ b/lib/Hakyll/Main.hs
@@ -7,6 +7,9 @@
     , hakyllWith
     , hakyllWithArgs
     , hakyllWithExitCode
+    , hakyllWithExitCodeAndArgs
+    , Options(..)
+    , Command(..)
     ) where
 
 
@@ -81,7 +84,7 @@
 invokeCommands args conf check logger rules =
     case args of
         Build          -> Commands.build conf logger rules
-        Check   _      -> Commands.check conf logger check >> ok
+        Check   _      -> Commands.check conf logger check
         Clean          -> Commands.clean conf logger >> ok
         Deploy         -> Commands.deploy conf
         Preview p      -> Commands.preview conf logger rules p >> ok
@@ -94,19 +97,31 @@
 
 --------------------------------------------------------------------------------
 
+-- | The parsed command-line options.
 data Options = Options {verbosity :: Bool, optCommand :: Command}
     deriving (Show)
 
+-- | The command to run.
 data Command
     = Build
+    -- ^ Generate the site.
     | Check   {internal_links :: Bool}
+    -- ^ Validate the site output.
     | Clean
+    -- ^ Clean up and remove cache.
     | Deploy
+    -- ^ Upload/deploy your site.
     | Preview {port :: Int}
+    -- ^ [DEPRECATED] Please use the watch command.
     | Rebuild
+    -- ^ Clean and build again.
     | Server  {host :: String, port :: Int}
+    -- ^ Start a preview server.
     | Watch   {host :: String, port :: Int, no_server :: Bool }
+    -- ^ Autocompile on changes and start a preview server.
     deriving (Show)
+
+{-# DEPRECATED Preview "Use Watch instead." #-}
 
 optionParser :: Config.Configuration -> OA.Parser Options
 optionParser conf = Options <$> verboseParser <*> commandParser conf
diff --git a/lib/Hakyll/Web/CompressCss.hs b/lib/Hakyll/Web/CompressCss.hs
--- a/lib/Hakyll/Web/CompressCss.hs
+++ b/lib/Hakyll/Web/CompressCss.hs
@@ -1,6 +1,7 @@
 --------------------------------------------------------------------------------
 -- | Module used for CSS compression. The compression is currently in a simple
 -- state, but would typically reduce the number of bytes by about 25%.
+{-# LANGUAGE PatternGuards #-}
 module Hakyll.Web.CompressCss
     ( compressCssCompiler
     , compressCss
@@ -34,6 +35,8 @@
 compressSeparators [] = []
 compressSeparators str
     | isConstant  = head str : retainConstants compressSeparators (head str) (drop 1 str)
+    | isPrefixOf "calc( " str = "calc(" ++ compressCalcSeparators 1 (drop 6 str)
+    | isPrefixOf "calc(" str = "calc(" ++ compressCalcSeparators 1 (drop 5 str)
     | stripFirst  = compressSeparators (drop 1 str)
     | stripSecond = compressSeparators (head str : (drop 2 str))
     | otherwise   = head str : compressSeparators (drop 1 str)
@@ -42,6 +45,21 @@
     stripFirst  = or $ map (isOfPrefix str) $ [";;", ";}"] ++ (map (\c -> " " ++ c) separators)
     stripSecond = or $ map (isOfPrefix str) $ map (\c -> c ++ " ") separators
     separators  = [" ", "{", "}", ":", ";", ",", ">", "+", "!"]
+
+-- | Compresses separators when starting inside calc().
+compressCalcSeparators :: Int -> String -> String
+compressCalcSeparators 0 str = compressSeparators str
+compressCalcSeparators depth str
+  | stripFirst = compressCalcSeparators depth (tail str)
+  | stripSecond = compressCalcSeparators depth (head str : (drop 2 str))
+  | ('(' : xs) <- str = '(' : compressCalcSeparators (depth + 1) xs
+  | isPrefixOf "calc( " str = compressCalcSeparators depth ("calc(" ++ (drop 6 str))
+  | isPrefixOf "calc(" str = '(' : compressCalcSeparators (depth + 1) (drop 5 str)
+  | (')' : xs) <- str = ')' : compressCalcSeparators (depth - 1) xs
+  | otherwise = head str : compressCalcSeparators depth (tail str)
+  where
+    stripFirst = or $ map (isOfPrefix str) $ map (\c -> " " ++ c) ["*", "/", ")"]
+    stripSecond = or $ map (isOfPrefix str) $ map (\c -> c ++ " ") ["*", "/", "("]
 
 --------------------------------------------------------------------------------
 -- | Compresses all whitespace.
diff --git a/lib/Hakyll/Web/Pandoc.hs b/lib/Hakyll/Web/Pandoc.hs
--- a/lib/Hakyll/Web/Pandoc.hs
+++ b/lib/Hakyll/Web/Pandoc.hs
@@ -22,9 +22,9 @@
 
 
 --------------------------------------------------------------------------------
-import qualified Data.Set                   as S
+import qualified Data.Text                  as T
 import           Text.Pandoc
-import           Text.Pandoc.Error          (PandocError (..))
+import           Text.Pandoc.Highlighting   (pygments)
 
 
 --------------------------------------------------------------------------------
@@ -48,12 +48,10 @@
     -> Item String             -- ^ String to read
     -> Compiler (Item Pandoc)  -- ^ Resulting document
 readPandocWith ropt item =
-    case traverse (reader ropt (itemFileType item)) item of
-        Left (ParseFailure err)  -> fail $
-            "Hakyll.Web.Pandoc.readPandocWith: parse failed: " ++ err
-        Left (ParsecError _ err) -> fail $
+    case runPure $ traverse (reader ropt (itemFileType item)) (fmap T.pack item) of
+        Left err    -> fail $
             "Hakyll.Web.Pandoc.readPandocWith: parse failed: " ++ show err
-        Right item'              -> return item'
+        Right item' -> return item'
   where
     reader ro t = case t of
         DocBook            -> readDocBook ro
@@ -69,7 +67,7 @@
             "Hakyll.Web.readPandocWith: I don't know how to read a file of " ++
             "the type " ++ show t ++ " for: " ++ show (itemIdentifier item)
 
-    addExt ro e = ro {readerExtensions = S.insert e $ readerExtensions ro}
+    addExt ro e = ro {readerExtensions = enableExtension e $ readerExtensions ro}
 
 
 --------------------------------------------------------------------------------
@@ -84,7 +82,10 @@
 writePandocWith :: WriterOptions  -- ^ Writer options for pandoc
                 -> Item Pandoc    -- ^ Document to write
                 -> Item String    -- ^ Resulting HTML
-writePandocWith wopt = fmap $ writeHtmlString wopt
+writePandocWith wopt (Item itemi doc) =
+    case runPure $ writeHtml5String wopt doc of
+        Left err    -> error $ "Hakyll.Web.Pandoc.writePandocWith: " ++ show err
+        Right item' -> Item itemi $ T.unpack item'
 
 
 --------------------------------------------------------------------------------
@@ -147,7 +148,7 @@
 defaultHakyllReaderOptions = def
     { -- The following option causes pandoc to read smart typography, a nice
       -- and free bonus.
-      readerSmart = True
+      readerExtensions = enableExtension Ext_smart pandocExtensions
     }
 
 
@@ -157,8 +158,8 @@
 defaultHakyllWriterOptions = def
     { -- This option causes literate haskell to be written using '>' marks in
       -- html, which I think is a good default.
-      writerExtensions = S.insert Ext_literate_haskell (writerExtensions def)
+      writerExtensions = enableExtension Ext_smart pandocExtensions
     , -- We want to have hightlighting by default, to be compatible with earlier
       -- Hakyll releases
-      writerHighlight  = True
+      writerHighlightStyle = Just pygments
     }
diff --git a/lib/Hakyll/Web/Redirect.hs b/lib/Hakyll/Web/Redirect.hs
--- a/lib/Hakyll/Web/Redirect.hs
+++ b/lib/Hakyll/Web/Redirect.hs
@@ -7,8 +7,9 @@
     ) where
 
 import           Control.Applicative    ((<$>))
-import           Control.Monad          (forM_)
+import           Control.Monad          (forM_, when)
 import           Data.Binary            (Binary (..))
+import           Data.List              (sort, group)
 import           Hakyll.Core.Compiler
 import           Hakyll.Core.Identifier
 import           Hakyll.Core.Routes
@@ -55,6 +56,17 @@
 -- See also <https://groups.google.com/d/msg/hakyll/sWc6zxfh-uM/fUpZPsFNDgAJ>.
 createRedirects :: [(Identifier, String)] -> Rules ()
 createRedirects redirects =
+ do -- redirects are many-to-fewer; keys must be unique, and must point somewhere else:
+    let gkeys = group $ sort $ map fst redirects
+    forM_ gkeys $ \gkey -> case gkey of
+        (k : _ : _) -> fail $
+            "Duplicate 301 redirects; " ++ show k ++ " is ambiguous."
+        _           -> return ()
+
+    forM_ redirects $ \(r, t) ->
+        when (toFilePath r == t) $ fail $
+            "Self-redirect detected: " ++ show r ++ " points to itself."
+
     forM_ redirects $ \(ident, to) ->
         create [ident] $ do
             route idRoute
@@ -81,6 +93,7 @@
 redirectToHtml :: Redirect -> String
 redirectToHtml (Redirect working) =
     "<!DOCTYPE html><html><head><meta charset=\"utf-8\"/><meta name=\"generator\" content=\"hakyll\"/>" ++
+    "<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">" ++
     "<meta http-equiv=\"refresh\" content=\"0; url=" ++ working ++
     "\"><link rel=\"canonical\" href=\"" ++ working ++
     "\"><title>Permanent Redirect</title></head><body><p>The page has moved to: <a href=\"" ++ working ++
diff --git a/src/Init.hs b/src/Init.hs
--- a/src/Init.hs
+++ b/src/Init.hs
@@ -8,10 +8,10 @@
 import           Control.Arrow         (first)
 import           Control.Monad         (forM_)
 import           Data.Char             (isAlphaNum, isNumber)
-import           Data.List             (foldl')
-import           Data.List             (intercalate, isPrefixOf)
+import           Data.List             (foldl', intercalate, isPrefixOf)
 import           Data.Version          (Version (..))
-import           System.Directory      (canonicalizePath, copyFile)
+import           System.Directory      (canonicalizePath, copyFile,
+                                        doesFileExist)
 import           System.Environment    (getArgs, getProgName)
 import           System.Exit           (exitFailure)
 import           System.FilePath       (splitDirectories, (</>))
@@ -37,22 +37,46 @@
         -- If dstDir begins with hyphens, the guard will prevent it from creating
         -- directory with that name so we can fall to the second alternative
         -- which prints a usage info for user.
-        [dstDir] | not ("-" `isPrefixOf` dstDir) -> do
-            forM_ files $ \file -> do
-                let dst = dstDir </> file
-                    src = srcDir </> file
-                putStrLn $ "Creating " ++ dst
-                makeDirectories dst
-                copyFile src dst
+        [dstDir] | not ("-" `isPrefixOf` dstDir) ->
+            createFiles False srcDir files dstDir
+        ["-f", dstDir] ->
+            createFiles True srcDir files dstDir
+        _ -> do
+            putStrLn $ "Usage: " ++ progName ++ "[-f] <directory>"
+            exitFailure
 
+    where
+        createFiles force srcDir files dstDir = do
             name <- makeName dstDir
             let cabalPath = dstDir </> name ++ ".cabal"
-            putStrLn $ "Creating " ++ cabalPath
-            createCabal cabalPath name
-        _ -> do
-            putStrLn $ "Usage: " ++ progName ++ " <directory>"
-            exitFailure
 
+            diff <- if force then return []
+                    else existingFiles dstDir (cabalPath : files)
+
+            case diff of
+                [] -> do
+                    forM_ files $ \file -> do
+                        let dst = dstDir </> file
+                            src = srcDir </> file
+                        putStrLn $ "Creating " ++ dst
+                        makeDirectories dst
+                        copyFile src dst
+
+                    putStrLn $ "Creating " ++ cabalPath
+                    createCabal cabalPath name
+                fs -> do
+                    putStrLn $ "The following files will be overwritten:"
+                    foldMap putStrLn fs
+                    putStrLn $ "Use -f to overwrite them"
+                    exitFailure
+
+existingFiles :: FilePath -> [FilePath] -> IO [FilePath]
+existingFiles dstDir = foldMap $ \file -> do
+    let dst = dstDir </> file
+    exists <- doesFileExist dst
+    return $ if exists then [dst] else []
+
+
 -- | Figure out a good cabal package name from the given (existing) directory
 -- name
 makeName :: FilePath -> IO String
@@ -77,7 +101,7 @@
     safeLast = foldl' (\_ x -> Just x) Nothing
 
 createCabal :: FilePath -> String -> IO ()
-createCabal path name = do
+createCabal path name =
     writeFile path $ unlines [
         "name:               " ++ name
       , "version:            0.1.0.0"
diff --git a/tests/Hakyll/Core/UnixFilter/Tests.hs b/tests/Hakyll/Core/UnixFilter/Tests.hs
--- a/tests/Hakyll/Core/UnixFilter/Tests.hs
+++ b/tests/Hakyll/Core/UnixFilter/Tests.hs
@@ -17,6 +17,7 @@
 import           Hakyll.Core.Compiler.Internal
 import           Hakyll.Core.Item
 import           Hakyll.Core.UnixFilter
+import           Hakyll.Core.Identifier
 import           TestSuite.Util
 
 
@@ -25,16 +26,19 @@
 tests = testGroup "Hakyll.Core.UnixFilter.Tests"
     [ testCase "unixFilter rev"   unixFilterRev
     , testCase "unixFilter false" unixFilterFalse
+    , testCase "unixFilter error" unixFilterError
     ]
 
+testMarkdown :: Identifier
+testMarkdown = "russian.md"
 
 --------------------------------------------------------------------------------
 unixFilterRev :: H.Assertion
 unixFilterRev = do
     store    <- newTestStore
     provider <- newTestProvider store
-    output   <- testCompilerDone store provider "russian.md" compiler
-    expected <- testCompilerDone store provider "russian.md" getResourceString
+    output   <- testCompilerDone store provider testMarkdown compiler
+    expected <- testCompilerDone store provider testMarkdown getResourceString
     H.assert $ rev (itemBody expected) == lines (itemBody output)
     cleanTestEnv
   where
@@ -47,10 +51,24 @@
 unixFilterFalse = do
     store    <- newTestStore
     provider <- newTestProvider store
-    result   <- testCompiler store provider "russian.md" compiler
+    result   <- testCompiler store provider testMarkdown compiler
     H.assert $ case result of
         CompilerError es -> any ("exit code" `isInfixOf`) es
         _                -> False
     cleanTestEnv
   where
     compiler = getResourceString >>= withItemBody (unixFilter "false" [])
+
+
+--------------------------------------------------------------------------------
+unixFilterError :: H.Assertion
+unixFilterError = do
+    store    <- newTestStore
+    provider <- newTestProvider store
+    result   <- testCompiler store provider testMarkdown compiler
+    H.assert $ case result of
+        CompilerError es -> any ("invalid option" `isInfixOf`) es
+        _                -> False
+    cleanTestEnv
+  where
+    compiler = getResourceString >>= withItemBody (unixFilter "head" ["-#"])
diff --git a/tests/Hakyll/Web/CompressCss/Tests.hs b/tests/Hakyll/Web/CompressCss/Tests.hs
--- a/tests/Hakyll/Web/CompressCss/Tests.hs
+++ b/tests/Hakyll/Web/CompressCss/Tests.hs
@@ -5,9 +5,8 @@
 
 
 --------------------------------------------------------------------------------
-import           Data.Char              (toUpper)
 import           Test.Tasty             (TestTree, testGroup)
-import           Test.Tasty.HUnit       (assert, (@=?))
+import           Test.Tasty.HUnit       ((@=?))
 
 
 --------------------------------------------------------------------------------
@@ -42,6 +41,8 @@
         , "a>b"           @=? compressCss "a > b"
         , "a+b"           @=? compressCss "a + b"
         , "a!b"           @=? compressCss "a ! b"
+          -- compress calc()
+        , "calc(1px + 100%/(5 + 3) - (3px + 2px)*5)" @=? compressCss "calc( 1px + 100% / ( 5 +  3) - calc( 3px + 2px ) * 5 )"
           -- compress whitespace even after this curly brace
         , "}"             @=? compressCss ";   }  "
           -- but do not compress separators inside of constants
diff --git a/tests/TestSuite/Util.hs b/tests/TestSuite/Util.hs
--- a/tests/TestSuite/Util.hs
+++ b/tests/TestSuite/Util.hs
@@ -76,13 +76,14 @@
     result <- testCompiler store provider underlying compiler
     case result of
         CompilerDone x _    -> return x
-        CompilerError e     -> error $
+        CompilerError e     -> fail $
             "TestSuite.Util.testCompilerDone: compiler " ++ show underlying ++
             " threw: " ++ intercalate "; " e
-        CompilerRequire i _ -> error $
+        CompilerRequire i _ -> fail $
             "TestSuite.Util.testCompilerDone: compiler " ++ show underlying ++
             " requires: " ++ show i
-
+        CompilerSnapshot _ _ -> fail
+            "TestSuite.Util.testCompilerDone: unexpected CompilerSnapshot"
 
 
 --------------------------------------------------------------------------------
