1
0
Fork 0
mirror of https://code.sup39.dev/repos/Wqawg synced 2025-03-20 04:46:22 +09:00

Split git repo source handler into sane small functions

This commit is contained in:
fr33domlover 2016-05-04 17:17:47 +00:00
parent 2c73158c47
commit c8c323f695
5 changed files with 149 additions and 115 deletions
src/Data/Git

View file

@ -14,44 +14,45 @@
-}
module Data.Git.Local
( initRepo
( -- * Initialize repo
createRepo
-- * View repo content
, EntObjType (..)
, TreeRows
, PathView (..)
, viewPath
)
where
import Prelude
import Control.Monad (when)
import Data.Byteable (toBytes)
import Data.Git
import Data.Git.Harder
import Data.Text (Text)
import Data.Text.Encoding (decodeUtf8With)
import Data.Text.Encoding.Error (lenientDecode)
import System.Directory.Tree
import qualified Data.ByteString as B (ByteString, writeFile)
initialConfig :: B.ByteString
initialConfig =
"[core]\n\
\ repositoryformatversion = 0\n\
\ filemode = true\n\
\ bare = true"
initialDescription :: B.ByteString
initialDescription =
"Unnamed repository; edit this file to name the repository."
initialHead :: B.ByteString
initialHead = "ref: refs/heads/master"
initialExclude :: B.ByteString
initialExclude = ""
import qualified Data.ByteString.Lazy as BL (ByteString)
initialRepoTree :: FileName -> DirTree B.ByteString
initialRepoTree repo =
Dir repo
[ Dir "branches" []
, File "config" initialConfig
, File "description" initialDescription
, File "HEAD" initialHead
, File "config"
"[core]\n\
\ repositoryformatversion = 0\n\
\ filemode = true\n\
\ bare = true"
, File "description"
"Unnamed repository; edit this file to name the repository."
, File "HEAD" "ref: refs/heads/master"
, Dir "hooks" []
, Dir "info"
[ File "exclude" initialExclude
[ File "exclude" ""
]
, Dir "objects"
[ Dir "info" []
@ -68,14 +69,41 @@ initialRepoTree repo =
-- Currently in the @hit@ package, i.e. version 0.6.3, the initRepo function
-- creates a directory which the git executable doesn't recognize as a git
-- repository. The version here creates a properly initialized repo.
initRepo
createRepo
:: FilePath
-- ^ Parent directory which already exists
-> String
-- ^ Name of new repo, i.e. new directory to create under the parent
-> IO ()
initRepo path name = do
createRepo path name = do
let tree = path :/ initialRepoTree name
result <- writeDirectoryWith B.writeFile tree
let errs = failures $ dirTree result
when (not . null $ errs) $ error $ show errs
data EntObjType = EntObjBlob | EntObjTree
type TreeRows = [(ModePerm, ObjId, Text, EntObjType)]
data PathView
= RootView TreeRows
| TreeView Text ObjId TreeRows
| BlobView Text ObjId BL.ByteString
viewPath :: Git -> Tree -> EntPath -> IO PathView
viewPath git root path = do
let toEnt False = EntObjBlob
toEnt True = EntObjTree
toText = decodeUtf8With lenientDecode . toBytes
adapt (perm, oid, name, isTree) =
(perm, oid, toText name, toEnt isTree)
mkRows t = map adapt <$> viewTree git t
mno <- resolveTreePath git root path
case mno of
Nothing -> RootView <$> mkRows root
Just (name, oid) -> do
let nameT = toText name
target <- getEntryObject_ git oid
case target of
Left blob -> return $ BlobView nameT oid (blobGetContent blob)
Right tree -> TreeView nameT oid <$> mkRows tree