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

Commit 2b5e93377bab6ebf38f5e06cebdd49418093d9de
Parent: 8ba4cbfe7f06ed441920a74315705f7a24a09984
Author: mcol <mcol@posteo.net>
Date: 2022-06-04 23:01:53 +0100
Committer: mcol <mcol@posteo.net>
Committed: 2022-06-04 23:08:43 +0100

Check commit diffs to update outputs for only updated files

src/Types.hs Modified

@@ -91,8 +91,8 @@
 
 commitAsLookup :: Commit -> T.Text -> Maybe (GVal m)
 commitAsLookup commit = \case
-    "id" -> Just . toGVal . show . untag . Git.commitOid . commitGit $ commit
-    "href" -> Just . toGVal . (<> ".html") . show . untag . Git.commitOid . commitGit $ commit
+    "id" -> Just . toGVal . commitHash $ commit
+    "href" -> Just . toGVal . (<> ".html") . commitHash $ commit
     "title" -> Just . toGVal . T.strip . T.takeWhile (/= '\n') . Git.commitLog . commitGit $ commit
     "body" -> Just . toGVal . T.strip . T.dropWhile (/= '\n') . Git.commitLog . commitGit $ commit
     "message" -> Just . toGVal . T.strip . Git.commitLog . commitGit $ commit
@@ -107,6 +107,9 @@
     "diffs" -> Just . toGVal . commitDiffs $ commit
     _ -> Nothing
 
+commitHash :: Commit -> String
+commitHash = show . untag . Git.commitOid . commitGit
+
 {-
 With `Diff`s there is a hierarchy:
 

src/Repositories.hs Modified

@@ -136,18 +136,25 @@
                     ensureDir commitDir
                     ensureDir fileDir
 
+                    -- Check which commits are new since the last run --
+                    newCommits <- getUpdates commitDir commits
+
                     -- Run the generator --
                     let quiet = envQuiet env
                         force = envForce env
-                        gen = genTarget scope runInIO quiet force
+                        gen = genTarget scope runInIO quiet
 
                     mapM_ (generate scope runInIO quiet directory) (envRepoTemplates env)
 
                     whenJust (envCommitTemplate env) \commitT -> do
-                        mapM_ (gen commitT "commit" commitDir commitHref) commits
+                        mapM_ (gen force commitT "commit" commitDir commitHref) newCommits
 
                     whenJust (envFileTemplate env) \fileT -> do
-                        mapM_ (gen fileT "file" fileDir fileHref) tree -- TODO: detect file changes
+                        if force
+                            then mapM_ (gen True fileT "file" fileDir fileHref) tree
+                            else
+                                let updatedFiles = getUpdatedFiles tree newCommits
+                                 in mapM_ (gen True fileT "file" fileDir fileHref) updatedFiles
 
                     -- Copy any static files/folders into the output directory --
                     envRepoCopyStatics env directory
@@ -348,6 +355,32 @@
     dropName Nothing _ = Nothing
 
 {-
+Get the list of commits that need updating since the last run. New commits are
+identified by the absence of their output file.
+-}
+getUpdates :: Path Abs Dir -> [Commit] -> IO [Commit]
+getUpdates _ [] = return []
+getUpdates directory cs = go cs
+  where
+    dir = toFilePath directory
+
+    go :: [Commit] -> IO [Commit]
+    go [] = return []
+    go (x : xs) =
+        ifM
+            (D.doesFileExist $ dir FP.</> commitHref x)
+            (return [])
+            ((x :) <$> go xs)
+
+getUpdatedFiles :: [TreeFile] -> [Commit] -> [TreeFile]
+getUpdatedFiles [] _ = []
+getUpdatedFiles _ [] = []
+getUpdatedFiles files commits = filter ((`elem` updated) . treeFilePath) files
+  where
+    updated :: [T.Text]
+    updated = fmap (bsToText . diffNewFile) . concatMap commitDiffs $ commits
+
+{-
 Render repository data into a template and save it to file.
 -}
 generate ::
@@ -390,7 +423,7 @@
         TL.writeFile output' =<< render (cbRepoLookup scope' runInIO) template
 
 commitHref :: Commit -> FilePath
-commitHref = (++ ".html") . show . untag . Git.commitOid . commitGit
+commitHref = (++ ".html") . commitHash
 
 fileHref :: TreeFile -> FilePath
 fileHref = T.unpack . treePathToHref