diff --git a/CHANGELOG.md b/CHANGELOG.md
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,17 @@
 
 ## Unreleased
 
+## [0.3.5] - 2020-01-10
+
+### Added
+
+- #265: print store path size before compressing/pushing
+
+### Fixed
+
+- #258: don't swallow exceptions while --watch-store
+- NixOS: instruct to use sudo
+
 ## [0.3.4] - 2019-10-01
 
 ### Fixed
diff --git a/cachix.cabal b/cachix.cabal
--- a/cachix.cabal
+++ b/cachix.cabal
@@ -1,6 +1,6 @@
 cabal-version:      2.2
 name:               cachix
-version:            0.3.4
+version: 0.3.5
 license:            Apache-2.0
 license-file:       LICENSE
 copyright:          2018 Domen Kožar
@@ -47,6 +47,7 @@
     Cachix.Client.Config.Orphans
     Cachix.Client.Env
     Cachix.Client.Exception
+    Cachix.Client.HumanSize
     Cachix.Client.InstallationMode
     Cachix.Client.NetRc
     Cachix.Client.NixConf
diff --git a/src/Cachix/Client.hs b/src/Cachix/Client.hs
--- a/src/Cachix/Client.hs
+++ b/src/Cachix/Client.hs
@@ -1,6 +1,6 @@
 module Cachix.Client
-  ( main
-    )
+  ( main,
+  )
 where
 
 import Cachix.Client.Commands as Commands
diff --git a/src/Cachix/Client/Commands.hs b/src/Cachix/Client/Commands.hs
--- a/src/Cachix/Client/Commands.hs
+++ b/src/Cachix/Client/Commands.hs
@@ -8,8 +8,8 @@
     create,
     generateKeypair,
     push,
-    use
-    )
+    use,
+  )
 where
 
 import qualified Cachix.Api as Api
@@ -18,29 +18,30 @@
   ( BinaryCacheConfig (..),
     Config (..),
     mkConfig,
-    writeConfig
-    )
+    writeConfig,
+  )
 import qualified Cachix.Client.Config as Config
 import Cachix.Client.Env (Env (..))
 import Cachix.Client.Exception (CachixException (..))
+import Cachix.Client.HumanSize (humanSize)
 import Cachix.Client.InstallationMode
 import qualified Cachix.Client.NixConf as NixConf
 import Cachix.Client.NixVersion (assertNixVersion)
 import Cachix.Client.OptionsParser
   ( CachixOptions (..),
     PushArguments (..),
-    PushOptions (..)
-    )
+    PushOptions (..),
+  )
 import Cachix.Client.Push
 import Cachix.Client.Secrets
   ( SigningKey (SigningKey),
     exportSigningKey,
-    parseSigningKeyLenient
-    )
+    parseSigningKeyLenient,
+  )
 import Cachix.Client.Servant
 import qualified Cachix.Types.SigningKeyCreate as SigningKeyCreate
 import Control.Concurrent (threadDelay)
-import Control.Exception.Safe (throwM)
+import Control.Exception.Safe (handle, throwM)
 import Control.Retry (RetryStatus (rsIterNumber))
 import Crypto.Sign.Ed25519
 import qualified Data.ByteString.Base64 as B64
@@ -68,9 +69,9 @@
   putStrLn
     ( [hereLit|
 Continue by creating a binary cache at https://cachix.org
-  |]
-        :: Text
-      )
+  |] ::
+        Text
+    )
 
 create :: Env -> Text -> IO ()
 create _ _ =
@@ -85,14 +86,12 @@
       bcc = BinaryCacheConfig name signingKey
   -- we first validate if key can be added to the binary cache
   (_ :: NoContent) <-
-    escalate
-      =<< ( (`runClientM` clientenv env)
-              $ Api.createKey (cachixBCClient name) (authToken config) signingKeyCreate
-            )
+    escalate <=< (`runClientM` clientenv env) $
+      Api.createKey (cachixBCClient name) (authToken config) signingKeyCreate
   -- if key was successfully added, write it to the config
   -- TODO: warn if binary cache with the same key already exists
-  writeConfig (configPath (cachixoptions env))
-    $ config {binaryCaches = binaryCaches config <> [bcc]}
+  writeConfig (configPath (cachixoptions env)) $
+    config {binaryCaches = binaryCaches config <> [bcc]}
   putStrLn
     ( [iTrim|
 Secret signing key has been saved in the file above. To populate
@@ -110,9 +109,9 @@
     $ cachix use ${name}
 
 IMPORTANT: Make sure to make a backup for the signing key above, as you have the only copy.
-  |]
-        :: Text
-      )
+  |] ::
+        Text
+    )
 
 envToToken :: Env -> Token
 envToToken env =
@@ -146,9 +145,9 @@
             { isRoot = user == "root",
               isTrusted = isTrusted,
               isNixOS = isNixOS
-              }
-      addBinaryCache (config env) binaryCache useOptions
-        $ fromMaybe (getInstallationMode nixEnv) (useMode useOptions)
+            }
+      addBinaryCache (config env) binaryCache useOptions $
+        fromMaybe (getInstallationMode nixEnv) (useMode useOptions)
 
 -- TODO: lots of room for performance improvements
 push :: Env -> PushArguments -> IO ()
@@ -166,17 +165,18 @@
       (_, paths) -> return paths
   sk <- findSigningKey env name
   store <- wait (storeAsync env)
-  void
-    $ pushClosure
-        (mapConcurrentlyBounded 4)
-        (clientenv env)
-        store PushCache
+  void $
+    pushClosure
+      (mapConcurrentlyBounded 4)
+      (clientenv env)
+      store
+      PushCache
         { pushCacheToken = envToToken env,
           pushCacheName = name,
           pushCacheSigningKey = sk
-          }
-        (pushStrategy env opts name)
-        inputStorePaths
+        }
+      (pushStrategy env opts name)
+      inputStorePaths
   putText "All done."
 push env (PushWatchStore opts name) = withManager $ \mgr -> do
   _ <- watchDir mgr "/nix/store" filterF action
@@ -184,9 +184,14 @@
   putText "Watching /nix/store for new builds ..."
   forever $ threadDelay 1000000
   where
+    logErr :: FilePath -> SomeException -> IO ()
+    logErr fp e = hPutStrLn stderr $ "Exception occured while pushing " <> fp <> ": " <> show e
     action :: Action
     action (Removed fp _ _) =
-      pushStorePath env opts name $ toS $ dropEnd 5 fp
+      Control.Exception.Safe.handle (logErr fp)
+        $ pushStorePath env opts name
+        $ toS
+        $ dropEnd 5 fp
     action _ = return ()
     filterF :: ActionPredicate
     filterF (Removed fp _ _)
@@ -196,10 +201,12 @@
     dropEnd index xs = take (length xs - index) xs
 
 -- | Find a secret key in the 'Config' or environment variable
-findSigningKey
-  :: Env
-  -> Text -- ^ Cache name
-  -> IO SigningKey -- ^ Secret key or exception
+findSigningKey ::
+  Env ->
+  -- | Cache name
+  Text ->
+  -- | Secret key or exception
+  IO SigningKey
 findSigningKey env name = do
   maybeEnvSK <- lookupEnv "CACHIX_SIGNING_KEY"
   -- we reverse list of caches to prioritize keys added as last
@@ -224,12 +231,12 @@
         then throwM $ accessDeniedBinaryCache name
         else throwM notAuthenticatedBinaryCache,
     onError = throwM,
-    onAttempt = \retrystatus ->
+    onAttempt = \retrystatus size ->
       -- we append newline instead of putStrLn due to https://github.com/haskell/text/issues/242
-      putStr $ "pushing " <> retryText retrystatus <> storePath <> "\n",
+      putStr $ retryText retrystatus <> "compressing and pushing " <> storePath <> " (" <> humanSize (fromIntegral size) <> ")\n",
     onDone = pass,
     withXzipCompressor = defaultWithXzipCompressorWithLevel (compressionLevel opts)
-    }
+  }
 
 pushStorePath :: Env -> PushOptions -> Text -> Text -> IO ()
 pushStorePath env opts name storePath = do
@@ -239,10 +246,11 @@
   store <- wait (storeAsync env)
   pushSingleStorePath
     (clientenv env)
-    store PushCache
-    { pushCacheToken = envToToken env,
-      pushCacheName = name,
-      pushCacheSigningKey = sk
+    store
+    PushCache
+      { pushCacheToken = envToToken env,
+        pushCacheName = name,
+        pushCacheSigningKey = sk
       }
     (pushStrategy env opts name storePath)
     storePath
diff --git a/src/Cachix/Client/Config.hs b/src/Cachix/Client/Config.hs
--- a/src/Cachix/Client/Config.hs
+++ b/src/Cachix/Client/Config.hs
@@ -7,8 +7,8 @@
     writeConfig,
     getDefaultFilename,
     ConfigPath,
-    mkConfig
-    )
+    mkConfig,
+  )
 where
 
 import Cachix.Client.Config.Orphans ()
@@ -21,35 +21,35 @@
   ( XdgDirectory (..),
     createDirectoryIfMissing,
     doesFileExist,
-    getXdgDirectory
-    )
+    getXdgDirectory,
+  )
 import System.FilePath.Posix (takeDirectory)
 import System.Posix.Files
   ( ownerReadMode,
     ownerWriteMode,
     setFileMode,
-    unionFileModes
-    )
+    unionFileModes,
+  )
 
 data BinaryCacheConfig
   = BinaryCacheConfig
       { name :: Text,
         secretKey :: Text
-        }
+      }
   deriving (Show, Generic, Interpret, Inject)
 
 data Config
   = Config
       { authToken :: Token,
         binaryCaches :: [BinaryCacheConfig]
-        }
+      }
   deriving (Show, Generic, Interpret, Inject)
 
 mkConfig :: Text -> Config
 mkConfig token = Config
   { authToken = Token (toS token),
     binaryCaches = []
-    }
+  }
 
 type ConfigPath = FilePath
 
diff --git a/src/Cachix/Client/Config/Orphans.hs b/src/Cachix/Client/Config/Orphans.hs
--- a/src/Cachix/Client/Config/Orphans.hs
+++ b/src/Cachix/Client/Config/Orphans.hs
@@ -11,18 +11,16 @@
 import Servant.Auth.Client
 
 instance Interpret Token where
-
   autoWith _ = Type
     { extract = ex,
       expected = Text
-      }
+    }
     where
       ex (TextLit (Chunks [] t)) = pure (Token (toS t))
       ex _ = panic "Unexpected Dhall value. Did it typecheck?"
 
 instance Inject Token where
-
   injectWith _ = InputType
     { embed = TextLit . Chunks [] . toS . getToken,
       declared = Text
-      }
+    }
diff --git a/src/Cachix/Client/Env.hs b/src/Cachix/Client/Env.hs
--- a/src/Cachix/Client/Env.hs
+++ b/src/Cachix/Client/Env.hs
@@ -1,8 +1,8 @@
 module Cachix.Client.Env
   ( Env (..),
     mkEnv,
-    cachixVersion
-    )
+    cachixVersion,
+  )
 where
 
 import Cachix.Client.Config (Config, readConfig)
@@ -15,8 +15,8 @@
   ( ManagerSettings,
     managerModifyRequest,
     managerResponseTimeout,
-    responseTimeoutNone
-    )
+    responseTimeoutNone,
+  )
 import Network.HTTP.Client.TLS (newTlsManagerWith, tlsManagerSettings)
 import Network.HTTP.Simple (setRequestHeader)
 import Paths_cachix (version)
@@ -30,7 +30,7 @@
         clientenv :: ClientEnv,
         cachixoptions :: CachixOptions,
         storeAsync :: Async Store
-        }
+      }
 
 mkEnv :: CachixOptions -> IO Env
 mkEnv rawcachixoptions = do
@@ -46,7 +46,7 @@
       clientenv = clientenv,
       cachixoptions = cachixoptions,
       storeAsync = store
-      }
+    }
 
 customManagerSettings :: ManagerSettings
 customManagerSettings =
@@ -54,7 +54,7 @@
     { managerResponseTimeout = responseTimeoutNone,
       -- managerModifyRequest :: Request -> IO Request
       managerModifyRequest = return . setRequestHeader "User-Agent" [toS cachixVersion]
-      }
+    }
 
 cachixVersion :: Text
 cachixVersion = "cachix " <> toS (showVersion version)
diff --git a/src/Cachix/Client/Exception.hs b/src/Cachix/Client/Exception.hs
--- a/src/Cachix/Client/Exception.hs
+++ b/src/Cachix/Client/Exception.hs
@@ -18,6 +18,5 @@
   deriving (Show, Typeable)
 
 instance Exception CachixException where
-
   displayException (NixOSInstructions txt) = toS txt
   displayException e = show e
diff --git a/src/Cachix/Client/HumanSize.hs b/src/Cachix/Client/HumanSize.hs
new file mode 100644
--- /dev/null
+++ b/src/Cachix/Client/HumanSize.hs
@@ -0,0 +1,19 @@
+module Cachix.Client.HumanSize where
+
+import Protolude
+import Text.Printf (printf)
+import qualified Prelude
+
+humanSize :: Double -> Text
+humanSize size
+  | size < unitstep 1 = render "B" size
+  | size < unitstep 2 = render "KiB" $ size / unitstep 1
+  | size < unitstep 3 = render "MiB" $ size / unitstep 2
+  | size < unitstep 4 = render "GiB" $ size / unitstep 3
+  | otherwise = render "TiB" $ size / unitstep 4
+  where
+    unitstep :: Int -> Double
+    unitstep i = 1024.0 ^ i
+    render :: Text -> Double -> Text
+    render unit unitsize =
+      toS (printf "%.2f" unitsize :: Prelude.String) <> " " <> unit
diff --git a/src/Cachix/Client/InstallationMode.hs b/src/Cachix/Client/InstallationMode.hs
--- a/src/Cachix/Client/InstallationMode.hs
+++ b/src/Cachix/Client/InstallationMode.hs
@@ -9,8 +9,8 @@
     getUser,
     fromString,
     toString,
-    UseOptions (..)
-    )
+    UseOptions (..),
+  )
 where
 
 import Cachix.Api as Api
@@ -31,7 +31,7 @@
       { isTrusted :: Bool,
         isRoot :: Bool,
         isNixOS :: Bool
-        }
+      }
 
 -- NOTE: update the list of options for --mode argument in OptionsParser.hs
 data InstallationMode
@@ -44,7 +44,7 @@
   = UseOptions
       { useMode :: Maybe InstallationMode,
         useNixOSFolder :: FilePath
-        }
+      }
   deriving (Show)
 
 fromString :: String -> Maybe InstallationMode
@@ -70,8 +70,8 @@
 -- | Add a Binary cache to nix.conf, print nixos config or fail
 addBinaryCache :: Maybe Config -> Api.BinaryCache -> UseOptions -> InstallationMode -> IO ()
 addBinaryCache _ _ _ UntrustedRequiresSudo =
-  throwIO
-    $ MustBeRoot "Run command as root OR execute: $ echo \"trusted-users = root $USER\" | sudo tee -a /etc/nix/nix.conf && sudo pkill nix-daemon"
+  throwIO $
+    MustBeRoot "Run command as root OR execute: $ echo \"trusted-users = root $USER\" | sudo tee -a /etc/nix/nix.conf && sudo pkill nix-daemon"
 addBinaryCache maybeConfig bc useOptions WriteNixOS =
   nixosBinaryCache maybeConfig bc useOptions
 addBinaryCache maybeConfig bc _ (Install ncl) = do
@@ -140,7 +140,7 @@
 
 Then run:
 
-    $ nixos-rebuild switch
+    $ sudo nixos-rebuild switch
     |]
     glueModule :: Text
     glueModule =
diff --git a/src/Cachix/Client/NetRc.hs b/src/Cachix/Client/NetRc.hs
--- a/src/Cachix/Client/NetRc.hs
+++ b/src/Cachix/Client/NetRc.hs
@@ -1,7 +1,7 @@
 -- Deals with adding private caches to netrc
 module Cachix.Client.NetRc
-  ( add
-    )
+  ( add,
+  )
 where
 
 import qualified Cachix.Api as Api
@@ -20,11 +20,11 @@
 -- | Add a list of binary caches to netrc under `filename`.
 --   Makes sure there are no duplicate entries (using domain as a key).
 --   If file under filename doesn't exist it's created.
-add
-  :: Config
-  -> [Api.BinaryCache]
-  -> FilePath
-  -> IO ()
+add ::
+  Config ->
+  [Api.BinaryCache] ->
+  FilePath ->
+  IO ()
 add config binarycaches filename = do
   doesExist <- doesFileExist filename
   netrc <-
@@ -51,7 +51,7 @@
         nrhPassword = getToken (authToken config),
         nrhAccount = "",
         nrhMacros = []
-        }
+      }
       where
         -- stripPrefix that either strips or returns the same string
         stripPrefix :: Text -> Text -> Text
diff --git a/src/Cachix/Client/NixConf.hs b/src/Cachix/Client/NixConf.hs
--- a/src/Cachix/Client/NixConf.hs
+++ b/src/Cachix/Client/NixConf.hs
@@ -28,8 +28,8 @@
     isTrustedUsers,
     defaultPublicURI,
     defaultSigningKey,
-    setNetRC
-    )
+    setNetRC,
+  )
 where
 
 import Cachix.Api (BinaryCache (..))
@@ -41,8 +41,8 @@
   ( XdgDirectory (..),
     createDirectoryIfMissing,
     doesFileExist,
-    getXdgDirectory
-    )
+    getXdgDirectory,
+  )
 import System.FilePath.Posix (takeDirectory)
 import qualified Text.Megaparsec as Mega
 import Text.Megaparsec.Char
@@ -87,8 +87,8 @@
 -- | Pure version of addIO
 add :: BinaryCache -> [NixConf] -> NixConf -> NixConf
 add bc toRead toWrite =
-  writeLines isPublicKey (TrustedPublicKeys $ nub publicKeys)
-    $ writeLines isSubstituter (Substituters $ nub substituters) toWrite
+  writeLines isPublicKey (TrustedPublicKeys $ nub publicKeys) $
+    writeLines isSubstituter (Substituters $ nub substituters) toWrite
   where
     -- Note: some defaults are always appended since overriding some setttings in nix.conf overrides defaults otherwise
     substituters = (defaultPublicURI : readLines toRead isSubstituter) <> [uri bc]
@@ -122,14 +122,13 @@
   doesExist <- doesFileExist filename
   if not doesExist
     then return Nothing
-    else
-      do
-        result <- parse <$> readFile filename
-        case result of
-          Left err -> do
-            putStrLn (Mega.errorBundlePretty err)
-            panic $ toS filename <> " failed to parse, please copy the above error and contents of nix.conf and open an issue at https://github.com/cachix/cachix"
-          Right conf -> return $ Just conf
+    else do
+      result <- parse <$> readFile filename
+      case result of
+        Left err -> do
+          putStrLn (Mega.errorBundlePretty err)
+          panic $ toS filename <> " failed to parse, please copy the above error and contents of nix.conf and open an issue at https://github.com/cachix/cachix"
+        Right conf -> return $ Just conf
 
 update :: NixConfLoc -> (Maybe NixConf -> NixConf) -> IO ()
 update ncl f = do
diff --git a/src/Cachix/Client/NixVersion.hs b/src/Cachix/Client/NixVersion.hs
--- a/src/Cachix/Client/NixVersion.hs
+++ b/src/Cachix/Client/NixVersion.hs
@@ -1,7 +1,7 @@
 module Cachix.Client.NixVersion
   ( assertNixVersion,
-    parseNixVersion
-    )
+    parseNixVersion,
+  )
 where
 
 import Data.Text as T
diff --git a/src/Cachix/Client/OptionsParser.hs b/src/Cachix/Client/OptionsParser.hs
--- a/src/Cachix/Client/OptionsParser.hs
+++ b/src/Cachix/Client/OptionsParser.hs
@@ -4,8 +4,8 @@
     PushArguments (..),
     PushOptions (..),
     BinaryCacheName,
-    getOpts
-    )
+    getOpts,
+  )
 where
 
 import qualified Cachix.Client.Config as Config
@@ -19,40 +19,41 @@
     URIRef,
     parseURI,
     serializeURIRef',
-    strictURIParserOptions
-    )
+    strictURIParserOptions,
+  )
 
 data CachixOptions
   = CachixOptions
       { host :: URIRef Absolute,
         configPath :: Config.ConfigPath,
         verbose :: Bool
-        }
+      }
   deriving (Show)
 
 parserCachixOptions :: Config.ConfigPath -> Parser CachixOptions
 parserCachixOptions defaultConfigPath =
   CachixOptions
-    <$> option uriOption
-          ( long "host"
-              <> value defaultCachixURI
-              <> metavar "URI"
-              <> showDefaultWith (toS . serializeURIRef')
-              <> help "Host to connect to"
-            )
+    <$> option
+      uriOption
+      ( long "host"
+          <> value defaultCachixURI
+          <> metavar "URI"
+          <> showDefaultWith (toS . serializeURIRef')
+          <> help "Host to connect to"
+      )
     <*> strOption
-          ( long "config"
-              <> short 'c'
-              <> value defaultConfigPath
-              <> metavar "CONFIGPATH"
-              <> showDefault
-              <> help "Cachix configuration file"
-            )
+      ( long "config"
+          <> short 'c'
+          <> value defaultConfigPath
+          <> metavar "CONFIGPATH"
+          <> showDefault
+          <> help "Cachix configuration file"
+      )
     <*> switch
-          ( long "verbose"
-              <> short 'v'
-              <> help "Verbose mode"
-            )
+      ( long "verbose"
+          <> short 'v'
+          <> help "Verbose mode"
+      )
 
 uriOption :: ReadM (URIRef Absolute)
 uriOption = eitherReader $ \s ->
@@ -77,17 +78,17 @@
 data PushOptions
   = PushOptions
       { compressionLevel :: Int
-        }
+      }
   deriving (Show)
 
 parserCachixCommand :: Parser CachixCommand
 parserCachixCommand =
-  subparser
-    $ command "authtoken" (infoH authtoken (progDesc "Configure token for authentication to cachix.org"))
-    <> command "create" (infoH create (progDesc "DEPRECATED: Go to https://cachix.org instead"))
-    <> command "generate-keypair" (infoH generateKeypair (progDesc "Generate keypair for a binary cache"))
-    <> command "push" (infoH push (progDesc "Upload Nix store paths to the binary cache"))
-    <> command "use" (infoH use (progDesc "Configure nix.conf to enable binary cache during builds"))
+  subparser $
+    command "authtoken" (infoH authtoken (progDesc "Configure token for authentication to cachix.org"))
+      <> command "create" (infoH create (progDesc "DEPRECATED: Go to https://cachix.org instead"))
+      <> command "generate-keypair" (infoH generateKeypair (progDesc "Generate keypair for a binary cache"))
+      <> command "push" (infoH push (progDesc "Upload Nix store paths to the binary cache"))
+      <> command "use" (infoH use (progDesc "Configure nix.conf to enable binary cache during builds"))
   where
     nameArg = strArgument (metavar "NAME")
     authtoken = AuthToken <$> strArgument (metavar "TOKEN")
@@ -98,44 +99,47 @@
     pushOptions :: Parser PushOptions
     pushOptions =
       PushOptions
-        <$> option (auto >>= validatedLevel)
-              ( long "compression-level"
-                  <> metavar "[0..9]"
-                  <> help
-                       "The compression level for XZ compression.\
-                   \ Take compressor *and* decompressor memory usage into account before using [7..9]!"
-                  <> showDefault
-                  <> value 2
-                )
+        <$> option
+          (auto >>= validatedLevel)
+          ( long "compression-level"
+              <> metavar "[0..9]"
+              <> help
+                "The compression level for XZ compression.\
+                \ Take compressor *and* decompressor memory usage into account before using [7..9]!"
+              <> showDefault
+              <> value 2
+          )
     push = (\opts cache f -> Push $ f opts cache) <$> pushOptions <*> nameArg <*> (pushPaths <|> pushWatchStore)
     pushPaths =
       (\paths opts cache -> PushPaths opts cache paths)
         <$> many (strArgument (metavar "PATHS..."))
     pushWatchStore =
       (\() opts cache -> PushWatchStore opts cache)
-        <$> flag' ()
-              ( long "watch-store"
-                  <> short 'w'
-                  <> help "Run in daemon mode and push store paths as they are added to /nix/store"
-                )
+        <$> flag'
+          ()
+          ( long "watch-store"
+              <> short 'w'
+              <> help "Run in daemon mode and push store paths as they are added to /nix/store"
+          )
     use =
       Use <$> nameArg
         <*> ( InstallationMode.UseOptions
                 <$> optional
-                      ( option (maybeReader InstallationMode.fromString)
-                          ( long "mode"
-                              <> short 'm'
-                              <> help "Mode in which to configure binary caches for Nix. Supported values: nixos, root-nixconf, user-nixconf"
-                            )
-                        )
+                  ( option
+                      (maybeReader InstallationMode.fromString)
+                      ( long "mode"
+                          <> short 'm'
+                          <> help "Mode in which to configure binary caches for Nix. Supported values: nixos, root-nixconf, user-nixconf"
+                      )
+                  )
                 <*> strOption
-                      ( long "nixos-folder"
-                          <> short 'd'
-                          <> help "Base directory for NixOS configuration"
-                          <> value "/etc/nixos/"
-                          <> showDefault
-                        )
-              )
+                  ( long "nixos-folder"
+                      <> short 'd'
+                      <> help "Base directory for NixOS configuration"
+                      <> value "/etc/nixos/"
+                      <> showDefault
+                  )
+            )
 
 getOpts :: IO (CachixOptions, CachixCommand)
 getOpts = do
@@ -148,11 +152,12 @@
     parser = (,) <$> parserCachixOptions configpath <*> (parserCachixCommand <|> versionParser)
     versionParser :: Parser CachixCommand
     versionParser =
-      flag' Version
+      flag'
+        Version
         ( long "version"
             <> short 'V'
             <> help "Show cachix version"
-          )
+        )
 
 desc :: InfoMod a
 desc =
diff --git a/src/Cachix/Client/Push.hs b/src/Cachix/Client/Push.hs
--- a/src/Cachix/Client/Push.hs
+++ b/src/Cachix/Client/Push.hs
@@ -10,10 +10,11 @@
     PushStrategy (..),
     defaultWithXzipCompressor,
     defaultWithXzipCompressorWithLevel,
+
     -- * Pushing a closure of store paths
     pushClosure,
-    mapConcurrentlyBounded
-    )
+    mapConcurrentlyBounded,
+  )
 where
 
 import qualified Cachix.Api as Api
@@ -54,17 +55,18 @@
       { pushCacheName :: Text,
         pushCacheSigningKey :: SigningKey,
         pushCacheToken :: Token
-        }
+      }
 
 data PushStrategy m r
   = PushStrategy
-      { onAlreadyPresent :: m r, -- ^ Called when a path is already in the cache.
-        onAttempt :: RetryStatus -> m (),
+      { -- | Called when a path is already in the cache.
+        onAlreadyPresent :: m r,
+        onAttempt :: RetryStatus -> Int64 -> m (),
         on401 :: m r,
         onError :: ClientError -> m r,
         onDone :: m r,
         withXzipCompressor :: forall a. (ConduitM ByteString ByteString (ResourceT IO) () -> m a) -> m a
-        }
+      }
 
 defaultWithXzipCompressor :: forall m a. (ConduitM ByteString ByteString (ResourceT IO) () -> m a) -> m a
 defaultWithXzipCompressor = ($ compress (Just 2))
@@ -72,25 +74,30 @@
 defaultWithXzipCompressorWithLevel :: Int -> forall m a. (ConduitM ByteString ByteString (ResourceT IO) () -> m a) -> m a
 defaultWithXzipCompressorWithLevel l = ($ compress (Just l))
 
-pushSingleStorePath
-  :: (MonadMask m, MonadIO m)
-  => ClientEnv -- ^ cachix base url, connection manager, see 'Cachix.Client.URI.defaultCachixBaseUrl', 'Servant.Client.mkClientEnv'
-  -> Store
-  -> PushCache -- ^ details for pushing to cache
-  -> PushStrategy m r -- ^ how to report results, (some) errors, and do some things
-  -> Text -- ^ store path
-  -> m r -- ^ r is determined by the 'PushStrategy'
+pushSingleStorePath ::
+  (MonadMask m, MonadIO m) =>
+  -- | cachix base url, connection manager, see 'Cachix.Client.URI.defaultCachixBaseUrl', 'Servant.Client.mkClientEnv'
+  ClientEnv ->
+  Store ->
+  -- | details for pushing to cache
+  PushCache ->
+  -- | how to report results, (some) errors, and do some things
+  PushStrategy m r ->
+  -- | store path
+  Text ->
+  -- | r is determined by the 'PushStrategy'
+  m r
 pushSingleStorePath clientEnv _store cache cb storePath = retryAll $ \retrystatus -> do
   let storeHash = fst $ splitStorePath $ toS storePath
       name = pushCacheName cache
   -- Check if narinfo already exists
   -- TODO: query also cache.nixos.org? server-side?
   res <-
-    liftIO $ (`runClientM` clientEnv)
-      $ Api.narinfoHead
-          (cachixBCClient name)
-          (pushCacheToken cache)
-          (Api.NarInfoC storeHash)
+    liftIO $ (`runClientM` clientEnv) $
+      Api.narinfoHead
+        (cachixBCClient name)
+        (pushCacheToken cache)
+        (Api.NarInfoC storeHash)
   case res of
     Right NoContent -> onAlreadyPresent cb -- we're done as store path is already in the cache
     Left err
@@ -98,25 +105,34 @@
       | isErr err status401 -> on401 cb
       | otherwise -> onError cb err
 
-uploadStorePath
-  :: (MonadMask m, MonadIO m)
-  => ClientEnv -- ^ cachix base url, connection manager, see 'Cachix.Client.URI.defaultCachixBaseUrl', 'Servant.Client.mkClientEnv'
-  -> Store
-  -> PushCache -- ^ details for pushing to cache
-  -> PushStrategy m r -- ^ how to report results, (some) errors, and do some things
-  -> Text -- ^ store path
-  -> RetryStatus
-  -> m r -- ^ r is determined by the 'PushStrategy'
-uploadStorePath clientEnv _store cache cb storePath retrystatus = do
+uploadStorePath ::
+  (MonadMask m, MonadIO m) =>
+  -- | cachix base url, connection manager, see 'Cachix.Client.URI.defaultCachixBaseUrl', 'Servant.Client.mkClientEnv'
+  ClientEnv ->
+  Store ->
+  -- | details for pushing to cache
+  PushCache ->
+  -- | how to report results, (some) errors, and do some things
+  PushStrategy m r ->
+  -- | store path
+  Text ->
+  RetryStatus ->
+  -- | r is determined by the 'PushStrategy'
+  m r
+uploadStorePath clientEnv store cache cb storePath retrystatus = do
   let (storeHash, storeSuffix) = splitStorePath $ toS storePath
       name = pushCacheName cache
-  onAttempt cb retrystatus
   narSizeRef <- liftIO $ newIORef 0
   fileSizeRef <- liftIO $ newIORef 0
   narHashRef <- liftIO $ newIORef ("" :: ByteString)
   fileHashRef <- liftIO $ newIORef ("" :: ByteString)
+  normalized <- liftIO $ Store.followLinksToStorePath store $ toS storePath
+  pathinfo <- liftIO $ Store.queryPathInfo store normalized
   -- stream store path as xz compressed nar file
   let cmd = proc "nix-store" ["--dump", toS storePath]
+      storePathSize :: Int64
+      storePathSize = Store.validPathInfoNarSize pathinfo
+  onAttempt cb retrystatus storePathSize
   -- TODO: print process stderr?
   (ClosedStream, (stdoutStream, closeStdout), ClosedStream, cph) <- liftIO $ streamingProcess cmd
   withXzipCompressor cb $ \xzCompressor -> do
@@ -127,50 +143,54 @@
             .| xzCompressor
             .| passthroughSizeSink fileSizeRef
             .| passthroughHashSinkB16 fileHashRef
-    -- for now we need to use letsencrypt domain instead of cloudflare due to its upload limits
-    let newClientEnv =
+    let subdomain =
+          -- TODO: multipart
+          if (fromIntegral storePathSize / (1024 * 1024)) > 100
+            then "api"
+            else toS name
+        newClientEnv =
           clientEnv
-            { baseUrl = (baseUrl clientEnv) {baseUrlHost = toS name <> "." <> baseUrlHost (baseUrl clientEnv)}
-              }
+            { baseUrl = (baseUrl clientEnv) {baseUrlHost = subdomain <> "." <> baseUrlHost (baseUrl clientEnv)}
+            }
     (_ :: NoContent) <-
       liftIO
         $ (`withClientM` newClientEnv)
-            (Api.createNar (cachixBCStreamingClient name) stream')
+          (Api.createNar (cachixBCStreamingClient name) stream')
         $ escalate
-        >=> \NoContent -> do
-          closeStdout
-          exitcode <- waitForStreamingProcess cph
-          when (exitcode /= ExitSuccess) $ throwM $ NarStreamingError exitcode $ show cmd
-          -- TODO: we're done, so we can leave withClientM. Doing so
-          --       will allow more concurrent requests when the number
-          --       of XZ compressors is limited
-          narSize <- readIORef narSizeRef
-          narHash <- ("sha256:" <>) . System.Nix.Base32.encode <$> readIORef narHashRef
-          fileHash <- readIORef fileHashRef
-          fileSize <- readIORef fileSizeRef
-          deriverRaw <- T.strip . toS <$> readProcess "nix-store" ["-q", "--deriver", toS storePath] mempty
-          let deriver =
-                if deriverRaw == "unknown-deriver"
-                  then deriverRaw
-                  else T.drop 11 deriverRaw
-          references <- sort . T.lines . T.strip . toS <$> readProcess "nix-store" ["-q", "--references", toS storePath] mempty
-          let fp = fingerprint storePath narHash narSize references
-              sig = dsign (signingSecretKey $ pushCacheSigningKey cache) fp
-              nic = Api.NarInfoCreate
-                { Api.cStoreHash = storeHash,
-                  Api.cStoreSuffix = storeSuffix,
-                  Api.cNarHash = narHash,
-                  Api.cNarSize = narSize,
-                  Api.cFileSize = fileSize,
-                  Api.cFileHash = toS fileHash,
-                  Api.cReferences = fmap (T.drop 11) references,
-                  Api.cDeriver = deriver,
-                  Api.cSig = toS $ B64.encode $ unSignature sig
+          >=> \NoContent -> do
+            closeStdout
+            exitcode <- waitForStreamingProcess cph
+            when (exitcode /= ExitSuccess) $ throwM $ NarStreamingError exitcode $ show cmd
+            -- TODO: we're done, so we can leave withClientM. Doing so
+            --       will allow more concurrent requests when the number
+            --       of XZ compressors is limited
+            narSize <- readIORef narSizeRef
+            narHash <- ("sha256:" <>) . System.Nix.Base32.encode <$> readIORef narHashRef
+            fileHash <- readIORef fileHashRef
+            fileSize <- readIORef fileSizeRef
+            deriverRaw <- T.strip . toS <$> readProcess "nix-store" ["-q", "--deriver", toS storePath] mempty
+            let deriver =
+                  if deriverRaw == "unknown-deriver"
+                    then deriverRaw
+                    else T.drop 11 deriverRaw
+            references <- sort . T.lines . T.strip . toS <$> readProcess "nix-store" ["-q", "--references", toS storePath] mempty
+            let fp = fingerprint storePath narHash narSize references
+                sig = dsign (signingSecretKey $ pushCacheSigningKey cache) fp
+                nic = Api.NarInfoCreate
+                  { Api.cStoreHash = storeHash,
+                    Api.cStoreSuffix = storeSuffix,
+                    Api.cNarHash = narHash,
+                    Api.cNarSize = narSize,
+                    Api.cFileSize = fileSize,
+                    Api.cFileHash = toS fileHash,
+                    Api.cReferences = fmap (T.drop 11) references,
+                    Api.cDeriver = deriver,
+                    Api.cSig = toS $ B64.encode $ unSignature sig
                   }
-          escalate $ Api.isNarInfoCreateValid nic
-          -- Upload narinfo with signature
-          escalate <=< (`runClientM` clientEnv)
-            $ Api.createNarinfo
+            escalate $ Api.isNarInfoCreateValid nic
+            -- Upload narinfo with signature
+            escalate <=< (`runClientM` clientEnv) $
+              Api.createNarinfo
                 (cachixBCClient name)
                 (Api.NarInfoC storeHash)
                 nic
@@ -187,18 +207,21 @@
 -- | Push an entire closure
 --
 -- Note: 'onAlreadyPresent' will be called less often in the future.
-pushClosure
-  :: (MonadIO m, MonadMask m)
-  => (forall a b. (a -> m b) -> [a] -> m [b])
-  -- ^ Traverse paths, responsible for bounding parallel processing of paths
+pushClosure ::
+  (MonadIO m, MonadMask m) =>
+  -- | Traverse paths, responsible for bounding parallel processing of paths
   --
   -- For example: @'mapConcurrentlyBounded' 4@
-  -> ClientEnv -- ^ See 'pushSingleStorePath'
-  -> Store
-  -> PushCache
-  -> (Text -> PushStrategy m r)
-  -> [Text] -- ^ Initial store paths
-  -> m [r] -- ^ Every @r@ per store path of the entire closure of store paths
+  (forall a b. (a -> m b) -> [a] -> m [b]) ->
+  -- | See 'pushSingleStorePath'
+  ClientEnv ->
+  Store ->
+  PushCache ->
+  (Text -> PushStrategy m r) ->
+  -- | Initial store paths
+  [Text] ->
+  -- | Every @r@ per store path of the entire closure of store paths
+  m [r]
 pushClosure traversal clientEnv store pushCache pushStrategy inputStorePaths = do
   -- Get the transitive closure of dependencies
   paths <-
@@ -215,12 +238,12 @@
     retryAll $ \_ ->
       escalate
         =<< liftIO
-              ( (`runClientM` clientEnv)
-                  $ Api.narinfoBulk
-                      (cachixBCClient (pushCacheName pushCache))
-                      (pushCacheToken pushCache)
-                      (fst . splitStorePath <$> paths)
-                )
+          ( (`runClientM` clientEnv) $
+              Api.narinfoBulk
+                (cachixBCClient (pushCacheName pushCache))
+                (pushCacheToken pushCache)
+                (fst . splitStorePath <$> paths)
+          )
   let missingHashes = Set.fromList missingHashesList
       missingPaths = filter (\path -> Set.member (fst (splitStorePath path)) missingHashes) paths
   -- TODO: make pool size configurable, on beefier machines this could be doubled
diff --git a/src/Cachix/Client/Secrets.hs b/src/Cachix/Client/Secrets.hs
--- a/src/Cachix/Client/Secrets.hs
+++ b/src/Cachix/Client/Secrets.hs
@@ -4,8 +4,8 @@
   ( -- * NAR signing
     SigningKey (..),
     parseSigningKeyLenient,
-    exportSigningKey
-    )
+    exportSigningKey,
+  )
 where
 
 -- TODO: * Auth token
@@ -18,9 +18,11 @@
 -- | A secret key for signing nars.
 newtype SigningKey = SigningKey {signingSecretKey :: SecretKey}
 
-parseSigningKeyLenientBS
-  :: ByteString -- ^ ASCII (Base64)
-  -> Either Text SigningKey -- ^ Error message or signing key
+parseSigningKeyLenientBS ::
+  -- | ASCII (Base64)
+  ByteString ->
+  -- | Error message or signing key
+  Either Text SigningKey
 parseSigningKeyLenientBS raw =
   let bcDropWhileEnd f = BC.reverse . BC.dropWhile f . BC.reverse
       bcDropAround f = bcDropWhileEnd f . BC.dropWhile f
@@ -28,14 +30,17 @@
       nonNull = if BC.null stripped then Left "A signing key must not be empty" else pure stripped
    in SigningKey . SecretKey . B64.decodeLenient <$> nonNull
 
-parseSigningKeyLenient
-  :: Text -- ^ Base64
-  -> Either Text SigningKey -- ^ Error message or signing key
+parseSigningKeyLenient ::
+  -- | Base64
+  Text ->
+  -- | Error message or signing key
+  Either Text SigningKey
 parseSigningKeyLenient = parseSigningKeyLenientBS . toSL
 
-exportSigningKeyBS
-  :: SigningKey
-  -> ByteString -- ^ ASCII (Base64)
+exportSigningKeyBS ::
+  SigningKey ->
+  -- | ASCII (Base64)
+  ByteString
 exportSigningKeyBS (SigningKey (SecretKey bs)) = B64.encode bs
 
 exportSigningKey :: SigningKey -> Text
diff --git a/src/Cachix/Client/Servant.hs b/src/Cachix/Client/Servant.hs
--- a/src/Cachix/Client/Servant.hs
+++ b/src/Cachix/Client/Servant.hs
@@ -59,6 +59,5 @@
 runAuthenticatedClient env m = do
   config <- escalate $ maybeToEither (Exception.NoConfig
      "Start with visiting https://cachix.org and copying the token to $ cachix authtoken <token>") (Env.config env)
-  escalate
-    =<< ((`runClientM` Env.clientenv env)
-    $ m (Config.authToken config))
+  escalate <=< (`runClientM` Env.clientenv env) $
+    m (Config.authToken config)
diff --git a/src/Cachix/Client/Store.hs b/src/Cachix/Client/Store.hs
--- a/src/Cachix/Client/Store.hs
+++ b/src/Cachix/Client/Store.hs
@@ -4,12 +4,16 @@
 
 module Cachix.Client.Store
   ( Store,
+
     -- * Getting a Store
     openStore,
     releaseStore,
+
     -- * Query a path
     followLinksToStorePath,
     queryPathInfo,
+    validPathInfoNarSize,
+
     -- * Get closures
     computeFSClosure,
     ClosureParams (..),
@@ -18,9 +22,10 @@
     newEmptyPathSet,
     addToPathSet,
     traversePathSet,
+
     -- * Miscellaneous
-    storeUri
-    )
+    storeUri,
+  )
 where
 
 import Cachix.Client.Store.Context (NixStore, Ref, ValidPathInfo, context)
@@ -85,17 +90,21 @@
              return strdup(uri.c_str());
            } |]
 
--- TODO: test queryPathInfo
-queryPathInfo :: Store -> ByteString -> IO (ForeignPtr (Ref ValidPathInfo))
+queryPathInfo ::
+  Store ->
+  -- | Exact store path, not a subpath
+  ByteString ->
+  -- | ValidPathInfo or exception
+  IO (ForeignPtr (Ref ValidPathInfo))
 queryPathInfo (Store store) path = do
   vpi <-
-    [C.exp| refValidPathInfo* {
-             new refValidPathInfo((*$(refStore* store))->queryPathInfo($bs-cstr:path))
-           } |]
+    [C.throwBlock| refValidPathInfo*
+      {
+        return new refValidPathInfo((*$(refStore* store))->queryPathInfo($bs-cstr:path));
+      } |]
   newForeignPtr finalizeRefValidPathInfo vpi
 
 finalizeRefValidPathInfo :: FinalizerPtr (Ref ValidPathInfo)
-
 {-# NOINLINE finalizeRefValidPathInfo #-}
 finalizeRefValidPathInfo =
   unsafePerformIO
@@ -104,11 +113,19 @@
     [](refValidPathInfo *v){ delete v; }
   } |]
 
+-- | The narSize field of a ValidPathInfo struct. Source: store-api.hh
+validPathInfoNarSize :: ForeignPtr (Ref ValidPathInfo) -> Int64
+validPathInfoNarSize vpi =
+  fromIntegral $
+    toInteger
+      [C.pure| long
+        { (*$fptr-ptr:(refValidPathInfo* vpi))->narSize }
+      |]
+
 ----- PathSet -----
 newtype PathSet = PathSet (ForeignPtr (C.Set C.CxxString))
 
 finalizePathSet :: FinalizerPtr C.PathSet
-
 {-# NOINLINE finalizePathSet #-}
 finalizePathSet =
   unsafePerformIO
@@ -143,21 +160,20 @@
           delete $(PathSetIterator *i);
           delete $(PathSetIterator *end);
         }|]
-  flip finally cleanup
-    $ let go :: ([a] -> [a]) -> IO [a]
-          go acc = do
-            isDone <-
-              [C.exp| int {
+  flip finally cleanup $
+    let go :: ([a] -> [a]) -> IO [a]
+        go acc = do
+          isDone <-
+            [C.exp| int {
             *$(PathSetIterator *i) == *$(PathSetIterator *end)
           }|]
-            if isDone /= 0
-              then pure $ acc []
-              else
-                do
-                  somePath <- unsafePackMallocCString =<< [C.exp| const char *{ strdup((*$(PathSetIterator *i))->c_str()) } |]
-                  a <- f somePath
-                  [C.throwBlock| void { (*$(PathSetIterator *i))++; } |]
-                  go (acc . (a :))
+          if isDone /= 0
+            then pure $ acc []
+            else do
+              somePath <- unsafePackMallocCString =<< [C.exp| const char *{ strdup((*$(PathSetIterator *i))->c_str()) } |]
+              a <- f somePath
+              [C.throwBlock| void { (*$(PathSetIterator *i))++; } |]
+              go (acc . (a :))
      in go identity
 
 ----- computeFSClosure -----
@@ -166,14 +182,14 @@
       { flipDirection :: Bool,
         includeOutputs :: Bool,
         includeDerivers :: Bool
-        }
+      }
 
 defaultClosureParams :: ClosureParams
 defaultClosureParams = ClosureParams
   { flipDirection = False,
     includeOutputs = False,
     includeDerivers = False
-    }
+  }
 
 computeFSClosure :: Store -> ClosureParams -> PathSet -> IO PathSet
 computeFSClosure (Store store) params startingSet_ = withPathSet startingSet_ $ \startingSet -> do
diff --git a/src/Cachix/Client/Store/Context.hs b/src/Cachix/Client/Store/Context.hs
--- a/src/Cachix/Client/Store/Context.hs
+++ b/src/Cachix/Client/Store/Context.hs
@@ -34,8 +34,9 @@
     <> mempty
       { C.ctxTypesTable =
           M.singleton (C.TypeName "refStore") [t|Ref NixStore|]
-            <> M.singleton (C.TypeName "refValidPathInfo")
-                 [t|Ref ValidPathInfo|]
+            <> M.singleton
+              (C.TypeName "refValidPathInfo")
+              [t|Ref ValidPathInfo|]
             <> M.singleton (C.TypeName "PathSet") [t|PathSet|]
             <> M.singleton (C.TypeName "PathSetIterator") [t|Iterator PathSet|]
-        }
+      }
diff --git a/src/Cachix/Client/URI.hs b/src/Cachix/Client/URI.hs
--- a/src/Cachix/Client/URI.hs
+++ b/src/Cachix/Client/URI.hs
@@ -4,8 +4,8 @@
 module Cachix.Client.URI
   ( getBaseUrl,
     defaultCachixURI,
-    defaultCachixBaseUrl
-    )
+    defaultCachixBaseUrl,
+  )
 where
 
 import Protolude
@@ -17,7 +17,6 @@
 -- TODO: make getBaseUrl internal
 
 -- | Partial function from URI to BaseUrl
---
 getBaseUrl :: URIRef Absolute -> BaseUrl
 getBaseUrl uriref =
   case uriAuthority uriref of
diff --git a/test/InstallationModeSpec.hs b/test/InstallationModeSpec.hs
--- a/test/InstallationModeSpec.hs
+++ b/test/InstallationModeSpec.hs
@@ -7,59 +7,59 @@
 
 spec :: Spec
 spec = describe "getInstallationMode" $ do
-  it "NixOS with root prints configuration"
-    $ let nixenv = NixEnv
-            { isTrusted = True, -- any
-              isRoot = True,
-              isNixOS = True
-              }
+  it "NixOS with root prints configuration" $
+    let nixenv = NixEnv
+          { isTrusted = True, -- any
+            isRoot = True,
+            isNixOS = True
+          }
      in getInstallationMode nixenv `shouldBe` WriteNixOS
-  it "NixOS without trust prints configuration plus trust"
-    $ let nixenv = NixEnv
-            { isTrusted = False,
-              isRoot = False,
-              isNixOS = True
-              }
+  it "NixOS without trust prints configuration plus trust" $
+    let nixenv = NixEnv
+          { isTrusted = False,
+            isRoot = False,
+            isNixOS = True
+          }
      in getInstallationMode nixenv `shouldBe` UntrustedRequiresSudo
-  it "NixOS without trust prints configuration on older Nix"
-    $ let nixenv = NixEnv
-            { isTrusted = False,
-              isRoot = False,
-              isNixOS = True
-              }
+  it "NixOS without trust prints configuration on older Nix" $
+    let nixenv = NixEnv
+          { isTrusted = False,
+            isRoot = False,
+            isNixOS = True
+          }
      in getInstallationMode nixenv `shouldBe` UntrustedRequiresSudo
-  it "NixOS non-root trusted results into local install"
-    $ let nixenv = NixEnv
-            { isTrusted = True,
-              isRoot = False,
-              isNixOS = True
-              }
+  it "NixOS non-root trusted results into local install" $
+    let nixenv = NixEnv
+          { isTrusted = True,
+            isRoot = False,
+            isNixOS = True
+          }
      in getInstallationMode nixenv `shouldBe` Install NixConf.Local
-  it "non-NixOS root results into global install"
-    $ let nixenv = NixEnv
-            { isTrusted = True,
-              isRoot = True,
-              isNixOS = False
-              }
+  it "non-NixOS root results into global install" $
+    let nixenv = NixEnv
+          { isTrusted = True,
+            isRoot = True,
+            isNixOS = False
+          }
      in getInstallationMode nixenv `shouldBe` Install NixConf.Global
-  it "non-NixOS with Nix 1.X root results into global install"
-    $ let nixenv = NixEnv
-            { isTrusted = True,
-              isRoot = True,
-              isNixOS = False -- any
-              }
+  it "non-NixOS with Nix 1.X root results into global install" $
+    let nixenv = NixEnv
+          { isTrusted = True,
+            isRoot = True,
+            isNixOS = False -- any
+          }
      in getInstallationMode nixenv `shouldBe` Install NixConf.Global
-  it "non-NixOS non-root trusted results into local install"
-    $ let nixenv = NixEnv
-            { isTrusted = True,
-              isRoot = False,
-              isNixOS = False
-              }
+  it "non-NixOS non-root trusted results into local install" $
+    let nixenv = NixEnv
+          { isTrusted = True,
+            isRoot = False,
+            isNixOS = False
+          }
      in getInstallationMode nixenv `shouldBe` Install NixConf.Local
-  it "non-NixOS non-root non-trusted results into required sudo"
-    $ let nixenv = NixEnv
-            { isTrusted = False,
-              isRoot = False,
-              isNixOS = False
-              }
+  it "non-NixOS non-root non-trusted results into required sudo" $
+    let nixenv = NixEnv
+          { isTrusted = False,
+            isRoot = False,
+            isNixOS = False
+          }
      in getInstallationMode nixenv `shouldBe` UntrustedRequiresSudo
diff --git a/test/Main.hs b/test/Main.hs
--- a/test/Main.hs
+++ b/test/Main.hs
@@ -10,4 +10,4 @@
     config =
       defaultConfig
         { configColorMode = ColorAlways
-          }
+        }
diff --git a/test/NetRcSpec.hs b/test/NetRcSpec.hs
--- a/test/NetRcSpec.hs
+++ b/test/NetRcSpec.hs
@@ -15,7 +15,7 @@
     publicSigningKeys = ["pub"],
     isPublic = False,
     githubUsername = "foobar"
-    }
+  }
 
 bc2 :: BinaryCache
 bc2 = BinaryCache
@@ -24,13 +24,13 @@
     publicSigningKeys = ["pub2"],
     isPublic = False,
     githubUsername = "foobar2"
-    }
+  }
 
 config :: Config
 config = Config
   { authToken = "token123",
     binaryCaches = []
-    }
+  }
 
 -- TODO: poor man's golden tests, use https://github.com/stackbuilders/hspec-golden
 test :: [BinaryCache] -> Text -> Expectation
diff --git a/test/NixConfSpec.hs b/test/NixConfSpec.hs
--- a/test/NixConfSpec.hs
+++ b/test/NixConfSpec.hs
@@ -18,127 +18,127 @@
     isPublic = True,
     publicSigningKeys = ["pub"],
     githubUsername = "foobar"
-    }
+  }
 
 spec :: Spec
 spec = do
   describe "render . parse" $ do
-    it "handles single value substituters"
-      $ property "substituters = a\n"
-    it "handles multi value substituters"
-      $ property "substituters = a b c\n"
-    it "handles all known keys"
-      $ property "substituters = a b c\ntrusted-users = him me\ntrusted-public-keys = a\n"
-    it "random content"
-      $ property "blabla = foobar\nfoo = bar\n"
+    it "handles single value substituters" $
+      property "substituters = a\n"
+    it "handles multi value substituters" $
+      property "substituters = a b c\n"
+    it "handles all known keys" $
+      property "substituters = a b c\ntrusted-users = him me\ntrusted-public-keys = a\n"
+    it "random content" $
+      property "blabla = foobar\nfoo = bar\n"
   describe "add" $ do
-    it "merges binary caches from both files"
-      $ let globalConf =
-              NixConf
-                [ Substituters ["bc1"],
-                  TrustedPublicKeys ["pub1"]
-                  ]
-            localConf =
-              NixConf
-                [ Substituters ["bc2"],
-                  TrustedPublicKeys ["pub2"]
-                  ]
-            result =
-              NixConf
-                [ Substituters [defaultPublicURI, "bc1", "bc2", "https://name.cachix.org"],
-                  TrustedPublicKeys [defaultSigningKey, "pub1", "pub2", "pub"]
-                  ]
+    it "merges binary caches from both files" $
+      let globalConf =
+            NixConf
+              [ Substituters ["bc1"],
+                TrustedPublicKeys ["pub1"]
+              ]
+          localConf =
+            NixConf
+              [ Substituters ["bc2"],
+                TrustedPublicKeys ["pub2"]
+              ]
+          result =
+            NixConf
+              [ Substituters [defaultPublicURI, "bc1", "bc2", "https://name.cachix.org"],
+                TrustedPublicKeys [defaultSigningKey, "pub1", "pub2", "pub"]
+              ]
        in add bc [globalConf, localConf] localConf `shouldBe` result
-    it "is noop if binary cache exists in one file"
-      $ let globalConf =
-              NixConf
-                [ Substituters [defaultPublicURI, "https://name.cachix.org"],
-                  TrustedPublicKeys [defaultSigningKey, "pub"]
-                  ]
-            localConf = NixConf []
-            result =
-              NixConf
-                [ Substituters [defaultPublicURI, "https://name.cachix.org"],
-                  TrustedPublicKeys [defaultSigningKey, "pub"]
-                  ]
+    it "is noop if binary cache exists in one file" $
+      let globalConf =
+            NixConf
+              [ Substituters [defaultPublicURI, "https://name.cachix.org"],
+                TrustedPublicKeys [defaultSigningKey, "pub"]
+              ]
+          localConf = NixConf []
+          result =
+            NixConf
+              [ Substituters [defaultPublicURI, "https://name.cachix.org"],
+                TrustedPublicKeys [defaultSigningKey, "pub"]
+              ]
        in add bc [globalConf, localConf] localConf `shouldBe` result
-    it "preserves other nixconf entries"
-      $ let globalConf =
-              NixConf
-                [ Substituters ["http"],
-                  TrustedPublicKeys ["pub1"],
-                  TrustedUsers ["user"],
-                  Other "foo"
-                  ]
-            localConf =
-              NixConf
-                [ TrustedUsers ["user2"],
-                  Other "bar"
-                  ]
-            result =
-              NixConf
-                [ TrustedUsers ["user2"],
-                  Other "bar",
-                  Substituters [defaultPublicURI, "http", "https://name.cachix.org"],
-                  TrustedPublicKeys [defaultSigningKey, "pub1", "pub"]
-                  ]
+    it "preserves other nixconf entries" $
+      let globalConf =
+            NixConf
+              [ Substituters ["http"],
+                TrustedPublicKeys ["pub1"],
+                TrustedUsers ["user"],
+                Other "foo"
+              ]
+          localConf =
+            NixConf
+              [ TrustedUsers ["user2"],
+                Other "bar"
+              ]
+          result =
+            NixConf
+              [ TrustedUsers ["user2"],
+                Other "bar",
+                Substituters [defaultPublicURI, "http", "https://name.cachix.org"],
+                TrustedPublicKeys [defaultSigningKey, "pub1", "pub"]
+              ]
        in add bc [globalConf, localConf] localConf `shouldBe` result
-    it "removed duplicates"
-      $ let globalConf =
-              NixConf
-                [ Substituters ["bc1", "bc1"],
-                  TrustedPublicKeys ["pub1", "pub1"]
-                  ]
-            localConf =
-              NixConf
-                [ Substituters ["bc2", "bc2"],
-                  TrustedPublicKeys ["pub2", "pub2"]
-                  ]
-            result =
-              NixConf
-                [ Substituters [defaultPublicURI, "bc1", "bc2", "https://name.cachix.org"],
-                  TrustedPublicKeys [defaultSigningKey, "pub1", "pub2", "pub"]
-                  ]
+    it "removed duplicates" $
+      let globalConf =
+            NixConf
+              [ Substituters ["bc1", "bc1"],
+                TrustedPublicKeys ["pub1", "pub1"]
+              ]
+          localConf =
+            NixConf
+              [ Substituters ["bc2", "bc2"],
+                TrustedPublicKeys ["pub2", "pub2"]
+              ]
+          result =
+            NixConf
+              [ Substituters [defaultPublicURI, "bc1", "bc2", "https://name.cachix.org"],
+                TrustedPublicKeys [defaultSigningKey, "pub1", "pub2", "pub"]
+              ]
        in add bc [globalConf, localConf] localConf `shouldBe` result
-    it "adds binary cache and defaults if no existing entries exist"
-      $ let globalConf = NixConf []
-            localConf = NixConf []
-            result =
-              NixConf
-                [ Substituters [defaultPublicURI, "https://name.cachix.org"],
-                  TrustedPublicKeys [defaultSigningKey, "pub"]
-                  ]
+    it "adds binary cache and defaults if no existing entries exist" $
+      let globalConf = NixConf []
+          localConf = NixConf []
+          result =
+            NixConf
+              [ Substituters [defaultPublicURI, "https://name.cachix.org"],
+                TrustedPublicKeys [defaultSigningKey, "pub"]
+              ]
        in add bc [globalConf, localConf] localConf `shouldBe` result
   describe "parse" $ do
-    it "parses substituters"
-      $ parse "substituters = a\n"
-      `shouldBe` (Right $ NixConf [Substituters ["a"]])
-    it "parses long key"
-      $ parse "binary-caches-parallel-connections = 40\n"
-      `shouldBe` (Right $ NixConf [Other "binary-caches-parallel-connections = 40"])
-    it "parses substituters with multiple values"
-      $ parse "substituters = a b c\n"
-      `shouldBe` (Right $ NixConf [Substituters ["a", "b", "c"]])
-    it "parses equal sign after the first key as literal"
-      $ parse "substituters = a b c= d\n"
-      `shouldBe` (Right $ NixConf [Substituters ["a", "b", "c=", "d"]])
-    it "parses with missing endline"
-      $ parse "allowed-users = *"
-      `shouldBe` (Right $ NixConf [Other "allowed-users = *"])
-    it "parses a complex example"
-      $ parse realExample
-      `shouldBe` ( Right
-                     $ NixConf
-                         [ Other "",
-                           Substituters ["a", "b", "c"],
-                           TrustedUsers ["him", "me"],
-                           TrustedPublicKeys ["a"],
-                           Other "blabla =  asd",
-                           Other "# comment",
-                           Other "",
-                           Other ""
-                           ]
-                   )
+    it "parses substituters" $
+      parse "substituters = a\n"
+        `shouldBe` Right (NixConf [Substituters ["a"]])
+    it "parses long key" $
+      parse "binary-caches-parallel-connections = 40\n"
+        `shouldBe` Right (NixConf [Other "binary-caches-parallel-connections = 40"])
+    it "parses substituters with multiple values" $
+      parse "substituters = a b c\n"
+        `shouldBe` Right (NixConf [Substituters ["a", "b", "c"]])
+    it "parses equal sign after the first key as literal" $
+      parse "substituters = a b c= d\n"
+        `shouldBe` Right (NixConf [Substituters ["a", "b", "c=", "d"]])
+    it "parses with missing endline" $
+      parse "allowed-users = *"
+        `shouldBe` Right (NixConf [Other "allowed-users = *"])
+    it "parses a complex example" $
+      parse realExample
+        `shouldBe` Right
+          ( NixConf
+              [ Other "",
+                Substituters ["a", "b", "c"],
+                TrustedUsers ["him", "me"],
+                TrustedPublicKeys ["a"],
+                Other "blabla =  asd",
+                Other "# comment",
+                Other "",
+                Other ""
+              ]
+          )
 
 realExample :: Text
 realExample =
diff --git a/test/NixVersionSpec.hs b/test/NixVersionSpec.hs
--- a/test/NixVersionSpec.hs
+++ b/test/NixVersionSpec.hs
@@ -6,21 +6,21 @@
 
 spec :: Spec
 spec = describe "parseNixVersion" $ do
-  it "parses 'nix-env (Nix) 2.0' as Nix20"
-    $ parseNixVersion "nix-env (Nix) 2.0"
-    `shouldBe` Left "Nix 2.0.2 or lower is not supported. Please upgrade: https://nixos.org/nix/"
-  it "parses 'nix-env (Nix) 2.0.1' as Nix201"
-    $ parseNixVersion "nix-env (Nix) 2.0.1"
-    `shouldBe` Right ()
-  it "parses 'nix-env (Nix) 1.11.13' as Nix1XX"
-    $ parseNixVersion "nix-env (Nix) 1.11.13"
-    `shouldBe` Left "Nix 2.0.2 or lower is not supported. Please upgrade: https://nixos.org/nix/"
-  it "parses 'nix-env (Nix) 2.0.5' as Nix201"
-    $ parseNixVersion "nix-env (Nix) 2.0.5"
-    `shouldBe` Right ()
-  it "parses 'nix-env (Nix) 2.0.1pre6053_444b921' as Nix201"
-    $ parseNixVersion "nix-env (Nix) 2.0.1pre6053_444b921"
-    `shouldBe` Right ()
-  it "fails with unknown string 'foobar'"
-    $ parseNixVersion "foobar"
-    `shouldBe` Left "Couldn't parse 'nix-env --version' output: foobar"
+  it "parses 'nix-env (Nix) 2.0' as Nix20" $
+    parseNixVersion "nix-env (Nix) 2.0"
+      `shouldBe` Left "Nix 2.0.2 or lower is not supported. Please upgrade: https://nixos.org/nix/"
+  it "parses 'nix-env (Nix) 2.0.1' as Nix201" $
+    parseNixVersion "nix-env (Nix) 2.0.1"
+      `shouldBe` Right ()
+  it "parses 'nix-env (Nix) 1.11.13' as Nix1XX" $
+    parseNixVersion "nix-env (Nix) 1.11.13"
+      `shouldBe` Left "Nix 2.0.2 or lower is not supported. Please upgrade: https://nixos.org/nix/"
+  it "parses 'nix-env (Nix) 2.0.5' as Nix201" $
+    parseNixVersion "nix-env (Nix) 2.0.5"
+      `shouldBe` Right ()
+  it "parses 'nix-env (Nix) 2.0.1pre6053_444b921' as Nix201" $
+    parseNixVersion "nix-env (Nix) 2.0.1pre6053_444b921"
+      `shouldBe` Right ()
+  it "fails with unknown string 'foobar'" $
+    parseNixVersion "foobar"
+      `shouldBe` Left "Couldn't parse 'nix-env --version' output: foobar"
