Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[3.15] backport #10442 #10449

Merged
merged 2 commits into from
Apr 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
86 changes: 49 additions & 37 deletions src/dune_rules/dir_status.ml
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,38 @@ let error_no_module_consumer ~loc (qualification : Include_subdirs.qualification
]
;;

let extract_directory_targets ~dir stanzas =
Memo.List.fold_left stanzas ~init:Path.Build.Map.empty ~f:(fun acc stanza ->
match Stanza.repr stanza with
| Rule_conf.T { targets = Static { targets = l; _ }; loc = rule_loc; enabled_if; _ }
->
let directory_targets_of_rule ~dir { Rule_conf.targets; loc = rule_loc; enabled_if; _ } =
match targets with
| Infer ->
(* we don't infer directory targets *)
Memo.return Path.Build.Map.empty
| Static { targets; _ } ->
let directory_targets =
List.fold_left targets ~init:Path.Build.Map.empty ~f:(fun acc (target, kind) ->
match (kind : Targets_spec.Kind.t) with
| File -> acc
| Directory ->
let loc = String_with_vars.loc target in
(match String_with_vars.text_only target with
| None ->
User_error.raise
~loc
[ Pp.text "Variables are not allowed in directory targets." ]
| Some target ->
let dir_target = Path.Build.relative ~error_loc:loc dir target in
if Path.Build.is_descendant dir_target ~of_:dir
then
(* We ignore duplicates here as duplicates are detected and
reported by [Load_rules]. *)
Path.Build.Map.set acc dir_target rule_loc
else
(* This will be checked when we interpret the stanza
completely, so just ignore this rule for now. *)
acc))
in
if Path.Build.Map.is_empty directory_targets
then Memo.return directory_targets
else
(match enabled_if with
| Blang.Const const -> Memo.return const
| _ ->
Expand All @@ -99,42 +126,27 @@ let extract_directory_targets ~dir stanzas =
let* expander = Expander0.get ~dir in
Expander0.eval_blang expander enabled_if)
>>| (function
| false -> acc
| true ->
List.fold_left l ~init:acc ~f:(fun acc (target, kind) ->
let loc = String_with_vars.loc target in
match (kind : Targets_spec.Kind.t) with
| File -> acc
| Directory ->
(match String_with_vars.text_only target with
| None ->
User_error.raise
~loc
[ Pp.text "Variables are not allowed in directory targets." ]
| Some target ->
let dir_target = Path.Build.relative ~error_loc:loc dir target in
if Path.Build.is_descendant dir_target ~of_:dir
then
(* We ignore duplicates here as duplicates are detected and
reported by [Load_rules]. *)
Path.Build.Map.set acc dir_target rule_loc
else
(* This will be checked when we interpret the stanza
completely, so just ignore this rule for now. *)
acc)))
| false -> Path.Build.Map.empty
| true -> directory_targets)
;;

let extract_directory_targets ~dir stanzas =
Memo.parallel_map stanzas ~f:(fun stanza ->
match Stanza.repr stanza with
| Rule_conf.T rule -> directory_targets_of_rule ~dir rule
| Coq_stanza.Theory.T m ->
(* It's unfortunate that we need to pull in the coq rules here. But
we don't have a generic mechanism for this yet. *)
Coq_doc.coqdoc_directory_targets ~dir m
>>| Path.Build.Map.union acc ~f:(fun path loc1 loc2 ->
User_error.raise
~loc:loc1
[ Pp.textf
"The following both define the same directory target: %s"
(Path.Build.to_string path)
; Pp.enumerate ~f:Loc.pp_file_colon_line [ loc1; loc2 ]
])
| _ -> Memo.return acc)
| _ -> Memo.return Path.Build.Map.empty)
>>| Path.Build.Map.union_all ~f:(fun path loc1 loc2 ->
User_error.raise
~loc:loc1
[ Pp.textf
"The following both define the same directory target: %s"
(Path.Build.to_string path)
; Pp.enumerate ~f:Loc.pp_file_colon_line [ loc1; loc2 ]
])
;;

module rec DB : sig
Expand Down
22 changes: 11 additions & 11 deletions test/blackbox-tests/test-cases/coq/coqdoc-dir-target-clash.t/run.t
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
We try to build the documentation but there will be a clash between the
directory targets. Notice how the tex one fails before html one.
directory targets.
$ dune build @check
Warning: Coq Language Versions lower than 0.8 have been deprecated in Dune
3.8 and will be removed in an upcoming Dune version.
Hint: To disable this warning, add the following to your dune-project file:
(warnings (deprecated_coq_lang_lt_08 disabled))
File "dune", line 9, characters 0-116:
9 | (rule
10 | (targets
11 | (dir base.tex))
12 | (action
13 | (progn
14 | (run mkdir base.tex)
15 | (run touch base.tex/base.base.tex))))
File "dune", line 1, characters 0-120:
1 | (rule
2 | (targets
3 | (dir base.html))
4 | (action
5 | (progn
6 | (run mkdir base.html)
7 | (run touch base.html/base.base.html))))
Error: The following both define the same directory target:
_build/default/base.tex
- dune:9
_build/default/base.html
- dune:1
- dune:17
[1]
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
Duplicate directory targets

$ dune build
Error: Multiple rules generated for _build/default/foo:
- dune:5
File "dune", line 1, characters 0-53:
1 | (rule
2 | (targets (dir foo))
3 | (action (run mkdir foo)))
Error: The following both define the same directory target:
_build/default/foo
- dune:1
- dune:5
[1]
Loading