-- File created: 2008-07-19 17:53:12

-- | Coadjute is a generic build tool, intended as an easier to use and more
-- portable (in the sense that implementations don't differ) replacement for
-- make. It's not tailored toward any particular language, and is not meant to
-- replace tools which target a specific environment.
--
-- An example of simple usage:
--
-- > import Coadjute
-- > import System.Directory
-- >
-- > main = coadjute $ do
-- >    rule' "Copy foo from src to obj"
-- >          (\[s] t -> copyFile s t)
-- >          (sourceDatum' (("obj"++) . drop 3) ["src/foo"])
--
-- By convention, this file should be called /Adjutant.hs/.
--
-- Compiled and run, it would copy @src\/foo@ to @obj\/foo@ whenever @src\/foo@
-- is older than @obj\/foo@. With @-d@ or @--use-db@ passed, it would hash
-- (currently MD5) @src/foo@, using that instead of modification time data to
-- decide whether to run the @copyFile@ or not.
module Coadjute
   ( -- * Coadjute blocks
     --
     -- | When using Coadjute, you give it all the information it needs within
     -- a monad inspiringly called 'Coadjute'. Use 'coadjute' to escape into
     -- the IO monad, letting Coadjute do all your hard work for you.
     Coadjute
   , coadjute
     -- ** Defining rules
     -- $rules
   , rule, ruleM
     -- $convenience
   , rule', ruleM'
     -- ** Other functions within Coadjute
   , getUserArgs
     -- ** Sources and Targets
     -- $sourcesTargets
   , Source, Target
   ) where

import Coadjute.Main (coadjute)
import Coadjute.Rule ( Coadjute
                     , rule, rule', ruleM, ruleM'
                     , getUserArgs
                     )
import Coadjute.Task (Source, Target)

-- $sourcesTargets
--
-- Sources and targets are both paths to files or directories.

-- $taskdata
--
-- These types pair up a target or targets with a list of dependencies.

-- $rules
--
-- These are the primary functions available to you inside a 'Coadjute' block:
-- each one adds a single build rule, on the basis of which many build tasks
-- may be constructed.
--
-- Each function takes:
--
--   * A name for the rule. (Currently only used in error messages.)
--
--   * A build action: this function will be run if the dependencies are deemed
--     out of date compared to the target.
--
--   * A list of dependencies paŃ–red with one or more targets.
--
-- For instance, you might have a rule \"C files\" which handles building of C
-- code, thus:
--
-- > rule' "C files"
-- >       (\_ c -> system ("gcc -c " ++ c))
-- >       [(["foo.c"],"foo.o"), (["bar.c"],"bar.o")]
--
-- This example also demonstrates poor practices: you should really specify
-- complete dependency data, such as header files.
--
-- The above example did not use command line arguments, so let's have a look
-- at those. Let's say you want to build either a debug or a release version of
-- your program, depending on a flag you pass in. Since this flag will affect
-- all your object files, you want to tell Coadjute that you're interested in
-- it:
--
-- > rule "C files" ["--debug"] ...
--
-- Now, if you've built your C files in release mode and want to switch to
-- debug mode, Coadjute will know to rebuild even those files which you haven't
-- changed, based simply on the fact that last time you did not pass @--debug@
-- and this time you did.
--
-- You must still handle the flag's presence yourself using 'getUserArgs' and
-- acting on it: the @[String]@ parameter is simply to tell Coadjute which
-- flags that particular rule is affected by.
--
-- For now, only boolean flags are supported: either they're present or not.
--
-- Note that you must build with @-d@ to store the argument data. You need
-- specify this only the first time: as long as the database exists it will be
-- used.

-- $convenience
--
-- @rule'@ and @ruleM'@ are a pair of convenience functions for when you don't
-- care about command line arguments.