feat(rule): chain rules and depend on the tool they run

This commit is contained in:
sneeker committed 2022-08-04 15:59:54 +00:00
1 parent 034095ceac
commit c8048c6213
2 files changed
+34 -23

No files matched your search

+2 -2
View File
@@ -113,8 +113,8 @@ let of_project p =
(fun r ->
let cmd = Array.of_list r.rcmd in
(* a tool the rule runs is an input like any other, so building it first is
ordering and rebuilding it is invalidation *)
let tools = List.filter_map (fun u -> Option.map (out_of p) (find p u)) r.ruses in
ordering and rebuilding it is invalidation; a script is already a file *)
let tools = List.map (fun u -> match find p u with Some t -> out_of p t | None -> u) r.ruses in
add
(Graph.make ~id:!n ~tag:"gen" ~label:r.rdesc ~cmd ~outs:r.routs ~ins:(r.rin @ tools) ()))
p.rules;
+32 -21
View File
@@ -42,24 +42,30 @@ let subst table s =
done;
Buffer.contents b
(* Rules are read in written order, the way checks are, so a later rule can glob
what an earlier one produces and a pipeline can be spelled out in stages. *)
let rules_of blocks =
List.concat_map
(fun ((b : block), base) ->
if b.kind <> "rule" then []
else begin
check_fields b rule_fields;
let inputs = texts (get b "inputs") in
let outputs = texts (get b "outputs") in
let command = texts (get b "command") in
let descr = Option.value (get1 b "description") ~default:("gen " ^ b.bname) in
if outputs = [] then Diag.error ~span:b.nspan "rule %s declares no outputs" b.bname;
if command = [] then Diag.error ~span:b.nspan "rule %s declares no command" b.bname;
let files =
List.concat_map (fun p -> Glob.expand (Eval.under base p)) inputs |> List.sort_uniq compare
in
if files = [] then
Diag.error ~span:b.nspan ~hint:"the inputs pattern matched nothing"
"rule %s has no inputs" b.bname;
let generated = ref [] in
let of_block ((b : block), base) =
if b.kind <> "rule" then []
else begin
check_fields b rule_fields;
let inputs = texts (get b "inputs") in
let outputs = texts (get b "outputs") in
let command = texts (get b "command") in
let descr = Option.value (get1 b "description") ~default:("gen " ^ b.bname) in
if outputs = [] then Diag.error ~span:b.nspan "rule %s declares no outputs" b.bname;
if command = [] then Diag.error ~span:b.nspan "rule %s declares no command" b.bname;
let files =
List.concat_map
(fun p -> Glob.expand_with ~extra:!generated (Eval.under base p))
inputs
|> List.sort_uniq compare
in
if files = [] then
Diag.error ~span:b.nspan ~hint:"the inputs pattern matched nothing"
"rule %s has no inputs" b.bname;
let rs =
List.map
(fun f ->
let stem = Filename.remove_extension (Filename.basename f) in
@@ -82,8 +88,13 @@ let rules_of blocks =
rspan = b.nspan;
})
files
end)
blocks
in
generated := !generated @ List.concat_map (fun r -> r.routs) rs;
rs
end
in
(* fold_left, not map: each block must see what the ones before it generated *)
List.rev (List.fold_left (fun acc bb -> List.rev_append (of_block bb) acc) [] blocks)
let target_of pkgs ((b : block), base) =
check_fields b target_fields;
@@ -235,10 +246,10 @@ let project (env : Eval.env) =
(fun (r : rule) ->
List.iter
(fun u ->
if find p u = None then
if find p u = None && not (Sys.file_exists u) then
Diag.error ~span:r.rspan
~hint:(Suggest.hint u (List.map (fun (x : target) -> x.name) targets))
"rule %s uses %S, which is not a target" r.rname u)
"rule %s uses %S, which is neither a target nor a file" r.rname u)
r.ruses)
p.rules;
let seen_runs = Hashtbl.create 4 in