Skip to content

Commit a43da16

Browse files
committed
fix(opam-create): only upgrade existing menhir deps; do not add new
Fixes #14428. The 3.23 menhir auto-injection (#14168) was triggered by the project-wide `(using menhir ...)` extension and added `menhir` as a new dependency to every package's generated opam file, regardless of whether the package's own `(depends ...)` field declared it. In multi-package projects where only some packages used menhir, every package gained a spurious build-time dependency. The original ask in #10707 was narrower: when a generated opam file *already* lists `menhir`, fill in the lower bound `{>= "20180523"}` that dune's menhir rules require. Restrict the behaviour to that. - A package that does not declare `(depends menhir)` no longer has `menhir` added by dune. - A package that declares bare `(depends menhir)` has the lower bound filled in, as before. - A package whose `(depends ...)` already specifies a constraint (version bound, `{with-test}`, etc.) is preserved verbatim. The convenience of auto-adding `menhir` for users who use a `(menhir ...)` stanza but forget to declare `(depends menhir)` is deliberately removed: the dependency-inference logic that supported it was the source of #14428 and out of scope for #10707. Signed-off-by: Robin Bate Boerop <me@robinbb.com>
1 parent 5fa4ca0 commit a43da16

3 files changed

Lines changed: 44 additions & 36 deletions

File tree

doc/changes/fixed/14434.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
- Fix the `menhir` opam dependency injection introduced in 3.23. Dune
2+
now only fills in the lower bound `{>= "20180523"}` on an existing
3+
user-declared `menhir` dependency; it no longer adds `menhir` as a
4+
new dependency to packages that did not declare it themselves. The
5+
3.23 behaviour, which auto-injected `menhir` into every package's
6+
generated opam file whenever `(using menhir ...)` was enabled,
7+
added spurious build-time dependencies in multi-package projects
8+
where only some packages used menhir. (#14434, fixes #14428,
9+
@robinbb)

src/dune_rules/opam_create.ml

Lines changed: 14 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -300,22 +300,19 @@ let insert_odoc_dep depends =
300300
which dune's menhir rules rely on unconditionally. *)
301301
let menhir_constraint : Package_constraint.t = Uop (Gte, String_literal "20180523")
302302

303-
let insert_menhir_dep depends =
304-
let menhir_dep =
305-
{ Package_dependency.name = menhir_name; constraint_ = Some menhir_constraint }
306-
in
307-
if
308-
List.exists depends ~f:(fun (dep : Package_dependency.t) ->
309-
Package.Name.equal dep.name menhir_name)
310-
then
311-
List.map depends ~f:(fun (dep : Package_dependency.t) ->
312-
if Package.Name.equal dep.name menhir_name
313-
then
314-
{ dep with
315-
constraint_ = Some (Option.value dep.constraint_ ~default:menhir_constraint)
316-
}
317-
else dep)
318-
else depends @ [ menhir_dep ]
303+
(* If the package's [(depends ...)] field already lists [menhir]
304+
without a constraint, fill in the lower bound. Existing user-
305+
written constraints (whether version bounds, [{with-test}], or
306+
anything else) are preserved verbatim. We do not add menhir as a
307+
new dependency: that was the over-injection class fixed by #14428. *)
308+
let upgrade_menhir_constraint depends =
309+
List.map depends ~f:(fun (dep : Package_dependency.t) ->
310+
if Package.Name.equal dep.name menhir_name
311+
then
312+
{ dep with
313+
constraint_ = Some (Option.value dep.constraint_ ~default:menhir_constraint)
314+
}
315+
else dep)
319316
;;
320317

321318
let maintenance_intent dune_version info =
@@ -344,7 +341,7 @@ let opam_fields project (package : Package.t) =
344341
let package =
345342
match Dune_project.find_extension_version project Dune_lang.Menhir.syntax with
346343
| None -> package
347-
| Some _ -> Package.map_depends package ~f:insert_menhir_dep
344+
| Some _ -> Package.map_depends package ~f:upgrade_menhir_constraint
348345
in
349346
let package_fields = package_fields package ~project in
350347
let open Opam_file.Create in
Lines changed: 21 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,55 +1,57 @@
1-
When a project uses (using menhir ...), the generated opam file should include
2-
a lower bound on the menhir version, since dune assumes menhir supports
3-
--infer-write-query and --infer-read-reply (available since menhir 20180523).
1+
When a package's [(depends ...)] field lists [menhir] without a
2+
version constraint, the generated opam file should fill in the
3+
lower bound [{>= "20180523"}], since dune's menhir rules rely on
4+
features available since menhir 20180523.
45

5-
See https://github.com/ocaml/dune/issues/10707
6+
See https://github.com/ocaml/dune/issues/10707.
67

7-
Case 1: menhir used, no explicit menhir dependency declared.
8-
The generated opam file should include "menhir" {>= "20180523"}.
8+
Case 0: package does not declare menhir. Dune does not add it.
99

1010
$ cat > dune-project << EOF
11-
> (lang dune 3.23)
11+
> (lang dune 3.24)
1212
> (using menhir 2.1)
1313
> (generate_opam_files true)
1414
> (package (name foo) (allow_empty))
1515
> EOF
1616

17-
$ dune build @opam --auto-promote > /dev/null 2>&1 || true
17+
$ dune build @opam --auto-promote > /dev/null 2>&1
18+
[1]
19+
$ dune build @opam
1820
$ grep menhir foo.opam
19-
"menhir" {>= "20180523"}
21+
[1]
2022

21-
Case 2: user already declared menhir with a sufficient lower bound.
22-
The auto-injected constraint should not duplicate it.
23+
Case 1: bare [(depends menhir)]. Dune fills in the lower bound.
2324

2425
$ cat > dune-project << EOF
25-
> (lang dune 3.23)
26+
> (lang dune 3.24)
2627
> (using menhir 2.1)
2728
> (generate_opam_files true)
2829
> (package
2930
> (name foo)
3031
> (allow_empty)
31-
> (depends (menhir (>= 20211128))))
32+
> (depends menhir))
3233
> EOF
3334

3435
$ dune build @opam --auto-promote > /dev/null 2>&1
3536
[1]
37+
$ dune build @opam
3638
$ grep menhir foo.opam
37-
"menhir" {>= "20211128"}
39+
"menhir" {>= "20180523"}
3840

39-
Case 3: user declared menhir with no version constraint.
40-
The auto-injected lower bound should be merged in.
41+
Case 2: user-written version bound is preserved verbatim.
4142

4243
$ cat > dune-project << EOF
43-
> (lang dune 3.23)
44+
> (lang dune 3.24)
4445
> (using menhir 2.1)
4546
> (generate_opam_files true)
4647
> (package
4748
> (name foo)
4849
> (allow_empty)
49-
> (depends menhir))
50+
> (depends (menhir (>= 20211128))))
5051
> EOF
5152

5253
$ dune build @opam --auto-promote > /dev/null 2>&1
5354
[1]
55+
$ dune build @opam
5456
$ grep menhir foo.opam
55-
"menhir" {>= "20180523"}
57+
"menhir" {>= "20211128"}

0 commit comments

Comments
 (0)