Your existing approach of using environment variables should work, and since environment variables are already tracked by Shake, one approach is to parse DEBUG=YES
and turn it into an environment variable. For example:
main = shakeArgsWith shakeOptions [] $ \_ args -> do
let (vars,files) = partition ('=' `elem`) args
forM_ vars $ \v -> let (a,'=':b) = break (== '=') v in setEnv a b
return $ Just $ if null files then rules else want files >> withoutActions rules
rules :: Rules ()
rules = ...
Since environment variables are local to a process (and their child processes), this will probably work fine.
Of course, storing such information in the environment variables is a bit ugly. You can create your own oracle to store the information instead:
main = shakeArgsWith shakeOptions [] $ \_ args -> do
let (vars,files) = partition ('=' `elem`) args
let vars2 = [(a,b) | v <- vars, let (a,'=':b) = break (== '=') v]
return $ Just $ do
global <- addOracle $ \(Global x) -> return $ lookup x vars2
if null files then rules global else want files >> withoutActions (rules global)
newtype Global = Global String deriving (Show,Typeable,Eq,Hashable,Binary,NFData)
rules :: (Global -> Action (Maybe String)) -> Rules ()
rules global = undefined
Now, instead of writing the information into an environment variable with setEnv
, we store it in an oracle with addOracle
, which will still be tracked and not conflict with any other environment-variable pieces.