Skip to content

Commit 8da8988

Browse files
committed
refactory
1 parent 9c0e044 commit 8da8988

File tree

1 file changed

+39
-36
lines changed

1 file changed

+39
-36
lines changed

src/MyGit.hs

Lines changed: 39 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -56,60 +56,63 @@ getDotGitPath fp = do
5656
else getDotGitPath dirName
5757

5858
func :: String -> CString -> Pointers -> IO (Map FilePath Integer)
59-
func require repoPath pointers = do
59+
func matchPrefix repoPath pointers = do
6060
c'git_repository_open (pointers ^. repoP) repoPath >>= errorCheck
6161
repo <- peek $ pointers ^. repoP
6262
c'git_repository_head (pointers ^. headP) repo >>= errorCheck
6363
headOid <- peek (pointers ^. headP) >>= c'git_reference_target
6464
c'git_commit_lookup (pointers ^. commitP) repo headOid >>= errorCheck
6565
headCommit <- peek (pointers ^. commitP)
6666
lineage <- unfoldCommits headCommit
67-
maps <- mapM (makeEntryMap require) lineage
67+
let constructEntryMap' = constructEntrymap matchPrefix repo
68+
maps <- mapM (getRootAndTime >=> uncurry constructEntryMap') lineage
6869
c'git_repository_free repo
6970
return $ Map.unionsWith min maps
7071

72+
getRootAndTime :: Ptr C'git_commit -> IO (Ptr C'git_tree, Integer)
73+
getRootAndTime commit = do
74+
alloca $ \rootP -> do
75+
c'git_commit_tree rootP commit >>= errorCheck
76+
root <- peek rootP
77+
time <- c'git_commit_time commit
78+
return (root, toInteger time)
79+
7180
unfoldCommits :: Ptr C'git_commit -> IO [Ptr C'git_commit]
7281
unfoldCommits commit = alloca $ \parentP -> do
7382
result <- c'git_commit_parent parentP commit 0
7483
if result == 0
7584
then peek parentP >>= unfoldCommits <&> (++ [commit])
7685
else return [commit]
7786

78-
makeEntryMap'' :: String -> Ptr C'git_repository -> String -> Integer -> Ptr C'git_tree_entry -> IO (Map FilePath Integer)
79-
makeEntryMap'' require repo prefix time entry = do
80-
entryType <- c'git_tree_entry_type entry
81-
name <- c'git_tree_entry_name entry >>= peekCString
82-
if entryType == c'GIT_OBJ_TREE
83-
then do
84-
eoid <- c'git_tree_entry_id entry
85-
alloca $ \subTreeP -> do
86-
c'git_tree_lookup subTreeP repo eoid >>= errorCheck
87-
subTree <- peek subTreeP
88-
let next = prefix ++ name ++ "/"
89-
if next `isPrefixOf` require || require `isPrefixOf` next
90-
then makeEntryMap' require (prefix ++ name ++ "/") time subTree
91-
else return Map.empty
92-
else do
93-
if require `isPrefixOf` prefix
94-
then do
95-
let relPath = makeRelative require (prefix ++ name)
96-
return $ Map.singleton relPath time
97-
else return Map.empty
87+
constructEntrymap :: String -> Ptr C'git_repository -> Ptr C'git_tree -> Integer -> IO (Map FilePath Integer)
88+
constructEntrymap matchPrefix repo root time =
89+
let makeEntryMap'' :: String -> Ptr C'git_tree_entry -> IO (Map FilePath Integer)
90+
makeEntryMap'' parentDir entry = do
91+
entryType <- c'git_tree_entry_type entry
92+
name <- c'git_tree_entry_name entry >>= peekCString
93+
let next = parentDir ++ name ++ "/"
94+
if entryType == c'GIT_OBJ_TREE
95+
then do
96+
eoid <- c'git_tree_entry_id entry
97+
alloca $ \subTreeP -> do
98+
c'git_tree_lookup subTreeP repo eoid >>= errorCheck
99+
subTree <- peek subTreeP
100+
if next `isPrefixOf` matchPrefix || matchPrefix `isPrefixOf` next
101+
then makeEntryMap' (parentDir ++ name ++ "/") subTree
102+
else return Map.empty
103+
else do
104+
if matchPrefix `isPrefixOf` parentDir
105+
then do
106+
let relPath = makeRelative matchPrefix (parentDir ++ name)
107+
return $ Map.singleton relPath time
108+
else return Map.empty
98109

99-
makeEntryMap' :: String -> String -> Integer -> Ptr C'git_tree -> IO (Map FilePath Integer)
100-
makeEntryMap' require prefix time tree = do
101-
entryCountC <- c'git_tree_entrycount tree
102-
let f = c'git_tree_entry_byindex tree
103-
repo <- c'git_tree_owner tree
104-
foldMap (f >=> makeEntryMap'' require repo prefix time) [0 .. (entryCountC - 1)]
105-
106-
makeEntryMap :: String -> Ptr C'git_commit -> IO (Map FilePath Integer)
107-
makeEntryMap require commit = do
108-
alloca $ \treeP -> do
109-
c'git_commit_tree treeP commit >>= errorCheck
110-
tree <- peek treeP
111-
time <- c'git_commit_time commit
112-
makeEntryMap' require "" (toInteger time) tree
110+
makeEntryMap' :: String -> Ptr C'git_tree -> IO (Map FilePath Integer)
111+
makeEntryMap' parentDir tree = do
112+
entryCountC <- c'git_tree_entrycount tree
113+
let f = c'git_tree_entry_byindex tree
114+
foldMap (f >=> makeEntryMap'' parentDir) [0 .. (entryCountC - 1)]
115+
in makeEntryMap' "" root
113116

114117
errorCheck r = when (r /= 0) $ error "fail"
115118

0 commit comments

Comments
 (0)