{-# LANGUAGE TupleSections #-}

-- | Command line parsing flags.
module Development.Shake.Internal.Args(
    shakeOptDescrs,
    shake,
    shakeArgs, shakeArgsWith, shakeArgsOptionsWith
    ) where

import Development.Shake.Internal.Paths
import Development.Shake.Internal.Options
import Development.Shake.Internal.Core.Rules
import Development.Shake.Internal.Errors
import Development.Shake.Internal.CompactUI
import Development.Shake.Internal.Demo
import Development.Shake.Internal.Core.Action
import Development.Shake.FilePath
import Development.Shake.Internal.Rules.File
import Development.Shake.Internal.Progress
import Development.Shake.Database
import General.Timing
import General.Extra
import General.Thread
import General.GetOpt
import General.EscCodes

import Data.Tuple.Extra
import Control.DeepSeq
import Control.Exception.Extra
import Control.Monad
import Data.Either
import Data.List.Extra
import Data.Maybe
import System.Directory.Extra
import System.Environment
import System.Exit
import System.Time.Extra


-- | Main entry point for running Shake build systems. For an example see the top of the module "Development.Shake".
--   Use 'ShakeOptions' to specify how the system runs, and 'Rules' to specify what to build. The function will throw
--   an exception if the build fails.
--
--   To use command line flags to modify 'ShakeOptions' see 'shakeArgs'.
shake :: ShakeOptions -> Rules () -> IO ()
shake :: ShakeOptions -> Rules () -> IO ()
shake ShakeOptions
opts Rules ()
rules = do
    String -> IO ()
addTiming String
"Function shake"
    ([Any]
_, [IO ()]
after) <- forall a.
ShakeOptions -> Rules () -> (ShakeDatabase -> IO a) -> IO a
shakeWithDatabase ShakeOptions
opts Rules ()
rules forall a b. (a -> b) -> a -> b
$ \ShakeDatabase
db -> do
        ShakeDatabase -> IO ()
shakeOneShotDatabase ShakeDatabase
db
        forall a. ShakeDatabase -> [Action a] -> IO ([a], [IO ()])
shakeRunDatabase ShakeDatabase
db []
    ShakeOptions -> [IO ()] -> IO ()
shakeRunAfter ShakeOptions
opts [IO ()]
after


-- | Run a build system using command line arguments for configuration.
--   The available flags are those from 'shakeOptDescrs', along with a few additional
--   @make@ compatible flags that are not represented in 'ShakeOptions', such as @--print-directory@.
--   If there are no file arguments then the 'Rules' are used directly, otherwise the file arguments
--   are 'want'ed (after calling 'withoutActions'). As an example:
--
-- @
-- main = 'shakeArgs' 'shakeOptions'{'shakeFiles' = \"_make\", 'shakeProgress' = 'progressSimple'} $ do
--     'phony' \"clean\" $ 'Development.Shake.removeFilesAfter' \"_make\" [\"\/\/*\"]
--     'want' [\"_make\/neil.txt\",\"_make\/emily.txt\"]
--     \"_make\/*.txt\" '%>' \\out ->
--         ... build action here ...
-- @
--
--   This build system will default to building @neil.txt@ and @emily.txt@, while showing progress messages,
--   and putting the Shake files in locations such as @_make\/.database@. Some example command line flags:
--
-- * @main --no-progress@ will turn off progress messages.
--
-- * @main -j6@ will build on 6 threads.
--
-- * @main --help@ will display a list of supported flags.
--
-- * @main clean@ will not build anything, but will remove the @_make@ directory, including the
--   any 'shakeFiles'.
--
-- * @main _make/henry.txt@ will not build @neil.txt@ or @emily.txt@, but will instead build @henry.txt@.
shakeArgs :: ShakeOptions -> Rules () -> IO ()
shakeArgs :: ShakeOptions -> Rules () -> IO ()
shakeArgs ShakeOptions
opts Rules ()
rules = forall a.
ShakeOptions
-> [OptDescr (Either String a)]
-> ([a] -> [String] -> IO (Maybe (Rules ())))
-> IO ()
shakeArgsWith ShakeOptions
opts [] forall {f :: * -> *} {p}.
Applicative f =>
p -> [String] -> f (Maybe (Rules ()))
f
    where f :: p -> [String] -> f (Maybe (Rules ()))
f p
_ [String]
files = forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
files then Rules ()
rules else Partial => [String] -> Rules ()
want [String]
files forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> forall a. Rules a -> Rules a
withoutActions Rules ()
rules


-- | A version of 'shakeArgs' with more flexible handling of command line arguments.
--   The caller of 'shakeArgsWith' can add additional flags (the second argument) and chose how to convert
--   the flags/arguments into rules (the third argument). Given:
--
-- @
-- 'shakeArgsWith' opts flags (\\flagValues argValues -> result)
-- @
--
-- * @opts@ is the initial 'ShakeOptions' value, which may have some fields overridden by command line flags.
--   This argument is usually 'shakeOptions', perhaps with a few fields overridden.
--
-- * @flags@ is a list of flag descriptions, which either produce a 'String' containing an error
--   message (typically for flags with invalid arguments, .e.g. @'Left' \"could not parse as int\"@), or a value
--   that is passed as @flagValues@. If you have no custom flags, pass @[]@.
--
-- * @flagValues@ is a list of custom flags that the user supplied. If @flags == []@ then this list will
--   be @[]@.
--
-- * @argValues@ is a list of non-flag arguments, which are often treated as files and passed to 'want'.
--   If arguments are specified then typically the 'want' calls from the rules are discarded using 'withoutActions'.
--
-- * @result@ should produce a 'Nothing' to indicate that no building needs to take place, or a 'Just'
--   providing the rules that should be used.
--
--   As an example of a build system that can use either @gcc@ or @distcc@ for compiling:
--
-- @
-- import System.Console.GetOpt
--
-- data Flags = DistCC deriving Eq
-- flags = [Option \"\" [\"distcc\"] (NoArg $ Right DistCC) \"Run distributed.\"]
--
-- main = 'shakeArgsWith' 'shakeOptions' flags $ \\flags targets -> pure $ Just $ do
--     let compiler = if DistCC \`elem\` flags then \"distcc\" else \"gcc\"
--     let rules = do
--         \"*.o\" '%>' \\out -> do
--             'need' ...
--             'cmd' compiler ...
--         'want' [\"target.exe\"]
--         ...
--     if null targets then rules else 'want' targets >> 'withoutActions' rules
-- @
--
--   Now you can pass @--distcc@ to use the @distcc@ compiler.
shakeArgsWith :: ShakeOptions -> [OptDescr (Either String a)] -> ([a] -> [String] -> IO (Maybe (Rules ()))) -> IO ()
shakeArgsWith :: forall a.
ShakeOptions
-> [OptDescr (Either String a)]
-> ([a] -> [String] -> IO (Maybe (Rules ())))
-> IO ()
shakeArgsWith ShakeOptions
opt [OptDescr (Either String a)]
args [a] -> [String] -> IO (Maybe (Rules ()))
f = forall a.
ShakeOptions
-> [OptDescr (Either String a)]
-> (ShakeOptions
    -> [a] -> [String] -> IO (Maybe (ShakeOptions, Rules ())))
-> IO ()
shakeArgsOptionsWith ShakeOptions
opt [OptDescr (Either String a)]
args forall a b. (a -> b) -> a -> b
$ \ShakeOptions
so [a]
a [String]
b -> forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (ShakeOptions
so,) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [a] -> [String] -> IO (Maybe (Rules ()))
f [a]
a [String]
b

-- | Like 'shakeArgsWith', but also lets you manipulate the 'ShakeOptions'.
shakeArgsOptionsWith
    :: ShakeOptions
    -> [OptDescr (Either String a)]
    -> (ShakeOptions -> [a] -> [String] -> IO (Maybe (ShakeOptions, Rules ())))
    -> IO ()
shakeArgsOptionsWith :: forall a.
ShakeOptions
-> [OptDescr (Either String a)]
-> (ShakeOptions
    -> [a] -> [String] -> IO (Maybe (ShakeOptions, Rules ())))
-> IO ()
shakeArgsOptionsWith ShakeOptions
baseOpts [OptDescr (Either String a)]
userOptions ShakeOptions
-> [a] -> [String] -> IO (Maybe (ShakeOptions, Rules ()))
rules = do
    String -> IO ()
addTiming String
"shakeArgsWith"
    let baseOpts2 :: [OptDescr (Either String ([Extra], ShakeOptions -> ShakeOptions))]
baseOpts2 = forall b a. [OptDescr b] -> [OptDescr a] -> [OptDescr a]
removeOverlap [OptDescr (Either String a)]
userOptions forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map forall a b. (a, b) -> b
snd [(Bool,
  OptDescr (Either String ([Extra], ShakeOptions -> ShakeOptions)))]
shakeOptsEx
    [String]
args <- IO [String]
getArgs
    let ([Either ([Extra], ShakeOptions -> ShakeOptions) a]
flag1,[String]
files,[String]
errs) = forall a.
[OptDescr (Either String a)]
-> [String] -> ([a], [String], [String])
getOpt ([OptDescr (Either String ([Extra], ShakeOptions -> ShakeOptions))]
baseOpts2 forall a b.
[OptDescr (Either String a)]
-> [OptDescr (Either String b)]
-> [OptDescr (Either String (Either a b))]
`mergeOptDescr` [OptDescr (Either String a)]
userOptions) [String]
args
        ([([Extra], ShakeOptions -> ShakeOptions)]
self,[a]
user) = forall a b. [Either a b] -> ([a], [b])
partitionEithers [Either ([Extra], ShakeOptions -> ShakeOptions) a]
flag1
        ([Extra]
flagsExtra,[ShakeOptions -> ShakeOptions]
flagsShake) = forall a a' b. (a -> a') -> (a, b) -> (a', b)
first forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat forall a b. (a -> b) -> a -> b
$ forall a b. [(a, b)] -> ([a], [b])
unzip [([Extra], ShakeOptions -> ShakeOptions)]
self
        progressReplays :: [String]
progressReplays = [String
x | ProgressReplay String
x <- [Extra]
flagsExtra]
        progressRecords :: [String]
progressRecords = [String
x | ProgressRecord String
x <- [Extra]
flagsExtra]
        changeDirectory :: Maybe String
changeDirectory = forall a. [a] -> Maybe a
listToMaybe [String
x | ChangeDirectory String
x <- [Extra]
flagsExtra]
        printDirectory :: Bool
printDirectory = forall a. a -> [a] -> a
lastDef Bool
False [Bool
x | PrintDirectory Bool
x <- [Extra]
flagsExtra]
        shareRemoves :: [String]
shareRemoves = [String
x | ShareRemove String
x <- [Extra]
flagsExtra]
        oshakeOpts :: ShakeOptions
oshakeOpts = forall (t :: * -> *) b a.
Foldable t =>
(b -> a -> b) -> b -> t a -> b
foldl' (forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a b. (a -> b) -> a -> b
($)) ShakeOptions
baseOpts [ShakeOptions -> ShakeOptions]
flagsShake
    [String]
lintInside <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
(a -> m b) -> t a -> m (t b)
mapM String -> IO String
canonicalizePath forall a b. (a -> b) -> a -> b
$ ShakeOptions -> [String]
shakeLintInside ShakeOptions
oshakeOpts
    let shakeOpts :: ShakeOptions
shakeOpts = ShakeOptions
oshakeOpts {shakeLintInside :: [String]
shakeLintInside = forall a b. (a -> b) -> [a] -> [b]
map (String -> String
toStandard forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> String
addTrailingPathSeparator) [String]
lintInside
                               ,shakeLintIgnore :: [String]
shakeLintIgnore = forall a b. (a -> b) -> [a] -> [b]
map String -> String
toStandard forall a b. (a -> b) -> a -> b
$ ShakeOptions -> [String]
shakeLintIgnore ShakeOptions
oshakeOpts
                               ,shakeOutput :: Verbosity -> String -> IO ()
shakeOutput     = if ShakeOptions -> Bool
shakeColor ShakeOptions
oshakeOpts
                                                  then (Verbosity -> String -> IO ()) -> Verbosity -> String -> IO ()
outputColor (ShakeOptions -> Verbosity -> String -> IO ()
shakeOutput ShakeOptions
oshakeOpts)
                                                  else ShakeOptions -> Verbosity -> String -> IO ()
shakeOutput ShakeOptions
oshakeOpts
                               }
    let putWhen :: Verbosity -> String -> IO ()
putWhen Verbosity
v String
msg = forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (ShakeOptions -> Verbosity
shakeVerbosity ShakeOptions
oshakeOpts forall a. Ord a => a -> a -> Bool
>= Verbosity
v) forall a b. (a -> b) -> a -> b
$ ShakeOptions -> Verbosity -> String -> IO ()
shakeOutput ShakeOptions
oshakeOpts Verbosity
v String
msg
    let putWhenLn :: Verbosity -> String -> IO ()
putWhenLn Verbosity
v String
msg = Verbosity -> String -> IO ()
putWhen Verbosity
v forall a b. (a -> b) -> a -> b
$ String
msg forall a. [a] -> [a] -> [a]
++ String
"\n"
    let showHelp :: Bool -> IO ()
showHelp Bool
long = do
            String
progName <- IO String
getProgName
            ([String]
targets, [String]
helpSuffix) <- if Bool -> Bool
not Bool
long then forall (f :: * -> *) a. Applicative f => a -> f a
pure ([], []) else
                forall a. (SomeException -> IO a) -> IO a -> IO a
handleSynchronous (\SomeException
e -> do Verbosity -> String -> IO ()
putWhenLn Verbosity
Info forall a b. (a -> b) -> a -> b
$ String
"Failure to collect targets: " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show SomeException
e; forall (f :: * -> *) a. Applicative f => a -> f a
pure ([], [])) forall a b. (a -> b) -> a -> b
$ do
                    -- run the rules as simply as we can
                    Maybe (ShakeOptions, Rules ())
rs <- ShakeOptions
-> [a] -> [String] -> IO (Maybe (ShakeOptions, Rules ()))
rules ShakeOptions
shakeOpts [] []
                    case Maybe (ShakeOptions, Rules ())
rs of
                        Just (ShakeOptions
_, Rules ()
rs) -> do
                            [(String, Maybe String)]
xs <- ShakeOptions -> Rules () -> IO [(String, Maybe String)]
getTargets ShakeOptions
shakeOpts Rules ()
rs
                            [String]
helpSuffix <- ShakeOptions -> Rules () -> IO [String]
getHelpSuffix ShakeOptions
shakeOpts Rules ()
rs
                            forall a. a -> IO a
evaluate forall a b. (a -> b) -> a -> b
$ forall a. NFData a => a -> a
force ([String
"  - " forall a. [a] -> [a] -> [a]
++ String
a forall a. [a] -> [a] -> [a]
++ forall b a. b -> (a -> b) -> Maybe a -> b
maybe String
"" (String
" - " forall a. [a] -> [a] -> [a]
++) Maybe String
b | (String
a,Maybe String
b) <- [(String, Maybe String)]
xs], [String]
helpSuffix)
                        Maybe (ShakeOptions, Rules ())
_ -> forall (f :: * -> *) a. Applicative f => a -> f a
pure ([], [])
            [String]
changes<- forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$
                let as :: [(String, String)]
as = ShakeOptions -> [(String, String)]
shakeOptionsFields ShakeOptions
baseOpts
                    bs :: [(String, String)]
bs = ShakeOptions -> [(String, String)]
shakeOptionsFields ShakeOptions
oshakeOpts
                in [String
"  - " forall a. [a] -> [a] -> [a]
++ String
lbl forall a. [a] -> [a] -> [a]
++ String
": " forall a. [a] -> [a] -> [a]
++ String
v1 forall a. [a] -> [a] -> [a]
++ String
" => " forall a. [a] -> [a] -> [a]
++ String
v2 | Bool
long, ((String
lbl, String
v1), (String
_, String
v2)) <- forall a b. [a] -> [b] -> [(a, b)]
zip [(String, String)]
as [(String, String)]
bs, String
v1 forall a. Eq a => a -> a -> Bool
/= String
v2]

            Verbosity -> String -> IO ()
putWhen Verbosity
Error forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines forall a b. (a -> b) -> a -> b
$
                (String
"Usage: " forall a. [a] -> [a] -> [a]
++ String
progName forall a. [a] -> [a] -> [a]
++ String
" [options] [target] ...") forall a. a -> [a] -> [a]
:
                (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [OptDescr (Either String ([Extra], ShakeOptions -> ShakeOptions))]
baseOpts2 then [] else String
"" forall a. a -> [a] -> [a]
: (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [OptDescr (Either String a)]
userOptions then String
"Options:" else String
"Standard options:") forall a. a -> [a] -> [a]
: forall a. [OptDescr a] -> [String]
showOptDescr [OptDescr (Either String ([Extra], ShakeOptions -> ShakeOptions))]
baseOpts2) forall a. [a] -> [a] -> [a]
++
                (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [OptDescr (Either String a)]
userOptions then [] else String
"" forall a. a -> [a] -> [a]
: String
"Extra options:" forall a. a -> [a] -> [a]
: forall a. [OptDescr a] -> [String]
showOptDescr [OptDescr (Either String a)]
userOptions) forall a. [a] -> [a] -> [a]
++
                (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
changes then [] else String
"" forall a. a -> [a] -> [a]
: String
"Changed ShakeOptions:" forall a. a -> [a] -> [a]
: [String]
changes) forall a. [a] -> [a] -> [a]
++
                (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
targets then [] else String
"" forall a. a -> [a] -> [a]
: String
"Targets:" forall a. a -> [a] -> [a]
: [String]
targets) forall a. [a] -> [a] -> [a]
++
                (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
helpSuffix then [] else String
"" forall a. a -> [a] -> [a]
: [String]
helpSuffix)

    forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when ([String]
errs forall a. Eq a => a -> a -> Bool
/= []) forall a b. (a -> b) -> a -> b
$ do
        Verbosity -> String -> IO ()
putWhen Verbosity
Error forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines forall a b. (a -> b) -> a -> b
$ forall a b. (a -> b) -> [a] -> [b]
map (String
"shake: " forall a. [a] -> [a] -> [a]
++) forall a b. (a -> b) -> a -> b
$ 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 => t a -> Bool
null) forall a b. (a -> b) -> a -> b
$ String -> [String]
lines forall a b. (a -> b) -> a -> b
$ [String] -> String
unlines [String]
errs
        Bool -> IO ()
showHelp Bool
False
        forall a. IO a
exitFailure

    if Extra
Help forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra then
        Bool -> IO ()
showHelp Bool
True
     else if Extra
Version forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra then
        Verbosity -> String -> IO ()
putWhenLn Verbosity
Info forall a b. (a -> b) -> a -> b
$ String
"Shake build system, version " forall a. [a] -> [a] -> [a]
++ String
shakeVersionString
     else if Extra
NumericVersion forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra then
        Verbosity -> String -> IO ()
putWhenLn Verbosity
Info String
shakeVersionString
     else if Extra
Demo forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra then
        Bool -> IO ()
demo forall a b. (a -> b) -> a -> b
$ ShakeOptions -> Bool
shakeStaunch ShakeOptions
shakeOpts
     else if Bool -> Bool
not forall a b. (a -> b) -> a -> b
$ forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
progressReplays then do
        [(String, [(Seconds, Progress)])]
dat <- forall (t :: * -> *) (m :: * -> *) a b.
(Traversable t, Monad m) =>
t a -> (a -> m b) -> m (t b)
forM [String]
progressReplays forall a b. (a -> b) -> a -> b
$ \String
file -> do
            String
src <- String -> IO String
readFile String
file
            forall (f :: * -> *) a. Applicative f => a -> f a
pure (String
file, forall a b. (a -> b) -> [a] -> [b]
map forall a. Read a => String -> a
read forall a b. (a -> b) -> a -> b
$ String -> [String]
lines String
src)
        forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ (if forall (t :: * -> *) a. Foldable t => t a -> Bool
null forall a b. (a -> b) -> a -> b
$ ShakeOptions -> [String]
shakeReport ShakeOptions
shakeOpts then [String
"-"] else ShakeOptions -> [String]
shakeReport ShakeOptions
shakeOpts) forall a b. (a -> b) -> a -> b
$ \String
file -> do
            Verbosity -> String -> IO ()
putWhenLn Verbosity
Info forall a b. (a -> b) -> a -> b
$ String
"Writing report to " forall a. [a] -> [a] -> [a]
++ String
file
            String -> [(String, [(Seconds, Progress)])] -> IO ()
writeProgressReport String
file [(String, [(Seconds, Progress)])]
dat
     else do
        forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Extra
Sleep forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra) forall a b. (a -> b) -> a -> b
$ Seconds -> IO ()
sleep Seconds
1
        IO Seconds
start <- IO (IO Seconds)
offsetTime
        IO ()
initDataDirectory -- must be done before we start changing directory
        let redir :: IO a -> IO a
redir = forall b a. b -> (a -> b) -> Maybe a -> b
maybe forall a. a -> a
id forall a. String -> IO a -> IO a
withCurrentDirectory Maybe String
changeDirectory
        ShakeOptions
shakeOpts <- if forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
progressRecords then forall (f :: * -> *) a. Applicative f => a -> f a
pure ShakeOptions
shakeOpts else do
            IO Seconds
t <- IO (IO Seconds)
offsetTime
            forall (f :: * -> *) a. Applicative f => a -> f a
pure ShakeOptions
shakeOpts{shakeProgress :: IO Progress -> IO ()
shakeProgress = \IO Progress
p ->
                forall (f :: * -> *) a. Functor f => f a -> f ()
void forall a b. (a -> b) -> a -> b
$ forall a b. IO a -> IO b -> IO (a, b)
withThreadsBoth (ShakeOptions -> IO Progress -> IO ()
shakeProgress ShakeOptions
shakeOpts IO Progress
p) forall a b. (a -> b) -> a -> b
$
                    Seconds -> (String -> IO ()) -> IO Progress -> IO ()
progressDisplay Seconds
1 (forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ()) forall a b. (a -> b) -> a -> b
$ do
                        Progress
p <- IO Progress
p
                        Seconds
t <- IO Seconds
t
                        forall (t :: * -> *) (m :: * -> *) a b.
(Foldable t, Monad m) =>
t a -> (a -> m b) -> m ()
forM_ [String]
progressRecords forall a b. (a -> b) -> a -> b
$ \String
file ->
                            String -> String -> IO ()
appendFile String
file forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show (Seconds
t,Progress
p) forall a. [a] -> [a] -> [a]
++ String
"\n"
                        forall (f :: * -> *) a. Applicative f => a -> f a
pure Progress
p
            }
        (Bool
ran,ShakeOptions
shakeOpts,Either SomeException ()
res) <- forall {a}. IO a -> IO a
redir forall a b. (a -> b) -> a -> b
$ do
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when Bool
printDirectory forall a b. (a -> b) -> a -> b
$ do
                String
curdir <- IO String
getCurrentDirectory
                Verbosity -> String -> IO ()
putWhenLn Verbosity
Info forall a b. (a -> b) -> a -> b
$ String
"shake: In directory `" forall a. [a] -> [a] -> [a]
++ String
curdir forall a. [a] -> [a] -> [a]
++ String
"'"
            (ShakeOptions
shakeOpts, IO (Bool, ShakeOptions, Either SomeException ())
-> IO (Bool, ShakeOptions, Either SomeException ())
ui) <- do
                let compact :: Auto
compact = forall a. a -> [a] -> a
lastDef Auto
No [Auto
x | Compact Auto
x <- [Extra]
flagsExtra]
                Bool
use <- if Auto
compact forall a. Eq a => a -> a -> Bool
== Auto
Auto then IO Bool
checkEscCodes else forall (f :: * -> *) a. Applicative f => a -> f a
pure forall a b. (a -> b) -> a -> b
$ Auto
compact forall a. Eq a => a -> a -> Bool
== Auto
Yes
                if Bool
use
                    then forall b b' a. (b -> b') -> (a, b) -> (a, b')
second forall a. IO () -> IO a -> IO a
withThreadSlave forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> ShakeOptions -> IO (ShakeOptions, IO ())
compactUI ShakeOptions
shakeOpts
                    else forall (f :: * -> *) a. Applicative f => a -> f a
pure (ShakeOptions
shakeOpts, forall a. a -> a
id)
            Maybe (ShakeOptions, Rules ())
rules <- ShakeOptions
-> [a] -> [String] -> IO (Maybe (ShakeOptions, Rules ()))
rules ShakeOptions
shakeOpts [a]
user [String]
files
            IO (Bool, ShakeOptions, Either SomeException ())
-> IO (Bool, ShakeOptions, Either SomeException ())
ui forall a b. (a -> b) -> a -> b
$ case Maybe (ShakeOptions, Rules ())
rules of
                Maybe (ShakeOptions, Rules ())
Nothing -> forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool
False, ShakeOptions
shakeOpts, forall a b. b -> Either a b
Right ())
                Just (ShakeOptions
shakeOpts, Rules ()
rules) -> do
                    Either SomeException ()
res <- forall a. IO a -> IO (Either SomeException a)
try_ forall a b. (a -> b) -> a -> b
$ ShakeOptions -> Rules () -> IO ()
shake ShakeOptions
shakeOpts forall a b. (a -> b) -> a -> b
$
                        if Extra
NoBuild forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra then
                            forall a. Rules a -> Rules a
withoutActions Rules ()
rules
                        else if Extra
ShareList forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra Bool -> Bool -> Bool
||
                                Bool -> Bool
not (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
shareRemoves) Bool -> Bool -> Bool
||
                                Extra
ShareSanity forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra then do
                            forall a. Partial => Action a -> Rules ()
action forall a b. (a -> b) -> a -> b
$ do
                                forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
unless (forall (t :: * -> *) a. Foldable t => t a -> Bool
null [String]
shareRemoves) forall a b. (a -> b) -> a -> b
$
                                    [String] -> Action ()
actionShareRemove [String]
shareRemoves
                                forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Extra
ShareList forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra)
                                    Action ()
actionShareList
                                forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Extra
ShareSanity forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra)
                                    Action ()
actionShareSanity
                            forall a. Rules a -> Rules a
withoutActions Rules ()
rules
                        else
                            Rules ()
rules
                    forall (f :: * -> *) a. Applicative f => a -> f a
pure (Bool
True, ShakeOptions
shakeOpts, Either SomeException ()
res)

        if Bool -> Bool
not Bool
ran Bool -> Bool -> Bool
|| ShakeOptions -> Verbosity
shakeVerbosity ShakeOptions
shakeOpts forall a. Ord a => a -> a -> Bool
< Verbosity
Info Bool -> Bool -> Bool
|| Extra
NoTime forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra then
            forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either forall e a. Exception e => e -> IO a
throwIO forall (f :: * -> *) a. Applicative f => a -> f a
pure Either SomeException ()
res
         else
            let esc :: Color -> String -> String
esc = if ShakeOptions -> Bool
shakeColor ShakeOptions
shakeOpts then Color -> String -> String
escape else \Color
_ String
x -> String
x
            in case Either SomeException ()
res of
                Left SomeException
err ->
                    if Extra
Exception forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool
`elem` [Extra]
flagsExtra then
                        forall e a. Exception e => e -> IO a
throwIO SomeException
err
                    else do
                        Verbosity -> String -> IO ()
putWhenLn Verbosity
Error forall a b. (a -> b) -> a -> b
$ Color -> String -> String
esc Color
Red forall a b. (a -> b) -> a -> b
$ forall a. Show a => a -> String
show SomeException
err
                        forall a. IO a
exitFailure
                Right () -> do
                    Seconds
tot <- IO Seconds
start
                    Verbosity -> String -> IO ()
putWhenLn Verbosity
Info forall a b. (a -> b) -> a -> b
$ Color -> String -> String
esc Color
Green forall a b. (a -> b) -> a -> b
$ String
"Build completed in " forall a. [a] -> [a] -> [a]
++ Seconds -> String
showDuration Seconds
tot


-- | A list of command line options that can be used to modify 'ShakeOptions'. Each option returns
--   either an error message (invalid argument to the flag) or a function that changes some fields
--   in 'ShakeOptions'. The command line flags are @make@ compatible where possbile, but additional
--   flags have been added for the extra options Shake supports.
shakeOptDescrs :: [OptDescr (Either String (ShakeOptions -> ShakeOptions))]
shakeOptDescrs :: [OptDescr (Either String (ShakeOptions -> ShakeOptions))]
shakeOptDescrs = [forall a b.
(a -> b)
-> OptDescr (Either String a) -> OptDescr (Either String b)
fmapFmapOptDescr forall a b. (a, b) -> b
snd OptDescr (Either String ([Extra], ShakeOptions -> ShakeOptions))
o | (Bool
True, OptDescr (Either String ([Extra], ShakeOptions -> ShakeOptions))
o) <- [(Bool,
  OptDescr (Either String ([Extra], ShakeOptions -> ShakeOptions)))]
shakeOptsEx]

data Extra = ChangeDirectory FilePath
           | Version
           | NumericVersion
           | PrintDirectory Bool
           | Help
           | Sleep
           | NoTime
           | Exception
           | NoBuild
           | ProgressRecord FilePath
           | ProgressReplay FilePath
           | Demo
           | ShareList
           | ShareSanity
           | ShareRemove String
           | Compact Auto
             deriving Extra -> Extra -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Extra -> Extra -> Bool
$c/= :: Extra -> Extra -> Bool
== :: Extra -> Extra -> Bool
$c== :: Extra -> Extra -> Bool
Eq

data Auto = Yes | No | Auto
    deriving Auto -> Auto -> Bool
forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a
/= :: Auto -> Auto -> Bool
$c/= :: Auto -> Auto -> Bool
== :: Auto -> Auto -> Bool
$c== :: Auto -> Auto -> Bool
Eq

escape :: Color -> String -> String
escape :: Color -> String -> String
escape Color
color String
x = Color -> String
escForeground Color
color forall a. [a] -> [a] -> [a]
++ String
x forall a. [a] -> [a] -> [a]
++ String
escNormal

outputColor :: (Verbosity -> String -> IO ()) -> Verbosity -> String -> IO ()
outputColor :: (Verbosity -> String -> IO ()) -> Verbosity -> String -> IO ()
outputColor Verbosity -> String -> IO ()
output Verbosity
v String
msg = Verbosity -> String -> IO ()
output Verbosity
v forall a b. (a -> b) -> a -> b
$ String -> String
color String
msg
  where color :: String -> String
color = case Verbosity
v of
            Verbosity
Silent -> forall a. a -> a
id
            Verbosity
Error  -> Color -> String -> String
escape Color
Red
            Verbosity
Warn   -> Color -> String -> String
escape Color
Yellow
            Verbosity
_      -> Color -> String -> String
escape Color
Blue

-- | True if it has a potential effect on ShakeOptions
shakeOptsEx :: [(Bool, OptDescr (Either String ([Extra], ShakeOptions -> ShakeOptions)))]
shakeOptsEx :: [(Bool,
  OptDescr (Either String ([Extra], ShakeOptions -> ShakeOptions)))]
shakeOptsEx =
    [forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"a" [String
"abbrev"] (forall {b}.
String
-> String -> ((String, String) -> b) -> ArgDescr (Either String b)
reqArgPair String
"abbrev" String
"FULL=SHORT" forall a b. (a -> b) -> a -> b
$ \(String, String)
a ShakeOptions
s -> ShakeOptions
s{shakeAbbreviations :: [(String, String)]
shakeAbbreviations=ShakeOptions -> [(String, String)]
shakeAbbreviations ShakeOptions
s forall a. [a] -> [a] -> [a]
++ [(String, String)
a]}) String
"Use abbreviation in status messages."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"allow-redefine-rules"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeAllowRedefineRules :: Bool
shakeAllowRedefineRules = Bool
True}) String
"Allow redefining built-in rules"
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"no-allow-redefine-rules"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeAllowRedefineRules :: Bool
shakeAllowRedefineRules = Bool
False}) String
"Forbid redefining built-in rules (default)"
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"no-build"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg [Extra
NoBuild]) String
"Don't build anything."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"C" [String
"directory"] (forall {b} {a}. String -> (String -> b) -> ArgDescr (Either a b)
reqArg String
"DIRECTORY" forall a b. (a -> b) -> a -> b
$ \String
x -> [String -> Extra
ChangeDirectory String
x]) String
"Change to DIRECTORY before doing anything."
--    ,yes $ Option ""  ["cloud"] (reqArg "URL" $ \x s -> s{shakeCloud=shakeCloud s ++ [x]}) "HTTP server providing a cloud cache."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"color",String
"colour"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeColor :: Bool
shakeColor=Bool
True}) String
"Colorize the output."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"no-color",String
"no-colour"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeColor :: Bool
shakeColor=Bool
False}) String
"Don't colorize the output."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"compact"] (forall {b}.
String -> String -> (Auto -> b) -> ArgDescr (Either String b)
optArgAuto String
"auto" String
"yes|no|auto" forall a b. (a -> b) -> a -> b
$ \Auto
x -> [Auto -> Extra
Compact Auto
x]) String
"Use a compact Bazel/Buck style output."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"d" [String
"debug"] (forall {b} {a}.
String -> (Maybe String -> b) -> ArgDescr (Either a b)
optArg String
"FILE" forall a b. (a -> b) -> a -> b
$ \Maybe String
x ShakeOptions
s -> ShakeOptions
s{shakeVerbosity :: Verbosity
shakeVerbosity=Verbosity
Diagnostic, shakeOutput :: Verbosity -> String -> IO ()
shakeOutput=(Verbosity -> String -> IO ())
-> Maybe String -> Verbosity -> String -> IO ()
outputDebug (ShakeOptions -> Verbosity -> String -> IO ()
shakeOutput ShakeOptions
s) Maybe String
x}) String
"Print lots of debugging information."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"demo"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg [Extra
Demo]) String
"Run in demo mode."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"digest"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeChange :: Change
shakeChange=Change
ChangeDigest}) String
"Files change when digest changes."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"digest-and"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeChange :: Change
shakeChange=Change
ChangeModtimeAndDigest}) String
"Files change when modtime and digest change."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"digest-and-input"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeChange :: Change
shakeChange=Change
ChangeModtimeAndDigestInput}) String
"Files change on modtime (and digest for inputs)."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"digest-or"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeChange :: Change
shakeChange=Change
ChangeModtimeOrDigest}) String
"Files change when modtime or digest change."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"digest-not"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeChange :: Change
shakeChange=Change
ChangeModtime}) String
"Files change when modtime changes."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"exception"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg [Extra
Exception]) String
"Throw exceptions directly."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"flush"] (forall {a} {b}.
(Read a, Ord a, Show a) =>
a -> String -> String -> (a -> b) -> ArgDescr (Either String b)
reqIntArg Seconds
1 String
"flush" String
"N" (\Seconds
i ShakeOptions
s -> ShakeOptions
s{shakeFlush :: Maybe Seconds
shakeFlush=forall a. a -> Maybe a
Just Seconds
i})) String
"Flush metadata every N seconds."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"never-flush"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeFlush :: Maybe Seconds
shakeFlush=forall a. Maybe a
Nothing}) String
"Never explicitly flush metadata."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"h" [String
"help"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg [Extra
Help]) String
"Print this message and exit."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"j" [String
"jobs"] (forall {a} {b}.
(Read a, Ord a, Show a) =>
a
-> String -> String -> (Maybe a -> b) -> ArgDescr (Either String b)
optArgInt Int
0 String
"jobs" String
"N" forall a b. (a -> b) -> a -> b
$ \Maybe Int
i ShakeOptions
s -> ShakeOptions
s{shakeThreads :: Int
shakeThreads=forall a. a -> Maybe a -> a
fromMaybe Int
0 Maybe Int
i}) String
"Allow N jobs/threads at once [default CPUs]."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"k" [String
"keep-going"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeStaunch :: Bool
shakeStaunch=Bool
True}) String
"Keep going when some targets can't be made."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"l" [String
"lint"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeLint :: Maybe Lint
shakeLint=forall a. a -> Maybe a
Just Lint
LintBasic}) String
"Perform limited validation after the run."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"lint-watch"] (forall {b} {a}. String -> (String -> b) -> ArgDescr (Either a b)
reqArg String
"PATTERN" forall a b. (a -> b) -> a -> b
$ \String
x ShakeOptions
s -> ShakeOptions
s{shakeLintWatch :: [String]
shakeLintWatch=ShakeOptions -> [String]
shakeLintWatch ShakeOptions
s forall a. [a] -> [a] -> [a]
++ [String
x]}) String
"Error if any of the patterns are created (expensive)."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"lint-fsatrace"] (forall {b} {a}.
String -> (Maybe String -> b) -> ArgDescr (Either a b)
optArg String
"DIR" forall a b. (a -> b) -> a -> b
$ \Maybe String
x ShakeOptions
s -> ShakeOptions
s{shakeLint :: Maybe Lint
shakeLint=forall a. a -> Maybe a
Just Lint
LintFSATrace, shakeLintInside :: [String]
shakeLintInside=ShakeOptions -> [String]
shakeLintInside ShakeOptions
s forall a. [a] -> [a] -> [a]
++ [forall a. a -> Maybe a -> a
fromMaybe String
"." Maybe String
x]}) String
"Use fsatrace to do validation [in current dir]."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"lint-ignore"] (forall {b} {a}. String -> (String -> b) -> ArgDescr (Either a b)
reqArg String
"PATTERN" forall a b. (a -> b) -> a -> b
$ \String
x ShakeOptions
s -> ShakeOptions
s{shakeLintIgnore :: [String]
shakeLintIgnore=ShakeOptions -> [String]
shakeLintIgnore ShakeOptions
s forall a. [a] -> [a] -> [a]
++ [String
x]}) String
"Ignore any lint errors in these patterns."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"no-lint"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeLint :: Maybe Lint
shakeLint=forall a. Maybe a
Nothing}) String
"Turn off --lint."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"live"] (forall {b} {a}.
String -> (Maybe String -> b) -> ArgDescr (Either a b)
optArg String
"FILE" forall a b. (a -> b) -> a -> b
$ \Maybe String
x ShakeOptions
s -> ShakeOptions
s{shakeLiveFiles :: [String]
shakeLiveFiles=ShakeOptions -> [String]
shakeLiveFiles ShakeOptions
s forall a. [a] -> [a] -> [a]
++ [forall a. a -> Maybe a -> a
fromMaybe String
"live.txt" Maybe String
x]}) String
"List the files that are live [to live.txt]."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"m" [String
"metadata"] (forall {b} {a}. String -> (String -> b) -> ArgDescr (Either a b)
reqArg String
"PREFIX" forall a b. (a -> b) -> a -> b
$ \String
x ShakeOptions
s -> ShakeOptions
s{shakeFiles :: String
shakeFiles=String
x}) String
"Prefix for storing metadata files."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"numeric-version"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg [Extra
NumericVersion]) String
"Print just the version number and exit."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"skip-commands"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeRunCommands :: Bool
shakeRunCommands=Bool
False}) String
"Try and avoid running external programs."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"B" [String
"rebuild"] (forall {b} {a}.
String -> (Maybe String -> b) -> ArgDescr (Either a b)
optArg String
"PATTERN" forall a b. (a -> b) -> a -> b
$ \Maybe String
x ShakeOptions
s -> ShakeOptions
s{shakeRebuild :: [(Rebuild, String)]
shakeRebuild=ShakeOptions -> [(Rebuild, String)]
shakeRebuild ShakeOptions
s forall a. [a] -> [a] -> [a]
++ [(Rebuild
RebuildNow, forall a. a -> Maybe a -> a
fromMaybe String
"**" Maybe String
x)]}) String
"If required, these files will rebuild even if nothing has changed."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"no-rebuild"] (forall {b} {a}.
String -> (Maybe String -> b) -> ArgDescr (Either a b)
optArg String
"PATTERN" forall a b. (a -> b) -> a -> b
$ \Maybe String
x ShakeOptions
s -> ShakeOptions
s{shakeRebuild :: [(Rebuild, String)]
shakeRebuild=ShakeOptions -> [(Rebuild, String)]
shakeRebuild ShakeOptions
s forall a. [a] -> [a] -> [a]
++ [(Rebuild
RebuildNormal, forall a. a -> Maybe a -> a
fromMaybe String
"**" Maybe String
x)]}) String
"If required, these files will rebuild only if things have changed (default)."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"skip"] (forall {b} {a}.
String -> (Maybe String -> b) -> ArgDescr (Either a b)
optArg String
"PATTERN" forall a b. (a -> b) -> a -> b
$ \Maybe String
x ShakeOptions
s -> ShakeOptions
s{shakeRebuild :: [(Rebuild, String)]
shakeRebuild=ShakeOptions -> [(Rebuild, String)]
shakeRebuild ShakeOptions
s forall a. [a] -> [a] -> [a]
++ [(Rebuild
RebuildLater, forall a. a -> Maybe a -> a
fromMaybe String
"**" Maybe String
x)]}) String
"Don't rebuild matching files this run."
--    ,yes $ Option ""  ["skip-forever"] (OptArg (\x -> Right ([], \s -> s{shakeRebuild=shakeRebuild s ++ [(RebuildNever, fromMaybe "**" x)]})) "PATTERN") "Don't rebuild matching files until they change."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"r" [String
"report",String
"profile"] (forall {b} {a}.
String -> (Maybe String -> b) -> ArgDescr (Either a b)
optArg String
"FILE" forall a b. (a -> b) -> a -> b
$ \Maybe String
x ShakeOptions
s -> ShakeOptions
s{shakeReport :: [String]
shakeReport=ShakeOptions -> [String]
shakeReport ShakeOptions
s forall a. [a] -> [a] -> [a]
++ [forall a. a -> Maybe a -> a
fromMaybe String
"report.html" Maybe String
x]}) String
"Write out profiling information [to report.html]."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"no-reports"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeReport :: [String]
shakeReport=[]}) String
"Turn off --report."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"rule-version"] (forall {b} {a}. String -> (String -> b) -> ArgDescr (Either a b)
reqArg String
"VERSION" forall a b. (a -> b) -> a -> b
$ \String
x ShakeOptions
s -> ShakeOptions
s{shakeVersion :: String
shakeVersion=String
x}) String
"Version of the build rules."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"no-rule-version"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeVersionIgnore :: Bool
shakeVersionIgnore=Bool
True}) String
"Ignore the build rules version."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"share"] (forall {b} {a}.
String -> (Maybe String -> b) -> ArgDescr (Either a b)
optArg String
"DIRECTORY" forall a b. (a -> b) -> a -> b
$ \Maybe String
x ShakeOptions
s -> ShakeOptions
s{shakeShare :: Maybe String
shakeShare=forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe String
"" Maybe String
x, shakeChange :: Change
shakeChange=Change -> Change
ensureHash forall a b. (a -> b) -> a -> b
$ ShakeOptions -> Change
shakeChange ShakeOptions
s}) String
"Shared cache location."
    ,forall {b}. b -> (Bool, b)
hide forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"share-list"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg ([Extra
ShareList], ShakeOptions -> ShakeOptions
ensureShare)) String
"List the shared cache files."
    ,forall {b}. b -> (Bool, b)
hide forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"share-sanity"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg ([Extra
ShareSanity], ShakeOptions -> ShakeOptions
ensureShare)) String
"Sanity check the shared cache files."
    ,forall {b}. b -> (Bool, b)
hide forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"share-remove"] (forall a. (Maybe String -> a) -> String -> ArgDescr a
OptArg (\Maybe String
x -> forall a b. b -> Either a b
Right ([String -> Extra
ShareRemove forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe String
"**" Maybe String
x], ShakeOptions -> ShakeOptions
ensureShare)) String
"SUBSTRING") String
"Remove the shared cache keys."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"share-copy"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeSymlink :: Bool
shakeSymlink=Bool
False}) String
"Copy files into the cache."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"share-symlink"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeSymlink :: Bool
shakeSymlink=Bool
True}) String
"Symlink files into the cache."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"s" [String
"silent"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeVerbosity :: Verbosity
shakeVerbosity=Verbosity
Silent}) String
"Don't print anything."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"sleep"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg [Extra
Sleep]) String
"Sleep for a second before building."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"S" [String
"no-keep-going",String
"stop"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeStaunch :: Bool
shakeStaunch=Bool
False}) String
"Turns off -k."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"storage"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeStorageLog :: Bool
shakeStorageLog=Bool
True}) String
"Write a storage log."
    ,forall {b}. b -> (Bool, b)
both forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"p" [String
"progress"] (forall {a} {a}.
ArgDescr (Either a (a -> a))
-> ArgDescr (Either a ([Extra], a -> a))
progress forall a b. (a -> b) -> a -> b
$ forall {a} {b}.
(Read a, Ord a, Show a) =>
a
-> String -> String -> (Maybe a -> b) -> ArgDescr (Either String b)
optArgInt Seconds
1 String
"progress" String
"N" forall a b. (a -> b) -> a -> b
$ \Maybe Seconds
i ShakeOptions
s -> ShakeOptions
s{shakeProgress :: IO Progress -> IO ()
shakeProgress=Seconds -> IO Progress -> IO ()
prog forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe Seconds
5 Maybe Seconds
i}) String
"Show progress messages [every N secs, default 5]."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"no-progress"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeProgress :: IO Progress -> IO ()
shakeProgress=forall a b. a -> b -> a
const forall a b. (a -> b) -> a -> b
$ forall (f :: * -> *) a. Applicative f => a -> f a
pure ()}) String
"Don't show progress messages."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"q" [String
"quiet"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeVerbosity :: Verbosity
shakeVerbosity=Verbosity -> (Int -> Int) -> Verbosity
move (ShakeOptions -> Verbosity
shakeVerbosity ShakeOptions
s) forall a. Enum a => a -> a
pred}) String
"Print less (pass repeatedly for even less)."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"no-time"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg [Extra
NoTime]) String
"Don't print build time."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"timings"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeTimings :: Bool
shakeTimings=Bool
True}) String
"Print phase timings."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"V" [String
"verbose",String
"trace"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg forall a b. (a -> b) -> a -> b
$ \ShakeOptions
s -> ShakeOptions
s{shakeVerbosity :: Verbosity
shakeVerbosity=Verbosity -> (Int -> Int) -> Verbosity
move (ShakeOptions -> Verbosity
shakeVerbosity ShakeOptions
s) forall a. Enum a => a -> a
succ}) String
"Print more (pass repeatedly for even more)."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"v" [String
"version"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg [Extra
Version]) String
"Print the version number and exit."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
"w" [String
"print-directory"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg [Bool -> Extra
PrintDirectory Bool
True]) String
"Print the current directory."
    ,forall {a} {a}.
OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr forall a b. (a -> b) -> a -> b
$ forall a. String -> [String] -> ArgDescr a -> String -> OptDescr a
Option String
""  [String
"no-print-directory"] (forall {a} {a}. a -> ArgDescr (Either a a)
noArg [Bool -> Extra
PrintDirectory Bool
False]) String
"Turn off -w, even if it was turned on implicitly."
    ]
    where
        opts :: OptDescr (Either String a)
-> (Bool, OptDescr (Either String ([a], a)))
opts OptDescr (Either String a)
o = (Bool
True, forall a b.
(a -> b)
-> OptDescr (Either String a) -> OptDescr (Either String b)
fmapFmapOptDescr ([],) OptDescr (Either String a)
o)
        extr :: OptDescr (Either String a)
-> (Bool, OptDescr (Either String (a, a -> a)))
extr OptDescr (Either String a)
o = (Bool
False, forall a b.
(a -> b)
-> OptDescr (Either String a) -> OptDescr (Either String b)
fmapFmapOptDescr (,forall a. a -> a
id) OptDescr (Either String a)
o)
        both :: b -> (Bool, b)
both b
o = (Bool
True, b
o)
        hide :: b -> (Bool, b)
hide b
o = (Bool
False, b
o) -- I do modify the options, but not in a meaningful way

        move :: Verbosity -> (Int -> Int) -> Verbosity
        move :: Verbosity -> (Int -> Int) -> Verbosity
move Verbosity
x Int -> Int
by = forall a. Enum a => Int -> a
toEnum forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> a -> a
min (forall a. Enum a => a -> Int
fromEnum Verbosity
mx) forall a b. (a -> b) -> a -> b
$ forall a. Ord a => a -> a -> a
max (forall a. Enum a => a -> Int
fromEnum Verbosity
mn) forall a b. (a -> b) -> a -> b
$ Int -> Int
by forall a b. (a -> b) -> a -> b
$ forall a. Enum a => a -> Int
fromEnum Verbosity
x
            where (Verbosity
mn,Verbosity
mx) = (forall a. a -> a -> a
asTypeOf forall a. Bounded a => a
minBound Verbosity
x, forall a. a -> a -> a
asTypeOf forall a. Bounded a => a
maxBound Verbosity
x)

        noArg :: a -> ArgDescr (Either a a)
noArg = forall a. a -> ArgDescr a
NoArg forall b c a. (b -> c) -> (a -> b) -> a -> c
. forall a b. b -> Either a b
Right
        reqArg :: String -> (String -> b) -> ArgDescr (Either a b)
reqArg String
a String -> b
f = forall a. (String -> a) -> String -> ArgDescr a
ReqArg (forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. String -> b
f) String
a
        optArg :: String -> (Maybe String -> b) -> ArgDescr (Either a b)
optArg String
a Maybe String -> b
f = forall a. (Maybe String -> a) -> String -> ArgDescr a
OptArg (forall a b. b -> Either a b
Right forall b c a. (b -> c) -> (a -> b) -> a -> c
. Maybe String -> b
f) String
a

        reqIntArg :: a -> String -> String -> (a -> b) -> ArgDescr (Either String b)
reqIntArg a
mn String
flag String
a a -> b
f = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. (String -> a) -> String -> ArgDescr a
ReqArg String
a forall a b. (a -> b) -> a -> b
$ \String
x -> case forall a. Read a => ReadS a
reads String
x of
            [(a
i,String
"")] | a
i forall a. Ord a => a -> a -> Bool
>= a
mn -> forall a b. b -> Either a b
Right (a -> b
f a
i)
            [(a, String)]
_ -> forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ String
"the `--" forall a. [a] -> [a] -> [a]
++ String
flag forall a. [a] -> [a] -> [a]
++ String
"' option requires a number, " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
mn forall a. [a] -> [a] -> [a]
++ String
" or above"

        optArgInt :: a
-> String -> String -> (Maybe a -> b) -> ArgDescr (Either String b)
optArgInt a
mn String
flag String
a Maybe a -> b
f = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. (Maybe String -> a) -> String -> ArgDescr a
OptArg String
a forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a b. b -> Either a b
Right (Maybe a -> b
f forall a. Maybe a
Nothing)) forall a b. (a -> b) -> a -> b
$ \String
x -> case forall a. Read a => ReadS a
reads String
x of
            [(a
i,String
"")] | a
i forall a. Ord a => a -> a -> Bool
>= a
mn -> forall a b. b -> Either a b
Right (Maybe a -> b
f forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a
Just a
i)
            [(a, String)]
_ -> forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ String
"the `--" forall a. [a] -> [a] -> [a]
++ String
flag forall a. [a] -> [a] -> [a]
++ String
"' option requires a number, " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show a
mn forall a. [a] -> [a] -> [a]
++ String
" or above"

        optArgAuto :: String -> String -> (Auto -> b) -> ArgDescr (Either String b)
optArgAuto String
flag String
a Auto -> b
f = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. (Maybe String -> a) -> String -> ArgDescr a
OptArg String
a forall a b. (a -> b) -> a -> b
$ forall b a. b -> (a -> b) -> Maybe a -> b
maybe (forall a b. b -> Either a b
Right (Auto -> b
f Auto
Yes)) forall a b. (a -> b) -> a -> b
$ \String
x -> case String
x of
            String
"yes" -> forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ Auto -> b
f Auto
Yes
            String
"no" -> forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ Auto -> b
f Auto
No
            String
"auto" -> forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ Auto -> b
f Auto
Auto
            String
_ -> forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ String
"the `--" forall a. [a] -> [a] -> [a]
++ String
flag forall a. [a] -> [a] -> [a]
++ String
"' option requires yes|no|auto, but got " forall a. [a] -> [a] -> [a]
++ forall a. Show a => a -> String
show String
x

        reqArgPair :: String
-> String -> ((String, String) -> b) -> ArgDescr (Either String b)
reqArgPair String
flag String
a (String, String) -> b
f = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. (String -> a) -> String -> ArgDescr a
ReqArg String
a forall a b. (a -> b) -> a -> b
$ \String
x -> case forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
== Char
'=') String
x of
            (String
a,Char
'=':String
b) -> forall a b. b -> Either a b
Right forall a b. (a -> b) -> a -> b
$ (String, String) -> b
f (String
a,String
b)
            (String, String)
_ -> forall a b. a -> Either a b
Left forall a b. (a -> b) -> a -> b
$ String
"the `--" forall a. [a] -> [a] -> [a]
++ String
flag forall a. [a] -> [a] -> [a]
++ String
"' option requires an = in the argument"

        progress :: ArgDescr (Either a (a -> a))
-> ArgDescr (Either a ([Extra], a -> a))
progress (OptArg Maybe String -> Either a (a -> a)
func String
msg) = forall a b c. (a -> b -> c) -> b -> a -> c
flip forall a. (Maybe String -> a) -> String -> ArgDescr a
OptArg String
msg forall a b. (a -> b) -> a -> b
$ \Maybe String
x -> case forall a. (a -> Bool) -> [a] -> ([a], [a])
break (forall a. Eq a => a -> a -> Bool
== Char
'=') forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
`fmap` Maybe String
x of
            Just (String
"record",String
file) -> forall a b. b -> Either a b
Right ([String -> Extra
ProgressRecord forall a b. (a -> b) -> a -> b
$ if forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
file then String
"progress.txt" else forall a. [a] -> [a]
tail String
file], forall a. a -> a
id)
            Just (String
"replay",String
file) -> forall a b. b -> Either a b
Right ([String -> Extra
ProgressReplay forall a b. (a -> b) -> a -> b
$ if forall (t :: * -> *) a. Foldable t => t a -> Bool
null String
file then String
"progress.txt" else forall a. [a] -> [a]
tail String
file], forall a. a -> a
id)
            Maybe (String, String)
_ -> ([],) forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Maybe String -> Either a (a -> a)
func Maybe String
x
        progress ArgDescr (Either a (a -> a))
_ = forall a. SomeException -> a
throwImpure forall a b. (a -> b) -> a -> b
$ Partial => String -> SomeException
errorInternal String
"incomplete pattern, progress"

        outputDebug :: (Verbosity -> String -> IO ())
-> Maybe String -> Verbosity -> String -> IO ()
outputDebug Verbosity -> String -> IO ()
output Maybe String
Nothing = Verbosity -> String -> IO ()
output
        outputDebug Verbosity -> String -> IO ()
output (Just String
file) = \Verbosity
v String
msg -> do
            forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Verbosity
v forall a. Eq a => a -> a -> Bool
/= Verbosity
Diagnostic) forall a b. (a -> b) -> a -> b
$ Verbosity -> String -> IO ()
output Verbosity
v String
msg
            String -> String -> IO ()
appendFile String
file forall a b. (a -> b) -> a -> b
$ String -> String
removeEscCodes String
msg forall a. [a] -> [a] -> [a]
++ String
"\n"

        prog :: Seconds -> IO Progress -> IO ()
prog Seconds
i IO Progress
p = do
            String -> IO ()
program <- IO (String -> IO ())
progressProgram
            Seconds -> (String -> IO ()) -> IO Progress -> IO ()
progressDisplay Seconds
i (\String
s -> String -> IO ()
progressTitlebar String
s forall (m :: * -> *) a b. Monad m => m a -> m b -> m b
>> String -> IO ()
program String
s) IO Progress
p

        -- ensure the file system always computes a hash, required for --share
        ensureHash :: Change -> Change
ensureHash Change
ChangeModtime = Change
ChangeModtimeAndDigest
        ensureHash Change
ChangeModtimeAndDigestInput = Change
ChangeModtimeAndDigest
        ensureHash Change
x = Change
x

        ensureShare :: ShakeOptions -> ShakeOptions
ensureShare ShakeOptions
s = ShakeOptions
s{shakeShare :: Maybe String
shakeShare = forall a. a -> Maybe a
Just forall a b. (a -> b) -> a -> b
$ forall a. a -> Maybe a -> a
fromMaybe String
"." forall a b. (a -> b) -> a -> b
$ ShakeOptions -> Maybe String
shakeShare ShakeOptions
s}