{-# LANGUAGE RankNTypes #-}
{-# LANGUAGE KindSignatures #-}
{-# LANGUAGE TupleSections #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE LambdaCase #-}
{-# LANGUAGE FlexibleContexts #-}
module Control.Lens.FileSystem
(
ls
, ls'ed
, path
, pathL
, branching
, dirs
, files
, contents
, exts
, crawled
, crawling
, absolute
, withPerms
, symLinksFollowed
, filteredM
, merging
, including
, recovering
, tryOrContinue
, tryCatch
, (</>)
, readable
, writable
, executable
, module System.FilePath.Lens
) where
import Control.Lens
import Control.Lens.Action
import Control.Lens.FileSystem.Internal.Combinators
import System.Directory
import System.FilePath.Posix
import System.FilePath.Lens
ls :: Monoid r => Acting IO r FilePath [FilePath]
ls :: Acting IO r FilePath [FilePath]
ls = Acting IO r FilePath [FilePath] -> Acting IO r FilePath [FilePath]
forall (m :: * -> *) r (f :: * -> *) (p :: * -> * -> *) s a.
(Monad m, Alternative m, Monoid r, Effective m r f) =>
Over' p f s a -> Over' p f s a
recovering (Acting IO r FilePath [FilePath]
-> Acting IO r FilePath [FilePath])
-> Acting IO r FilePath [FilePath]
-> Acting IO r FilePath [FilePath]
forall a b. (a -> b) -> a -> b
$ (FilePath -> IO [FilePath])
-> IndexPreservingAction IO FilePath [FilePath]
forall (m :: * -> *) s a.
Monad m =>
(s -> m a) -> IndexPreservingAction m s a
act (\fp :: FilePath
fp -> ((FilePath -> FilePath) -> [FilePath] -> [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (FilePath
fp FilePath -> FilePath -> FilePath
</>)) ([FilePath] -> [FilePath]) -> IO [FilePath] -> IO [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO [FilePath]
listDirectory FilePath
fp)
ls'ed :: Monoid r => Acting IO r FilePath FilePath
ls'ed :: Acting IO r FilePath FilePath
ls'ed = Acting IO r FilePath [FilePath]
forall r. Monoid r => Acting IO r FilePath [FilePath]
ls Acting IO r FilePath [FilePath]
-> ((FilePath -> Effect IO r FilePath)
-> [FilePath] -> Effect IO r [FilePath])
-> Acting IO r FilePath FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath -> Effect IO r FilePath)
-> [FilePath] -> Effect IO r [FilePath]
forall (f :: * -> *) a b.
Traversable f =>
IndexedTraversal Int (f a) (f b) a b
traversed
path :: FilePath -> Getter FilePath FilePath
path :: FilePath -> Getter FilePath FilePath
path filePath :: FilePath
filePath = (FilePath -> FilePath) -> Optic' (->) f FilePath FilePath
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to (FilePath -> FilePath -> FilePath
</> FilePath
filePath)
pathL :: [FilePath] -> Getter FilePath FilePath
pathL :: [FilePath] -> Getter FilePath FilePath
pathL filePaths :: [FilePath]
filePaths = (FilePath -> FilePath) -> Optic' (->) f FilePath FilePath
forall (p :: * -> * -> *) (f :: * -> *) s a.
(Profunctor p, Contravariant f) =>
(s -> a) -> Optic' p f s a
to (FilePath -> FilePath -> FilePath
</> [FilePath] -> FilePath
joinPath [FilePath]
filePaths)
branching :: [FilePath] -> Fold FilePath FilePath
branching :: [FilePath] -> Fold FilePath FilePath
branching filePaths :: [FilePath]
filePaths = (FilePath -> [FilePath]) -> Fold FilePath FilePath
forall (f :: * -> *) s a. Foldable f => (s -> f a) -> Fold s a
folding (\fp :: FilePath
fp -> (FilePath
fp FilePath -> FilePath -> FilePath
</>) (FilePath -> FilePath) -> [FilePath] -> [FilePath]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [FilePath]
filePaths)
dirs :: (Monoid r) => Acting IO r FilePath FilePath
dirs :: Acting IO r FilePath FilePath
dirs = (FilePath -> IO Bool) -> Acting IO r FilePath FilePath
forall (m :: * -> *) r a.
(Monad m, Monoid r) =>
(a -> m Bool) -> Acting m r a a
filteredM FilePath -> IO Bool
doesDirectoryExist
files :: (Monoid r) => Acting IO r FilePath FilePath
files :: Acting IO r FilePath FilePath
files = (FilePath -> IO Bool) -> Acting IO r FilePath FilePath
forall (m :: * -> *) r a.
(Monad m, Monoid r) =>
(a -> m Bool) -> Acting m r a a
filteredM FilePath -> IO Bool
doesFileExist
contents :: (Indexable FilePath p, Effective IO r f, Monoid r) => Over' p f FilePath String
contents :: Over' p f FilePath FilePath
contents = Over' p f FilePath FilePath -> Over' p f FilePath FilePath
forall (m :: * -> *) r (f :: * -> *) (p :: * -> * -> *) s a.
(Monad m, Alternative m, Monoid r, Effective m r f) =>
Over' p f s a -> Over' p f s a
recovering ((FilePath -> IO (FilePath, FilePath))
-> IndexedAction FilePath IO FilePath FilePath
forall (m :: * -> *) s i a.
Monad m =>
(s -> m (i, a)) -> IndexedAction i m s a
iact FilePath -> IO (FilePath, FilePath)
go)
where
go :: FilePath -> IO (FilePath, FilePath)
go fp :: FilePath
fp = do
FilePath
contents' <- FilePath -> IO FilePath
readFile FilePath
fp
(FilePath, FilePath) -> IO (FilePath, FilePath)
forall (m :: * -> *) a. Monad m => a -> m a
return (FilePath
fp, FilePath
contents')
exts :: [String] -> Traversal' FilePath FilePath
exts :: [FilePath] -> Traversal' FilePath FilePath
exts extList :: [FilePath]
extList = (FilePath -> Bool) -> Optic' (->) f FilePath FilePath
forall (p :: * -> * -> *) (f :: * -> *) a.
(Choice p, Applicative f) =>
(a -> Bool) -> Optic' p f a a
filtered FilePath -> Bool
check
where
check :: FilePath -> Bool
check fp :: FilePath
fp = Int -> FilePath -> FilePath
forall a. Int -> [a] -> [a]
drop 1 (FilePath -> FilePath
takeExtension FilePath
fp) FilePath -> [FilePath] -> Bool
forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [FilePath]
extList
crawled :: Monoid r => Acting IO r FilePath FilePath
crawled :: Acting IO r FilePath FilePath
crawled = Acting IO r FilePath FilePath -> Acting IO r FilePath FilePath
forall (f :: * -> *) a.
(Applicative f, Contravariant f) =>
LensLike' f a a -> LensLike' f a a
including (Acting IO r FilePath FilePath
forall r. Monoid r => Acting IO r FilePath FilePath
dirs Acting IO r FilePath FilePath
-> Acting IO r FilePath FilePath -> Acting IO r FilePath FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Acting IO r FilePath [FilePath]
forall r. Monoid r => Acting IO r FilePath [FilePath]
ls Acting IO r FilePath [FilePath]
-> ((FilePath -> Effect IO r FilePath)
-> [FilePath] -> Effect IO r [FilePath])
-> Acting IO r FilePath FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath -> Effect IO r FilePath)
-> [FilePath] -> Effect IO r [FilePath]
forall (f :: * -> *) a b.
Traversable f =>
IndexedTraversal Int (f a) (f b) a b
traversed ((FilePath -> Effect IO r FilePath)
-> [FilePath] -> Effect IO r [FilePath])
-> Acting IO r FilePath FilePath
-> (FilePath -> Effect IO r FilePath)
-> [FilePath]
-> Effect IO r [FilePath]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Acting IO r FilePath FilePath
forall r. Monoid r => Acting IO r FilePath FilePath
crawled)
crawling :: Monoid r => Acting IO r FilePath FilePath -> Acting IO r FilePath FilePath
crawling :: Acting IO r FilePath FilePath -> Acting IO r FilePath FilePath
crawling fld :: Acting IO r FilePath FilePath
fld = Acting IO r FilePath FilePath -> Acting IO r FilePath FilePath
forall (f :: * -> *) a.
(Applicative f, Contravariant f) =>
LensLike' f a a -> LensLike' f a a
including (Acting IO r FilePath FilePath -> Acting IO r FilePath FilePath
forall (m :: * -> *) r (f :: * -> *) (p :: * -> * -> *) s a.
(Monad m, Alternative m, Monoid r, Effective m r f) =>
Over' p f s a -> Over' p f s a
recovering (Acting IO r FilePath FilePath
fld Acting IO r FilePath FilePath
-> Acting IO r FilePath FilePath -> Acting IO r FilePath FilePath
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Acting IO r FilePath FilePath -> Acting IO r FilePath FilePath
forall r.
Monoid r =>
Acting IO r FilePath FilePath -> Acting IO r FilePath FilePath
crawling Acting IO r FilePath FilePath
fld))
absolute :: MonadicFold IO FilePath FilePath
absolute :: (FilePath -> f FilePath) -> FilePath -> f FilePath
absolute = (FilePath -> IO FilePath)
-> IndexPreservingAction IO FilePath FilePath
forall (m :: * -> *) s a.
Monad m =>
(s -> m a) -> IndexPreservingAction m s a
act FilePath -> IO FilePath
makeAbsolute
withPerms :: Monoid r => [Permissions -> Bool] -> Acting IO r FilePath FilePath
withPerms :: [Permissions -> Bool] -> Acting IO r FilePath FilePath
withPerms permChecks :: [Permissions -> Bool]
permChecks = (FilePath -> IO Bool) -> Acting IO r FilePath FilePath
forall (m :: * -> *) r a.
(Monad m, Monoid r) =>
(a -> m Bool) -> Acting m r a a
filteredM FilePath -> IO Bool
checkAll
where
checkAll :: FilePath -> IO Bool
checkAll fp :: FilePath
fp = do
Permissions
perms <- FilePath -> IO Permissions
getPermissions FilePath
fp
Bool -> IO Bool
forall (m :: * -> *) a. Monad m => a -> m a
return (Bool -> IO Bool) -> Bool -> IO Bool
forall a b. (a -> b) -> a -> b
$ ((Permissions -> Bool) -> Bool) -> [Permissions -> Bool] -> Bool
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all ((Permissions -> Bool) -> Permissions -> Bool
forall a b. (a -> b) -> a -> b
$ Permissions
perms) [Permissions -> Bool]
permChecks
symLinksFollowed :: Monoid r => Acting IO r FilePath FilePath
symLinksFollowed :: Acting IO r FilePath FilePath
symLinksFollowed = Acting IO r FilePath FilePath -> Acting IO r FilePath FilePath
forall (m :: * -> *) r a.
(Monad m, Alternative m) =>
Acting m r a a -> Acting m r a a
tryOrContinue ((FilePath -> IO FilePath)
-> IndexPreservingAction IO FilePath FilePath
forall (m :: * -> *) s a.
Monad m =>
(s -> m a) -> IndexPreservingAction m s a
act FilePath -> IO FilePath
getSymbolicLinkTarget)