-- Hoogle documentation, generated by Haddock -- See Hoogle, http://www.haskell.org/hoogle/ -- | Build system library, like Make, but more accurate dependencies. -- -- Shake is a Haskell library for writing build systems - designed as a -- replacement for make. See Development.Shake for an -- introduction, including an example. The homepage contains links to a -- user manual, an academic paper and further information: -- https://shakebuild.com -- -- To use Shake the user writes a Haskell program that imports -- Development.Shake, defines some build rules, and calls the -- Development.Shake.shakeArgs function. Thanks to do notation and -- infix operators, a simple Shake build system is not too dissimilar -- from a simple Makefile. However, as build systems get more complex, -- Shake is able to take advantage of the excellent abstraction -- facilities offered by Haskell and easily support much larger projects. -- The Shake library provides all the standard features available in -- other build systems, including automatic parallelism and minimal -- rebuilds. Shake also provides more accurate dependency tracking, -- including seamless support for generated files, and dependencies on -- system information (e.g. compiler version). @package shake @version 0.19 -- | This module reexports the six necessary type classes that many rule -- types must support through ShakeValue. You can use this -- module to define new rules without depending on the binary, -- deepseq and hashable packages. module Development.Shake.Classes -- | Conversion of values to readable Strings. -- -- Derived instances of Show have the following properties, which -- are compatible with derived instances of Read: -- -- -- -- For example, given the declarations -- --
--   infixr 5 :^:
--   data Tree a =  Leaf a  |  Tree a :^: Tree a
--   
-- -- the derived instance of Show is equivalent to -- --
--   instance (Show a) => Show (Tree a) where
--   
--          showsPrec d (Leaf m) = showParen (d > app_prec) $
--               showString "Leaf " . showsPrec (app_prec+1) m
--            where app_prec = 10
--   
--          showsPrec d (u :^: v) = showParen (d > up_prec) $
--               showsPrec (up_prec+1) u .
--               showString " :^: "      .
--               showsPrec (up_prec+1) v
--            where up_prec = 5
--   
-- -- Note that right-associativity of :^: is ignored. For example, -- -- class Show a -- | Convert a value to a readable String. -- -- showsPrec should satisfy the law -- --
--   showsPrec d x r ++ s  ==  showsPrec d x (r ++ s)
--   
-- -- Derived instances of Read and Show satisfy the -- following: -- -- -- -- That is, readsPrec parses the string produced by -- showsPrec, and delivers the value that showsPrec started -- with. showsPrec :: Show a => Int -> a -> ShowS -- | A specialised variant of showsPrec, using precedence context -- zero, and returning an ordinary String. show :: Show a => a -> String -- | The method showList is provided to allow the programmer to give -- a specialised way of showing lists of values. For example, this is -- used by the predefined Show instance of the Char type, -- where values of type String should be shown in double quotes, -- rather than between square brackets. showList :: Show a => [a] -> ShowS -- | The class Typeable allows a concrete representation of a type -- to be calculated. class Typeable (a :: k) -- | The Eq class defines equality (==) and inequality -- (/=). All the basic datatypes exported by the Prelude -- are instances of Eq, and Eq may be derived for any -- datatype whose constituents are also instances of Eq. -- -- The Haskell Report defines no laws for Eq. However, == -- is customarily expected to implement an equivalence relationship where -- two values comparing equal are indistinguishable by "public" -- functions, with a "public" function being one not allowing to see -- implementation details. For example, for a type representing -- non-normalised natural numbers modulo 100, a "public" function doesn't -- make the difference between 1 and 201. It is expected to have the -- following properties: -- -- -- -- Minimal complete definition: either == or /=. class Eq a (==) :: Eq a => a -> a -> Bool (/=) :: Eq a => a -> a -> Bool infix 4 == infix 4 /= -- | The class of types that can be converted to a hash value. -- -- Minimal implementation: hashWithSalt. class Hashable a -- | Return a hash value for the argument, using the given salt. -- -- The general contract of hashWithSalt is: -- -- hashWithSalt :: Hashable a => Int -> a -> Int -- | Like hashWithSalt, but no salt is used. The default -- implementation uses hashWithSalt with some default salt. -- Instances might want to implement this method to provide a more -- efficient implementation than the default implementation. hash :: Hashable a => a -> Int infixl 0 `hashWithSalt` -- | The Binary class provides put and get, methods to -- encode and decode a Haskell value to a lazy ByteString. It -- mirrors the Read and Show classes for textual -- representation of Haskell types, and is suitable for serialising -- Haskell values to disk, over the network. -- -- For decoding and generating simple external binary formats (e.g. C -- structures), Binary may be used, but in general is not suitable for -- complex protocols. Instead use the PutM and Get -- primitives directly. -- -- Instances of Binary should satisfy the following property: -- --
--   decode . encode == id
--   
-- -- That is, the get and put methods should be the inverse -- of each other. A range of instances are provided for basic Haskell -- types. class Binary t -- | Encode a value in the Put monad. put :: Binary t => t -> Put -- | Decode a value in the Get monad get :: Binary t => Get t -- | Encode a list of values in the Put monad. The default implementation -- may be overridden to be more efficient but must still have the same -- encoding format. putList :: Binary t => [t] -> Put -- | A class of types that can be fully evaluated. class NFData a -- | rnf should reduce its argument to normal form (that is, fully -- evaluate all sub-components), and then return '()'. -- --

Generic NFData deriving

-- -- Starting with GHC 7.2, you can automatically derive instances for -- types possessing a Generic instance. -- -- Note: Generic1 can be auto-derived starting with GHC 7.4 -- --
--   {-# LANGUAGE DeriveGeneric #-}
--   
--   import GHC.Generics (Generic, Generic1)
--   import Control.DeepSeq
--   
--   data Foo a = Foo a String
--                deriving (Eq, Generic, Generic1)
--   
--   instance NFData a => NFData (Foo a)
--   instance NFData1 Foo
--   
--   data Colour = Red | Green | Blue
--                 deriving Generic
--   
--   instance NFData Colour
--   
-- -- Starting with GHC 7.10, the example above can be written more -- concisely by enabling the new DeriveAnyClass extension: -- --
--   {-# LANGUAGE DeriveGeneric, DeriveAnyClass #-}
--   
--   import GHC.Generics (Generic)
--   import Control.DeepSeq
--   
--   data Foo a = Foo a String
--                deriving (Eq, Generic, Generic1, NFData, NFData1)
--   
--   data Colour = Red | Green | Blue
--                 deriving (Generic, NFData)
--   
-- --

Compatibility with previous deepseq versions

-- -- Prior to version 1.4.0.0, the default implementation of the rnf -- method was defined as -- --
--   rnf a = seq a ()
--   
-- -- However, starting with deepseq-1.4.0.0, the default -- implementation is based on DefaultSignatures allowing for -- more accurate auto-derived NFData instances. If you need the -- previously used exact default rnf method implementation -- semantics, use -- --
--   instance NFData Colour where rnf x = seq x ()
--   
-- -- or alternatively -- --
--   instance NFData Colour where rnf = rwhnf
--   
-- -- or -- --
--   {-# LANGUAGE BangPatterns #-}
--   instance NFData Colour where rnf !_ = ()
--   
rnf :: NFData a => a -> () -- | A module for FilePath operations exposing -- System.FilePath plus some additional operations. -- -- Windows note: The extension methods (<.>, -- takeExtension etc) use the Posix variants since on Windows -- "//*" <.> "txt" produces "//*\\.txt" -- (which is bad for FilePattern values). module Development.Shake.FilePath -- | File and directory names are values of type String, whose -- precise meaning is operating system dependent. Files can be opened, -- yielding a handle which can then be used to operate on the contents of -- that file. type FilePath = String -- | Combine two paths with a path separator. If the second path starts -- with a path separator or a drive letter, then it returns the second. -- The intention is that readFile (dir </> file) -- will access the same file as setCurrentDirectory dir; readFile -- file. -- --
--   Posix:   "/directory" </> "file.ext" == "/directory/file.ext"
--   Windows: "/directory" </> "file.ext" == "/directory\\file.ext"
--            "directory" </> "/file.ext" == "/file.ext"
--   Valid x => (takeDirectory x </> takeFileName x) `equalFilePath` x
--   
-- -- Combined: -- --
--   Posix:   "/" </> "test" == "/test"
--   Posix:   "home" </> "bob" == "home/bob"
--   Posix:   "x:" </> "foo" == "x:/foo"
--   Windows: "C:\\foo" </> "bar" == "C:\\foo\\bar"
--   Windows: "home" </> "bob" == "home\\bob"
--   
-- -- Not combined: -- --
--   Posix:   "home" </> "/bob" == "/bob"
--   Windows: "home" </> "C:\\bob" == "C:\\bob"
--   
-- -- Not combined (tricky): -- -- On Windows, if a filepath starts with a single slash, it is relative -- to the root of the current drive. In [1], this is (confusingly) -- referred to as an absolute path. The current behavior of -- </> is to never combine these forms. -- --
--   Windows: "home" </> "/bob" == "/bob"
--   Windows: "home" </> "\\bob" == "\\bob"
--   Windows: "C:\\home" </> "\\bob" == "\\bob"
--   
-- -- On Windows, from [1]: "If a file name begins with only a disk -- designator but not the backslash after the colon, it is interpreted as -- a relative path to the current directory on the drive with the -- specified letter." The current behavior of </> is to -- never combine these forms. -- --
--   Windows: "D:\\foo" </> "C:bar" == "C:bar"
--   Windows: "C:\\foo" </> "C:bar" == "C:bar"
--   
() :: FilePath -> FilePath -> FilePath infixr 5 -- | Contract a filename, based on a relative path. Note that the resulting -- path will never introduce .. paths, as the presence of -- symlinks means ../b may not reach a/b if it starts -- from a/c. For a worked example see this blog post. -- -- The corresponding makeAbsolute function can be found in -- System.Directory. -- --
--            makeRelative "/directory" "/directory/file.ext" == "file.ext"
--            Valid x => makeRelative (takeDirectory x) x `equalFilePath` takeFileName x
--            makeRelative x x == "."
--            Valid x y => equalFilePath x y || (isRelative x && makeRelative y x == x) || equalFilePath (y </> makeRelative y x) x
--   Windows: makeRelative "C:\\Home" "c:\\home\\bob" == "bob"
--   Windows: makeRelative "C:\\Home" "c:/home/bob" == "bob"
--   Windows: makeRelative "C:\\Home" "D:\\Home\\Bob" == "D:\\Home\\Bob"
--   Windows: makeRelative "C:\\Home" "C:Home\\Bob" == "C:Home\\Bob"
--   Windows: makeRelative "/Home" "/home/bob" == "bob"
--   Windows: makeRelative "/" "//" == "//"
--   Posix:   makeRelative "/Home" "/home/bob" == "/home/bob"
--   Posix:   makeRelative "/home/" "/home/bob/foo/bar" == "bob/foo/bar"
--   Posix:   makeRelative "/fred" "bob" == "bob"
--   Posix:   makeRelative "/file/test" "/file/test/fred" == "fred"
--   Posix:   makeRelative "/file/test" "/file/test/fred/" == "fred/"
--   Posix:   makeRelative "some/path" "some/path/a/b/c" == "a/b/c"
--   
makeRelative :: FilePath -> FilePath -> FilePath -- | Remove any trailing path separators -- --
--   dropTrailingPathSeparator "file/test/" == "file/test"
--             dropTrailingPathSeparator "/" == "/"
--   Windows:  dropTrailingPathSeparator "\\" == "\\"
--   Posix:    not (hasTrailingPathSeparator (dropTrailingPathSeparator x)) || isDrive x
--   
dropTrailingPathSeparator :: FilePath -> FilePath -- | Normalise a file -- -- -- --
--   Posix:   normalise "/file/\\test////" == "/file/\\test/"
--   Posix:   normalise "/file/./test" == "/file/test"
--   Posix:   normalise "/test/file/../bob/fred/" == "/test/file/../bob/fred/"
--   Posix:   normalise "../bob/fred/" == "../bob/fred/"
--   Posix:   normalise "./bob/fred/" == "bob/fred/"
--   Windows: normalise "c:\\file/bob\\" == "C:\\file\\bob\\"
--   Windows: normalise "c:\\" == "C:\\"
--   Windows: normalise "C:.\\" == "C:"
--   Windows: normalise "\\\\server\\test" == "\\\\server\\test"
--   Windows: normalise "//server/test" == "\\\\server\\test"
--   Windows: normalise "c:/file" == "C:\\file"
--   Windows: normalise "/file" == "\\file"
--   Windows: normalise "\\" == "\\"
--   Windows: normalise "/./" == "\\"
--            normalise "." == "."
--   Posix:   normalise "./" == "./"
--   Posix:   normalise "./." == "./"
--   Posix:   normalise "/./" == "/"
--   Posix:   normalise "/" == "/"
--   Posix:   normalise "bob/fred/." == "bob/fred/"
--   Posix:   normalise "//home" == "/home"
--   
normalise :: FilePath -> FilePath -- |
--   not . isRelative
--   
-- --
--   isAbsolute x == not (isRelative x)
--   
isAbsolute :: FilePath -> Bool -- | Is a path relative, or is it fixed to the root? -- --
--   Windows: isRelative "path\\test" == True
--   Windows: isRelative "c:\\test" == False
--   Windows: isRelative "c:test" == True
--   Windows: isRelative "c:\\" == False
--   Windows: isRelative "c:/" == False
--   Windows: isRelative "c:" == True
--   Windows: isRelative "\\\\foo" == False
--   Windows: isRelative "\\\\?\\foo" == False
--   Windows: isRelative "\\\\?\\UNC\\foo" == False
--   Windows: isRelative "/foo" == True
--   Windows: isRelative "\\foo" == True
--   Posix:   isRelative "test/path" == True
--   Posix:   isRelative "/test" == False
--   Posix:   isRelative "/" == False
--   
-- -- According to [1]: -- -- isRelative :: FilePath -> Bool -- | Take a FilePath and make it valid; does not change already valid -- FilePaths. -- --
--   isValid (makeValid x)
--   isValid x ==> makeValid x == x
--   makeValid "" == "_"
--   makeValid "file\0name" == "file_name"
--   Windows: makeValid "c:\\already\\/valid" == "c:\\already\\/valid"
--   Windows: makeValid "c:\\test:of_test" == "c:\\test_of_test"
--   Windows: makeValid "test*" == "test_"
--   Windows: makeValid "c:\\test\\nul" == "c:\\test\\nul_"
--   Windows: makeValid "c:\\test\\prn.txt" == "c:\\test\\prn_.txt"
--   Windows: makeValid "c:\\test/prn.txt" == "c:\\test/prn_.txt"
--   Windows: makeValid "c:\\nul\\file" == "c:\\nul_\\file"
--   Windows: makeValid "\\\\\\foo" == "\\\\drive"
--   Windows: makeValid "\\\\?\\D:file" == "\\\\?\\D:\\file"
--   Windows: makeValid "nul .txt" == "nul _.txt"
--   
makeValid :: FilePath -> FilePath -- | Is a FilePath valid, i.e. could you create a file like it? This -- function checks for invalid names, and invalid characters, but does -- not check if length limits are exceeded, as these are typically -- filesystem dependent. -- --
--            isValid "" == False
--            isValid "\0" == False
--   Posix:   isValid "/random_ path:*" == True
--   Posix:   isValid x == not (null x)
--   Windows: isValid "c:\\test" == True
--   Windows: isValid "c:\\test:of_test" == False
--   Windows: isValid "test*" == False
--   Windows: isValid "c:\\test\\nul" == False
--   Windows: isValid "c:\\test\\prn.txt" == False
--   Windows: isValid "c:\\nul\\file" == False
--   Windows: isValid "\\\\" == False
--   Windows: isValid "\\\\\\foo" == False
--   Windows: isValid "\\\\?\\D:file" == False
--   Windows: isValid "foo\tbar" == False
--   Windows: isValid "nul .txt" == False
--   Windows: isValid " nul.txt" == True
--   
isValid :: FilePath -> Bool -- | Equality of two FilePaths. If you call -- System.Directory.canonicalizePath first this has a much -- better chance of working. Note that this doesn't follow symlinks or -- DOSNAM~1s. -- --
--            x == y ==> equalFilePath x y
--            normalise x == normalise y ==> equalFilePath x y
--            equalFilePath "foo" "foo/"
--            not (equalFilePath "foo" "/foo")
--   Posix:   not (equalFilePath "foo" "FOO")
--   Windows: equalFilePath "foo" "FOO"
--   Windows: not (equalFilePath "C:" "C:/")
--   
equalFilePath :: FilePath -> FilePath -> Bool -- | Join path elements back together. -- --
--   joinPath ["/","directory/","file.ext"] == "/directory/file.ext"
--   Valid x => joinPath (splitPath x) == x
--   joinPath [] == ""
--   Posix: joinPath ["test","file","path"] == "test/file/path"
--   
joinPath :: [FilePath] -> FilePath -- | Just as splitPath, but don't add the trailing slashes to each -- element. -- --
--            splitDirectories "/directory/file.ext" == ["/","directory","file.ext"]
--            splitDirectories "test/file" == ["test","file"]
--            splitDirectories "/test/file" == ["/","test","file"]
--   Windows: splitDirectories "C:\\test\\file" == ["C:\\", "test", "file"]
--            Valid x => joinPath (splitDirectories x) `equalFilePath` x
--            splitDirectories "" == []
--   Windows: splitDirectories "C:\\test\\\\\\file" == ["C:\\", "test", "file"]
--            splitDirectories "/test///file" == ["/","test","file"]
--   
splitDirectories :: FilePath -> [FilePath] -- | Split a path by the directory separator. -- --
--   splitPath "/directory/file.ext" == ["/","directory/","file.ext"]
--   concat (splitPath x) == x
--   splitPath "test//item/" == ["test//","item/"]
--   splitPath "test/item/file" == ["test/","item/","file"]
--   splitPath "" == []
--   Windows: splitPath "c:\\test\\path" == ["c:\\","test\\","path"]
--   Posix:   splitPath "/file/test" == ["/","file/","test"]
--   
splitPath :: FilePath -> [FilePath] -- | An alias for </>. combine :: FilePath -> FilePath -> FilePath -- | Set the directory, keeping the filename the same. -- --
--   replaceDirectory "root/file.ext" "/directory/" == "/directory/file.ext"
--   Valid x => replaceDirectory x (takeDirectory x) `equalFilePath` x
--   
replaceDirectory :: FilePath -> String -> FilePath -- | Get the directory name, move up one level. -- --
--             takeDirectory "/directory/other.ext" == "/directory"
--             takeDirectory x `isPrefixOf` x || takeDirectory x == "."
--             takeDirectory "foo" == "."
--             takeDirectory "/" == "/"
--             takeDirectory "/foo" == "/"
--             takeDirectory "/foo/bar/baz" == "/foo/bar"
--             takeDirectory "/foo/bar/baz/" == "/foo/bar/baz"
--             takeDirectory "foo/bar/baz" == "foo/bar"
--   Windows:  takeDirectory "foo\\bar" == "foo"
--   Windows:  takeDirectory "foo\\bar\\\\" == "foo\\bar"
--   Windows:  takeDirectory "C:\\" == "C:\\"
--   
takeDirectory :: FilePath -> FilePath -- | Add a trailing file path separator if one is not already present. -- --
--   hasTrailingPathSeparator (addTrailingPathSeparator x)
--   hasTrailingPathSeparator x ==> addTrailingPathSeparator x == x
--   Posix:    addTrailingPathSeparator "test/rest" == "test/rest/"
--   
addTrailingPathSeparator :: FilePath -> FilePath -- | Is an item either a directory or the last character a path separator? -- --
--   hasTrailingPathSeparator "test" == False
--   hasTrailingPathSeparator "test/" == True
--   
hasTrailingPathSeparator :: FilePath -> Bool -- | Set the base name. -- --
--   replaceBaseName "/directory/other.ext" "file" == "/directory/file.ext"
--   replaceBaseName "file/test.txt" "bob" == "file/bob.txt"
--   replaceBaseName "fred" "bill" == "bill"
--   replaceBaseName "/dave/fred/bob.gz.tar" "new" == "/dave/fred/new.tar"
--   Valid x => replaceBaseName x (takeBaseName x) == x
--   
replaceBaseName :: FilePath -> String -> FilePath -- | Get the base name, without an extension or path. -- --
--   takeBaseName "/directory/file.ext" == "file"
--   takeBaseName "file/test.txt" == "test"
--   takeBaseName "dave.ext" == "dave"
--   takeBaseName "" == ""
--   takeBaseName "test" == "test"
--   takeBaseName (addTrailingPathSeparator x) == ""
--   takeBaseName "file/file.tar.gz" == "file.tar"
--   
takeBaseName :: FilePath -> String -- | Get the file name. -- --
--   takeFileName "/directory/file.ext" == "file.ext"
--   takeFileName "test/" == ""
--   takeFileName x `isSuffixOf` x
--   takeFileName x == snd (splitFileName x)
--   Valid x => takeFileName (replaceFileName x "fred") == "fred"
--   Valid x => takeFileName (x </> "fred") == "fred"
--   Valid x => isRelative (takeFileName x)
--   
takeFileName :: FilePath -> FilePath -- | Drop the filename. Unlike takeDirectory, this function will -- leave a trailing path separator on the directory. -- --
--   dropFileName "/directory/file.ext" == "/directory/"
--   dropFileName x == fst (splitFileName x)
--   
dropFileName :: FilePath -> FilePath -- | Set the filename. -- --
--   replaceFileName "/directory/other.txt" "file.ext" == "/directory/file.ext"
--   Valid x => replaceFileName x (takeFileName x) == x
--   
replaceFileName :: FilePath -> String -> FilePath -- | Split a filename into directory and file. </> is the -- inverse. The first component will often end with a trailing slash. -- --
--   splitFileName "/directory/file.ext" == ("/directory/","file.ext")
--   Valid x => uncurry (</>) (splitFileName x) == x || fst (splitFileName x) == "./"
--   Valid x => isValid (fst (splitFileName x))
--   splitFileName "file/bob.txt" == ("file/", "bob.txt")
--   splitFileName "file/" == ("file/", "")
--   splitFileName "bob" == ("./", "bob")
--   Posix:   splitFileName "/" == ("/","")
--   Windows: splitFileName "c:" == ("c:","")
--   
splitFileName :: FilePath -> (String, String) -- | Is an element a drive -- --
--   Posix:   isDrive "/" == True
--   Posix:   isDrive "/foo" == False
--   Windows: isDrive "C:\\" == True
--   Windows: isDrive "C:\\foo" == False
--            isDrive "" == False
--   
isDrive :: FilePath -> Bool -- | Does a path have a drive. -- --
--   not (hasDrive x) == null (takeDrive x)
--   Posix:   hasDrive "/foo" == True
--   Windows: hasDrive "C:\\foo" == True
--   Windows: hasDrive "C:foo" == True
--            hasDrive "foo" == False
--            hasDrive "" == False
--   
hasDrive :: FilePath -> Bool -- | Delete the drive, if it exists. -- --
--   dropDrive x == snd (splitDrive x)
--   
dropDrive :: FilePath -> FilePath -- | Get the drive from a filepath. -- --
--   takeDrive x == fst (splitDrive x)
--   
takeDrive :: FilePath -> FilePath -- | Join a drive and the rest of the path. -- --
--   Valid x => uncurry joinDrive (splitDrive x) == x
--   Windows: joinDrive "C:" "foo" == "C:foo"
--   Windows: joinDrive "C:\\" "bar" == "C:\\bar"
--   Windows: joinDrive "\\\\share" "foo" == "\\\\share\\foo"
--   Windows: joinDrive "/:" "foo" == "/:\\foo"
--   
joinDrive :: FilePath -> FilePath -> FilePath -- | Split a path into a drive and a path. On Posix, / is a Drive. -- --
--   uncurry (++) (splitDrive x) == x
--   Windows: splitDrive "file" == ("","file")
--   Windows: splitDrive "c:/file" == ("c:/","file")
--   Windows: splitDrive "c:\\file" == ("c:\\","file")
--   Windows: splitDrive "\\\\shared\\test" == ("\\\\shared\\","test")
--   Windows: splitDrive "\\\\shared" == ("\\\\shared","")
--   Windows: splitDrive "\\\\?\\UNC\\shared\\file" == ("\\\\?\\UNC\\shared\\","file")
--   Windows: splitDrive "\\\\?\\UNCshared\\file" == ("\\\\?\\","UNCshared\\file")
--   Windows: splitDrive "\\\\?\\d:\\file" == ("\\\\?\\d:\\","file")
--   Windows: splitDrive "/d" == ("","/d")
--   Posix:   splitDrive "/test" == ("/","test")
--   Posix:   splitDrive "//test" == ("//","test")
--   Posix:   splitDrive "test/file" == ("","test/file")
--   Posix:   splitDrive "file" == ("","file")
--   
splitDrive :: FilePath -> (FilePath, FilePath) -- | Replace all extensions of a file with a new extension. Note that -- replaceExtension and addExtension both work for adding -- multiple extensions, so only required when you need to drop all -- extensions first. -- --
--   replaceExtensions "file.fred.bob" "txt" == "file.txt"
--   replaceExtensions "file.fred.bob" "tar.gz" == "file.tar.gz"
--   
replaceExtensions :: FilePath -> String -> FilePath -- | Drop the given extension from a FilePath, and the "." -- preceding it. Returns Nothing if the FilePath does not have the -- given extension, or Just and the part before the extension if -- it does. -- -- This function can be more predictable than dropExtensions, -- especially if the filename might itself contain . characters. -- --
--   stripExtension "hs.o" "foo.x.hs.o" == Just "foo.x"
--   stripExtension "hi.o" "foo.x.hs.o" == Nothing
--   dropExtension x == fromJust (stripExtension (takeExtension x) x)
--   dropExtensions x == fromJust (stripExtension (takeExtensions x) x)
--   stripExtension ".c.d" "a.b.c.d"  == Just "a.b"
--   stripExtension ".c.d" "a.b..c.d" == Just "a.b."
--   stripExtension "baz"  "foo.bar"  == Nothing
--   stripExtension "bar"  "foobar"   == Nothing
--   stripExtension ""     x          == Just x
--   
stripExtension :: String -> FilePath -> Maybe FilePath -- | Does the given filename have the specified extension? -- --
--   "png" `isExtensionOf` "/directory/file.png" == True
--   ".png" `isExtensionOf` "/directory/file.png" == True
--   ".tar.gz" `isExtensionOf` "bar/foo.tar.gz" == True
--   "ar.gz" `isExtensionOf` "bar/foo.tar.gz" == False
--   "png" `isExtensionOf` "/directory/file.png.jpg" == False
--   "csv/table.csv" `isExtensionOf` "/data/csv/table.csv" == False
--   
isExtensionOf :: String -> FilePath -> Bool -- | Remove the current extension and add another, equivalent to -- replaceExtension. -- --
--   "/directory/path.txt" -<.> "ext" == "/directory/path.ext"
--   "/directory/path.txt" -<.> ".ext" == "/directory/path.ext"
--   "foo.o" -<.> "c" == "foo.c"
--   
(-<.>) :: FilePath -> String -> FilePath infixr 7 -<.> -- | Get a list of FilePaths in the $PATH variable. getSearchPath :: IO [FilePath] -- | Take a string, split it on the searchPathSeparator character. -- Blank items are ignored on Windows, and converted to . on -- Posix. On Windows path elements are stripped of quotes. -- -- Follows the recommendations in -- http://www.opengroup.org/onlinepubs/009695399/basedefs/xbd_chap08.html -- --
--   Posix:   splitSearchPath "File1:File2:File3"  == ["File1","File2","File3"]
--   Posix:   splitSearchPath "File1::File2:File3" == ["File1",".","File2","File3"]
--   Windows: splitSearchPath "File1;File2;File3"  == ["File1","File2","File3"]
--   Windows: splitSearchPath "File1;;File2;File3" == ["File1","File2","File3"]
--   Windows: splitSearchPath "File1;\"File2\";File3" == ["File1","File2","File3"]
--   
splitSearchPath :: String -> [FilePath] -- | Is the character an extension character? -- --
--   isExtSeparator a == (a == extSeparator)
--   
isExtSeparator :: Char -> Bool -- | File extension character -- --
--   extSeparator == '.'
--   
extSeparator :: Char -- | Is the character a file separator? -- --
--   isSearchPathSeparator a == (a == searchPathSeparator)
--   
isSearchPathSeparator :: Char -> Bool -- | The character that is used to separate the entries in the $PATH -- environment variable. -- --
--   Windows: searchPathSeparator == ';'
--   Posix:   searchPathSeparator == ':'
--   
searchPathSeparator :: Char -- | Rather than using (== pathSeparator), use this. Test -- if something is a path separator. -- --
--   isPathSeparator a == (a `elem` pathSeparators)
--   
isPathSeparator :: Char -> Bool -- | The list of all possible separators. -- --
--   Windows: pathSeparators == ['\\', '/']
--   Posix:   pathSeparators == ['/']
--   pathSeparator `elem` pathSeparators
--   
pathSeparators :: [Char] -- | The character that separates directories. In the case where more than -- one character is possible, pathSeparator is the 'ideal' one. -- --
--   Windows: pathSeparator == '\\'
--   Posix:   pathSeparator ==  '/'
--   isPathSeparator pathSeparator
--   
pathSeparator :: Char -- | Get all extensions. -- --
--   takeExtensions "/directory/path.ext" == ".ext"
--   takeExtensions "file.tar.gz" == ".tar.gz"
--   
takeExtensions :: FilePath -> String -- | Drop all extensions. -- --
--   dropExtensions "/directory/path.ext" == "/directory/path"
--   dropExtensions "file.tar.gz" == "file"
--   not $ hasExtension $ dropExtensions x
--   not $ any isExtSeparator $ takeFileName $ dropExtensions x
--   
dropExtensions :: FilePath -> FilePath -- | Split on all extensions. -- --
--   splitExtensions "/directory/path.ext" == ("/directory/path",".ext")
--   splitExtensions "file.tar.gz" == ("file",".tar.gz")
--   uncurry (++) (splitExtensions x) == x
--   Valid x => uncurry addExtension (splitExtensions x) == x
--   splitExtensions "file.tar.gz" == ("file",".tar.gz")
--   
splitExtensions :: FilePath -> (FilePath, String) -- | Does the given filename have an extension? -- --
--   hasExtension "/directory/path.ext" == True
--   hasExtension "/directory/path" == False
--   null (takeExtension x) == not (hasExtension x)
--   
hasExtension :: FilePath -> Bool -- | Add an extension, even if there is already one there, equivalent to -- <.>. -- --
--   addExtension "/directory/path" "ext" == "/directory/path.ext"
--   addExtension "file.txt" "bib" == "file.txt.bib"
--   addExtension "file." ".bib" == "file..bib"
--   addExtension "file" ".bib" == "file.bib"
--   addExtension "/" "x" == "/.x"
--   addExtension x "" == x
--   Valid x => takeFileName (addExtension (addTrailingPathSeparator x) "ext") == ".ext"
--   Windows: addExtension "\\\\share" ".txt" == "\\\\share\\.txt"
--   
addExtension :: FilePath -> String -> FilePath -- | Remove last extension, and the "." preceding it. -- --
--   dropExtension "/directory/path.ext" == "/directory/path"
--   dropExtension x == fst (splitExtension x)
--   
dropExtension :: FilePath -> FilePath -- | Add an extension, even if there is already one there, equivalent to -- addExtension. -- --
--   "/directory/path" <.> "ext" == "/directory/path.ext"
--   "/directory/path" <.> ".ext" == "/directory/path.ext"
--   
(<.>) :: FilePath -> String -> FilePath infixr 7 <.> -- | Set the extension of a file, overwriting one if already present, -- equivalent to -<.>. -- --
--   replaceExtension "/directory/path.txt" "ext" == "/directory/path.ext"
--   replaceExtension "/directory/path.txt" ".ext" == "/directory/path.ext"
--   replaceExtension "file.txt" ".bob" == "file.bob"
--   replaceExtension "file.txt" "bob" == "file.bob"
--   replaceExtension "file" ".bob" == "file.bob"
--   replaceExtension "file.txt" "" == "file"
--   replaceExtension "file.fred.bob" "txt" == "file.fred.txt"
--   replaceExtension x y == addExtension (dropExtension x) y
--   
replaceExtension :: FilePath -> String -> FilePath -- | Get the extension of a file, returns "" for no extension, -- .ext otherwise. -- --
--   takeExtension "/directory/path.ext" == ".ext"
--   takeExtension x == snd (splitExtension x)
--   Valid x => takeExtension (addExtension x "ext") == ".ext"
--   Valid x => takeExtension (replaceExtension x "ext") == ".ext"
--   
takeExtension :: FilePath -> String -- | Split on the extension. addExtension is the inverse. -- --
--   splitExtension "/directory/path.ext" == ("/directory/path",".ext")
--   uncurry (++) (splitExtension x) == x
--   Valid x => uncurry addExtension (splitExtension x) == x
--   splitExtension "file.txt" == ("file",".txt")
--   splitExtension "file" == ("file","")
--   splitExtension "file/file.txt" == ("file/file",".txt")
--   splitExtension "file.txt/boris" == ("file.txt/boris","")
--   splitExtension "file.txt/boris.ext" == ("file.txt/boris",".ext")
--   splitExtension "file/path.txt.bob.fred" == ("file/path.txt.bob",".fred")
--   splitExtension "file/path.txt/" == ("file/path.txt/","")
--   
splitExtension :: FilePath -> (String, String) -- | Drop the first directory from a FilePath. Should only be used -- on relative paths. -- --
--   dropDirectory1 "aaa/bbb" == "bbb"
--   dropDirectory1 "aaa/" == ""
--   dropDirectory1 "aaa" == ""
--   dropDirectory1 "" == ""
--   
dropDirectory1 :: FilePath -> FilePath -- | Take the first component of a FilePath. Should only be used on -- relative paths. -- --
--   takeDirectory1 "aaa/bbb" == "aaa"
--   takeDirectory1 "aaa/" == "aaa"
--   takeDirectory1 "aaa" == "aaa"
--   
takeDirectory1 :: FilePath -> FilePath -- | Replace the first component of a FilePath. Should only be used -- on relative paths. -- --
--   replaceDirectory1 "root/file.ext" "directory" == "directory/file.ext"
--   replaceDirectory1 "root/foo/bar/file.ext" "directory" == "directory/foo/bar/file.ext"
--   
replaceDirectory1 :: FilePath -> String -> FilePath -- | Make a path relative. Returns Nothing only when the given paths are on -- different drives. This will try the pure function makeRelative first. -- If that fails, the paths are canonicalised (removing any indirection -- and symlinks) and a relative path is derived from there. -- --
--   > -- Given that "/root/a/" is not a symlink
--   > makeRelativeEx "/root/a/" "/root/b/file.out"
--   Just "../b/file.out"
--   
--   > -- Given that "/root/c/" is a symlink to "/root/e/f/g/"
--   > makeRelativeEx "/root/c/" "/root/b/file.out"
--   Just "../../../b/file.out"
--   
--   > -- On Windows
--   > makeRelativeEx "C:\\foo" "D:\\foo\\bar"
--   Nothing
--   
makeRelativeEx :: FilePath -> FilePath -> IO (Maybe FilePath) -- | Normalise a FilePath, applying the rules: -- -- -- -- This function is not based on the normalise function from the -- filepath library, as that function is quite broken. normaliseEx :: FilePath -> FilePath -- | Convert to native path separators, namely \ on Windows. toNative :: FilePath -> FilePath -- | Convert all path separators to /, even on Windows. toStandard :: FilePath -> FilePath -- | The extension of executables, "exe" on Windows and -- "" otherwise. exe :: String -- | This module is used for defining new types of rules for Shake build -- systems, e.g. to support values stored in a database. Most users will -- find the built-in set of rules sufficient. The functions in this -- module are designed for high-performance, not ease of use or -- abstraction. As a result, they are difficult to work with and change -- more often than the other parts of Shake. Before writing a builtin -- rule you are encouraged to use addOracle or -- addOracleCache if possible. With all those warnings out the -- way, read on for the grungy details. module Development.Shake.Rule -- | Define a builtin rule, passing the functions to run in the right -- circumstances. The key and value types will be what -- is used by apply. As a start, you can use noLint and -- noIdentity as the first two functions, but are required to -- supply a suitable BuiltinRun. -- -- Raises an error if any other rule exists at this type. addBuiltinRule :: (RuleResult key ~ value, ShakeValue key, Typeable value, NFData value, Show value, Partial) => BuiltinLint key value -> BuiltinIdentity key value -> BuiltinRun key value -> Rules () -- | The action performed by --lint for a given -- key/value pair. At the end of the build the lint -- action will be called for each key that was built this run, -- passing the value it produced. Return Nothing to -- indicate the value has not changed and is acceptable, or Just -- an error message to indicate failure. -- -- For builtin rules where the value is expected to change, or has no -- useful checks to perform. use noLint. type BuiltinLint key value = key -> value -> IO (Maybe String) -- | A suitable BuiltinLint that always succeeds. noLint :: BuiltinLint key value -- | Produce an identity for a value that can be used to do direct -- equality. If you have a custom notion of equality then the result -- should return only one member from each equivalence class, as values -- will be compared for literal equality. The result of the identity -- should be reasonably short (if it is excessively long, hash it). -- -- For rules where the value is never compatible use noIdentity, -- which returns Nothing. This will disable shared caches of -- anything that depends on it. type BuiltinIdentity key value = key -> value -> Maybe ByteString -- | A suitable BuiltinIdentity that always fails with a runtime -- error, incompatible with shakeShare. Use this function if you -- don't care about shakeShare, or if your rule provides a -- dependency that can never be cached (in which case you should also -- call historyDisable). noIdentity :: BuiltinIdentity key value -- | Define a rule between key and value. As an example, -- a typical BuiltinRun will look like: -- --
--   run key oldStore mode = do
--       ...
--       pure $ RunResult change newStore newValue
--   
-- -- Where you have: -- -- type BuiltinRun key value = key -> Maybe ByteString -> RunMode -> Action (RunResult value) -- | What mode a rule is running in, passed as an argument to -- BuiltinRun. data RunMode -- | My dependencies have not changed. RunDependenciesSame :: RunMode -- | At least one of my dependencies from last time have changed, or I have -- no recorded dependencies. RunDependenciesChanged :: RunMode -- | How the output of a rule has changed. data RunChanged -- | Nothing has changed. ChangedNothing :: RunChanged -- | The stored value has changed, but in a way that should be considered -- identical (used rarely). ChangedStore :: RunChanged -- | I recomputed the value and it was the same. ChangedRecomputeSame :: RunChanged -- | I recomputed the value and it was different. ChangedRecomputeDiff :: RunChanged -- | The result of BuiltinRun. data RunResult value RunResult :: RunChanged -> ByteString -> value -> RunResult value -- | How has the RunResult changed from what happened last time. [runChanged] :: RunResult value -> RunChanged -- | The value to store in the Shake database. [runStore] :: RunResult value -> ByteString -- | The value to return from apply. [runValue] :: RunResult value -> value -- | Execute a rule, returning the associated values. If possible, the -- rules will be run in parallel. This function requires that appropriate -- rules have been added with addBuiltinRule. All key -- values passed to apply become dependencies of the -- Action. apply :: (Partial, RuleResult key ~ value, ShakeValue key, Typeable value) => [key] -> Action [value] -- | Apply a single rule, equivalent to calling apply with a -- singleton list. Where possible, use apply to allow parallelism. apply1 :: (Partial, RuleResult key ~ value, ShakeValue key, Typeable value) => key -> Action value -- | Add a user rule. In general these should be specialised to the type -- expected by a builtin rule. The user rules can be retrieved by -- getUserRuleList. addUserRule :: Typeable a => a -> Rules () -- | Get the user rules that were added at a particular type which return -- Just on a given function. Return all equally applicable rules, -- paired with the version of the rule (set by versioned). Where -- rules are specified with alternatives or priority the -- less-applicable rules will not be returned. -- -- If you can only deal with zero/one results, call -- getUserRuleMaybe or getUserRuleOne, which raise -- informative errors. getUserRuleList :: Typeable a => (a -> Maybe b) -> Action [(Int, b)] -- | A version of getUserRuleList that fails if there is more than -- one result Requires a key for better error messages. getUserRuleMaybe :: (ShakeValue key, Typeable a) => key -> (a -> Maybe String) -> (a -> Maybe b) -> Action (Maybe (Int, b)) -- | A version of getUserRuleList that fails if there is not exactly -- one result Requires a key for better error messages. getUserRuleOne :: (ShakeValue key, Typeable a) => key -> (a -> Maybe String) -> (a -> Maybe b) -> Action (Int, b) -- | Track that a key has been used/read by the action preceding it when -- shakeLint is active. lintTrackRead :: ShakeValue key => [key] -> Action () -- | Track that a key has been changed/written by the action preceding it -- when shakeLint is active. lintTrackWrite :: ShakeValue key => [key] -> Action () -- | Allow any matching key recorded with lintTrackRead or -- lintTrackWrite in this action, after this call, to violate the -- tracking rules. lintTrackAllow :: ShakeValue key => (key -> Bool) -> Action () -- | Is the history enabled, returns True if you have a -- shakeShare or shakeCloud, and haven't called -- historyDisable so far in this rule. historyIsEnabled :: Action Bool -- | Save a value to the history. Record the version of any user rule (or -- 0), and a payload. Must be run at the end of the rule, after -- any dependencies have been captured. If history is enabled, stores the -- information in a cache. -- -- This function relies on produces to have been called -- correctly to describe which files were written during the execution of -- this rule. historySave :: Int -> ByteString -> Action () -- | Load a value from the history. Given a version from any user rule (or -- 0), return the payload that was stored by historySave. -- -- If this function returns Just it will also have restored any -- files that were saved by historySave. historyLoad :: Int -> Action (Maybe ByteString) -- | This module provides functions for calling command line programs, -- primarily command and cmd. As a simple example: -- --
--   command [] "gcc" ["-c",myfile]
--   
-- -- The functions from this module are now available directly from -- Development.Shake. You should only need to import this module -- if you are using the cmd function in the IO monad. module Development.Shake.Command -- | Execute a system command. Before running command make sure you -- need any files that are used by the command. -- -- This function takes a list of options (often just [], see -- CmdOption for the available options), the name of the -- executable (either a full name, or a program on the $PATH) -- and a list of arguments. The result is often (), but can be a -- tuple containg any of Stdout, Stderr and Exit. -- Some examples: -- --
--   command_ [] "gcc" ["-c","myfile.c"]                          -- compile a file, throwing an exception on failure
--   Exit c <- command [] "gcc" ["-c",myfile]                     -- run a command, recording the exit code
--   (Exit c, Stderr err) <- command [] "gcc" ["-c","myfile.c"]   -- run a command, recording the exit code and error output
--   Stdout out <- command [] "gcc" ["-MM","myfile.c"]            -- run a command, recording the output
--   command_ [Cwd "generated"] "gcc" ["-c",myfile]               -- run a command in a directory
--   
-- -- Unless you retrieve the ExitCode using Exit, any -- ExitFailure will throw an error, including the Stderr in -- the exception message. If you capture the Stdout or -- Stderr, that stream will not be echoed to the console, unless -- you use the option EchoStdout or EchoStderr. -- -- If you use command inside a do block and do not use -- the result, you may get a compile-time error about being unable to -- deduce CmdResult. To avoid this error, use command_. -- -- By default the stderr stream will be captured for use in -- error messages, and also echoed. To only echo pass -- WithStderr False, which causes no streams to be -- captured by Shake, and certain programs (e.g. gcc) to detect -- they are running in a terminal. command :: (Partial, CmdResult r) => [CmdOption] -> String -> [String] -> Action r -- | A version of command where you do not require any results, used -- to avoid errors about being unable to deduce CmdResult. command_ :: Partial => [CmdOption] -> String -> [String] -> Action () -- | Build or execute a system command. Before using cmd to run a -- command, make sure you need any files that are used by the -- command. -- -- -- -- Typically only string literals should be passed as String -- arguments. When using variables prefer [myvar] so that if -- myvar contains spaces they are properly escaped. -- -- As some examples, here are some calls, and the resulting command -- string: -- --
--   cmd_ "git log --pretty=" "oneline"           -- git log --pretty= oneline
--   cmd_ "git log --pretty=" ["oneline"]         -- git log --pretty= oneline
--   cmd_ "git log" ("--pretty=" ++ "oneline")    -- git log --pretty=oneline
--   cmd_ "git log" ("--pretty=" ++ "one line")   -- git log --pretty=one line
--   cmd_ "git log" ["--pretty=" ++ "one line"]   -- git log "--pretty=one line"
--   
-- -- More examples, including return values, see this translation of the -- examples given for the command function: -- --
--   cmd_ "gcc -c myfile.c"                                       -- compile a file, throwing an exception on failure
--   Exit c <- cmd "gcc -c" [myfile]                              -- run a command, recording the exit code
--   (Exit c, Stderr err) <- cmd "gcc -c myfile.c"                -- run a command, recording the exit code and error output
--   Stdout out <- cmd "gcc -MM myfile.c"                         -- run a command, recording the output
--   cmd (Cwd "generated") "gcc -c" [myfile] :: Action ()         -- run a command in a directory
--   
--   let gccCommand = cmd "gcc -c" :: CmdArgument                 -- build a sub-command. cmd can return CmdArgument values as well as execute commands
--   cmd (Cwd "generated") gccCommand [myfile]                 -- splice that command into a greater command
--   
-- -- If you use cmd inside a do block and do not use the -- result, you may get a compile-time error about being unable to deduce -- CmdResult. To avoid this error, use cmd_. If you enable -- OverloadedStrings or OverloadedLists you may have to -- give type signatures to the arguments, or use the more constrained -- command instead. -- -- The cmd function can also be run in the IO monad, but -- then Traced is ignored and command lines are not echoed. As an -- example: -- --
--   cmd (Cwd "generated") Shell "gcc -c myfile.c" :: IO ()
--   
cmd :: (Partial, CmdArguments args) => args :-> Action r -- | See cmd. Same as cmd except with a unit result. -- cmd is to cmd_ as command is to command_. cmd_ :: (Partial, CmdArguments args, Unit args) => args :-> Action () -- | The identity function which requires the inner argument to be -- (). Useful for functions with overloaded return types. -- --
--   \(x :: Maybe ()) -> unit x == x
--   
unit :: () => m () -> m () -- | The arguments to cmd - see cmd for examples and -- semantics. newtype CmdArgument CmdArgument :: [Either CmdOption String] -> CmdArgument -- | The arguments to cmd - see cmd for examples and -- semantics. class CmdArguments t -- | Arguments to cmd cmdArguments :: (CmdArguments t, Partial) => CmdArgument -> t -- | Class to convert an a to a CmdArgument class IsCmdArgument a -- | Conversion to a CmdArgument toCmdArgument :: IsCmdArgument a => a -> CmdArgument -- | A type annotation, equivalent to the first argument, but in variable -- argument contexts, gives a clue as to what return type is expected -- (not actually enforced). type a :-> t = a -- | Collect the stdout of the process. If used, the -- stdout will not be echoed to the terminal, unless you include -- EchoStdout. The value type may be either String, or -- either lazy or strict ByteString. -- -- Note that most programs end their output with a trailing newline, so -- calling ghc --numeric-version will result in Stdout of -- "6.8.3\n". If you want to automatically trim the resulting -- string, see StdoutTrim. newtype Stdout a Stdout :: a -> Stdout a [fromStdout] :: Stdout a -> a -- | Like Stdout but remove all leading and trailing whitespaces. newtype StdoutTrim a StdoutTrim :: a -> StdoutTrim a [fromStdoutTrim] :: StdoutTrim a -> a -- | Collect the stderr of the process. If used, the -- stderr will not be echoed to the terminal, unless you include -- EchoStderr. The value type may be either String, or -- either lazy or strict ByteString. newtype Stderr a Stderr :: a -> Stderr a [fromStderr] :: Stderr a -> a -- | Collect the stdout and stderr of the process. If -- used, the stderr and stdout will not be echoed to -- the terminal, unless you include EchoStdout and -- EchoStderr. The value type may be either String, or -- either lazy or strict ByteString. newtype Stdouterr a Stdouterr :: a -> Stdouterr a [fromStdouterr] :: Stdouterr a -> a -- | Collect the ExitCode of the process. If you do not collect the -- exit code, any ExitFailure will cause an exception. newtype Exit Exit :: ExitCode -> Exit [fromExit] :: Exit -> ExitCode -- | Collect the ProcessHandle of the process. If you do collect the -- process handle, the command will run asyncronously and the call to -- cmd / command will return as soon as the process is -- spawned. Any Stdout / Stderr captures will return empty -- strings. newtype Process Process :: ProcessHandle -> Process [fromProcess] :: Process -> ProcessHandle -- | Collect the time taken to execute the process. Can be used in -- conjunction with CmdLine to write helper functions that print -- out the time of a result. -- --
--   timer :: (CmdResult r, MonadIO m) => (forall r . CmdResult r => m r) -> m r
--   timer act = do
--       (CmdTime t, CmdLine x, r) <- act
--       liftIO $ putStrLn $ "Command " ++ x ++ " took " ++ show t ++ " seconds"
--       pure r
--   
--   run :: IO ()
--   run = timer $ cmd "ghc --version"
--   
newtype CmdTime CmdTime :: Double -> CmdTime [fromCmdTime] :: CmdTime -> Double -- | Collect the command line used for the process. This command line will -- be approximate - suitable for user diagnostics, but not for direct -- execution. newtype CmdLine CmdLine :: String -> CmdLine [fromCmdLine] :: CmdLine -> String -- | The results produced by fsatrace. All files will be absolute -- paths. You can get the results for a cmd by requesting a value -- of type [FSATrace]. data FSATrace a -- | Writing to a file FSAWrite :: a -> FSATrace a -- | Reading from a file FSARead :: a -> FSATrace a -- | Deleting a file FSADelete :: a -> FSATrace a -- | Moving, arguments destination, then source FSAMove :: a -> a -> FSATrace a -- | Querying/stat on a file FSAQuery :: a -> FSATrace a -- | Touching a file FSATouch :: a -> FSATrace a -- | A class for specifying what results you want to collect from a -- process. Values are formed of Stdout, Stderr, -- Exit and tuples of those. class CmdResult a -- | The allowable String-like values that can be captured. class CmdString a -- | Options passed to command or cmd to control how -- processes are executed. data CmdOption -- | Change the current directory in the spawned process. By default uses -- this processes current directory. Successive Cwd options are -- joined together, to change into nested directories. Cwd :: FilePath -> CmdOption -- | Change the environment variables in the spawned process. By default -- uses this processes environment. Env :: [(String, String)] -> CmdOption -- | Add an environment variable in the child process. AddEnv :: String -> String -> CmdOption -- | Remove an environment variable from the child process. RemEnv :: String -> CmdOption -- | Add some items to the prefix and suffix of the $PATH -- variable. AddPath :: [String] -> [String] -> CmdOption -- | Given as the stdin of the spawned process. By default the -- stdin is inherited. Stdin :: String -> CmdOption -- | Given as the stdin of the spawned process. StdinBS :: ByteString -> CmdOption -- | Take the stdin from a file. FileStdin :: FilePath -> CmdOption -- | Pass the command to the shell without escaping - any arguments will be -- joined with spaces. By default arguments are escaped properly. Shell :: CmdOption -- | Treat the stdin/stdout/stderr messages as -- binary. By default String results use text encoding and -- ByteString results use binary encoding. BinaryPipes :: CmdOption -- | Name to use with traced, or "" for no tracing. By -- default traces using the name of the executable. Traced :: String -> CmdOption -- | Abort the computation after N seconds, will raise a failure exit code. -- Calls interruptProcessGroupOf and terminateProcess, -- but may sometimes fail to abort the process and not timeout. Timeout :: Double -> CmdOption -- | Should I include the stdout in the exception if the command -- fails? Defaults to False. WithStdout :: Bool -> CmdOption -- | Should I include the stderr in the exception if the command -- fails? Defaults to True. WithStderr :: Bool -> CmdOption -- | Should I echo the stdout? Defaults to True unless a -- Stdout result is required or you use FileStdout. EchoStdout :: Bool -> CmdOption -- | Should I echo the stderr? Defaults to True unless a -- Stderr result is required or you use FileStderr. EchoStderr :: Bool -> CmdOption -- | Should I put the stdout to a file. FileStdout :: FilePath -> CmdOption -- | Should I put the stderr to a file. FileStderr :: FilePath -> CmdOption -- | Compute dependencies automatically. Only works if -- shakeLintInside has been set to the files where autodeps -- might live. AutoDeps :: CmdOption -- | The command the user thinks about, before any munging. Defaults to the -- actual command. UserCommand :: String -> CmdOption -- | Options to fsatrace, a list of strings with characters such -- as "r" (reads) "w" (writes). Defaults to -- "rwmdqt" if the output of fsatrace is required. FSAOptions :: String -> CmdOption -- | Before starting the command in the child process, close all file -- handles except stdin, stdout, stderr in the child process. Uses -- close_fds from package process and comes with the same -- caveats, i.e. runtime is linear with the maximum number of open file -- handles (RLIMIT_NOFILE, see man 2 getrlimit on -- Linux). CloseFileHandles :: CmdOption -- | Don't run the process in its own group. Required when running -- docker. Will mean that process timeouts and asyncronous -- exceptions may not properly clean up child processes. NoProcessGroup :: CmdOption -- | Cause the stdin from the parent to be inherited. Might also require -- NoProcessGroup on Linux. Ignored if you explicitly pass a stdin. InheritStdin :: CmdOption -- | Deprecated: Use AddPath. This function will be removed -- in a future version. -- -- Add a prefix and suffix to the $PATH environment variable. -- For example: -- --
--   opt <- addPath ["/usr/special"] []
--   cmd opt "userbinary --version"
--   
-- -- Would prepend /usr/special to the current $PATH, and -- the command would pick /usr/special/userbinary, if it exists. -- To add other variables see addEnv. addPath :: MonadIO m => [String] -> [String] -> m CmdOption -- | Deprecated: Use AddEnv. This function will be removed in -- a future version. -- -- Add a single variable to the environment. For example: -- --
--   opt <- addEnv [("CFLAGS","-O2")]
--   cmd opt "gcc -c main.c"
--   
-- -- Would add the environment variable $CFLAGS with value -- -O2. If the variable $CFLAGS was already defined it -- would be overwritten. If you wish to modify $PATH see -- addPath. addEnv :: MonadIO m => [(String, String)] -> m CmdOption instance GHC.Show.Show Development.Shake.Command.CmdArgument instance GHC.Base.Monoid Development.Shake.Command.CmdArgument instance GHC.Base.Semigroup Development.Shake.Command.CmdArgument instance GHC.Classes.Eq Development.Shake.Command.CmdArgument instance GHC.Show.Show Development.Shake.Command.Params instance GHC.Show.Show Development.Shake.Command.Result instance GHC.Classes.Eq Development.Shake.Command.Result instance GHC.Base.Functor Development.Shake.Command.FSATrace instance Data.Data.Data a => Data.Data.Data (Development.Shake.Command.FSATrace a) instance GHC.Classes.Ord a => GHC.Classes.Ord (Development.Shake.Command.FSATrace a) instance GHC.Classes.Eq a => GHC.Classes.Eq (Development.Shake.Command.FSATrace a) instance GHC.Show.Show a => GHC.Show.Show (Development.Shake.Command.FSATrace a) instance GHC.Show.Show Development.Shake.Command.Str instance GHC.Classes.Eq Development.Shake.Command.Str instance (Development.Shake.Command.IsCmdArgument a, Development.Shake.Command.CmdArguments r) => Development.Shake.Command.CmdArguments (a -> r) instance Development.Shake.Command.IsCmdArgument () instance Development.Shake.Command.IsCmdArgument GHC.Base.String instance Development.Shake.Command.IsCmdArgument [GHC.Base.String] instance Development.Shake.Command.IsCmdArgument Development.Shake.Internal.CmdOption.CmdOption instance Development.Shake.Command.IsCmdArgument [Development.Shake.Internal.CmdOption.CmdOption] instance Development.Shake.Command.IsCmdArgument Development.Shake.Command.CmdArgument instance Development.Shake.Command.IsCmdArgument a => Development.Shake.Command.IsCmdArgument (GHC.Maybe.Maybe a) instance Development.Shake.Command.CmdResult r => Development.Shake.Command.CmdArguments (Development.Shake.Internal.Core.Types.Action r) instance Development.Shake.Command.CmdResult r => Development.Shake.Command.CmdArguments (GHC.Types.IO r) instance Development.Shake.Command.CmdArguments Development.Shake.Command.CmdArgument instance Development.Shake.Command.CmdResult Development.Shake.Command.Exit instance Development.Shake.Command.CmdResult GHC.IO.Exception.ExitCode instance Development.Shake.Command.CmdResult Development.Shake.Command.Process instance Development.Shake.Command.CmdResult System.Process.Common.ProcessHandle instance Development.Shake.Command.CmdResult Development.Shake.Command.CmdLine instance Development.Shake.Command.CmdResult Development.Shake.Command.CmdTime instance Development.Shake.Command.CmdResult [Development.Shake.Command.FSATrace GHC.IO.FilePath] instance Development.Shake.Command.CmdResult [Development.Shake.Command.FSATrace Data.ByteString.Internal.ByteString] instance Development.Shake.Command.CmdString a => Development.Shake.Command.CmdResult (Development.Shake.Command.Stdout a) instance Development.Shake.Command.CmdString a => Development.Shake.Command.CmdResult (Development.Shake.Command.StdoutTrim a) instance Development.Shake.Command.CmdString a => Development.Shake.Command.CmdResult (Development.Shake.Command.Stderr a) instance Development.Shake.Command.CmdString a => Development.Shake.Command.CmdResult (Development.Shake.Command.Stdouterr a) instance Development.Shake.Command.CmdResult () instance (Development.Shake.Command.CmdResult x1, Development.Shake.Command.CmdResult x2) => Development.Shake.Command.CmdResult (x1, x2) instance (Development.Shake.Command.CmdResult x1, Development.Shake.Command.CmdResult x2, Development.Shake.Command.CmdResult x3) => Development.Shake.Command.CmdResult (x1, x2, x3) instance (Development.Shake.Command.CmdResult x1, Development.Shake.Command.CmdResult x2, Development.Shake.Command.CmdResult x3, Development.Shake.Command.CmdResult x4) => Development.Shake.Command.CmdResult (x1, x2, x3, x4) instance (Development.Shake.Command.CmdResult x1, Development.Shake.Command.CmdResult x2, Development.Shake.Command.CmdResult x3, Development.Shake.Command.CmdResult x4, Development.Shake.Command.CmdResult x5) => Development.Shake.Command.CmdResult (x1, x2, x3, x4, x5) instance Development.Shake.Command.Unit b => Development.Shake.Command.Unit (a -> b) instance (a Data.Type.Equality.~ ()) => Development.Shake.Command.Unit (m a) instance Development.Shake.Command.CmdString () instance Development.Shake.Command.CmdString GHC.Base.String instance Development.Shake.Command.CmdString Data.ByteString.Internal.ByteString instance Development.Shake.Command.CmdString Data.ByteString.Lazy.Internal.ByteString instance Development.Shake.Command.MonadTempDir GHC.Types.IO instance Development.Shake.Command.MonadTempDir Development.Shake.Internal.Core.Types.Action instance GHC.Classes.Eq Development.Shake.Command.PID instance GHC.Show.Show Development.Shake.Command.PID -- | Lower-level primitives to drive Shake, which are wrapped into the -- shake function. Useful if you want to perform multiple Shake -- runs in a row without reloading from the database. Sometimes used in -- conjunction with shakeFiles="/dev/null". Using these -- functions you can approximate the shake experience with: -- --
--   shake opts rules = do
--       (_, after) <- shakeWithDatabase opts rules $ \db -> do
--           shakeOneShotDatabase db
--           shakeRunDatabase db []
--       shakeRunAfter opts after
--   
module Development.Shake.Database -- | The type of an open Shake database. Created with -- shakeOpenDatabase or shakeWithDatabase. Used with -- shakeRunDatabase. You may not execute simultaneous calls using -- ShakeDatabase on separate threads (it will raise an error). data ShakeDatabase -- | Given some options and rules, return a pair. The first component opens -- the database, the second cleans it up. The creation does not -- need to be run masked, because the cleanup is able to run at any -- point. Most users should prefer shakeWithDatabase which handles -- exceptions duration creation properly. shakeOpenDatabase :: ShakeOptions -> Rules () -> IO (IO ShakeDatabase, IO ()) -- | Given some options and rules, create a ShakeDatabase that can -- be used to run executions. shakeWithDatabase :: ShakeOptions -> Rules () -> (ShakeDatabase -> IO a) -> IO a -- | Declare that a just-openned database will be used to call -- shakeRunDatabase at most once. If so, an optimisation can be -- applied to retain less memory. shakeOneShotDatabase :: ShakeDatabase -> IO () -- | Given an open ShakeDatabase, run both whatever actions were -- added to the Rules, plus the list of Action given here. -- Returns the results from the explicitly passed actions along with a -- list of actions to run after the database was closed, as added with -- runAfter and removeFilesAfter. shakeRunDatabase :: ShakeDatabase -> [Action a] -> IO ([a], [IO ()]) -- | Given a ShakeDatabase, what files did the execution ensure were -- up-to-date in the previous call to shakeRunDatabase. -- Corresponds to the list of files written out to shakeLiveFiles. shakeLiveFilesDatabase :: ShakeDatabase -> IO [FilePath] -- | Given a ShakeDatabase, generate profile information to the -- given file about the latest run. See shakeReport for the types -- of file that can be generated. shakeProfileDatabase :: ShakeDatabase -> FilePath -> IO () -- | Given a ShakeDatabase, what files did the execution reach an -- error on last time. Some special considerations when using this -- function: -- -- shakeErrorsDatabase :: ShakeDatabase -> IO [(String, SomeException)] -- | Run a set of IO actions, treated as "after" actions, typically -- returned from shakeRunDatabase. The actions will be run with -- diagnostics etc as specified in the ShakeOptions. shakeRunAfter :: ShakeOptions -> [IO ()] -> IO () -- | This module is used for defining Shake build systems. As a simple -- example of a Shake build system, let us build the file -- result.tar from the files listed by result.txt: -- --
--   import Development.Shake
--   import Development.Shake.FilePath
--   
--   main = shakeArgs shakeOptions $ do
--       want ["result.tar"]
--       "*.tar" %> \out -> do
--           contents <- readFileLines $ out -<.> "txt"
--           need contents
--           cmd "tar -cf" [out] contents
--   
-- -- We start by importing the modules defining both Shake and routines for -- manipulating FilePath values. We define main to call -- shake with the default shakeOptions. As the second -- argument to shake, we provide a set of rules. There are two -- common forms of rules, want to specify target files, and -- %> to define a rule which builds a FilePattern. We -- use want to require that after the build completes the file -- result.tar should be ready. -- -- The *.tar rule describes how to build files with the -- extension .tar, including result.tar. We -- readFileLines on result.txt, after changing the -- .tar extension to .txt. We read each line into the -- variable contents -- being a list of the files that should go -- into result.tar. Next, we depend (need) all the files -- in contents. If any of these files change, the rule will be -- repeated. Finally we call the tar program. If either -- result.txt changes, or any of the files listed by -- result.txt change, then result.tar will be rebuilt. -- -- To find out more: -- -- module Development.Shake -- | 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 () -- | The default set of ShakeOptions. shakeOptions :: ShakeOptions -- | Define a set of rules. Rules can be created with calls to functions -- such as %> or action. Rules are combined with either -- the Monoid instance, or (more commonly) the Monad -- instance and do notation. To define your own custom types of -- rule, see Development.Shake.Rule. data Rules a -- | Run an action, usually used for specifying top-level requirements. -- --
--   main = shake shakeOptions $ do
--      action $ do
--          b <- doesFileExist "file.src"
--          when b $ need ["file.out"]
--   
-- -- This action builds file.out, but only if -- file.src exists. The action will be run in every build -- execution (unless withoutActions is used), so only cheap -- operations should be performed. On the flip side, consulting system -- information (e.g. environment variables) can be done directly as the -- information will not be cached. All calls to action may be run -- in parallel, in any order. -- -- For the standard requirement of only needing a fixed list of -- files in the action, see want. action :: Partial => Action a -> Rules () -- | Remove all actions specified in a set of rules, usually used for -- implementing command line specification of what to build. withoutActions :: Rules a -> Rules a -- | Change the matching behaviour of rules so rules do not have to be -- disjoint, but are instead matched in order. Only recommended for small -- blocks containing a handful of rules. -- --
--   alternatives $ do
--       "hello.*" %> \out -> writeFile' out "hello.*"
--       "*.txt" %> \out -> writeFile' out "*.txt"
--   
-- -- In this example hello.txt will match the first rule, instead -- of raising an error about ambiguity. Inside alternatives the -- priority of each rule is not used to determine which rule -- matches, but the resulting match uses that priority compared to the -- rules outside the alternatives block. alternatives :: Rules a -> Rules a -- | Change the priority of a given set of rules, where higher values take -- precedence. All matching rules at a given priority must be disjoint, -- or an error is raised. All builtin Shake rules have priority between 0 -- and 1. Excessive use of priority is discouraged. As an example: -- --
--   priority 4 $ "hello.*" %> \out -> writeFile' out "hello.*"
--   priority 8 $ "*.txt" %> \out -> writeFile' out "*.txt"
--   
-- -- In this example hello.txt will match the second rule, instead -- of raising an error about ambiguity. -- -- The priority function obeys the invariants: -- --
--   priority p1 (priority p2 r1) === priority p1 r1
--   priority p1 (r1 >> r2) === priority p1 r1 >> priority p1 r2
--   
priority :: Double -> Rules a -> Rules a -- | Indicate that the nested rules have a given version. If you change the -- semantics of the rule then updating (or adding) a version will cause -- the rule to rebuild in some circumstances. -- --
--   versioned 1 $ "hello.*" %> \out ->
--       writeFile' out "Writes v1 now" -- previously wrote out v0
--   
-- -- You should only use versioned to track changes in the build -- source, for standard runtime dependencies you should use other -- mechanisms, e.g. addOracle. versioned :: Int -> Rules a -> Rules a -- | The Action monad, use liftIO to raise IO actions -- into it, and need to execute files. Action values are used by -- addUserRule and action. The Action monad -- tracks the dependencies of a rule. To raise an exception call -- error, MonadFail or liftIO . -- throwIO. data Action a -- | Write an action to the trace list, along with the start/end time of -- running the IO action. The cmd and command functions -- automatically call traced with the name of the executable. The -- trace list is used for profile reports (see shakeReport). -- -- By default traced prints some useful extra context about what -- Shake is building, e.g.: -- --
--   # traced message (for myobject.o)
--   
-- -- To suppress the output of traced (for example you want more -- control over the message using putInfo), use the quietly -- combinator. -- -- It is recommended that the string passed to traced is short and -- that only a small number of unique strings are used (makes profiling -- work better). The string does not need to make sense on its own, only -- in conjunction with the target it is building. traced :: String -> IO a -> Action a -- | Lift a computation from the IO monad. liftIO :: MonadIO m => IO a -> m a -- | If an exception is raised by the Action, perform some IO -- then reraise the exception. actionOnException :: Action a -> IO b -> Action a -- | After an Action, perform some IO, even if there is an -- exception. actionFinally :: Action a -> IO b -> Action a -- | Like bracket, but where the inner operation is of type -- Action. Usually used as actionBracket alloc free -- use. actionBracket :: IO a -> (a -> IO b) -> (a -> Action c) -> Action c -- | If a syncronous exception is raised by the Action, perform some -- handler. Note that there is no guarantee that the handler will run on -- shutdown (use actionFinally for that), and that -- actionCatch cannot catch exceptions thrown by -- dependencies, e.g. raised by need (to do so would allow -- untracked dependencies on failure conditions). actionCatch :: Exception e => Action a -> (e -> Action a) -> Action a -- | Retry an Action if it throws an exception, at most n -- times (where n must be positive). If you need to call this -- function, you should probably try and fix the underlying cause (but -- you also probably know that). actionRetry :: Int -> Action a -> Action a -- | Specify an action to be run after the database has been closed, if -- building completes successfully. runAfter :: IO () -> Action () -- | Error representing all expected exceptions thrown by Shake. Problems -- when executing rules will be raising using this exception type. data ShakeException ShakeException :: String -> [String] -> SomeException -> ShakeException -- | The target that was being built when the exception occurred. [shakeExceptionTarget] :: ShakeException -> String -- | A description of the call stack, one entry per line. [shakeExceptionStack] :: ShakeException -> [String] -- | The underlying exception that was raised. [shakeExceptionInner] :: ShakeException -> SomeException -- | Options to control the execution of Shake, usually specified by -- overriding fields in shakeOptions: -- --
--   shakeOptions{shakeThreads=4, shakeReport=["report.html"]}
--   
-- -- The Data instance for this type reports the -- shakeProgress and shakeOutput fields as having the -- abstract type Hidden, because Data cannot be defined for -- functions or TypeReps. data ShakeOptions ShakeOptions :: FilePath -> Int -> String -> Verbosity -> Bool -> [FilePath] -> Maybe Lint -> [FilePath] -> [FilePattern] -> [FilePattern] -> [CmdOption] -> Maybe Seconds -> [(Rebuild, FilePattern)] -> [(String, String)] -> Bool -> Bool -> Bool -> Bool -> Change -> Bool -> [FilePath] -> Bool -> Bool -> Maybe FilePath -> [String] -> Bool -> Bool -> (IO Progress -> IO ()) -> (Verbosity -> String -> IO ()) -> (String -> String -> Bool -> IO ()) -> HashMap TypeRep Dynamic -> ShakeOptions -- | Defaults to .shake. The directory used for storing Shake -- metadata files. All metadata files will be named -- shakeFiles/.shake.file-name, for some -- file-name. If the shakeFiles directory does not -- exist it will be created. If set to "/dev/null" then no -- shakeFiles are read or written (even on Windows). [shakeFiles] :: ShakeOptions -> FilePath -- | Defaults to 1. Maximum number of rules to run in parallel, -- similar to make --jobs=N. For many build systems, a -- number equal to or slightly less than the number of physical -- processors works well. Use 0 to match the detected number of -- processors (when 0, getShakeOptions will return the -- number of threads used). [shakeThreads] :: ShakeOptions -> Int -- | Defaults to "1". The version number of your build rules. -- Change the version number to force a complete rebuild, such as when -- making significant changes to the rules that require a wipe. The -- version number should be set in the source code, and not passed on the -- command line. [shakeVersion] :: ShakeOptions -> String -- | Defaults to Info. What level of messages should be printed out. [shakeVerbosity] :: ShakeOptions -> Verbosity -- | Defaults to False. Operate in staunch mode, where building -- continues even after errors, similar to make --keep-going. [shakeStaunch] :: ShakeOptions -> Bool -- | Defaults to []. Write a profiling report to a file, showing -- which rules rebuilt, why, and how much time they took. Useful for -- improving the speed of your build systems. If the file extension is -- .json it will write JSON data; if .js it will write -- Javascript; if .trace it will write trace events (load into -- about://tracing in Chrome); otherwise it will write HTML. [shakeReport] :: ShakeOptions -> [FilePath] -- | Defaults to Nothing. Perform sanity checks during building, see -- Lint for details. [shakeLint] :: ShakeOptions -> Maybe Lint -- | Directories in which the files will be tracked by the linter. [shakeLintInside] :: ShakeOptions -> [FilePath] -- | File patterns which are ignored from linter tracking, a bit like -- calling trackAllow in every rule. [shakeLintIgnore] :: ShakeOptions -> [FilePattern] -- | File patterns whose modification causes an error. Raises an error even -- if shakeLint is Nothing. [shakeLintWatch] :: ShakeOptions -> [FilePattern] -- | Defaults to []. Additional options to be passed to all -- command invocations. [shakeCommandOptions] :: ShakeOptions -> [CmdOption] -- | Defaults to Just 10. How often to flush Shake metadata -- files in seconds, or Nothing to never flush explicitly. It is -- possible that on abnormal termination (not Haskell exceptions) any -- rules that completed in the last shakeFlush seconds will be -- lost. [shakeFlush] :: ShakeOptions -> Maybe Seconds -- | What to rebuild [shakeRebuild] :: ShakeOptions -> [(Rebuild, FilePattern)] -- | Defaults to []. A list of substrings that should be -- abbreviated in status messages, and their corresponding abbreviation. -- Commonly used to replace the long paths (e.g. -- .make/i586-linux-gcc/output) with an abbreviation (e.g. -- $OUT). [shakeAbbreviations] :: ShakeOptions -> [(String, String)] -- | Defaults to False. Write a message to -- shakeFiles/.shake.storage.log whenever a storage event -- happens which may impact on the current stored progress. Examples -- include database version number changes, database compaction or -- corrupt files. [shakeStorageLog] :: ShakeOptions -> Bool -- | Defaults to True. Change stdout and stderr to -- line buffering while running Shake. [shakeLineBuffering] :: ShakeOptions -> Bool -- | Defaults to False. Print timing information for each stage at -- the end. [shakeTimings] :: ShakeOptions -> Bool -- | Default to True. Should you run command line actions, set to -- False to skip actions whose output streams and exit code are -- not used. Useful for profiling the non-command portion of the build -- system. [shakeRunCommands] :: ShakeOptions -> Bool -- | Default to ChangeModtime. How to check if a file has changed, -- see Change for details. [shakeChange] :: ShakeOptions -> Change -- | Default to True. After running a rule to create a file, is it -- an error if the file does not exist. Provided for compatibility with -- make and ninja (which have ugly file creation -- semantics). [shakeCreationCheck] :: ShakeOptions -> Bool -- | Default to []. After the build system completes, write a list -- of all files which were live in that run, i.e. those which -- Shake checked were valid or rebuilt. Produces best answers if nothing -- rebuilds. [shakeLiveFiles] :: ShakeOptions -> [FilePath] -- | Defaults to False. Ignore any differences in -- shakeVersion. [shakeVersionIgnore] :: ShakeOptions -> Bool -- | Defaults to False. Whether to colorize the output. [shakeColor] :: ShakeOptions -> Bool -- | Defaults to Nothing. Whether to use and store outputs in a -- shared directory. [shakeShare] :: ShakeOptions -> Maybe FilePath -- | Defaults to []. Cloud servers to talk to forming a shared -- cache. [shakeCloud] :: ShakeOptions -> [String] -- | Defaults to False. Use symlinks for shakeShare if they -- are available. If this setting is True (even if symlinks are -- not available) then files will be made read-only to avoid -- inadvertantly poisoning the shared cache. Note the links are actually -- hard links, not symlinks. [shakeSymlink] :: ShakeOptions -> Bool -- | Defaults to False. Is depending on a directory an error -- (default), or it is permitted with undefined results. Provided for -- compatibility with ninja. [shakeNeedDirectory] :: ShakeOptions -> Bool -- | Defaults to no action. A function called when the build starts, -- allowing progress to be reported. The function is called on a separate -- thread, and that thread is killed when the build completes. For -- applications that want to display progress messages, -- progressSimple is often sufficient, but more advanced users -- should look at the Progress data type. [shakeProgress] :: ShakeOptions -> IO Progress -> IO () -- | Defaults to writing using putStrLn. A function called to output -- messages from Shake, along with the Verbosity at which that -- message should be printed. This function will be called atomically -- from all other shakeOutput functions. The Verbosity will -- always be greater than or higher than shakeVerbosity. [shakeOutput] :: ShakeOptions -> Verbosity -> String -> IO () -- | Defaults to doing nothing. Called for each call of traced, with -- the key, the command and True for starting, False for -- stopping. [shakeTrace] :: ShakeOptions -> String -> String -> Bool -> IO () -- | This a map which can be used to store arbitrary extra information that -- a user may need when writing rules. The key of each entry must be the -- dynTypeRep of the value. Insert values using -- addShakeExtra and retrieve them using getShakeExtra. -- The correct way to use this field is to define a hidden newtype for -- the key, so that conflicts cannot occur. [shakeExtra] :: ShakeOptions -> HashMap TypeRep Dynamic -- | The current assumptions made by the build system, used by -- shakeRebuild. These options allow the end user to specify that -- any rules run are either to be treated as clean, or as dirty, -- regardless of what the build system thinks. -- -- These assumptions only operate on files reached by the current -- action commands. Any other files in the database are left -- unchanged. data Rebuild -- | Assume these files are dirty and require rebuilding. for benchmarking -- rebuild speed and for rebuilding if untracked dependencies have -- changed. This flag is safe, but may cause more rebuilding than -- necessary. RebuildNow :: Rebuild -- | Useful to reset the rebuild status to how it was before, equivalent to -- passing no Rebuild flags. RebuildNormal :: Rebuild -- | This assumption is unsafe, and may lead to incorrect build results -- in this run. Assume these files are clean in this run, but test -- them normally in future runs. RebuildLater :: Rebuild -- | Which lint checks to perform, used by shakeLint. data Lint -- | The most basic form of linting. Checks that the current directory does -- not change and that results do not change after they are first -- written. Any calls to needed will assert that they do not -- cause a rule to be rebuilt. LintBasic :: Lint -- | Track which files are accessed by command line programs using -- fsatrace. LintFSATrace :: Lint -- | How should you determine if a file has changed, used by -- shakeChange. The most common values are ChangeModtime -- (the default, very fast, touch causes files to rebuild) and -- ChangeModtimeAndDigestInput (slightly slower, touch -- and switching git branches does not cause input files to -- rebuild). data Change -- | Compare equality of modification timestamps, a file has changed if its -- last modified time changes. A touch will force a rebuild. -- This mode is fast and usually sufficiently accurate, so is the -- default. ChangeModtime :: Change -- | Compare equality of file contents digests, a file has changed if its -- digest changes. A touch will not force a rebuild. Use this -- mode if modification times on your file system are unreliable. ChangeDigest :: Change -- | A file is rebuilt if both its modification time and digest have -- changed. For efficiency reasons, the modification time is checked -- first, and if that has changed, the digest is checked. ChangeModtimeAndDigest :: Change -- | Use ChangeModtimeAndDigest for input/source files and -- ChangeModtime for output files. An input file is one which is a -- dependency but is not built by Shake as it has no matching rule and -- already exists on the file system. ChangeModtimeAndDigestInput :: Change -- | A file is rebuilt if either its modification time or its digest has -- changed. A touch will force a rebuild, but even if a files -- modification time is reset afterwards, changes will also cause a -- rebuild. ChangeModtimeOrDigest :: Change -- | Get the initial ShakeOptions, these will not change during the -- build process. getShakeOptions :: Action ShakeOptions -- | Get the ShakeOptions that were used. getShakeOptionsRules :: Rules ShakeOptions -- | Get a checksum of a list of files, suitable for using as -- shakeVersion. This will trigger a rebuild when the Shake rules -- defined in any of the files are changed. For example: -- --
--   main = do
--       ver <- getHashedShakeVersion ["Shakefile.hs"]
--       shakeArgs shakeOptions{shakeVersion = ver} ...
--   
-- -- To automatically detect the name of the current file, turn on the -- TemplateHaskell extension and write $(LitE . StringL . -- loc_filename <$> location). -- -- This feature can be turned off during development by passing the flag -- --no-rule-version or setting shakeVersionIgnore to -- True. getHashedShakeVersion :: [FilePath] -> IO String -- | Get an item from shakeExtra, using the requested type as the -- key. Fails if the value found at this key does not match the requested -- type. getShakeExtra :: Typeable a => Action (Maybe a) -- | A version of getShakeExtra in Rules. getShakeExtraRules :: Typeable a => Rules (Maybe a) -- | Add a properly structued value to shakeExtra which can be -- retrieved with getShakeExtra. addShakeExtra :: Typeable a => a -> HashMap TypeRep Dynamic -> HashMap TypeRep Dynamic -- | 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 wanted (after calling -- withoutActions). As an example: -- --
--   main = shakeArgs shakeOptions{shakeFiles = "_make", shakeProgress = progressSimple} $ do
--       phony "clean" $ 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: -- -- shakeArgs :: ShakeOptions -> Rules () -> IO () -- | 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)
--   
-- -- -- -- 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 () -- | Like shakeArgsWith, but also lets you manipulate the -- ShakeOptions. shakeArgsOptionsWith :: ShakeOptions -> [OptDescr (Either String a)] -> (ShakeOptions -> [a] -> [String] -> IO (Maybe (ShakeOptions, Rules ()))) -> IO () -- | 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))] -- | Adds some extra information at the end of --help. addHelpSuffix :: String -> Rules () -- | Get all targets registered in the given rules. The names in -- phony and ~> as well as the file patterns in -- %>, |%> and &%> are registered as -- targets, plus any explicit calls to addTarget. Returns the -- command, paired with the documentation (if any). getTargets :: ShakeOptions -> Rules () -> IO [(String, Maybe String)] -- | Register a target, as available when passing --help or -- through getTargets. Called automatically by rules such as -- phony and %> - to avoid that use -- withoutTargets. To add documentation to a target use -- withTargetDocs. addTarget :: String -> Rules () -- | For all addTarget targets within the Rules provide the -- specified documentation, if they don't already have documentation. withTargetDocs :: String -> Rules () -> Rules () -- | Remove all targets specified in a set of rules, typically because they -- are internal details. Overrides addTarget. withoutTargets :: Rules a -> Rules a -- | Information about the current state of the build, obtained by either -- passing a callback function to shakeProgress (asynchronous -- output) or getProgress (synchronous output). Typically a build -- system will pass progressDisplay to shakeProgress, -- which will poll this value and produce status messages. data Progress Progress :: !Maybe String -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Int -> {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> {-# UNPACK #-} !Double -> {-# UNPACK #-} !(Double, Int) -> Progress -- | Starts out Nothing, becomes Just a target name if a rule -- fails. [isFailure] :: Progress -> !Maybe String -- | Number of rules which were required, but were already in a valid -- state. [countSkipped] :: Progress -> {-# UNPACK #-} !Int -- | Number of rules which were have been built in this run. [countBuilt] :: Progress -> {-# UNPACK #-} !Int -- | Number of rules which have been built previously, but are not yet -- known to be required. [countUnknown] :: Progress -> {-# UNPACK #-} !Int -- | Number of rules which are currently required (ignoring dependencies -- that do not change), but not built. [countTodo] :: Progress -> {-# UNPACK #-} !Int -- | Time spent building countSkipped rules in previous runs. [timeSkipped] :: Progress -> {-# UNPACK #-} !Double -- | Time spent building countBuilt rules. [timeBuilt] :: Progress -> {-# UNPACK #-} !Double -- | Time spent building countUnknown rules in previous runs. [timeUnknown] :: Progress -> {-# UNPACK #-} !Double -- | Time spent building countTodo rules in previous runs, plus the -- number which have no known time (have never been built before). [timeTodo] :: Progress -> {-# UNPACK #-} !(Double, Int) -- | A simple method for displaying progress messages, suitable for using -- as shakeProgress. This function writes the current progress to -- the titlebar every five seconds using progressTitlebar, and -- calls any shake-progress program on the $PATH using -- progressProgram. progressSimple :: IO Progress -> IO () -- | Given a sampling interval (in seconds) and a way to display the status -- message, produce a function suitable for using as -- shakeProgress. This function polls the progress information -- every n seconds, produces a status message and displays it -- using the display function. -- -- Typical status messages will take the form of 1m25s (15%), -- indicating that the build is predicted to complete in 1 minute 25 -- seconds (85 seconds total), and 15% of the necessary build time has -- elapsed. This function uses past observations to predict future -- behaviour, and as such, is only guessing. The time is likely to go up -- as well as down, and will be less accurate from a clean build (as the -- system has fewer past observations). -- -- The current implementation is to predict the time remaining (based on -- timeTodo) and the work already done (timeBuilt). The -- percentage is then calculated as remaining / (done + -- remaining), while time left is calculated by scaling -- remaining by the observed work rate in this build, roughly -- done / time_elapsed. progressDisplay :: Double -> (String -> IO ()) -> IO Progress -> IO () -- | Set the title of the current console window to the given text. If the -- environment variable $TERM is set to xterm this uses -- xterm escape sequences. On Windows, if not detected as an xterm, this -- function uses the SetConsoleTitle API. progressTitlebar :: String -> IO () -- | Call the program shake-progress if it is on the -- $PATH. The program is called with the following arguments: -- -- -- -- The program will not be called consecutively with the same -- --state and --value options. -- -- Windows 7 or higher users can get taskbar progress notifications by -- placing the following program in their $PATH: -- https://github.com/ndmitchell/shake/releases. progressProgram :: IO (String -> IO ()) -- | Get the current Progress structure, as would be returned by -- shakeProgress. getProgress :: Action Progress -- | The verbosity data type, used by shakeVerbosity. data Verbosity -- | Don't print any messages. Silent :: Verbosity -- | Only print error messages. Error :: Verbosity -- | Print errors and warnings. Warn :: Verbosity -- | Print errors, warnings and # command-name (for -- file-name) when running a traced command. Info :: Verbosity -- | Print errors, warnings, full command lines when running a -- command or cmd command and status messages when starting -- a rule. Verbose :: Verbosity -- | Print messages for virtually everything (mostly for debugging). Diagnostic :: Verbosity -- | Get the current verbosity level, originally set by -- shakeVerbosity. If you want to output information to the -- console, you are recommended to use putVerbose / putInfo -- / putError, which ensures multiple messages are not -- interleaved. The verbosity can be modified locally by -- withVerbosity. getVerbosity :: Action Verbosity -- | Write an unimportant message to the output, only shown when -- shakeVerbosity is higher than normal (Verbose or above). -- The output will not be interleaved with any other Shake messages -- (other than those generated by system commands). putVerbose :: String -> Action () -- | Write a normal priority message to the output, only suppressed when -- shakeVerbosity is Error, Warn or Silent. -- The output will not be interleaved with any other Shake messages -- (other than those generated by system commands). putInfo :: String -> Action () -- | Write a semi important message to the output, only suppressed when -- shakeVerbosity is Error or Silent. The output -- will not be interleaved with any other Shake messages (other than -- those generated by system commands). putWarn :: String -> Action () -- | Write an important message to the output, only suppressed when -- shakeVerbosity is Silent. The output will not be -- interleaved with any other Shake messages (other than those generated -- by system commands). putError :: String -> Action () -- | Run an action with a particular verbosity level. Will not update the -- shakeVerbosity returned by getShakeOptions and will not -- have any impact on Diagnostic tracing. withVerbosity :: Verbosity -> Action a -> Action a -- | Run an action with Error verbosity, in particular messages -- produced by traced (including from cmd or -- command) will not be printed to the screen. Will not update the -- shakeVerbosity returned by getShakeOptions and will not -- turn off any Diagnostic tracing. quietly :: Action a -> Action a -- | Execute a system command. Before running command make sure you -- need any files that are used by the command. -- -- This function takes a list of options (often just [], see -- CmdOption for the available options), the name of the -- executable (either a full name, or a program on the $PATH) -- and a list of arguments. The result is often (), but can be a -- tuple containg any of Stdout, Stderr and Exit. -- Some examples: -- --
--   command_ [] "gcc" ["-c","myfile.c"]                          -- compile a file, throwing an exception on failure
--   Exit c <- command [] "gcc" ["-c",myfile]                     -- run a command, recording the exit code
--   (Exit c, Stderr err) <- command [] "gcc" ["-c","myfile.c"]   -- run a command, recording the exit code and error output
--   Stdout out <- command [] "gcc" ["-MM","myfile.c"]            -- run a command, recording the output
--   command_ [Cwd "generated"] "gcc" ["-c",myfile]               -- run a command in a directory
--   
-- -- Unless you retrieve the ExitCode using Exit, any -- ExitFailure will throw an error, including the Stderr in -- the exception message. If you capture the Stdout or -- Stderr, that stream will not be echoed to the console, unless -- you use the option EchoStdout or EchoStderr. -- -- If you use command inside a do block and do not use -- the result, you may get a compile-time error about being unable to -- deduce CmdResult. To avoid this error, use command_. -- -- By default the stderr stream will be captured for use in -- error messages, and also echoed. To only echo pass -- WithStderr False, which causes no streams to be -- captured by Shake, and certain programs (e.g. gcc) to detect -- they are running in a terminal. command :: (Partial, CmdResult r) => [CmdOption] -> String -> [String] -> Action r -- | A version of command where you do not require any results, used -- to avoid errors about being unable to deduce CmdResult. command_ :: Partial => [CmdOption] -> String -> [String] -> Action () -- | Build or execute a system command. Before using cmd to run a -- command, make sure you need any files that are used by the -- command. -- -- -- -- Typically only string literals should be passed as String -- arguments. When using variables prefer [myvar] so that if -- myvar contains spaces they are properly escaped. -- -- As some examples, here are some calls, and the resulting command -- string: -- --
--   cmd_ "git log --pretty=" "oneline"           -- git log --pretty= oneline
--   cmd_ "git log --pretty=" ["oneline"]         -- git log --pretty= oneline
--   cmd_ "git log" ("--pretty=" ++ "oneline")    -- git log --pretty=oneline
--   cmd_ "git log" ("--pretty=" ++ "one line")   -- git log --pretty=one line
--   cmd_ "git log" ["--pretty=" ++ "one line"]   -- git log "--pretty=one line"
--   
-- -- More examples, including return values, see this translation of the -- examples given for the command function: -- --
--   cmd_ "gcc -c myfile.c"                                       -- compile a file, throwing an exception on failure
--   Exit c <- cmd "gcc -c" [myfile]                              -- run a command, recording the exit code
--   (Exit c, Stderr err) <- cmd "gcc -c myfile.c"                -- run a command, recording the exit code and error output
--   Stdout out <- cmd "gcc -MM myfile.c"                         -- run a command, recording the output
--   cmd (Cwd "generated") "gcc -c" [myfile] :: Action ()         -- run a command in a directory
--   
--   let gccCommand = cmd "gcc -c" :: CmdArgument                 -- build a sub-command. cmd can return CmdArgument values as well as execute commands
--   cmd (Cwd "generated") gccCommand [myfile]                 -- splice that command into a greater command
--   
-- -- If you use cmd inside a do block and do not use the -- result, you may get a compile-time error about being unable to deduce -- CmdResult. To avoid this error, use cmd_. If you enable -- OverloadedStrings or OverloadedLists you may have to -- give type signatures to the arguments, or use the more constrained -- command instead. -- -- The cmd function can also be run in the IO monad, but -- then Traced is ignored and command lines are not echoed. As an -- example: -- --
--   cmd (Cwd "generated") Shell "gcc -c myfile.c" :: IO ()
--   
cmd :: (Partial, CmdArguments args) => args :-> Action r -- | See cmd. Same as cmd except with a unit result. -- cmd is to cmd_ as command is to command_. cmd_ :: (Partial, CmdArguments args, Unit args) => args :-> Action () -- | The identity function which requires the inner argument to be -- (). Useful for functions with overloaded return types. -- --
--   \(x :: Maybe ()) -> unit x == x
--   
unit :: () => m () -> m () -- | Collect the stdout of the process. If used, the -- stdout will not be echoed to the terminal, unless you include -- EchoStdout. The value type may be either String, or -- either lazy or strict ByteString. -- -- Note that most programs end their output with a trailing newline, so -- calling ghc --numeric-version will result in Stdout of -- "6.8.3\n". If you want to automatically trim the resulting -- string, see StdoutTrim. newtype Stdout a Stdout :: a -> Stdout a [fromStdout] :: Stdout a -> a -- | Like Stdout but remove all leading and trailing whitespaces. newtype StdoutTrim a StdoutTrim :: a -> StdoutTrim a [fromStdoutTrim] :: StdoutTrim a -> a -- | Collect the stderr of the process. If used, the -- stderr will not be echoed to the terminal, unless you include -- EchoStderr. The value type may be either String, or -- either lazy or strict ByteString. newtype Stderr a Stderr :: a -> Stderr a [fromStderr] :: Stderr a -> a -- | Collect the stdout and stderr of the process. If -- used, the stderr and stdout will not be echoed to -- the terminal, unless you include EchoStdout and -- EchoStderr. The value type may be either String, or -- either lazy or strict ByteString. newtype Stdouterr a Stdouterr :: a -> Stdouterr a [fromStdouterr] :: Stdouterr a -> a -- | Collect the ExitCode of the process. If you do not collect the -- exit code, any ExitFailure will cause an exception. newtype Exit Exit :: ExitCode -> Exit [fromExit] :: Exit -> ExitCode -- | Collect the ProcessHandle of the process. If you do collect the -- process handle, the command will run asyncronously and the call to -- cmd / command will return as soon as the process is -- spawned. Any Stdout / Stderr captures will return empty -- strings. newtype Process Process :: ProcessHandle -> Process [fromProcess] :: Process -> ProcessHandle -- | Collect the time taken to execute the process. Can be used in -- conjunction with CmdLine to write helper functions that print -- out the time of a result. -- --
--   timer :: (CmdResult r, MonadIO m) => (forall r . CmdResult r => m r) -> m r
--   timer act = do
--       (CmdTime t, CmdLine x, r) <- act
--       liftIO $ putStrLn $ "Command " ++ x ++ " took " ++ show t ++ " seconds"
--       pure r
--   
--   run :: IO ()
--   run = timer $ cmd "ghc --version"
--   
newtype CmdTime CmdTime :: Double -> CmdTime [fromCmdTime] :: CmdTime -> Double -- | Collect the command line used for the process. This command line will -- be approximate - suitable for user diagnostics, but not for direct -- execution. newtype CmdLine CmdLine :: String -> CmdLine [fromCmdLine] :: CmdLine -> String -- | The results produced by fsatrace. All files will be absolute -- paths. You can get the results for a cmd by requesting a value -- of type [FSATrace]. data FSATrace a -- | Writing to a file FSAWrite :: a -> FSATrace a -- | Reading from a file FSARead :: a -> FSATrace a -- | Deleting a file FSADelete :: a -> FSATrace a -- | Moving, arguments destination, then source FSAMove :: a -> a -> FSATrace a -- | Querying/stat on a file FSAQuery :: a -> FSATrace a -- | Touching a file FSATouch :: a -> FSATrace a -- | A class for specifying what results you want to collect from a -- process. Values are formed of Stdout, Stderr, -- Exit and tuples of those. class CmdResult a -- | The allowable String-like values that can be captured. class CmdString a -- | Options passed to command or cmd to control how -- processes are executed. data CmdOption -- | Change the current directory in the spawned process. By default uses -- this processes current directory. Successive Cwd options are -- joined together, to change into nested directories. Cwd :: FilePath -> CmdOption -- | Change the environment variables in the spawned process. By default -- uses this processes environment. Env :: [(String, String)] -> CmdOption -- | Add an environment variable in the child process. AddEnv :: String -> String -> CmdOption -- | Remove an environment variable from the child process. RemEnv :: String -> CmdOption -- | Add some items to the prefix and suffix of the $PATH -- variable. AddPath :: [String] -> [String] -> CmdOption -- | Given as the stdin of the spawned process. By default the -- stdin is inherited. Stdin :: String -> CmdOption -- | Given as the stdin of the spawned process. StdinBS :: ByteString -> CmdOption -- | Take the stdin from a file. FileStdin :: FilePath -> CmdOption -- | Pass the command to the shell without escaping - any arguments will be -- joined with spaces. By default arguments are escaped properly. Shell :: CmdOption -- | Treat the stdin/stdout/stderr messages as -- binary. By default String results use text encoding and -- ByteString results use binary encoding. BinaryPipes :: CmdOption -- | Name to use with traced, or "" for no tracing. By -- default traces using the name of the executable. Traced :: String -> CmdOption -- | Abort the computation after N seconds, will raise a failure exit code. -- Calls interruptProcessGroupOf and terminateProcess, -- but may sometimes fail to abort the process and not timeout. Timeout :: Double -> CmdOption -- | Should I include the stdout in the exception if the command -- fails? Defaults to False. WithStdout :: Bool -> CmdOption -- | Should I include the stderr in the exception if the command -- fails? Defaults to True. WithStderr :: Bool -> CmdOption -- | Should I echo the stdout? Defaults to True unless a -- Stdout result is required or you use FileStdout. EchoStdout :: Bool -> CmdOption -- | Should I echo the stderr? Defaults to True unless a -- Stderr result is required or you use FileStderr. EchoStderr :: Bool -> CmdOption -- | Should I put the stdout to a file. FileStdout :: FilePath -> CmdOption -- | Should I put the stderr to a file. FileStderr :: FilePath -> CmdOption -- | Compute dependencies automatically. Only works if -- shakeLintInside has been set to the files where autodeps -- might live. AutoDeps :: CmdOption -- | The command the user thinks about, before any munging. Defaults to the -- actual command. UserCommand :: String -> CmdOption -- | Options to fsatrace, a list of strings with characters such -- as "r" (reads) "w" (writes). Defaults to -- "rwmdqt" if the output of fsatrace is required. FSAOptions :: String -> CmdOption -- | Before starting the command in the child process, close all file -- handles except stdin, stdout, stderr in the child process. Uses -- close_fds from package process and comes with the same -- caveats, i.e. runtime is linear with the maximum number of open file -- handles (RLIMIT_NOFILE, see man 2 getrlimit on -- Linux). CloseFileHandles :: CmdOption -- | Don't run the process in its own group. Required when running -- docker. Will mean that process timeouts and asyncronous -- exceptions may not properly clean up child processes. NoProcessGroup :: CmdOption -- | Cause the stdin from the parent to be inherited. Might also require -- NoProcessGroup on Linux. Ignored if you explicitly pass a stdin. InheritStdin :: CmdOption -- | Deprecated: Use AddPath. This function will be removed -- in a future version. -- -- Add a prefix and suffix to the $PATH environment variable. -- For example: -- --
--   opt <- addPath ["/usr/special"] []
--   cmd opt "userbinary --version"
--   
-- -- Would prepend /usr/special to the current $PATH, and -- the command would pick /usr/special/userbinary, if it exists. -- To add other variables see addEnv. addPath :: MonadIO m => [String] -> [String] -> m CmdOption -- | Deprecated: Use AddEnv. This function will be removed in -- a future version. -- -- Add a single variable to the environment. For example: -- --
--   opt <- addEnv [("CFLAGS","-O2")]
--   cmd opt "gcc -c main.c"
--   
-- -- Would add the environment variable $CFLAGS with value -- -O2. If the variable $CFLAGS was already defined it -- would be overwritten. If you wish to modify $PATH see -- addPath. addEnv :: MonadIO m => [(String, String)] -> m CmdOption -- | Execute a list of actions in parallel. In most cases need -- will be more appropriate to benefit from parallelism. parallel :: [Action a] -> Action [a] -- | A parallel version of forM. forP :: [a] -> (a -> Action b) -> Action [b] -- | Execute two operations in parallel, based on parallel. par :: Action a -> Action b -> Action (a, b) -- | copyFile' old new copies the existing file from old -- to new. The old file will be tracked as a -- dependency. Also creates the new directory if necessary. copyFile' :: Partial => FilePath -> FilePath -> Action () -- | copyFileChanged old new copies the existing file from -- old to new, if the contents have changed. The -- old file will be tracked as a dependency. Also creates the -- new directory if necessary. copyFileChanged :: Partial => FilePath -> FilePath -> Action () -- | Read a file, after calling need. The argument file will be -- tracked as a dependency. readFile' :: Partial => FilePath -> Action String -- | A version of readFile' which also splits the result into lines. -- The argument file will be tracked as a dependency. readFileLines :: Partial => FilePath -> Action [String] -- | Write a file, lifted to the Action monad. writeFile' :: (MonadIO m, Partial) => FilePath -> String -> m () -- | A version of writeFile' which writes out a list of lines. writeFileLines :: (MonadIO m, Partial) => FilePath -> [String] -> m () -- | Write a file, but only if the contents would change. writeFileChanged :: (MonadIO m, Partial) => FilePath -> String -> m () -- | Remove all files and directories that match any of the patterns within -- a directory. Some examples: -- --
--   removeFiles "output" ["//*"]        -- delete everything inside 'output'
--   removeFiles "output" ["//"]         -- delete 'output' itself
--   removeFiles "." ["//*.hi","//*.o"] -- delete all '.hi' and '.o' files
--   
-- -- If the argument directory is missing no error is raised. This function -- will follow symlinks, so should be used with care. -- -- This function is often useful when writing a clean action for -- your build system, often as a phony rule. removeFiles :: FilePath -> [FilePattern] -> IO () -- | Remove files, like removeFiles, but executed after the build -- completes successfully using runAfter. Useful for implementing -- clean actions that delete files Shake may have open for -- building, e.g. shakeFiles. Where possible, delete the files -- as a normal part of the build, e.g. using liftIO $ -- removeFiles dir pats. removeFilesAfter :: FilePath -> [FilePattern] -> Action () -- | Create a temporary file in the temporary directory. The file will be -- deleted after the action completes (provided the file is not still -- open). The FilePath will not have any file extension, will -- exist, and will be zero bytes long. If you require a file with a -- specific name, use withTempDir. withTempFile :: (FilePath -> Action a) -> Action a -- | Create a temporary directory inside the system temporary directory. -- The directory will be deleted after the action completes. As an -- example: -- --
--   withTempDir $ \mydir -> do
--      putInfo $ "Temp directory is " ++ mydir
--      writeFile' (mydir </> "test.txt") "writing out a temp file"
--   
withTempDir :: (FilePath -> Action a) -> Action a -- | Like withTempFile but using a custom temporary directory. withTempFileWithin :: FilePath -> (FilePath -> Action a) -> Action a -- | Like withTempDir but using a custom temporary directory. withTempDirWithin :: FilePath -> (FilePath -> Action a) -> Action a -- | Add a dependency on the file arguments, ensuring they are built before -- continuing. The file arguments may be built in parallel, in any order. -- This function is particularly necessary when calling cmd or -- command. As an example: -- --
--   "//*.rot13" %> \out -> do
--       let src = dropExtension out
--       need [src]
--       cmd "rot13" [src] "-o" [out]
--   
-- -- Usually need [foo,bar] is preferable to need [foo] -- >> need [bar] as the former allows greater parallelism, -- while the latter requires foo to finish building before -- starting to build bar. -- -- This function should not be called with wildcards (e.g. *.txt -- - use getDirectoryFiles to expand them), environment -- variables (e.g. $HOME - use getEnv to expand them) -- or directories (directories cannot be tracked directly - track files -- within the directory instead). need :: Partial => [FilePath] -> Action () -- | Require that the argument files are built by the rules, used to -- specify the target. -- --
--   main = shake shakeOptions $ do
--      want ["Main.exe"]
--      ...
--   
-- -- This program will build Main.exe, given sufficient rules. All -- arguments to all want calls may be built in parallel, in any -- order. -- -- This function is defined in terms of action and need, -- use action if you need more complex targets than want -- allows. want :: Partial => [FilePath] -> Rules () -- | Define a rule that matches a FilePattern, see ?== for -- the pattern rules. Patterns with no wildcards have higher priority -- than those with wildcards, and no file required by the system may be -- matched by more than one pattern at the same priority (see -- priority and alternatives to modify this behaviour). -- This function will create the directory for the result file, if -- necessary. -- --
--   "*.asm.o" %> \out -> do
--       let src = dropExtension out
--       need [src]
--       cmd "as" [src] "-o" [out]
--   
-- -- To define a build system for multiple compiled languages, we recommend -- using .asm.o, .cpp.o, .hs.o, to indicate -- which language produces an object file. I.e., the file -- foo.cpp produces object file foo.cpp.o. -- -- Note that matching is case-sensitive, even on Windows. -- -- If the Action completes successfully the file is considered -- up-to-date, even if the file has not changed. (%>) :: Located => FilePattern -> (FilePath -> Action ()) -> Rules () infix 1 %> -- | Define a set of patterns, and if any of them match, run the associated -- rule. Defined in terms of %>. Think of it as the OR -- (||) equivalent of %>. (|%>) :: Located => [FilePattern] -> (FilePath -> Action ()) -> Rules () infix 1 |%> -- | Define a rule to build files. If the first argument returns -- True for a given file, the second argument will be used to -- build it. Usually %> is sufficient, but ?> gives -- additional power. For any file used by the build system, only one rule -- should return True. This function will create the directory for -- the result file, if necessary. -- --
--   (all isUpper . takeBaseName) ?> \out -> do
--       let src = replaceBaseName out $ map toLower $ takeBaseName out
--       writeFile' out . map toUpper =<< readFile' src
--   
-- -- If the Action completes successfully the file is considered -- up-to-date, even if the file has not changed. (?>) :: Located => (FilePath -> Bool) -> (FilePath -> Action ()) -> Rules () infix 1 ?> -- | Declare a Make-style phony action. A phony target does not name a file -- (despite living in the same namespace as file rules); rather, it names -- some action to be executed when explicitly requested. You can demand -- phony rules using want. (And need, although -- that's not recommended.) -- -- Phony actions are intended to define recipes that can be executed by -- the user. If you need a phony action in a rule then every -- execution where that rule is required will rerun both the rule and the -- phony action. However, note that phony actions are never executed more -- than once in a single build run. -- -- In make, the .PHONY attribute on non-file-producing rules has -- a similar effect. However, while in make it is acceptable to omit the -- .PHONY attribute as long as you don't create the file in -- question, a Shake rule which behaves this way will fail lint. For -- file-producing rules which should be rerun every execution of Shake, -- see alwaysRerun. phony :: Located => String -> Action () -> Rules () -- | Infix operator alias for phony, for sake of consistency with -- normal rules. (~>) :: Located => String -> Action () -> Rules () infix 1 ~> -- | A predicate version of phony, return Just with the -- Action for the matching rules. phonys :: Located => (String -> Maybe (Action ())) -> Rules () -- | Define a rule for building multiple files at the same time. Think of -- it as the AND (&&) equivalent of %>. As an -- example, a single invocation of GHC produces both .hi and -- .o files: -- --
--   ["*.o","*.hi"] &%> \[o,hi] -> do
--       let hs = o -<.> "hs"
--       need ... -- all files the .hs import
--       cmd "ghc -c" [hs]
--   
-- -- However, in practice, it's usually easier to define rules with -- %> and make the .hi depend on the .o. When -- defining rules that build multiple files, all the FilePattern -- values must have the same sequence of // and * -- wildcards in the same order. This function will create directories for -- the result files, if necessary. (&%>) :: Located => [FilePattern] -> ([FilePath] -> Action ()) -> Rules () infix 1 &%> -- | Define a rule for building multiple files at the same time, a more -- powerful and more dangerous version of &%>. Think of it -- as the AND (&&) equivalent of ?>. -- -- Given an application test &?> ..., test -- should return Just if the rule applies, and should return the -- list of files that will be produced. This list must include the -- file passed as an argument and should obey the invariant: -- --
--   forAll $ \x ys -> test x == Just ys ==> x `elem` ys && all ((== Just ys) . test) ys
--   
-- -- Intuitively, the function defines a set partitioning, mapping each -- element to the partition that contains it. As an example of a function -- satisfying the invariaint: -- --
--   test x | takeExtension x `elem` [".hi",".o"]
--          = Just [dropExtension x <.> "hi", dropExtension x <.> "o"]
--   test _ = Nothing
--   
-- -- Regardless of whether Foo.hi or Foo.o is passed, the -- function always returns [Foo.hi, Foo.o]. (&?>) :: Located => (FilePath -> Maybe [FilePath]) -> ([FilePath] -> Action ()) -> Rules () infix 1 &?> -- | Define order-only dependencies, these are dependencies that will -- always be built before continuing, but which aren't dependencies of -- this action. Mostly useful for defining generated dependencies you -- think might be real dependencies. If they turn out to be real -- dependencies, you should add an explicit dependency afterwards. -- --
--   "source.o" %> \out -> do
--       orderOnly ["header.h"]
--       cmd_ "gcc -c source.c -o source.o -MMD -MF source.m"
--       neededMakefileDependencies "source.m"
--   
-- -- If header.h is included by source.c then the call to -- needMakefileDependencies will cause it to be added as a real -- dependency. If it isn't, then the rule won't rebuild if it changes. orderOnly :: [FilePath] -> Action () -- | Run an action but do not depend on anything the action uses. A more -- general version of orderOnly. orderOnlyAction :: Action a -> Action a -- | A type synonym for file patterns, containing // and -- *. For the syntax and semantics of FilePattern see -- ?==. -- -- Most normaliseExd FilePath values are suitable as -- FilePattern values which match only that specific file. On -- Windows \ is treated as equivalent to /. -- -- You can write FilePattern values as a literal string, or build -- them up using the operators <.>, </> and -- <//>. However, beware that: -- -- type FilePattern = String -- | Match a FilePattern against a FilePath, There are three -- special forms: -- -- -- -- Some examples: -- -- -- -- Patterns with constructs such as foo/../bar will never match -- normalised FilePath values, so are unlikely to be correct. (?==) :: FilePattern -> FilePath -> Bool -- | Join two FilePattern values by inserting two / -- characters between them. Will first remove any trailing path -- separators on the first argument, and any leading separators on the -- second. -- --
--   "dir" <//> "*" == "dir//*"
--   
() :: FilePattern -> FilePattern -> FilePattern infixr 5 -- | Like ?==, but returns Nothing on if there is no match, -- otherwise Just with the list of fragments matching each -- wildcard. For example: -- --
--   filePattern "**/*.c" "test.txt" == Nothing
--   filePattern "**/*.c" "foo.c" == Just ["","foo"]
--   filePattern "**/*.c" "bar/baz/foo.c" == Just ["bar/baz/","foo"]
--   
-- -- Note that the ** will often contain a trailing /, -- and even on Windows any \ separators will be replaced by -- /. filePattern :: FilePattern -> FilePath -> Maybe [String] -- | Like need, but if shakeLint is set, check that the file -- does not rebuild. Used for adding dependencies on files that have -- already been used in this rule. needed :: Partial => [FilePath] -> Action () -- | Track that a file was read by the action preceding it. If -- shakeLint is activated then these files must be dependencies of -- this rule. Calls to trackRead are automatically inserted in -- LintFSATrace mode. trackRead :: [FilePath] -> Action () -- | Track that a file was written by the action preceding it. If -- shakeLint is activated then these files must either be the -- target of this rule, or never referred to by the build system. Calls -- to trackWrite are automatically inserted in LintFSATrace -- mode. trackWrite :: [FilePath] -> Action () -- | Allow accessing a file in this rule, ignoring any subsequent -- trackRead / trackWrite calls matching the pattern. trackAllow :: [FilePattern] -> Action () -- | Returns True if the file exists. The existence of the file is -- tracked as a dependency, and if the file is created or deleted the -- rule will rerun in subsequent builds. -- -- You should not call doesFileExist on files which can be created -- by the build system. doesFileExist :: FilePath -> Action Bool -- | Returns True if the directory exists. The existence of the -- directory is tracked as a dependency, and if the directory is created -- or delete the rule will rerun in subsequent builds. -- -- You should not call doesDirectoryExist on directories which can -- be created by the build system. doesDirectoryExist :: FilePath -> Action Bool -- | Get the contents of a directory. The result will be sorted, and will -- not contain the entries . or .. (unlike the standard -- Haskell version). The resulting paths will be relative to the first -- argument. The result itself is tracked as a dependency, but the files -- in the result are not. If the list of files changes in subsequent -- builds any rule calling it will rerun. -- -- It is usually simpler to call either getDirectoryFiles or -- getDirectoryDirs. getDirectoryContents :: FilePath -> Action [FilePath] -- | Get the files anywhere under a directory that match any of a set of -- patterns. For the interpretation of the patterns see ?==. All -- results will be relative to the directory argument. The result itself -- is tracked as a dependency, but the files in the result are not. If -- the list of files changes in subsequent builds any rule calling it -- will rerun. Some examples: -- --
--   getDirectoryFiles "Config" ["//*.xml"]
--       -- All .xml files anywhere under the Config directory
--       -- If Config/foo/bar.xml exists it will return ["foo/bar.xml"]
--   getDirectoryFiles "Modules" ["*.hs","*.lhs"]
--       -- All .hs or .lhs in the Modules directory
--       -- If Modules/foo.hs and Modules/foo.lhs exist, it will return ["foo.hs","foo.lhs"]
--   
-- -- If you require a qualified file name it is often easier to use -- "" as the FilePath argument, for example the following -- two expressions are equivalent: -- --
--   fmap (map ("Config" </>)) (getDirectoryFiles "Config" ["//*.xml"])
--   getDirectoryFiles "" ["Config//*.xml"]
--   
-- -- If the first argument directory does not exist it will raise an error. -- If foo does not exist, then the first of these error, but the -- second will not. -- --
--   getDirectoryFiles "foo" ["//*"] -- error
--   getDirectoryFiles "" ["foo//*"] -- returns []
--   
-- -- This function is tracked and serves as a dependency. If a rule calls -- getDirectoryFiles "" ["*.c"] and someone adds foo.c -- to the directory, that rule will rebuild. If someone changes one of -- the .c files, but the list of .c files -- doesn't change, then it will not rebuild. As a consequence of being -- tracked, if the contents change during the build (e.g. you are -- generating .c files in this directory) then the build not -- reach a stable point, which is an error - detected by running with -- --lint. You should normally only call this function returning -- source files. -- -- For an untracked variant see getDirectoryFilesIO. getDirectoryFiles :: FilePath -> [FilePattern] -> Action [FilePath] -- | Get the directories in a directory, not including . or -- ... All directories are relative to the argument directory. -- The result itself is tracked as a dependency, but the directories in -- the result are not. If the list of directories changes in subsequent -- builds any rule calling it will rerun. getDirectoryDirs :: FilePath -> Action [FilePath] -- | A version of getDirectoryFiles that is in IO, and thus -- untracked. getDirectoryFilesIO :: FilePath -> [FilePattern] -> IO [FilePath] -- | Return Just the value of the environment variable, or -- Nothing if the variable is not set. The environment variable is -- tracked as a dependency, and if it changes the rule will rerun in -- subsequent builds. This function is a tracked version of getEnv -- / lookupEnv from the base library. -- --
--   flags <- getEnv "CFLAGS"
--   cmd "gcc -c" [out] (maybe [] words flags)
--   
getEnv :: String -> Action (Maybe String) -- | getEnvWithDefault def var returns the value of the -- environment variable var, or the default value def -- if it is not set. Similar to getEnv. -- --
--   flags <- getEnvWithDefault "-Wall" "CFLAGS"
--   cmd "gcc -c" [out] flags
--   
getEnvWithDefault :: String -> String -> Action String -- | A partial variant of getEnv that returns the environment -- variable variable or fails. getEnvError :: Partial => String -> Action String -- | Define an alias for the six type classes required for things involved -- in Shake rules. Using this alias requires the ConstraintKinds -- extension. -- -- To define your own values meeting the necessary constraints it is -- convenient to use the extensions GeneralizedNewtypeDeriving -- and DeriveDataTypeable to write: -- --
--   newtype MyType = MyType (String, Bool) deriving (Show, Typeable, Eq, Hashable, Binary, NFData)
--   
-- -- Shake needs these instances on keys and values. They are used for: -- -- type ShakeValue a = (Show a, Typeable a, Eq a, Hashable a, Binary a, NFData a) -- | The type mapping between the key or a rule and the resulting -- value. See addBuiltinRule and apply. type family RuleResult key -- | Add extra information which rules can depend on. An oracle is a -- function from a question type q, to an answer type -- a. As an example, we can define an oracle allowing you to -- depend on the current version of GHC: -- --
--   newtype GhcVersion = GhcVersion () deriving (Show,Typeable,Eq,Hashable,Binary,NFData)
--   type instance RuleResult GhcVersion = String
--   rules = do
--       addOracle $ \(GhcVersion _) -> fromStdout <$> cmd "ghc --numeric-version" :: Action String
--       ... rules ...
--   
-- -- If a rule calls askOracle (GhcVersion ()), that rule -- will be rerun whenever the GHC version changes. Some notes: -- -- -- -- As a more complex example, consider tracking Haskell package versions: -- --
--   newtype GhcPkgList = GhcPkgList () deriving (Show,Typeable,Eq,Hashable,Binary,NFData)
--   type instance RuleResult GhcPkgList = [(String, String)]
--   newtype GhcPkgVersion = GhcPkgVersion String deriving (Show,Typeable,Eq,Hashable,Binary,NFData)
--   type instance RuleResult GhcPkgVersion = Maybe String
--   
--   rules = do
--       getPkgList <- addOracle $ \GhcPkgList{} -> do
--           Stdout out <- cmd "ghc-pkg list --simple-output"
--           pure [(reverse b, reverse a) | x <- words out, let (a,_:b) = break (== '-') $ reverse x]
--   
--       getPkgVersion <- addOracle $ \(GhcPkgVersion pkg) -> do
--           pkgs <- getPkgList $ GhcPkgList ()
--           pure $ lookup pkg pkgs
--   
--       "myrule" %> \_ -> do
--           getPkgVersion $ GhcPkgVersion "shake"
--           ... rule using the shake version ...
--   
-- -- Using these definitions, any rule depending on the version of -- shake should call getPkgVersion $ GhcPkgVersion -- "shake" to rebuild when shake is upgraded. -- -- If you apply versioned to an oracle it will cause that oracle -- result to be discarded, and not do early-termination. addOracle :: (RuleResult q ~ a, ShakeValue q, ShakeValue a, Partial) => (q -> Action a) -> Rules (q -> Action a) -- | A combination of addOracle and newCache - an action -- that only runs when its dependencies change, whose result is stored in -- the database. -- -- -- -- An alternative to using addOracleCache is introducing an -- intermediate file containing the result, which requires less storage -- in the Shake database and can be inspected by existing file-system -- viewing tools. addOracleCache :: (RuleResult q ~ a, ShakeValue q, ShakeValue a, Partial) => (q -> Action a) -> Rules (q -> Action a) -- | An alternative to to addOracle that relies on the hash -- function providing a perfect equality, doesn't support -- --skip, but requires less storage. addOracleHash :: (RuleResult q ~ a, ShakeValue q, ShakeValue a, Partial) => (q -> Action a) -> Rules (q -> Action a) -- | Get information previously added with addOracle or -- addOracleCache. The question/answer types must match those -- provided previously. askOracle :: (RuleResult q ~ a, ShakeValue q, ShakeValue a) => q -> Action a -- | A parallel version of askOracle. askOracles :: (RuleResult q ~ a, ShakeValue q, ShakeValue a) => [q] -> Action [a] -- | Always rerun the associated action. Useful for defining rules that -- query the environment. For example: -- --
--   "ghcVersion.txt" %> \out -> do
--       alwaysRerun
--       Stdout stdout <- cmd "ghc --numeric-version"
--       writeFileChanged out stdout
--   
-- -- In make, the .PHONY attribute on file-producing -- rules has a similar effect. -- -- Note that alwaysRerun is applied when a rule is executed. -- Modifying an existing rule to insert alwaysRerun will -- not cause that rule to rerun next time. alwaysRerun :: Action () -- | A type representing an external resource which the build system should -- respect. There are two ways to create Resources in Shake: -- -- -- -- These resources are used with withResource when defining rules. -- Typically only system commands (such as cmd) should be run -- inside withResource, not commands such as need. -- -- Be careful that the actions run within withResource do not -- themselves require further resources, or you may get a "thread blocked -- indefinitely in an MVar operation" exception. If an action requires -- multiple resources, use withResources to avoid deadlock. data Resource -- | Create a finite resource, given a name (for error messages) and a -- quantity of the resource that exists. Shake will ensure that actions -- using the same finite resource do not execute in parallel. As an -- example, only one set of calls to the Excel API can occur at one time, -- therefore Excel is a finite resource of quantity 1. You can write: -- --
--   shake shakeOptions{shakeThreads=2} $ do
--      want ["a.xls","b.xls"]
--      excel <- newResource "Excel" 1
--      "*.xls" %> \out ->
--          withResource excel 1 $
--              cmd "excel" out ...
--   
-- -- Now the two calls to excel will not happen in parallel. -- -- As another example, calls to compilers are usually CPU bound but calls -- to linkers are usually disk bound. Running 8 linkers will often cause -- an 8 CPU system to grid to a halt. We can limit ourselves to 4 linkers -- with: -- --
--   disk <- newResource "Disk" 4
--   want [show i <.> "exe" | i <- [1..100]]
--   "*.exe" %> \out ->
--       withResource disk 1 $
--           cmd "ld -o" [out] ...
--   "*.o" %> \out ->
--       cmd "cl -o" [out] ...
--   
newResource :: String -> Int -> Rules Resource -- | A version of newResource that runs in IO, and can be called -- before calling shake. Most people should use newResource -- instead. newResourceIO :: String -> Int -> IO Resource -- | Run an action which uses part of a finite resource. For more details -- see Resource. You cannot depend on a rule (e.g. need) -- while a resource is held. withResource :: Resource -> Int -> Action a -> Action a -- | Run an action which uses part of several finite resources. Acquires -- the resources in a stable order, to prevent deadlock. If all rules -- requiring more than one resource acquire those resources with a single -- call to withResources, resources will not deadlock. withResources :: [(Resource, Int)] -> Action a -> Action a -- | Create a throttled resource, given a name (for error messages) and a -- number of resources (the Int) that can be used per time period -- (the Double in seconds). Shake will ensure that actions using -- the same throttled resource do not exceed the limits. As an example, -- let us assume that making more than 1 request every 5 seconds to -- Google results in our client being blacklisted, we can write: -- --
--   google <- newThrottle "Google" 1 5
--   "*.url" %> \out -> do
--       withResource google 1 $
--           cmd "wget" ["https://google.com?q=" ++ takeBaseName out] "-O" [out]
--   
-- -- Now we will wait at least 5 seconds after querying Google before -- performing another query. If Google change the rules to allow 12 -- requests per minute we can instead use newThrottle "Google" -- 12 60, which would allow greater parallelisation, and avoid -- throttling entirely if only a small number of requests are necessary. -- -- In the original example we never make a fresh request until 5 seconds -- after the previous request has completed. If we instead want to -- throttle requests since the previous request started we can -- write: -- --
--   google <- newThrottle "Google" 1 5
--   "*.url" %> \out -> do
--       withResource google 1 $ pure ()
--       cmd "wget" ["https://google.com?q=" ++ takeBaseName out] "-O" [out]
--   
-- -- However, the rule may not continue running immediately after -- withResource completes, so while we will never exceed an -- average of 1 request every 5 seconds, we may end up running an -- unbounded number of requests simultaneously. If this limitation causes -- a problem in practice it can be fixed. newThrottle :: String -> Int -> Double -> Rules Resource -- | A version of newThrottle that runs in IO, and can be called -- before calling shake. Most people should use newThrottle -- instead. newThrottleIO :: String -> Int -> Double -> IO Resource -- | Run an action without counting to the thread limit, typically used for -- actions that execute on remote machines using barely any local CPU -- resources. Unsafe as it allows the shakeThreads limit to be -- exceeded. You cannot depend on a rule (e.g. need) while the -- extra thread is executing. If the rule blocks (e.g. calls -- withResource) then the extra thread may be used by some other -- action. Only really suitable for calling cmd / -- command. unsafeExtraThread :: Action a -> Action a -- | Given an action on a key, produce a cached version that will execute -- the action at most once per key per run. Using the cached result will -- still result include any dependencies that the action requires - e.g. -- if the action does need then those dependencies will be added -- to every rule that uses that cache. Each call to newCache -- creates a separate cache that is independent of all other calls to -- newCache. -- -- The operations will not be cached between runs and nothing will be -- persisted to the Shake database. For an alternative that does persist -- the cache, see addOracleCache. -- -- This function is useful when creating files that store intermediate -- values, to avoid the overhead of repeatedly reading from disk, -- particularly if the file requires expensive parsing. As an example: -- --
--   digits <- newCache $ \file -> do
--       src <- readFile' file
--       pure $ length $ filter isDigit src
--   "*.digits" %> \x -> do
--       v1 <- digits (dropExtension x)
--       v2 <- digits (dropExtension x)
--       writeFile' x $ show (v1,v2)
--   
-- -- To create the result MyFile.txt.digits the file -- MyFile.txt will be read and counted, but only at most once -- per execution. newCache :: (Eq k, Hashable k) => (k -> Action v) -> Rules (k -> Action v) -- | A version of newCache that runs in IO, and can be called before -- calling shake. Most people should use newCache instead. newCacheIO :: (Eq k, Hashable k) => (k -> Action v) -> IO (k -> Action v) -- | This rule should not be cached or recorded in the history because it -- makes use of untracked dependencies (e.g. files in a system directory -- or items on the $PATH), or is trivial to compute locally. historyDisable :: Action () -- | This rule builds the following files, in addition to any defined by -- its target. At the end of the rule these files must have been written. -- These files must not be tracked as part of the build system - -- two rules cannot produce the same file and you cannot need the -- files it produces. produces :: [FilePath] -> Action () -- | Like need but returns a list of rebuilt dependencies since the -- calling rule last built successfully. -- -- The following example writes a list of changed dependencies to a file -- as its action. -- --
--   "target" %> \out -> do
--         let sourceList = ["source1", "source2"]
--         rebuildList <- needHasChanged sourceList
--         writeFileLines out rebuildList
--   
-- -- This function can be used to alter the action depending on which -- dependency needed to be rebuild. -- -- Note that a rule can be run even if no dependency has changed, for -- example because of shakeRebuild or because the target has -- changed or been deleted. To detect the latter case you may wish to use -- resultHasChanged. needHasChanged :: Partial => [FilePath] -> Action [FilePath] -- | Has a file changed. This function will only give the correct answer if -- called in the rule producing the file, before the rule has -- modified the file in question. Best avoided, but sometimes necessary -- in conjunction with needHasChanged to cause rebuilds to happen -- if the result is deleted or modified. resultHasChanged :: FilePath -> Action Bool -- | Batch different outputs into a single Action, typically useful -- when a command has a high startup cost - e.g. apt-get install foo -- bar baz is a lot cheaper than three separate calls to apt-get -- install. As an example, if we have a standard build rule: -- --
--   "*.out" %> \out -> do
--       need [out -<.> "in"]
--       cmd "build-multiple" [out -<.> "in"]
--   
-- -- Assuming that build-multiple can compile multiple files in a -- single run, and that the cost of doing so is a lot less than running -- each individually, we can write: -- --
--   batch 3 ("*.out" %>)
--       (\out -> do need [out -<.> "in"]; pure out)
--       (\outs -> cmd "build-multiple" [out -<.> "in" | out <- outs])
--   
-- -- In constrast to the normal call, we have specified a maximum batch -- size of 3, an action to run on each output individually (typically all -- the need dependencies), and an action that runs on multiple -- files at once. If we were to require lots of *.out files, -- they would typically be built in batches of 3. -- -- If Shake ever has nothing else to do it will run batches before they -- are at the maximum, so you may see much smaller batches, especially at -- high parallelism settings. batch :: Int -> ((a -> Action ()) -> Rules ()) -> (a -> Action b) -> ([b] -> Action ()) -> Rules () -- | Given a running task, reschedule so it only continues after all other -- pending tasks, and all rescheduled tasks with a higher pool priority. -- Note that due to parallelism there is no guarantee that all actions of -- a higher pool priority will have completed before the action -- resumes. Only useful if the results are being interactively reported -- or consumed. reschedule :: Double -> Action () -- | Deprecated: Replace askOracleWith q a by -- askOracle q since the RuleResult type family -- now fixes the result type. -- | Deprecated: Use 'askOracle q' instead of 'askOracleWith q a', the -- result value is now unnecessary askOracleWith :: (RuleResult q ~ a, ShakeValue q, ShakeValue a) => q -> a -> Action a -- | Deprecated: Alias for reschedule. -- | Deprecated: Use reschedule instead deprioritize :: Double -> Action () -- | Deprecated: A bidirectional pattern synonym for Error. pattern Quiet :: Verbosity -- | Deprecated: A bidirectional pattern synonym for Info. pattern Normal :: Verbosity -- | Deprecated: A bidirectional pattern synonym for Verbose. pattern Loud :: Verbosity -- | Deprecated: A bidirectional pattern synonym for Verbose. pattern Chatty :: Verbosity -- | Deprecated: Alias for putVerbose. putLoud :: String -> Action () -- | Deprecated: Alias for putInfo. putNormal :: String -> Action () -- | Deprecated: Alias for putError. putQuiet :: String -> Action () -- | A module for useful utility functions for Shake build systems. module Development.Shake.Util -- | Given the text of a Makefile, extract the list of targets and -- dependencies. Assumes a small subset of Makefile syntax, mostly that -- generated by gcc -MM. -- --
--   parseMakefile "a: b c\nd : e" == [("a",["b","c"]),("d",["e"])]
--   
parseMakefile :: String -> [(FilePath, [FilePath])] -- | Depend on the dependencies listed in a Makefile. Does not depend on -- the Makefile itself. -- --
--   needMakefileDependencies file = need . concatMap snd . parseMakefile =<< liftIO (readFile file)
--   
needMakefileDependencies :: FilePath -> Action () -- | Depend on the dependencies listed in a Makefile. Does not depend on -- the Makefile itself. Use this function to indicate that you have -- already used the files in question. -- --
--   neededMakefileDependencies file = needed . concatMap snd . parseMakefile =<< liftIO (readFile file)
--   
neededMakefileDependencies :: FilePath -> Action () -- | Like shakeArgsWith, but instead of accumulating a list of -- flags, apply functions to a default value. Usually used to populate a -- record structure. As an example of a build system that can use either -- gcc or distcc for compiling: -- --
--   import System.Console.GetOpt
--   
--   data Flags = Flags {distCC :: Bool} deriving Eq
--   flags = [Option "" ["distcc"] (NoArg $ Right $ \x -> x{distCC=True}) "Run distributed."]
--   
--   main = shakeArgsAccumulate shakeOptions flags (Flags False) $ \flags targets -> pure $ Just $ do
--       if null targets then want ["result.exe"] else want targets
--       let compiler = if distCC flags then "distcc" else "gcc"
--       "*.o" %> \out -> do
--           need ...
--           cmd compiler ...
--       ...
--   
-- -- Now you can pass --distcc to use the distcc -- compiler. shakeArgsAccumulate :: ShakeOptions -> [OptDescr (Either String (a -> a))] -> a -> (a -> [String] -> IO (Maybe (Rules ()))) -> IO () -- | Like shakeArgs but also takes a pruning function. If -- --prune is passed, then after the build has completed, the -- second argument is called with a list of the files that the build -- checked were up-to-date. shakeArgsPrune :: ShakeOptions -> ([FilePath] -> IO ()) -> Rules () -> IO () -- | A version of shakeArgsPrune that also takes a list of extra -- options to use. shakeArgsPruneWith :: ShakeOptions -> ([FilePath] -> IO ()) -> [OptDescr (Either String a)] -> ([a] -> [String] -> IO (Maybe (Rules ()))) -> IO () -- | A module for producing forward-defined build systems, in contrast to -- standard backwards-defined build systems such as shake. Based around -- ideas from fabricate. As an example: -- --
--   import Development.Shake
--   import Development.Shake.Forward
--   import Development.Shake.FilePath
--   
--   main = shakeArgsForward shakeOptions $ do
--       contents <- readFileLines "result.txt"
--       cache $ cmd "tar -cf result.tar" contents
--   
-- -- Compared to backward-defined build systems (such as normal Shake), -- forward-defined build systems tend to be simpler for simple systems -- (less boilerplate, more direct style), but more complex for larger -- build systems (requires explicit parallelism, explicit sharing of -- build products, no automatic command line targets). As a general -- approach for writing forward-defined systems: -- -- -- -- All forward-defined systems use AutoDeps, which requires -- fsatrace to be on the $PATH. You can obtain -- fsatrace from https://github.com/jacereda/fsatrace. -- You must set shakeLintInside to specify where AutoDeps -- will look for dependencies - if you want all dependencies everywhere -- use [""]. -- -- This module is considered experimental - it has not been battle -- tested. There are now a few possible alternatives in this space: -- -- module Development.Shake.Forward -- | Run a forward-defined build system. shakeForward :: ShakeOptions -> Action () -> IO () -- | Run a forward-defined build system, interpreting command-line -- arguments. shakeArgsForward :: ShakeOptions -> Action () -> IO () -- | Given a ShakeOptions, set the options necessary to execute in -- forward mode. forwardOptions :: ShakeOptions -> ShakeOptions -- | Given an Action, turn it into a Rules structure which -- runs in forward mode. forwardRule :: Action () -> Rules () -- | Apply caching to an external command using the same arguments as -- cmd. -- --
--   cache $ cmd "gcc -c" ["foo.c"] "-o" ["foo.o"]
--   
-- -- This command will be cached, with the inputs/outputs traced. If any of -- the files used by this command (e.g. foo.c or header files it -- imports) then the command will rerun. cache :: (forall r. CmdArguments r => r) -> Action () -- | Cache an action, given a key and an Action. Each call in your -- program should specify a different key, but the key should remain -- consistent between runs. Ideally, the Action will gather all -- its dependencies with tracked operations, e.g. 'readFile\''. However, -- if information is accessed from the environment (e.g. the action is a -- closure), you should call cacheActionWith being explicit about -- what is captured. cacheAction :: (Typeable a, Binary a, Show a, Typeable b, Binary b, Show b) => a -> Action b -> Action b -- | Like cacheAction, but also specify which information is -- captured by the closure of the Action. If that information -- changes, the Action will be rerun. cacheActionWith :: (Typeable a, Binary a, Show a, Typeable b, Binary b, Show b, Typeable c, Binary c, Show c) => a -> b -> Action c -> Action c instance Data.Binary.Class.Binary Development.Shake.Forward.Command instance GHC.Show.Show a => GHC.Show.Show (Development.Shake.Forward.With a) instance Data.Binary.Class.Binary a => Data.Binary.Class.Binary (Development.Shake.Forward.With a) instance Data.Binary.Class.Binary Development.Shake.Forward.Forward instance Control.DeepSeq.NFData Development.Shake.Forward.Forward instance GHC.Classes.Eq Development.Shake.Forward.Forward instance Data.Hashable.Class.Hashable Development.Shake.Forward.Forward instance GHC.Show.Show Development.Shake.Forward.Command instance GHC.Show.Show Development.Shake.Forward.Forward -- | A module for parsing and using config files in a Shake build system. -- Config files consist of variable bindings, for example: -- --
--   # This is my Config file
--   HEADERS_DIR = /path/to/dir
--   CFLAGS = -g -I${HEADERS_DIR}
--   CFLAGS = $CFLAGS -O2
--   include extra/file.cfg
--   
-- -- This defines the variable HEADERS_DIR (equal to -- /path/to/dir), and CFLAGS (equal to -g -- -I/path/to/dir -O2), and also includes the configuration -- statements in the file extra/file.cfg. The full lexical -- syntax for configuration files is defined here: -- https://ninja-build.org/manual.html#_lexical_syntax. The use of -- Ninja file syntax is due to convenience and the desire to reuse an -- externally-defined specification (but the choice of configuration -- language is mostly arbitrary). -- -- To use the configuration file either use readConfigFile to -- parse the configuration file and use the values directly, or -- usingConfigFile and getConfig to track the configuration -- values, so they become build dependencies. module Development.Shake.Config -- | Read a config file, returning a list of the variables and their -- bindings. Config files use the Ninja lexical syntax: -- https://ninja-build.org/manual.html#_lexical_syntax readConfigFile :: FilePath -> IO (HashMap String String) -- | Read a config file with an initial environment, returning a list of -- the variables and their bindings. Config files use the Ninja lexical -- syntax: https://ninja-build.org/manual.html#_lexical_syntax readConfigFileWithEnv :: [(String, String)] -> FilePath -> IO (HashMap String String) -- | Specify the file to use with getConfig. usingConfigFile :: FilePath -> Rules () -- | Specify the values to use with getConfig, generally prefer -- usingConfigFile unless you also need access to the values of -- variables outside Action. usingConfig :: HashMap String String -> Rules () -- | Obtain the value of a configuration variable, returns Nothing -- to indicate the variable has no binding. Any build system using -- getConfig must call either usingConfigFile or -- usingConfig. The getConfig function will introduce a -- dependency on the configuration variable (but not the whole -- configuration file), and if the configuration variable changes, the -- rule will be rerun. As an example: -- --
--   usingConfigFile "myconfiguration.cfg"
--   "*.o" %> \out -> do
--       cflags <- getConfig "CFLAGS"
--       cmd "gcc" [out -<.> "c"] (fromMaybe "" cflags)
--   
getConfig :: String -> Action (Maybe String) -- | Obtain the configuration keys. Any build system using -- getConfigKeys must call either usingConfigFile or -- usingConfig. The getConfigKeys function will introduce a -- dependency on the configuration keys (but not the whole configuration -- file), and if the configuration keys change, the rule will be rerun. -- Usually use as part of an action. As an example: -- --
--   usingConfigFile "myconfiguration.cfg"
--   action $ need =<< getConfigKeys
--   
getConfigKeys :: Action [String] instance Control.DeepSeq.NFData Development.Shake.Config.ConfigKeys instance Data.Binary.Class.Binary Development.Shake.Config.ConfigKeys instance Data.Hashable.Class.Hashable Development.Shake.Config.ConfigKeys instance GHC.Classes.Eq Development.Shake.Config.ConfigKeys instance GHC.Show.Show Development.Shake.Config.ConfigKeys instance Control.DeepSeq.NFData Development.Shake.Config.Config instance Data.Binary.Class.Binary Development.Shake.Config.Config instance Data.Hashable.Class.Hashable Development.Shake.Config.Config instance GHC.Classes.Eq Development.Shake.Config.Config instance GHC.Show.Show Development.Shake.Config.Config