module System.FilePattern.Directory(
FilePattern,
getDirectoryFiles,
getDirectoryFilesIgnore,
getDirectoryFilesIgnoreSlow
) where
import Control.Monad.Extra
import Data.Functor
import Data.List
import System.Directory
import System.FilePath
import System.FilePattern.Core
import System.FilePattern.Step
import Prelude
getDirectoryFiles :: FilePath -> [FilePattern] -> IO [FilePath]
getDirectoryFiles :: FilePath -> [FilePath] -> IO [FilePath]
getDirectoryFiles FilePath
dir [FilePath]
match = Bool -> FilePath -> [FilePath] -> [FilePath] -> IO [FilePath]
operation Bool
False FilePath
dir [FilePath]
match []
getDirectoryFilesIgnore :: FilePath -> [FilePattern] -> [FilePattern] -> IO [FilePath]
getDirectoryFilesIgnore :: FilePath -> [FilePath] -> [FilePath] -> IO [FilePath]
getDirectoryFilesIgnore = Bool -> FilePath -> [FilePath] -> [FilePath] -> IO [FilePath]
operation Bool
False
getDirectoryFilesIgnoreSlow :: FilePath -> [FilePattern] -> [FilePattern] -> IO [FilePath]
getDirectoryFilesIgnoreSlow :: FilePath -> [FilePath] -> [FilePath] -> IO [FilePath]
getDirectoryFilesIgnoreSlow = Bool -> FilePath -> [FilePath] -> [FilePath] -> IO [FilePath]
operation Bool
True
operation :: Bool -> FilePath -> [FilePattern] -> [FilePattern] -> IO [FilePath]
operation :: Bool -> FilePath -> [FilePath] -> [FilePath] -> IO [FilePath]
operation Bool
slow FilePath
rootBad [FilePath]
yes [FilePath]
no = forall {a} {a}.
(Eq a, Eq a) =>
FilePath -> Step a -> Step a -> IO [FilePath]
f [] ([FilePath] -> Step ()
step_ [FilePath]
yes) ([FilePath] -> Step ()
step_ [FilePath]
no)
where
root :: FilePath
root = if FilePath
rootBad forall a. Eq a => a -> a -> Bool
== FilePath
"" then FilePath
"./" else FilePath -> FilePath
addTrailingPathSeparator FilePath
rootBad
f :: FilePath -> Step a -> Step a -> IO [FilePath]
f FilePath
parts Step a
yes Step a
no
| StepNext
StepEverything <- forall a. Step a -> StepNext
stepNext Step a
no = forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| Bool -> Bool
not Bool
slow, StepOnly [FilePath]
xs <- forall a. Step a -> StepNext
stepNext Step a
yes = FilePath -> Step a -> Step a -> [FilePath] -> IO [FilePath]
g FilePath
parts Step a
yes Step a
no [FilePath]
xs
| Bool
otherwise = do
[FilePath]
xs <- forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool
all (forall a. Eq a => a -> a -> Bool
== Char
'.')) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO [FilePath]
getDirectoryContents (FilePath
root forall a. [a] -> [a] -> [a]
++ FilePath
parts)
FilePath -> Step a -> Step a -> [FilePath] -> IO [FilePath]
g FilePath
parts Step a
yes Step a
no [FilePath]
xs
g :: FilePath -> Step a -> Step a -> [FilePath] -> IO [FilePath]
g FilePath
parts Step a
yes Step a
no [FilePath]
xs =
forall (m :: * -> *) a b. Monad m => [a] -> (a -> m [b]) -> m [b]
concatForM (forall a. Ord a => [a] -> [a]
sort [FilePath]
xs) forall a b. (a -> b) -> a -> b
$ \FilePath
x -> do
let path :: FilePath
path = FilePath
root forall a. [a] -> [a] -> [a]
++ FilePath
parts forall a. [a] -> [a] -> [a]
++ FilePath
x
Step a
yes <- forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Step a -> FilePath -> Step a
stepApply Step a
yes FilePath
x
Step a
no <- forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. Step a -> FilePath -> Step a
stepApply Step a
no FilePath
x
Maybe Bool
isFile <- forall (m :: * -> *) a. Applicative m => Bool -> m a -> m (Maybe a)
whenMaybe (forall a. Step a -> [(a, [FilePath])]
stepDone Step a
yes forall a. Eq a => a -> a -> Bool
/= [] Bool -> Bool -> Bool
&& forall a. Step a -> [(a, [FilePath])]
stepDone Step a
no forall a. Eq a => a -> a -> Bool
== []) (FilePath -> IO Bool
doesFileExist FilePath
path)
case Maybe Bool
isFile of
Just Bool
True -> forall (f :: * -> *) a. Applicative f => a -> f a
pure [FilePath
parts forall a. [a] -> [a] -> [a]
++ FilePath
x]
Maybe Bool
_ | StepNext
StepEverything <- forall a. Step a -> StepNext
stepNext Step a
no -> forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| StepOnly [] <- forall a. Step a -> StepNext
stepNext Step a
yes -> forall (f :: * -> *) a. Applicative f => a -> f a
pure []
| Bool
otherwise -> do
Bool
b <- FilePath -> IO Bool
doesDirectoryExist FilePath
path
if Bool -> Bool
not Bool
b then forall (f :: * -> *) a. Applicative f => a -> f a
pure [] else FilePath -> Step a -> Step a -> IO [FilePath]
f (FilePath
parts forall a. [a] -> [a] -> [a]
++ FilePath
x forall a. [a] -> [a] -> [a]
++ FilePath
"/") Step a
yes Step a
no