let rule name ?(tags=[]) ?(prods=[]) ?(deps=[]) ?prod ?dep ?stamp ?(insert = `bottom) code =
let res_add import xs xopt =
let init =
match xopt with
| None -> []
| Some r -> [import r]
in
List.fold_right begin fun x acc ->
let r = import x in
if List.mem r acc then
failwith (sprintf "in rule %s, multiple occurences of the resource %s" name x)
else r :: acc
end xs init
in
if prods = [] && prod = None && stamp = None then raise (Exit_rule_error "Can't make a rule that produce nothing");
let stamp, prods =
match stamp with
| None -> None, prods
| Some stamp ->
Some (Resource.import_pattern stamp), stamp :: prods
in
let prods = res_add Resource.import_pattern prods prod in
let code env build =
let cmd = code env build in
{ digest = Command.digest cmd
; command = cmd }
in
add_rule insert
{ name = name;
tags = List.fold_right Tags.add tags Tags.empty;
deps = res_add Resource.import deps dep;
stamp = stamp;
prods = prods;
code = code }