aboutsummaryrefslogtreecommitdiffstats
path: root/backend/app
diff options
context:
space:
mode:
authorLibravatar Alexander Foremny <aforemny@posteo.de>2024-06-05 18:02:33 +0200
committerLibravatar Alexander Foremny <aforemny@posteo.de>2024-06-05 18:03:59 +0200
commit2064b4e7767dca2858d8093597503a594dcd74ef (patch)
treefce8e41a218d2dcdb64a953f0e7161bafe36e907 /backend/app
parenta7a4dd01127506dba991cc5f3f39c4a370fff699 (diff)
support following HEAD
Diffstat (limited to 'backend/app')
-rw-r--r--backend/app/Main.hs64
1 files changed, 44 insertions, 20 deletions
diff --git a/backend/app/Main.hs b/backend/app/Main.hs
index 82d2d38..6773916 100644
--- a/backend/app/Main.hs
+++ b/backend/app/Main.hs
@@ -3,6 +3,8 @@ module Main where
import AutoTypes qualified as U
import AutoTypes.Unify qualified as U
import Control.Applicative ((<**>))
+import Control.Concurrent
+import Control.Concurrent.STM
import Control.Monad
import Control.Monad.Trans (liftIO)
import Data.Aeson qualified as J
@@ -14,7 +16,7 @@ import Data.ByteString.UTF8 qualified as B
import Data.List
import Data.Map qualified as M
import Data.String (IsString (fromString))
-import Data.Tagged (Tagged (..))
+import Data.Tagged (Tagged (..), untag)
import Debug.Trace
import Git qualified as G
import Git.Libgit2 qualified as GB
@@ -26,6 +28,7 @@ import Options.Applicative qualified as A
import Store qualified as Q
import System.Directory (setCurrentDirectory)
import System.FilePath
+import System.INotify
import Text.Printf (printf)
data Args = Args
@@ -84,39 +87,60 @@ fromAutoTypes path (U.Object ps) =
where
toProperty k (U.Scalar "string") = "string" :: String
-main :: IO ()
-main = do
- setCurrentDirectory "./blog"
- let root = "."
- ref = "HEAD"
+watch :: TMVar Repo -> FilePath -> G.RefName -> IO ()
+watch repoT root ref = do
+ i <- initINotify
+ qT <- newTQueueIO
+ wd <-
+ addWatch i [MoveIn] ".git/refs/heads" $ \e ->
+ atomically (writeTQueue qT e)
+ forever do
+ repo <- initRepo root ref
+ atomically do putTMVar repoT repo
+ _ <- atomically do
+ let loop = maybe (pure ()) (const loop) =<< tryReadTQueue qT
+ readTQueue qT >> loop
+ _ <- atomically do takeTMVar repoT
+ pure ()
+
+initRepo :: FilePath -> G.RefName -> IO Repo
+initRepo root ref = do
repo <- G.openRepository GB.lgFactory G.defaultRepositoryOptions {G.repoPath = root}
- repo <- G.runRepository GB.lgFactory repo do
+ G.runRepository GB.lgFactory repo do
Just cid <- fmap Tagged <$> G.resolveReference ref
c <- G.lookupCommit cid
cs <- mapM G.lookupCommit =<< G.listCommits Nothing cid
- let showCommit c = G.commitLog c
fmap Repo . forM cs $ \c -> do
let cid = G.commitOid c
- let tid = G.commitTree c
- t <- G.lookupTree tid
fs <-
- filter ((== ".json") . takeExtension)
- . map B.toString
- . map fst
- <$> G.listTreeEntries t
- let cls = M.toList (M.unionsWith (++) (map (\f -> M.singleton (takeDirectory f) [f]) fs))
- colls <- forM cls $ \(path, (file : files)) -> do
- schema <-
- fmap (fromAutoTypes path) . liftIO $ -- TODO read from HEAD
- U.autoTypes file files
+ fmap (filter ((== ".json") . takeExtension)) . liftIO $
+ Q.withStore root ref do
+ Q.withCommit cid Q.listAllFiles
+ let cls =
+ M.toList . M.unionsWith (++) $
+ map (\f -> M.singleton (takeDirectory f) [f]) fs
+ colls <- forM cls $ \(makeRelative "/" -> path, (file : files)) -> do
+ (value : values) <- do
+ liftIO $ Q.withStore root ref do
+ mapM (Q.withCommit cid . Q.readFile) (file : files)
+ let schema = fromAutoTypes path $ U.autoTypes' value values
pure $ Collection path files schema
pure (Commit cid colls)
+
+main :: IO ()
+main = do
+ setCurrentDirectory "../blog"
+ let root = "."
+ ref = "refs/heads/master"
+ repoT <- newEmptyTMVarIO
+ _ <- forkIO do watch repoT root ref
A.execParser (A.info (args <**> A.helper) A.idm) >>= \case
Args {cmd = Serve} -> do
W.runEnv 8081 $ \req respond -> do
case P.parseOnly routeP (W.rawPathInfo req) of
Right (SchemaJson path) -> do
- let [c] = filter ((== path) . (.path)) (head repo.commits).collections
+ repo <- atomically (readTMVar repoT)
+ let [c] = filter ((== path) . (.path)) (last repo.commits).collections
respond $ W.responseLBS W.status200 [] (J.encode c.schema)
Right Query -> do
q <-