{- This file is part of Vervis. - - Written in 2016 by fr33domlover . - - ♡ Copying is an act of love. Please copy, reuse and share. - - The author(s) have dedicated all copyright and related and neighboring - rights to this software to the public domain worldwide. This software is - distributed without any warranty. - - You should have received a copy of the CC0 Public Domain Dedication along - with this software. If not, see - . -} module Data.Git.Local ( -- * 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) import qualified Data.ByteString.Lazy as BL (ByteString) initialRepoTree :: FileName -> DirTree B.ByteString initialRepoTree repo = Dir repo [ Dir "branches" [] , 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" "" ] , Dir "objects" [ Dir "info" [] , Dir "pack" [] ] , Dir "refs" [ Dir "heads" [] , Dir "tags" [] ] ] -- | initialize a new bare repository at a specific location. -- -- 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. createRepo :: FilePath -- ^ Parent directory which already exists -> String -- ^ Name of new repo, i.e. new directory to create under the parent -> IO () 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