Merge branch 'darcs' into master
[git-darcs-import.git] / src / Darcs / PopulationData.hs
bloba63bbc76640260bc419291c4648338705ba078da
1 -- Copyright (C) 2003-2004 Jan Scheffczyk and David Roundy
2 --
3 -- This program is free software; you can redistribute it and/or modify
4 -- it under the terms of the GNU General Public License as published by
5 -- the Free Software Foundation; either version 2, or (at your option)
6 -- any later version.
7 --
8 -- This program is distributed in the hope that it will be useful,
9 -- but WITHOUT ANY WARRANTY; without even the implied warranty of
10 -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 -- GNU General Public License for more details.
13 -- You should have received a copy of the GNU General Public License
14 -- along with this program; see the file COPYING. If not, write to
15 -- the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
16 -- Boston, MA 02110-1301, USA.
18 module Darcs.PopulationData ( Population(..), PopTree(..), Info(..),
19 setPopState, notModified, setState,
20 DirMark(..), getPopFrom
21 ) where
22 import Darcs.Patch.Info
23 import Darcs.Utils ( withCurrentDirectory )
24 import System.Directory ( doesDirectoryExist, getDirectoryContents )
25 import qualified Data.ByteString.Char8 as BC
26 import qualified Data.ByteString as B (ByteString)
28 -- | the population of a darcs repository (simpler Slurpy)
29 data Population = Pop { popState :: PatchInfo -- ^ the state when last modified
30 , popTree :: PopTree -- ^ the directory listing
32 deriving (Show, Eq)
34 setPopState :: PatchInfo -> Population -> Population
35 setPopState i (Pop _ tr) = Pop i tr
37 -- | directory listing
38 data PopTree = PopDir !Info ![PopTree]
39 | PopFile !Info
40 deriving ( Ord, Eq )
42 -- | info of a directory member
43 data DirMark = AddedFile | RemovedFile | MovedFile String
44 | ModifiedFile | DullFile
45 | AddedDir | RemovedDir | MovedDir !String | DullDir
46 deriving ( Ord, Eq )
47 data Info = Info {nameI :: !B.ByteString, -- ^ name of the element
48 modifiedByI :: !PatchInfo, -- ^ last patch modifying this element
49 modifiedHowI :: !DirMark, -- ^ how was it modified
50 createdByI :: !(Maybe PatchInfo), -- ^ this can be unknown when restored backwards!
51 creationNameI :: !(Maybe B.ByteString) -- ^ the original name of the element
53 deriving ( Ord, Eq )
55 -- | was an Info record not modified?
56 notModified :: Info -> Bool
57 notModified i = (modifiedHowI i == DullFile) || (modifiedHowI i == DullDir)
59 -- | set the modifier for an Info record
60 setState :: Info -> PatchInfo -> Info
61 setState i pinfo = i { modifiedByI = pinfo }
63 instance Show PopTree where
64 show s = showPop "" s
66 showPop :: String -> PopTree -> String
67 showPop indent (PopDir i fs)
68 = indent ++ show i ++ "\n" ++
69 unlines (map (showPop (' ':indent)) fs)
70 showPop indent (PopFile i)
71 = indent ++ show i
73 instance Show Info where
74 show i = show (nameI i) ++ " " ++ show (modifiedHowI i) ++
75 " at state " ++ show (modifiedByI i)
77 instance Show DirMark where
78 show AddedFile = "File added"
79 show RemovedFile = "File removed"
80 show (MovedFile s) = "File moved to " ++ s
81 show ModifiedFile = "File modified"
82 show DullFile = "File old"
83 show AddedDir = "Dir added"
84 show RemovedDir = "Dir removed"
85 show (MovedDir s) = "Dir moved from " ++ s
86 show DullDir = "Dir old"
88 -- | read the population from a given directory @dirname@
89 -- all folders and documents get the given time @t@
91 -- This needs to be here in order to avoid a circular dependency
92 -- between Population and Pristine.
93 getPopFrom :: FilePath -> PatchInfo -> IO Population
94 getPopFrom the_directory pinfo =
95 withCurrentDirectory the_directory $
96 do popT <- getPopFrom_helper "."
97 return (Pop pinfo popT)
98 where getPopFrom_helper :: FilePath -> IO PopTree
99 getPopFrom_helper dirname = do
100 isdir <- doesDirectoryExist dirname
101 let n = BC.pack dirname
102 if isdir
103 then do
104 fnames <- getDirectoryContents dirname
105 sl <- withCurrentDirectory dirname
106 (sequence $ map getPopFrom_helper $ filter not_hidden fnames)
107 let i = Info {nameI = n,
108 modifiedByI = pinfo,
109 modifiedHowI = DullDir,
110 createdByI = Just pinfo,
111 creationNameI = Just n}
112 return $ PopDir i sl
113 else do let i = Info {nameI = n,
114 modifiedByI = pinfo,
115 modifiedHowI = DullFile,
116 createdByI = Just pinfo,
117 creationNameI = Just n}
118 return $ PopFile i
120 not_hidden :: FilePath -> Bool
121 not_hidden ('.':_) = False
122 not_hidden ('_':_) = False
123 not_hidden _ = True