Skip to content

Commit 6fcf74b

Browse files
add copyTo, moveTo, and remove
1 parent 12ea08f commit 6fcf74b

File tree

1 file changed

+25
-5
lines changed

1 file changed

+25
-5
lines changed

src/System/Directory/Tree.hs

Lines changed: 25 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,12 +25,15 @@ module System.Directory.Tree
2525
, extract, extractM
2626
-- **truncate tree to a maximum level
2727
, truncateAt
28+
-- **Copy, move, and remove directory trees
29+
, copyTo, moveTo, remove
2830
)where
2931

3032
import System.IO.Unsafe (unsafeInterleaveIO)
3133
import Unsafe.Coerce (unsafeCoerce)
32-
import System.Directory (getDirectoryContents, doesDirectoryExist)
33-
import System.FilePath ((</>))
34+
import System.Directory (getDirectoryContents, doesDirectoryExist
35+
,copyFile, renameFile, removeFile)
36+
import System.FilePath ((</>), replaceDirectory)
3437
import System.Posix.Files (getSymbolicLinkStatus, isSymbolicLink)
3538
import Data.Tree (Tree(..), Forest)
3639
import qualified Data.Tree as Tree (flatten)
@@ -43,6 +46,7 @@ import Control.Monad.Identity (runIdentity)
4346
import Control.Applicative ((<$>))
4447
import Control.Arrow (second)
4548
import Data.Maybe (mapMaybe)
49+
import Data.Function (on)
4650
import Control.Cond (ifM, (<||>), (<&&>), notM)
4751

4852
import Data.Default (Default(..))
@@ -113,6 +117,9 @@ getDir_ f Options {..} p = mkFSTree p <$> getChildren p
113117
( f . fmap (mkFSTree c) . getChildren $ c' )
114118
( return $ mkFSTree c [] )
115119

120+
isSymLink :: FilePath -> IO Bool
121+
isSymLink p = isSymbolicLink <$> getSymbolicLinkStatus p
122+
116123
pop :: FSTree -> (FilePath, FSForest)
117124
pop fs = (path, map prepend cs)
118125
where path = getL label fs
@@ -161,7 +168,6 @@ extractM_ p = foldrM extract' ([], DL.empty) . map prependPaths
161168
return (ts, FSTree t `cons` es)
162169
)
163170

164-
165171
truncateAt :: TreeLens t a => Word -> [t] -> [t]
166172
truncateAt n = mapMaybe (truncate' 0)
167173
where
@@ -177,5 +183,19 @@ prependPaths (FSTree t) = modL children (map (prepend' root)) t
177183
prepend' parentPath = modL label (parentPath </>) . prependChildren
178184
prependChildren fs = modL children (map (prepend' (rootLabel fs))) fs
179185

180-
isSymLink :: FilePath -> IO Bool
181-
isSymLink p = isSymbolicLink <$> getSymbolicLinkStatus p
186+
187+
copyTo :: FilePath -> FSTree -> IO FSTree
188+
copyTo = zipWithDestM copyFile
189+
190+
moveTo :: FilePath -> FSTree -> IO FSTree
191+
moveTo = zipWithDestM renameFile
192+
193+
remove :: FSTree -> IO ()
194+
remove = mapM_ removeFile . flatten
195+
196+
zipWithDestM :: Monad m =>
197+
(FilePath -> FilePath -> m ()) -> FilePath -> FSTree -> m FSTree
198+
zipWithDestM f dest fs = do
199+
sequence_ $ (zipWith f `on` flatten) fs destFs
200+
return destFs
201+
where destFs = modL label (`replaceDirectory` dest) fs

0 commit comments

Comments
 (0)