Safe Haskell | None |
---|---|
Language | Haskell2010 |
This module is used for defining new types of rules for Shake build systems. Most users will find the built-in set of rules sufficient.
- class (ShakeValue key, ShakeValue value) => Rule key value where
- storedValue :: ShakeOptions -> key -> IO (Maybe value)
- equalValue :: ShakeOptions -> key -> value -> value -> EqualCost
- data EqualCost
- rule :: Rule key value => (key -> Maybe (Action value)) -> Rules ()
- apply :: Rule key value => [key] -> Action [value]
- apply1 :: Rule key value => key -> Action value
- trackUse :: ShakeValue key => key -> Action ()
- trackChange :: ShakeValue key => key -> Action ()
- trackAllow :: ShakeValue key => (key -> Bool) -> Action ()
- defaultRule :: Rule key value => (key -> Maybe (Action value)) -> Rules ()
Documentation
class (ShakeValue key, ShakeValue value) => Rule key value where Source
Define a pair of types that can be used by Shake rules. To import all the type classes required see Development.Shake.Classes.
A Rule
instance for a class of artifacts (e.g. files) provides:
- How to identify individual artifacts, given by the
key
type, e.g. with file names. - How to describe the state of an artifact, given by the
value
type, e.g. the file modification time. - A way to compare two states of the same individual artifact, with
equalValue
returning eitherEqualCheap
orNotEqual
. - A way to query the current state of an artifact, with
storedValue
returning the current state, orNothing
if there is no current state (e.g. the file does not exist).
Checking if an artifact needs to be built consists of comparing two value
s
of the same key
with equalValue
. The first value is obtained by applying
storedValue
to the key
and the second is the value stored in the build
database after the last successful build.
As an example, below is a simplified rule for building files, where files are identified
by a FilePath
and their state is identified by a hash of their contents
(the builtin functions need
and %>
provide a similar rule).
newtype File = File FilePath deriving (Show, Typeable, Eq, Hashable, Binary, NFData) newtype Modtime = Modtime Double deriving (Show, Typeable, Eq, Hashable, Binary, NFData) getFileModtime file = ... instance Rule File Modtime where storedValue _ (File x) = do exists <- System.Directory.doesFileExist x if exists then Just <$> getFileModtime x else return Nothing equalValue _ _ t1 t2 = if t1 == t2 then EqualCheap else NotEqual
This example instance means:
- A value of type
File
uniquely identifies a generated file. - A value of type
Modtime
will be used to check if a file is up-to-date.
It is important to distinguish Rule
instances from actual rules. Rule
instances are one component required for the creation of rules.
Actual rules are functions from a key
to an Action
; they are
added to Rules
using the rule
function.
A rule can be created for the instance above with:
-- Compile foo files; for every foo output file there must be a -- single input file named "filename.foo". compileFoo ::Rules
() compileFoo =rule
(Just . compile) where compile :: File ->Action
Modtime compile (File outputFile) = do -- figure out the name of the input file let inputFile = outputFile<.>
"foo"unit
$cmd
"fooCC" inputFile outputFile -- return the (new) file modtime of the output file: getFileModtime outputFile
Note: In this example, the timestamps of the input files are never
used, let alone compared to the timestamps of the ouput files.
Dependencies between output and input files are not expressed by
Rule
instances. Dependencies are created automatically by apply
.
For rules whose values are not stored externally,
storedValue
should return Just
with a sentinel value
and equalValue
should always return EqualCheap
for that sentinel.
storedValue :: ShakeOptions -> key -> IO (Maybe value) Source
[Required] Retrieve the value
associated with a key
, if available.
As an example for filenames/timestamps, if the file exists you should return Just
the timestamp, but otherwise return Nothing
.
equalValue :: ShakeOptions -> key -> value -> value -> EqualCost Source
[Optional] Equality check, with a notion of how expensive the check was.
An equality check and a cost.
EqualCheap | The equality check was cheap. |
EqualExpensive | The equality check was expensive, as the results are not trivially equal. |
NotEqual | The values are not equal. |
trackUse :: ShakeValue key => key -> Action () Source
Track that a key has been used by the action preceeding it.
trackChange :: ShakeValue key => key -> Action () Source
Track that a key has been changed by the action preceeding it.
trackAllow :: ShakeValue key => (key -> Bool) -> Action () Source
Allow any matching key to violate the tracking rules.