git-annex/Git/LsTree.hs
Joey Hess bf460a0a98 reorder repo parameters last
Many functions took the repo as their first parameter. Changing it
consistently to be the last parameter allows doing some useful things with
currying, that reduce boilerplate.

In particular, g <- gitRepo is almost never needed now, instead
use inRepo to run an IO action in the repo, and fromRepo to get
a value from the repo.

This also provides more opportunities to use monadic and applicative
combinators.
2011-11-08 16:27:20 -04:00

52 lines
1.2 KiB
Haskell

{- git ls-tree interface
-
- Copyright 2011 Joey Hess <joey@kitenet.net>
-
- Licensed under the GNU GPL version 3 or higher.
-}
module Git.LsTree (
TreeItem(..),
lsTree,
parseLsTree
) where
import Numeric
import Control.Applicative
import System.Posix.Types
import qualified Data.ByteString.Lazy.Char8 as L
import Git
import Utility.SafeCommand
type Treeish = String
data TreeItem = TreeItem
{ mode :: FileMode
, typeobj :: String
, sha :: String
, file :: FilePath
} deriving Show
{- Lists the contents of a Treeish -}
lsTree :: Treeish -> Repo -> IO [TreeItem]
lsTree t repo = map parseLsTree <$>
pipeNullSplitB [Params "ls-tree --full-tree -z -r --", File t] repo
{- Parses a line of ls-tree output.
- (The --long format is not currently supported.) -}
parseLsTree :: L.ByteString -> TreeItem
parseLsTree l = TreeItem
{ mode = fst $ head $ readOct $ L.unpack m
, typeobj = L.unpack t
, sha = L.unpack s
, file = decodeGitFile $ L.unpack f
}
where
-- l = <mode> SP <type> SP <sha> TAB <file>
-- All fields are fixed, so we can pull them out of
-- specific positions in the line.
(m, past_m) = L.splitAt 7 l
(t, past_t) = L.splitAt 4 past_m
(s, past_s) = L.splitAt 40 $ L.tail past_t
f = L.tail past_s