{-# LANGUAGE GeneralizedNewtypeDeriving, ScopedTypeVariables, DeriveDataTypeable #-}
{-# LANGUAGE TypeFamilies, ConstraintKinds #-}
module Development.Shake.Internal.Rules.Directory(
doesFileExist, doesDirectoryExist,
getDirectoryContents, getDirectoryFiles, getDirectoryDirs,
getEnv, getEnvWithDefault, getEnvError,
removeFiles, removeFilesAfter,
getDirectoryFilesIO,
defaultRuleDirectory
) where
import Control.Exception.Extra
import Control.Monad.Extra
import Control.Monad.IO.Class
import Data.Maybe
import Data.Binary
import Data.List
import Data.Tuple.Extra
import qualified Data.HashSet as Set
import qualified System.Directory as IO
import qualified System.Environment as IO
import Development.Shake.Internal.Core.Types
import Development.Shake.Internal.Core.Action
import Development.Shake.Internal.Core.Rules
import Development.Shake.Internal.Core.Build
import Development.Shake.Internal.Value
import Development.Shake.Classes
import Development.Shake.FilePath
import Development.Shake.Internal.FilePattern
import General.Extra
import General.Binary
type instance RuleResult DoesFileExistQ = DoesFileExistA
newtype DoesFileExistQ = DoesFileExistQ FilePath
deriving (Typeable,DoesFileExistQ -> DoesFileExistQ -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DoesFileExistQ -> DoesFileExistQ -> Bool
$c/= :: DoesFileExistQ -> DoesFileExistQ -> Bool
== :: DoesFileExistQ -> DoesFileExistQ -> Bool
$c== :: DoesFileExistQ -> DoesFileExistQ -> Bool
Eq,Eq DoesFileExistQ
Int -> DoesFileExistQ -> Int
DoesFileExistQ -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: DoesFileExistQ -> Int
$chash :: DoesFileExistQ -> Int
hashWithSalt :: Int -> DoesFileExistQ -> Int
$chashWithSalt :: Int -> DoesFileExistQ -> Int
Hashable,Get DoesFileExistQ
[DoesFileExistQ] -> Put
DoesFileExistQ -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [DoesFileExistQ] -> Put
$cputList :: [DoesFileExistQ] -> Put
get :: Get DoesFileExistQ
$cget :: Get DoesFileExistQ
put :: DoesFileExistQ -> Put
$cput :: DoesFileExistQ -> Put
Binary,ByteString -> DoesFileExistQ
DoesFileExistQ -> Builder
forall a. (a -> Builder) -> (ByteString -> a) -> BinaryEx a
getEx :: ByteString -> DoesFileExistQ
$cgetEx :: ByteString -> DoesFileExistQ
putEx :: DoesFileExistQ -> Builder
$cputEx :: DoesFileExistQ -> Builder
BinaryEx,DoesFileExistQ -> ()
forall a. (a -> ()) -> NFData a
rnf :: DoesFileExistQ -> ()
$crnf :: DoesFileExistQ -> ()
NFData)
instance Show DoesFileExistQ where
show :: DoesFileExistQ -> FilePath
show (DoesFileExistQ FilePath
a) = FilePath
"doesFileExist " forall a. [a] -> [a] -> [a]
++ ShowS
wrapQuote FilePath
a
newtype DoesFileExistA = DoesFileExistA {DoesFileExistA -> Bool
fromDoesFileExistA :: Bool}
deriving (Typeable,DoesFileExistA -> DoesFileExistA -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DoesFileExistA -> DoesFileExistA -> Bool
$c/= :: DoesFileExistA -> DoesFileExistA -> Bool
== :: DoesFileExistA -> DoesFileExistA -> Bool
$c== :: DoesFileExistA -> DoesFileExistA -> Bool
Eq,ByteString -> DoesFileExistA
DoesFileExistA -> Builder
forall a. (a -> Builder) -> (ByteString -> a) -> BinaryEx a
getEx :: ByteString -> DoesFileExistA
$cgetEx :: ByteString -> DoesFileExistA
putEx :: DoesFileExistA -> Builder
$cputEx :: DoesFileExistA -> Builder
BinaryEx,DoesFileExistA -> ()
forall a. (a -> ()) -> NFData a
rnf :: DoesFileExistA -> ()
$crnf :: DoesFileExistA -> ()
NFData)
instance Show DoesFileExistA where
show :: DoesFileExistA -> FilePath
show (DoesFileExistA Bool
a) = forall a. Show a => a -> FilePath
show Bool
a
type instance RuleResult DoesDirectoryExistQ = DoesDirectoryExistA
newtype DoesDirectoryExistQ = DoesDirectoryExistQ FilePath
deriving (Typeable,DoesDirectoryExistQ -> DoesDirectoryExistQ -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DoesDirectoryExistQ -> DoesDirectoryExistQ -> Bool
$c/= :: DoesDirectoryExistQ -> DoesDirectoryExistQ -> Bool
== :: DoesDirectoryExistQ -> DoesDirectoryExistQ -> Bool
$c== :: DoesDirectoryExistQ -> DoesDirectoryExistQ -> Bool
Eq,Eq DoesDirectoryExistQ
Int -> DoesDirectoryExistQ -> Int
DoesDirectoryExistQ -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: DoesDirectoryExistQ -> Int
$chash :: DoesDirectoryExistQ -> Int
hashWithSalt :: Int -> DoesDirectoryExistQ -> Int
$chashWithSalt :: Int -> DoesDirectoryExistQ -> Int
Hashable,Get DoesDirectoryExistQ
[DoesDirectoryExistQ] -> Put
DoesDirectoryExistQ -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [DoesDirectoryExistQ] -> Put
$cputList :: [DoesDirectoryExistQ] -> Put
get :: Get DoesDirectoryExistQ
$cget :: Get DoesDirectoryExistQ
put :: DoesDirectoryExistQ -> Put
$cput :: DoesDirectoryExistQ -> Put
Binary,ByteString -> DoesDirectoryExistQ
DoesDirectoryExistQ -> Builder
forall a. (a -> Builder) -> (ByteString -> a) -> BinaryEx a
getEx :: ByteString -> DoesDirectoryExistQ
$cgetEx :: ByteString -> DoesDirectoryExistQ
putEx :: DoesDirectoryExistQ -> Builder
$cputEx :: DoesDirectoryExistQ -> Builder
BinaryEx,DoesDirectoryExistQ -> ()
forall a. (a -> ()) -> NFData a
rnf :: DoesDirectoryExistQ -> ()
$crnf :: DoesDirectoryExistQ -> ()
NFData)
instance Show DoesDirectoryExistQ where
show :: DoesDirectoryExistQ -> FilePath
show (DoesDirectoryExistQ FilePath
a) = FilePath
"doesDirectoryExist " forall a. [a] -> [a] -> [a]
++ ShowS
wrapQuote FilePath
a
newtype DoesDirectoryExistA = DoesDirectoryExistA {DoesDirectoryExistA -> Bool
fromDoesDirectoryExistA :: Bool}
deriving (Typeable,DoesDirectoryExistA -> DoesDirectoryExistA -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: DoesDirectoryExistA -> DoesDirectoryExistA -> Bool
$c/= :: DoesDirectoryExistA -> DoesDirectoryExistA -> Bool
== :: DoesDirectoryExistA -> DoesDirectoryExistA -> Bool
$c== :: DoesDirectoryExistA -> DoesDirectoryExistA -> Bool
Eq,ByteString -> DoesDirectoryExistA
DoesDirectoryExistA -> Builder
forall a. (a -> Builder) -> (ByteString -> a) -> BinaryEx a
getEx :: ByteString -> DoesDirectoryExistA
$cgetEx :: ByteString -> DoesDirectoryExistA
putEx :: DoesDirectoryExistA -> Builder
$cputEx :: DoesDirectoryExistA -> Builder
BinaryEx,DoesDirectoryExistA -> ()
forall a. (a -> ()) -> NFData a
rnf :: DoesDirectoryExistA -> ()
$crnf :: DoesDirectoryExistA -> ()
NFData)
instance Show DoesDirectoryExistA where
show :: DoesDirectoryExistA -> FilePath
show (DoesDirectoryExistA Bool
a) = forall a. Show a => a -> FilePath
show Bool
a
type instance RuleResult GetEnvQ = GetEnvA
newtype GetEnvQ = GetEnvQ String
deriving (Typeable,GetEnvQ -> GetEnvQ -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GetEnvQ -> GetEnvQ -> Bool
$c/= :: GetEnvQ -> GetEnvQ -> Bool
== :: GetEnvQ -> GetEnvQ -> Bool
$c== :: GetEnvQ -> GetEnvQ -> Bool
Eq,Eq GetEnvQ
Int -> GetEnvQ -> Int
GetEnvQ -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: GetEnvQ -> Int
$chash :: GetEnvQ -> Int
hashWithSalt :: Int -> GetEnvQ -> Int
$chashWithSalt :: Int -> GetEnvQ -> Int
Hashable,Get GetEnvQ
[GetEnvQ] -> Put
GetEnvQ -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [GetEnvQ] -> Put
$cputList :: [GetEnvQ] -> Put
get :: Get GetEnvQ
$cget :: Get GetEnvQ
put :: GetEnvQ -> Put
$cput :: GetEnvQ -> Put
Binary,ByteString -> GetEnvQ
GetEnvQ -> Builder
forall a. (a -> Builder) -> (ByteString -> a) -> BinaryEx a
getEx :: ByteString -> GetEnvQ
$cgetEx :: ByteString -> GetEnvQ
putEx :: GetEnvQ -> Builder
$cputEx :: GetEnvQ -> Builder
BinaryEx,GetEnvQ -> ()
forall a. (a -> ()) -> NFData a
rnf :: GetEnvQ -> ()
$crnf :: GetEnvQ -> ()
NFData)
instance Show GetEnvQ where
show :: GetEnvQ -> FilePath
show (GetEnvQ FilePath
a) = FilePath
"getEnv " forall a. [a] -> [a] -> [a]
++ ShowS
wrapQuote FilePath
a
newtype GetEnvA = GetEnvA {GetEnvA -> Maybe FilePath
fromGetEnvA :: Maybe String}
deriving (Typeable,GetEnvA -> GetEnvA -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GetEnvA -> GetEnvA -> Bool
$c/= :: GetEnvA -> GetEnvA -> Bool
== :: GetEnvA -> GetEnvA -> Bool
$c== :: GetEnvA -> GetEnvA -> Bool
Eq,Eq GetEnvA
Int -> GetEnvA -> Int
GetEnvA -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: GetEnvA -> Int
$chash :: GetEnvA -> Int
hashWithSalt :: Int -> GetEnvA -> Int
$chashWithSalt :: Int -> GetEnvA -> Int
Hashable,ByteString -> GetEnvA
GetEnvA -> Builder
forall a. (a -> Builder) -> (ByteString -> a) -> BinaryEx a
getEx :: ByteString -> GetEnvA
$cgetEx :: ByteString -> GetEnvA
putEx :: GetEnvA -> Builder
$cputEx :: GetEnvA -> Builder
BinaryEx,GetEnvA -> ()
forall a. (a -> ()) -> NFData a
rnf :: GetEnvA -> ()
$crnf :: GetEnvA -> ()
NFData)
instance Show GetEnvA where
show :: GetEnvA -> FilePath
show (GetEnvA Maybe FilePath
a) = forall b a. b -> (a -> b) -> Maybe a -> b
maybe FilePath
"<unset>" ShowS
wrapQuote Maybe FilePath
a
type instance RuleResult GetDirectoryContentsQ = GetDirectoryA
type instance RuleResult GetDirectoryFilesQ = GetDirectoryA
type instance RuleResult GetDirectoryDirsQ = GetDirectoryA
newtype GetDirectoryContentsQ = GetDirectoryContentsQ FilePath
deriving (Typeable,GetDirectoryContentsQ -> GetDirectoryContentsQ -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GetDirectoryContentsQ -> GetDirectoryContentsQ -> Bool
$c/= :: GetDirectoryContentsQ -> GetDirectoryContentsQ -> Bool
== :: GetDirectoryContentsQ -> GetDirectoryContentsQ -> Bool
$c== :: GetDirectoryContentsQ -> GetDirectoryContentsQ -> Bool
Eq,Eq GetDirectoryContentsQ
Int -> GetDirectoryContentsQ -> Int
GetDirectoryContentsQ -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: GetDirectoryContentsQ -> Int
$chash :: GetDirectoryContentsQ -> Int
hashWithSalt :: Int -> GetDirectoryContentsQ -> Int
$chashWithSalt :: Int -> GetDirectoryContentsQ -> Int
Hashable,Get GetDirectoryContentsQ
[GetDirectoryContentsQ] -> Put
GetDirectoryContentsQ -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [GetDirectoryContentsQ] -> Put
$cputList :: [GetDirectoryContentsQ] -> Put
get :: Get GetDirectoryContentsQ
$cget :: Get GetDirectoryContentsQ
put :: GetDirectoryContentsQ -> Put
$cput :: GetDirectoryContentsQ -> Put
Binary,ByteString -> GetDirectoryContentsQ
GetDirectoryContentsQ -> Builder
forall a. (a -> Builder) -> (ByteString -> a) -> BinaryEx a
getEx :: ByteString -> GetDirectoryContentsQ
$cgetEx :: ByteString -> GetDirectoryContentsQ
putEx :: GetDirectoryContentsQ -> Builder
$cputEx :: GetDirectoryContentsQ -> Builder
BinaryEx,GetDirectoryContentsQ -> ()
forall a. (a -> ()) -> NFData a
rnf :: GetDirectoryContentsQ -> ()
$crnf :: GetDirectoryContentsQ -> ()
NFData)
instance Show GetDirectoryContentsQ where
show :: GetDirectoryContentsQ -> FilePath
show (GetDirectoryContentsQ FilePath
dir) = FilePath
"getDirectoryContents " forall a. [a] -> [a] -> [a]
++ ShowS
wrapQuote FilePath
dir
newtype GetDirectoryFilesQ = GetDirectoryFilesQ (FilePath, [FilePattern])
deriving (Typeable,GetDirectoryFilesQ -> GetDirectoryFilesQ -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GetDirectoryFilesQ -> GetDirectoryFilesQ -> Bool
$c/= :: GetDirectoryFilesQ -> GetDirectoryFilesQ -> Bool
== :: GetDirectoryFilesQ -> GetDirectoryFilesQ -> Bool
$c== :: GetDirectoryFilesQ -> GetDirectoryFilesQ -> Bool
Eq,Eq GetDirectoryFilesQ
Int -> GetDirectoryFilesQ -> Int
GetDirectoryFilesQ -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: GetDirectoryFilesQ -> Int
$chash :: GetDirectoryFilesQ -> Int
hashWithSalt :: Int -> GetDirectoryFilesQ -> Int
$chashWithSalt :: Int -> GetDirectoryFilesQ -> Int
Hashable,Get GetDirectoryFilesQ
[GetDirectoryFilesQ] -> Put
GetDirectoryFilesQ -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [GetDirectoryFilesQ] -> Put
$cputList :: [GetDirectoryFilesQ] -> Put
get :: Get GetDirectoryFilesQ
$cget :: Get GetDirectoryFilesQ
put :: GetDirectoryFilesQ -> Put
$cput :: GetDirectoryFilesQ -> Put
Binary,ByteString -> GetDirectoryFilesQ
GetDirectoryFilesQ -> Builder
forall a. (a -> Builder) -> (ByteString -> a) -> BinaryEx a
getEx :: ByteString -> GetDirectoryFilesQ
$cgetEx :: ByteString -> GetDirectoryFilesQ
putEx :: GetDirectoryFilesQ -> Builder
$cputEx :: GetDirectoryFilesQ -> Builder
BinaryEx,GetDirectoryFilesQ -> ()
forall a. (a -> ()) -> NFData a
rnf :: GetDirectoryFilesQ -> ()
$crnf :: GetDirectoryFilesQ -> ()
NFData)
instance Show GetDirectoryFilesQ where
show :: GetDirectoryFilesQ -> FilePath
show (GetDirectoryFilesQ (FilePath
dir, [FilePath]
pat)) = FilePath
"getDirectoryFiles " forall a. [a] -> [a] -> [a]
++ ShowS
wrapQuote FilePath
dir forall a. [a] -> [a] -> [a]
++ FilePath
" [" forall a. [a] -> [a] -> [a]
++ [FilePath] -> FilePath
unwords (forall a b. (a -> b) -> [a] -> [b]
map ShowS
wrapQuote [FilePath]
pat) forall a. [a] -> [a] -> [a]
++ FilePath
"]"
newtype GetDirectoryDirsQ = GetDirectoryDirsQ FilePath
deriving (Typeable,GetDirectoryDirsQ -> GetDirectoryDirsQ -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GetDirectoryDirsQ -> GetDirectoryDirsQ -> Bool
$c/= :: GetDirectoryDirsQ -> GetDirectoryDirsQ -> Bool
== :: GetDirectoryDirsQ -> GetDirectoryDirsQ -> Bool
$c== :: GetDirectoryDirsQ -> GetDirectoryDirsQ -> Bool
Eq,Eq GetDirectoryDirsQ
Int -> GetDirectoryDirsQ -> Int
GetDirectoryDirsQ -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: GetDirectoryDirsQ -> Int
$chash :: GetDirectoryDirsQ -> Int
hashWithSalt :: Int -> GetDirectoryDirsQ -> Int
$chashWithSalt :: Int -> GetDirectoryDirsQ -> Int
Hashable,Get GetDirectoryDirsQ
[GetDirectoryDirsQ] -> Put
GetDirectoryDirsQ -> Put
forall t. (t -> Put) -> Get t -> ([t] -> Put) -> Binary t
putList :: [GetDirectoryDirsQ] -> Put
$cputList :: [GetDirectoryDirsQ] -> Put
get :: Get GetDirectoryDirsQ
$cget :: Get GetDirectoryDirsQ
put :: GetDirectoryDirsQ -> Put
$cput :: GetDirectoryDirsQ -> Put
Binary,ByteString -> GetDirectoryDirsQ
GetDirectoryDirsQ -> Builder
forall a. (a -> Builder) -> (ByteString -> a) -> BinaryEx a
getEx :: ByteString -> GetDirectoryDirsQ
$cgetEx :: ByteString -> GetDirectoryDirsQ
putEx :: GetDirectoryDirsQ -> Builder
$cputEx :: GetDirectoryDirsQ -> Builder
BinaryEx,GetDirectoryDirsQ -> ()
forall a. (a -> ()) -> NFData a
rnf :: GetDirectoryDirsQ -> ()
$crnf :: GetDirectoryDirsQ -> ()
NFData)
instance Show GetDirectoryDirsQ where
show :: GetDirectoryDirsQ -> FilePath
show (GetDirectoryDirsQ FilePath
dir) = FilePath
"getDirectoryDirs " forall a. [a] -> [a] -> [a]
++ ShowS
wrapQuote FilePath
dir
newtype GetDirectoryA = GetDirectoryA {GetDirectoryA -> [FilePath]
fromGetDirectoryA :: [FilePath]}
deriving (Typeable,GetDirectoryA -> GetDirectoryA -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: GetDirectoryA -> GetDirectoryA -> Bool
$c/= :: GetDirectoryA -> GetDirectoryA -> Bool
== :: GetDirectoryA -> GetDirectoryA -> Bool
$c== :: GetDirectoryA -> GetDirectoryA -> Bool
Eq,Eq GetDirectoryA
Int -> GetDirectoryA -> Int
GetDirectoryA -> Int
forall a. Eq a -> (Int -> a -> Int) -> (a -> Int) -> Hashable a
hash :: GetDirectoryA -> Int
$chash :: GetDirectoryA -> Int
hashWithSalt :: Int -> GetDirectoryA -> Int
$chashWithSalt :: Int -> GetDirectoryA -> Int
Hashable,ByteString -> GetDirectoryA
GetDirectoryA -> Builder
forall a. (a -> Builder) -> (ByteString -> a) -> BinaryEx a
getEx :: ByteString -> GetDirectoryA
$cgetEx :: ByteString -> GetDirectoryA
putEx :: GetDirectoryA -> Builder
$cputEx :: GetDirectoryA -> Builder
BinaryEx,GetDirectoryA -> ()
forall a. (a -> ()) -> NFData a
rnf :: GetDirectoryA -> ()
$crnf :: GetDirectoryA -> ()
NFData)
instance Show GetDirectoryA where
show :: GetDirectoryA -> FilePath
show (GetDirectoryA [FilePath]
xs) = [FilePath] -> FilePath
unwords forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map ShowS
wrapQuote [FilePath]
xs
queryRule :: (RuleResult key ~ value
,BinaryEx witness, Eq witness
,BinaryEx key, ShakeValue key
,Typeable value, NFData value, Show value, Eq value)
=> (value -> witness) -> (key -> IO value) -> Rules ()
queryRule :: forall key value witness.
(RuleResult key ~ value, BinaryEx witness, Eq witness,
BinaryEx key, ShakeValue key, Typeable value, NFData value,
Show value, Eq value) =>
(value -> witness) -> (key -> IO value) -> Rules ()
queryRule value -> witness
witness key -> IO value
query = forall key value.
(RuleResult key ~ value, ShakeValue key, BinaryEx key,
Typeable value, NFData value, Show value, Partial) =>
BuiltinLint key value
-> BuiltinIdentity key value -> BuiltinRun key value -> Rules ()
addBuiltinRuleEx
(\key
k value
old -> do
value
new <- key -> IO value
query key
k
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ if value
old forall a. Eq a => a -> a -> Bool
== value
new then forall a. Maybe a
Nothing else forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> FilePath
show value
new)
(\key
_ value
v -> forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ Builder -> ByteString
runBuilder forall a b. (a -> b) -> a -> b
$ forall a. BinaryEx a => a -> Builder
putEx forall a b. (a -> b) -> a -> b
$ value -> witness
witness value
v)
(\key
k Maybe ByteString
old RunMode
_ -> forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO forall a b. (a -> b) -> a -> b
$ do
value
new <- key -> IO value
query key
k
let wnew :: witness
wnew = value -> witness
witness value
new
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ case Maybe ByteString
old of
Just ByteString
old | witness
wnew forall a. Eq a => a -> a -> Bool
== forall a. BinaryEx a => ByteString -> a
getEx ByteString
old -> forall value. RunChanged -> ByteString -> value -> RunResult value
RunResult RunChanged
ChangedNothing ByteString
old value
new
Maybe ByteString
_ -> forall value. RunChanged -> ByteString -> value -> RunResult value
RunResult RunChanged
ChangedRecomputeDiff (Builder -> ByteString
runBuilder forall a b. (a -> b) -> a -> b
$ forall a. BinaryEx a => a -> Builder
putEx witness
wnew) value
new)
defaultRuleDirectory :: Rules ()
defaultRuleDirectory :: Rules ()
defaultRuleDirectory = do
forall key value witness.
(RuleResult key ~ value, BinaryEx witness, Eq witness,
BinaryEx key, ShakeValue key, Typeable value, NFData value,
Show value, Eq value) =>
(value -> witness) -> (key -> IO value) -> Rules ()
queryRule forall a. a -> a
id (\(DoesFileExistQ FilePath
x) -> Bool -> DoesFileExistA
DoesFileExistA forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO Bool
IO.doesFileExist FilePath
x)
forall key value witness.
(RuleResult key ~ value, BinaryEx witness, Eq witness,
BinaryEx key, ShakeValue key, Typeable value, NFData value,
Show value, Eq value) =>
(value -> witness) -> (key -> IO value) -> Rules ()
queryRule forall a. a -> a
id (\(DoesDirectoryExistQ FilePath
x) -> Bool -> DoesDirectoryExistA
DoesDirectoryExistA forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO Bool
IO.doesDirectoryExist FilePath
x)
forall key value witness.
(RuleResult key ~ value, BinaryEx witness, Eq witness,
BinaryEx key, ShakeValue key, Typeable value, NFData value,
Show value, Eq value) =>
(value -> witness) -> (key -> IO value) -> Rules ()
queryRule forall a. Hashable a => a -> Int
hash (\(GetEnvQ FilePath
x) -> Maybe FilePath -> GetEnvA
GetEnvA forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO (Maybe FilePath)
IO.lookupEnv FilePath
x)
forall key value witness.
(RuleResult key ~ value, BinaryEx witness, Eq witness,
BinaryEx key, ShakeValue key, Typeable value, NFData value,
Show value, Eq value) =>
(value -> witness) -> (key -> IO value) -> Rules ()
queryRule forall a. Hashable a => a -> Int
hash (\(GetDirectoryContentsQ FilePath
x) -> [FilePath] -> GetDirectoryA
GetDirectoryA forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO [FilePath]
getDirectoryContentsIO FilePath
x)
forall key value witness.
(RuleResult key ~ value, BinaryEx witness, Eq witness,
BinaryEx key, ShakeValue key, Typeable value, NFData value,
Show value, Eq value) =>
(value -> witness) -> (key -> IO value) -> Rules ()
queryRule forall a. Hashable a => a -> Int
hash (\(GetDirectoryFilesQ (FilePath
a,[FilePath]
b)) -> [FilePath] -> GetDirectoryA
GetDirectoryA forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> [FilePath] -> IO [FilePath]
getDirectoryFilesIO FilePath
a [FilePath]
b)
forall key value witness.
(RuleResult key ~ value, BinaryEx witness, Eq witness,
BinaryEx key, ShakeValue key, Typeable value, NFData value,
Show value, Eq value) =>
(value -> witness) -> (key -> IO value) -> Rules ()
queryRule forall a. Hashable a => a -> Int
hash (\(GetDirectoryDirsQ FilePath
x) -> [FilePath] -> GetDirectoryA
GetDirectoryA forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO [FilePath]
getDirectoryDirsIO FilePath
x)
doesFileExist :: FilePath -> Action Bool
doesFileExist :: FilePath -> Action Bool
doesFileExist = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DoesFileExistA -> Bool
fromDoesFileExistA forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall key value.
(Partial, RuleResult key ~ value, ShakeValue key,
Typeable value) =>
key -> Action value
apply1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> DoesFileExistQ
DoesFileExistQ forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
toStandard
doesDirectoryExist :: FilePath -> Action Bool
doesDirectoryExist :: FilePath -> Action Bool
doesDirectoryExist = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap DoesDirectoryExistA -> Bool
fromDoesDirectoryExistA forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall key value.
(Partial, RuleResult key ~ value, ShakeValue key,
Typeable value) =>
key -> Action value
apply1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> DoesDirectoryExistQ
DoesDirectoryExistQ forall b c a. (b -> c) -> (a -> b) -> a -> c
. ShowS
toStandard
getEnv :: String -> Action (Maybe String)
getEnv :: FilePath -> Action (Maybe FilePath)
getEnv = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GetEnvA -> Maybe FilePath
fromGetEnvA forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall key value.
(Partial, RuleResult key ~ value, ShakeValue key,
Typeable value) =>
key -> Action value
apply1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> GetEnvQ
GetEnvQ
getEnvWithDefault :: String -> String -> Action String
getEnvWithDefault :: FilePath -> FilePath -> Action FilePath
getEnvWithDefault FilePath
def FilePath
var = forall a. a -> Maybe a -> a
fromMaybe FilePath
def forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> Action (Maybe FilePath)
getEnv FilePath
var
getEnvError :: Partial => String -> Action String
getEnvError :: Partial => FilePath -> Action FilePath
getEnvError FilePath
name = FilePath -> FilePath -> Action FilePath
getEnvWithDefault (forall a. Partial => FilePath -> a
error forall a b. (a -> b) -> a -> b
$ FilePath
"getEnvError: Environment variable " forall a. [a] -> [a] -> [a]
++ FilePath
name forall a. [a] -> [a] -> [a]
++ FilePath
" is undefined") FilePath
name
getDirectoryContents :: FilePath -> Action [FilePath]
getDirectoryContents :: FilePath -> Action [FilePath]
getDirectoryContents = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GetDirectoryA -> [FilePath]
fromGetDirectoryA forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall key value.
(Partial, RuleResult key ~ value, ShakeValue key,
Typeable value) =>
key -> Action value
apply1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> GetDirectoryContentsQ
GetDirectoryContentsQ
getDirectoryFiles :: FilePath -> [FilePattern] -> Action [FilePath]
getDirectoryFiles :: FilePath -> [FilePath] -> Action [FilePath]
getDirectoryFiles FilePath
dir [FilePath]
pat = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GetDirectoryA -> [FilePath]
fromGetDirectoryA forall a b. (a -> b) -> a -> b
$ forall key value.
(Partial, RuleResult key ~ value, ShakeValue key,
Typeable value) =>
key -> Action value
apply1 forall a b. (a -> b) -> a -> b
$ (FilePath, [FilePath]) -> GetDirectoryFilesQ
GetDirectoryFilesQ (FilePath
dir,[FilePath]
pat)
getDirectoryDirs :: FilePath -> Action [FilePath]
getDirectoryDirs :: FilePath -> Action [FilePath]
getDirectoryDirs = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap GetDirectoryA -> [FilePath]
fromGetDirectoryA forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall key value.
(Partial, RuleResult key ~ value, ShakeValue key,
Typeable value) =>
key -> Action value
apply1 forall b c a. (b -> c) -> (a -> b) -> a -> c
. FilePath -> GetDirectoryDirsQ
GetDirectoryDirsQ
getDirectoryContentsIO :: FilePath -> IO [FilePath]
getDirectoryContentsIO :: FilePath -> IO [FilePath]
getDirectoryContentsIO FilePath
dir = forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (forall a. Ord a => [a] -> [a]
sort forall b c a. (b -> c) -> (a -> b) -> a -> c
. 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 a b. (a -> b) -> a -> b
$ FilePath -> IO [FilePath]
IO.getDirectoryContents forall a b. (a -> b) -> a -> b
$ if FilePath
dir forall a. Eq a => a -> a -> Bool
== FilePath
"" then FilePath
"." else FilePath
dir
getDirectoryDirsIO :: FilePath -> IO [FilePath]
getDirectoryDirsIO :: FilePath -> IO [FilePath]
getDirectoryDirsIO FilePath
dir = forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM FilePath -> IO Bool
f forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> IO [FilePath]
getDirectoryContentsIO FilePath
dir
where f :: FilePath -> IO Bool
f FilePath
x = FilePath -> IO Bool
IO.doesDirectoryExist forall a b. (a -> b) -> a -> b
$ FilePath
dir FilePath -> ShowS
</> FilePath
x
getDirectoryFilesIO :: FilePath -> [FilePattern] -> IO [FilePath]
getDirectoryFilesIO :: FilePath -> [FilePath] -> IO [FilePath]
getDirectoryFilesIO FilePath
root [FilePath]
pat = FilePath -> Walk -> IO [FilePath]
f FilePath
"" forall a b. (a -> b) -> a -> b
$ forall a b. (a, b) -> b
snd forall a b. (a -> b) -> a -> b
$ [FilePath] -> (Bool, Walk)
walk [FilePath]
pat
where
f :: FilePath -> Walk -> IO [FilePath]
f FilePath
dir (Walk [FilePath] -> ([FilePath], [(FilePath, Walk)])
op) = FilePath -> Walk -> IO [FilePath]
f FilePath
dir forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([FilePath], [(FilePath, Walk)]) -> Walk
WalkTo forall b c a. (b -> c) -> (a -> b) -> a -> c
. [FilePath] -> ([FilePath], [(FilePath, Walk)])
op forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> IO [FilePath]
getDirectoryContentsIO (FilePath
root FilePath -> ShowS
</> FilePath
dir)
f FilePath
dir (WalkTo ([FilePath]
files, [(FilePath, Walk)]
dirs)) = do
[FilePath]
files <- forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM (FilePath -> IO Bool
IO.doesFileExist forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath
root FilePath -> ShowS
</>)) forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (FilePath
dir FilePath -> ShowS
</>) [FilePath]
files
[FilePath]
dirs <- forall (m :: * -> *) a b. Monad m => (a -> m [b]) -> [a] -> m [b]
concatMapM (forall a b c. (a -> b -> c) -> (a, b) -> c
uncurry FilePath -> Walk -> IO [FilePath]
f) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< forall (m :: * -> *) a.
Applicative m =>
(a -> m Bool) -> [a] -> m [a]
filterM (FilePath -> IO Bool
IO.doesDirectoryExist forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath
root FilePath -> ShowS
</>) forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) (forall a b. (a -> b) -> [a] -> [b]
map (forall a a' b. (a -> a') -> (a, b) -> (a', b)
first (FilePath
dir FilePath -> ShowS
</>)) [(FilePath, Walk)]
dirs)
forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ [FilePath]
files forall a. [a] -> [a] -> [a]
++ [FilePath]
dirs
removeFiles :: FilePath -> [FilePattern] -> IO ()
removeFiles :: FilePath -> [FilePath] -> IO ()
removeFiles FilePath
dir [FilePath]
pat =
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (FilePath -> IO Bool
IO.doesDirectoryExist FilePath
dir) forall a b. (a -> b) -> a -> b
$ do
let (Bool
b,Walk
w) = [FilePath] -> (Bool, Walk)
walk [FilePath]
pat
if Bool
b then FilePath -> IO ()
removeDir FilePath
dir else FilePath -> Walk -> IO ()
f FilePath
dir Walk
w
where
f :: FilePath -> Walk -> IO ()
f FilePath
dir (Walk [FilePath] -> ([FilePath], [(FilePath, Walk)])
op) = FilePath -> Walk -> IO ()
f FilePath
dir forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([FilePath], [(FilePath, Walk)]) -> Walk
WalkTo forall b c a. (b -> c) -> (a -> b) -> a -> c
. [FilePath] -> ([FilePath], [(FilePath, Walk)])
op forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> IO [FilePath]
getDirectoryContentsIO FilePath
dir
f FilePath
dir (WalkTo ([FilePath]
files, [(FilePath, Walk)]
dirs)) = do
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [FilePath]
files forall a b. (a -> b) -> a -> b
$ \FilePath
fil ->
forall a. IO a -> IO (Either IOException a)
tryIO forall a b. (a -> b) -> a -> b
$ FilePath -> IO ()
removeItem forall a b. (a -> b) -> a -> b
$ FilePath
dir FilePath -> ShowS
</> FilePath
fil
let done :: HashSet FilePath
done = forall a. (Eq a, Hashable a) => [a] -> HashSet a
Set.fromList [FilePath]
files
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (forall a. (a -> Bool) -> [a] -> [a]
filter (Bool -> Bool
not forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. (Eq a, Hashable a) => a -> HashSet a -> Bool
Set.member HashSet FilePath
done forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. (a, b) -> a
fst) [(FilePath, Walk)]
dirs) forall a b. (a -> b) -> a -> b
$ \(FilePath
d,Walk
w) -> do
let dir2 :: FilePath
dir2 = FilePath
dir FilePath -> ShowS
</> FilePath
d
forall (m :: * -> *). Monad m => m Bool -> m () -> m ()
whenM (FilePath -> IO Bool
IO.doesDirectoryExist FilePath
dir2) forall a b. (a -> b) -> a -> b
$ FilePath -> Walk -> IO ()
f FilePath
dir2 Walk
w
removeItem :: FilePath -> IO ()
removeItem :: FilePath -> IO ()
removeItem FilePath
x = FilePath -> IO ()
IO.removeFile FilePath
x forall a. IO a -> (IOException -> IO a) -> IO a
`catchIO` \IOException
_ -> FilePath -> IO ()
removeDir FilePath
x
removeDir :: FilePath -> IO ()
removeDir :: FilePath -> IO ()
removeDir FilePath
x = do
forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
(a -> m b) -> t a -> m ()
mapM_ (FilePath -> IO ()
removeItem forall b c a. (b -> c) -> (a -> b) -> a -> c
. (FilePath
x FilePath -> ShowS
</>)) forall (m :: * -> *) a b. Monad m => (a -> m b) -> m a -> m b
=<< FilePath -> IO [FilePath]
getDirectoryContentsIO FilePath
x
FilePath -> IO ()
IO.removeDirectory FilePath
x
removeFilesAfter :: FilePath -> [FilePattern] -> Action ()
removeFilesAfter :: FilePath -> [FilePath] -> Action ()
removeFilesAfter FilePath
a [FilePath]
b = do
FilePath -> Action ()
putVerbose forall a b. (a -> b) -> a -> b
$ FilePath
"Will remove " forall a. [a] -> [a] -> [a]
++ [FilePath] -> FilePath
unwords [FilePath]
b forall a. [a] -> [a] -> [a]
++ FilePath
" from " forall a. [a] -> [a] -> [a]
++ FilePath
a
IO () -> Action ()
runAfter forall a b. (a -> b) -> a -> b
$ FilePath -> [FilePath] -> IO ()
removeFiles FilePath
a [FilePath]
b