🐙 Templated web page generator for your git repositories
git clone https://github.com/m-col/gitja
Files | Refs | Readme | License

Commit 33196497451a198dec6dbfbaa2cdd60677e749ec
Parent: 9cbe6eb1180919f49e184775e8a2ef383cf56952
Author: mcol <mcol@posteo.net>
Date: 2021-11-28 23:01:45 +0000
Committer: mcol <mcol@posteo.net>
Committed: 2021-11-28 23:01:45 +0000

Emit ginger data to IO ref and write to file once

This seems to speed things up

src/Templates.hs Modified

@@ -8,16 +8,28 @@
     generate,
 ) where
 
-import Control.Monad (filterM, join, void, when, (<=<))
+import Control.Monad (filterM, join, when, (<=<))
 import Control.Monad.Extra (findM)
 import Control.Monad.IO.Class (liftIO)
 import Control.Monad.Trans.Reader (ReaderT)
 import qualified Data.HashMap.Strict as HashMap
+import Data.IORef (modifyIORef', newIORef, readIORef)
 import Data.Maybe (catMaybes, fromMaybe)
-import Data.Text (Text, unpack)
+import qualified Data.Text as T
+import qualified Data.Text.Lazy.Builder as TB
+import qualified Data.Text.Lazy.IO as T
 import Git.Libgit2 (LgRepo)
 import Path (Abs, Dir, File, Path, Rel, dirname, filename, parseAbsDir, toFilePath, (</>))
-import Path.IO (copyDirRecur, copyFile, doesDirExist, ensureDir, forgivingAbsence, isSymlink, listDir)
+import Path.IO (
+    copyDirRecur,
+    copyFile,
+    doesDirExist,
+    ensureDir,
+    forgivingAbsence,
+    ignoringAbsence,
+    isSymlink,
+    listDir,
+ )
 import System.Directory (
     canonicalizePath,
     createDirectoryLink,
@@ -49,7 +61,7 @@
     , envRepoTemplates :: [Template]
     , envOutputDirectory :: Path Abs Dir
     , envRepoPaths :: [Path Abs Dir]
-    , envHost :: Text
+    , envHost :: T.Text
     , envQuiet :: Bool
     , envForce :: Bool
     }
@@ -130,17 +142,20 @@
 -}
 generate ::
     Path Abs File ->
-    HashMap.HashMap Text (GVal RunRepo) ->
+    HashMap.HashMap T.Text (GVal RunRepo) ->
     Template ->
     ReaderT LgRepo IO ()
 generate output context template = do
     let output' = toFilePath output
-    liftIO $ writeFile output' "" -- Clear contents of file if it exists
-    void . runGingerT (easyContext (writeTo output') context) . templateGinger $ template
-  where
-    -- This function gets the output HTML data and is responsible for saving it to file.
-    writeTo :: FilePath -> Html -> ReaderT LgRepo IO ()
-    writeTo path = liftIO . appendFile path . unpack . htmlSource
+    liftIO . ignoringAbsence . removeFile $ output'
+    content <- liftIO . newIORef . TB.fromText $ ""
+
+    let emit :: Html -> ReaderT LgRepo IO ()
+        emit = liftIO . modifyIORef' content . flip mappend . TB.fromText . htmlSource
+
+    runGingerT (easyContext emit context) . templateGinger $ template
+    result <- liftIO . readIORef $ content
+    liftIO . T.writeFile output' . TB.toLazyText $ result
 
 {-
 This takes the session's `Config` and maybe returns a loaded template for the