|
1 | | -Baseline: consumer-module rebuild count when individual modules of |
2 | | -an unwrapped dependency library change. |
| 1 | +Baseline: consumer-module rebuild targets when individual modules |
| 2 | +of an unwrapped dependency library change. |
3 | 3 |
|
4 | | -This is an observational test. It records the number of rebuild |
5 | | -targets for a single consumer module C when each of three entry |
6 | | -modules (A1, A2, A3) of the dependency library [base] has its |
7 | | -interface edited. C references only A2. |
| 4 | +This is an observational test. It records the rebuild targets for |
| 5 | +the consumer module [consumer] when each of three entry modules of |
| 6 | +the dependency library [dep_lib] has its interface edited. |
| 7 | +[consumer] references only [Referenced_dep] from [dep_lib]; |
| 8 | +[Unread_dep_a] and [Unread_dep_b] are present but unreferenced. |
8 | 9 |
|
9 | | -On current main, editing any one of A1/A2/A3 causes C to rebuild |
| 10 | +On current main, editing any of the three rebuilds [consumer] |
10 | 11 | because library-level dependency filtering (and, within that, |
11 | 12 | per-module tightening) is not yet in place: the consumer is |
12 | 13 | conservatively rebuilt whenever any entry module's cmi changes. |
13 | 14 | Work on https://github.com/ocaml/dune/issues/4572 is expected to |
14 | | -tighten this, at which point editing A1 or A3 leaves C untouched |
15 | | -and the emitted counts are promoted. |
| 15 | +tighten this, at which point editing [Unread_dep_a] or |
| 16 | +[Unread_dep_b] leaves [consumer] untouched and the emitted target |
| 17 | +list becomes empty. |
16 | 18 |
|
17 | 19 | See: https://github.com/ocaml/dune/issues/4572 |
18 | 20 |
|
19 | 21 | $ cat > dune-project <<EOF |
20 | | - > (lang dune 3.22) |
| 22 | + > (lang dune 3.23) |
21 | 23 | > EOF |
22 | 24 |
|
23 | | -base is an unwrapped library with three entry modules, each with an |
24 | | -explicit interface so signature changes propagate through .cmi files: |
| 25 | +[dep_lib] is an unwrapped library with three entry modules, each |
| 26 | +with an explicit interface so signature changes propagate through |
| 27 | +.cmi files: |
25 | 28 |
|
26 | | - $ mkdir base |
27 | | - $ cat > base/dune <<EOF |
28 | | - > (library (name base) (wrapped false)) |
| 29 | + $ mkdir dep_lib |
| 30 | + $ cat > dep_lib/dune <<EOF |
| 31 | + > (library (name dep_lib) (wrapped false)) |
29 | 32 | > EOF |
30 | | - $ cat > base/a1.ml <<EOF |
| 33 | + $ cat > dep_lib/unread_dep_a.ml <<EOF |
31 | 34 | > let v = 1 |
32 | 35 | > EOF |
33 | | - $ cat > base/a1.mli <<EOF |
| 36 | + $ cat > dep_lib/unread_dep_a.mli <<EOF |
34 | 37 | > val v : int |
35 | 38 | > EOF |
36 | | - $ cat > base/a2.ml <<EOF |
| 39 | + $ cat > dep_lib/referenced_dep.ml <<EOF |
37 | 40 | > let v = 2 |
38 | 41 | > EOF |
39 | | - $ cat > base/a2.mli <<EOF |
| 42 | + $ cat > dep_lib/referenced_dep.mli <<EOF |
40 | 43 | > val v : int |
41 | 44 | > EOF |
42 | | - $ cat > base/a3.ml <<EOF |
| 45 | + $ cat > dep_lib/unread_dep_b.ml <<EOF |
43 | 46 | > let v = 3 |
44 | 47 | > EOF |
45 | | - $ cat > base/a3.mli <<EOF |
| 48 | + $ cat > dep_lib/unread_dep_b.mli <<EOF |
46 | 49 | > val v : int |
47 | 50 | > EOF |
48 | 51 |
|
49 | | -consumer has two modules. The module of interest, [c.ml], references |
50 | | -only [A2] from [base]. A second, unused module [d.ml] is present only |
51 | | -to keep [consumer] a multi-module stanza: dune skips ocamldep for |
52 | | -single-module stanzas with no library deps as an optimisation, and |
53 | | -the per-module-lib-deps filter depends on ocamldep output. Including |
54 | | -[d.ml] isolates this test from the skip-ocamldep optimisation so the |
55 | | -rebuild count for [c] reflects only the per-module filter's work: |
| 52 | +[consumer_lib] has two modules. The module of interest, [consumer], |
| 53 | +references only [Referenced_dep] from [dep_lib]. A second, unused |
| 54 | +module [filler] is present only to keep [consumer_lib] a multi- |
| 55 | +module stanza: dune skips ocamldep for single-module stanzas with |
| 56 | +no library deps as an optimisation, and the per-module-lib-deps |
| 57 | +filter depends on ocamldep output. Including [filler] isolates |
| 58 | +this test from the skip-ocamldep optimisation so the rebuild |
| 59 | +targets for [consumer] reflect only the per-module filter's work: |
56 | 60 |
|
57 | | - $ mkdir consumer |
58 | | - $ cat > consumer/dune <<EOF |
59 | | - > (library (name consumer) (wrapped false) (libraries base)) |
| 61 | + $ mkdir consumer_lib |
| 62 | + $ cat > consumer_lib/dune <<EOF |
| 63 | + > (library (name consumer_lib) (wrapped false) (libraries dep_lib)) |
60 | 64 | > EOF |
61 | | - $ cat > consumer/c.ml <<EOF |
62 | | - > let w = A2.v |
| 65 | + $ cat > consumer_lib/consumer.ml <<EOF |
| 66 | + > let w = Referenced_dep.v |
63 | 67 | > EOF |
64 | | - $ cat > consumer/d.ml <<EOF |
| 68 | + $ cat > consumer_lib/filler.ml <<EOF |
65 | 69 | > let _ = () |
66 | 70 | > EOF |
67 | 71 |
|
68 | 72 | $ dune build @check |
69 | 73 |
|
70 | | -Edit A1's interface — a module C does not reference — and record |
71 | | -the rebuild-target count for C: |
| 74 | +Edit [Unread_dep_a]'s interface — a module [consumer] does not |
| 75 | +reference — and record the rebuild targets for [consumer]: |
72 | 76 |
|
73 | | - $ cat > base/a1.mli <<EOF |
| 77 | + $ cat > dep_lib/unread_dep_a.mli <<EOF |
74 | 78 | > val v : int |
75 | 79 | > val extra : unit -> int |
76 | 80 | > EOF |
77 | | - $ cat > base/a1.ml <<EOF |
| 81 | + $ cat > dep_lib/unread_dep_a.ml <<EOF |
78 | 82 | > let v = 1 |
79 | 83 | > let extra () = 7 |
80 | 84 | > EOF |
81 | 85 | $ dune build @check |
82 | | - $ dune trace cat | jq -s 'include "dune"; [.[] | targetsMatchingFilter(test("consumer/\\.consumer\\.objs/byte/c\\."))] | length' |
83 | | - 1 |
| 86 | + $ dune trace cat | jq -s 'include "dune"; [.[] | targetsMatchingFilter(test("consumer_lib/\\.consumer_lib\\.objs/byte/consumer\\."))]' |
| 87 | + [ |
| 88 | + { |
| 89 | + "target_files": [ |
| 90 | + "_build/default/consumer_lib/.consumer_lib.objs/byte/consumer.cmi", |
| 91 | + "_build/default/consumer_lib/.consumer_lib.objs/byte/consumer.cmo", |
| 92 | + "_build/default/consumer_lib/.consumer_lib.objs/byte/consumer.cmt" |
| 93 | + ] |
| 94 | + } |
| 95 | + ] |
84 | 96 |
|
85 | | -Same for A3: |
| 97 | +Same for [Unread_dep_b]: |
86 | 98 |
|
87 | | - $ cat > base/a3.mli <<EOF |
| 99 | + $ cat > dep_lib/unread_dep_b.mli <<EOF |
88 | 100 | > val v : int |
89 | 101 | > val other : string |
90 | 102 | > EOF |
91 | | - $ cat > base/a3.ml <<EOF |
| 103 | + $ cat > dep_lib/unread_dep_b.ml <<EOF |
92 | 104 | > let v = 3 |
93 | 105 | > let other = "hi" |
94 | 106 | > EOF |
95 | 107 | $ dune build @check |
96 | | - $ dune trace cat | jq -s 'include "dune"; [.[] | targetsMatchingFilter(test("consumer/\\.consumer\\.objs/byte/c\\."))] | length' |
97 | | - 1 |
| 108 | + $ dune trace cat | jq -s 'include "dune"; [.[] | targetsMatchingFilter(test("consumer_lib/\\.consumer_lib\\.objs/byte/consumer\\."))]' |
| 109 | + [ |
| 110 | + { |
| 111 | + "target_files": [ |
| 112 | + "_build/default/consumer_lib/.consumer_lib.objs/byte/consumer.cmi", |
| 113 | + "_build/default/consumer_lib/.consumer_lib.objs/byte/consumer.cmo", |
| 114 | + "_build/default/consumer_lib/.consumer_lib.objs/byte/consumer.cmt" |
| 115 | + ] |
| 116 | + } |
| 117 | + ] |
98 | 118 |
|
99 | | -Edit A2's interface — the one module C does reference — and check |
100 | | -that the count is positive (C must rebuild): |
| 119 | +Edit [Referenced_dep]'s interface — the one module [consumer] does |
| 120 | +reference — and record the rebuild targets ([consumer] must |
| 121 | +rebuild): |
101 | 122 |
|
102 | | - $ cat > base/a2.mli <<EOF |
| 123 | + $ cat > dep_lib/referenced_dep.mli <<EOF |
103 | 124 | > val v : int |
104 | 125 | > val new_fn : int -> int |
105 | 126 | > EOF |
106 | | - $ cat > base/a2.ml <<EOF |
| 127 | + $ cat > dep_lib/referenced_dep.ml <<EOF |
107 | 128 | > let v = 2 |
108 | 129 | > let new_fn x = x + 1 |
109 | 130 | > EOF |
110 | 131 | $ dune build @check |
111 | | - $ dune trace cat | jq -s 'include "dune"; [.[] | targetsMatchingFilter(test("consumer/\\.consumer\\.objs/byte/c\\."))] | length > 0' |
112 | | - true |
| 132 | + $ dune trace cat | jq -s 'include "dune"; [.[] | targetsMatchingFilter(test("consumer_lib/\\.consumer_lib\\.objs/byte/consumer\\."))]' |
| 133 | + [ |
| 134 | + { |
| 135 | + "target_files": [ |
| 136 | + "_build/default/consumer_lib/.consumer_lib.objs/byte/consumer.cmi", |
| 137 | + "_build/default/consumer_lib/.consumer_lib.objs/byte/consumer.cmo", |
| 138 | + "_build/default/consumer_lib/.consumer_lib.objs/byte/consumer.cmt" |
| 139 | + ] |
| 140 | + } |
| 141 | + ] |
0 commit comments