support following HEAD

This commit is contained in:
Alexander Foremny
2024-06-05 18:02:33 +02:00
parent a7a4dd0112
commit 2064b4e776
3 changed files with 47 additions and 21 deletions

View File

@@ -3,6 +3,8 @@ module Main where
import AutoTypes qualified as U import AutoTypes qualified as U
import AutoTypes.Unify qualified as U import AutoTypes.Unify qualified as U
import Control.Applicative ((<**>)) import Control.Applicative ((<**>))
import Control.Concurrent
import Control.Concurrent.STM
import Control.Monad import Control.Monad
import Control.Monad.Trans (liftIO) import Control.Monad.Trans (liftIO)
import Data.Aeson qualified as J import Data.Aeson qualified as J
@@ -14,7 +16,7 @@ import Data.ByteString.UTF8 qualified as B
import Data.List import Data.List
import Data.Map qualified as M import Data.Map qualified as M
import Data.String (IsString (fromString)) import Data.String (IsString (fromString))
import Data.Tagged (Tagged (..)) import Data.Tagged (Tagged (..), untag)
import Debug.Trace import Debug.Trace
import Git qualified as G import Git qualified as G
import Git.Libgit2 qualified as GB import Git.Libgit2 qualified as GB
@@ -26,6 +28,7 @@ import Options.Applicative qualified as A
import Store qualified as Q import Store qualified as Q
import System.Directory (setCurrentDirectory) import System.Directory (setCurrentDirectory)
import System.FilePath import System.FilePath
import System.INotify
import Text.Printf (printf) import Text.Printf (printf)
data Args = Args data Args = Args
@@ -84,39 +87,60 @@ fromAutoTypes path (U.Object ps) =
where where
toProperty k (U.Scalar "string") = "string" :: String toProperty k (U.Scalar "string") = "string" :: String
main :: IO () watch :: TMVar Repo -> FilePath -> G.RefName -> IO ()
main = do watch repoT root ref = do
setCurrentDirectory "./blog" i <- initINotify
let root = "." qT <- newTQueueIO
ref = "HEAD" 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.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 Just cid <- fmap Tagged <$> G.resolveReference ref
c <- G.lookupCommit cid c <- G.lookupCommit cid
cs <- mapM G.lookupCommit =<< G.listCommits Nothing cid cs <- mapM G.lookupCommit =<< G.listCommits Nothing cid
let showCommit c = G.commitLog c
fmap Repo . forM cs $ \c -> do fmap Repo . forM cs $ \c -> do
let cid = G.commitOid c let cid = G.commitOid c
let tid = G.commitTree c
t <- G.lookupTree tid
fs <- fs <-
filter ((== ".json") . takeExtension) fmap (filter ((== ".json") . takeExtension)) . liftIO $
. map B.toString Q.withStore root ref do
. map fst Q.withCommit cid Q.listAllFiles
<$> G.listTreeEntries t let cls =
let cls = M.toList (M.unionsWith (++) (map (\f -> M.singleton (takeDirectory f) [f]) fs)) M.toList . M.unionsWith (++) $
colls <- forM cls $ \(path, (file : files)) -> do map (\f -> M.singleton (takeDirectory f) [f]) fs
schema <- colls <- forM cls $ \(makeRelative "/" -> path, (file : files)) -> do
fmap (fromAutoTypes path) . liftIO $ -- TODO read from HEAD (value : values) <- do
U.autoTypes file files 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 $ Collection path files schema
pure (Commit cid colls) 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 A.execParser (A.info (args <**> A.helper) A.idm) >>= \case
Args {cmd = Serve} -> do Args {cmd = Serve} -> do
W.runEnv 8081 $ \req respond -> do W.runEnv 8081 $ \req respond -> do
case P.parseOnly routeP (W.rawPathInfo req) of case P.parseOnly routeP (W.rawPathInfo req) of
Right (SchemaJson path) -> do 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) respond $ W.responseLBS W.status200 [] (J.encode c.schema)
Right Query -> do Right Query -> do
q <- q <-

View File

@@ -28,10 +28,12 @@ executable backend
filepath, filepath,
gitlib, gitlib,
gitlib-libgit2, gitlib-libgit2,
hinotify,
hlibgit2, hlibgit2,
http-types, http-types,
mtl, mtl,
optparse-applicative, optparse-applicative,
stm,
tagged, tagged,
utf8-string, utf8-string,
wai, wai,

View File

@@ -2,7 +2,7 @@
"json2sql": { "json2sql": {
"branch": "main", "branch": "main",
"repo": "git@code.nomath.org:~/json2sql", "repo": "git@code.nomath.org:~/json2sql",
"rev": "04b43e75fb0822de7db67f108c3545dee451069c", "rev": "d8b2af98f594e4fc5cc4919c1efe95e1d8d9aafe",
"type": "git" "type": "git"
}, },
"nixpkgs": { "nixpkgs": {