Skip to content

Commit d212acb

Browse files
committed
Enable bisect_ppx via dune-workspace
Signed-off-by: Stephanie You <[email protected]>
1 parent b1a42f6 commit d212acb

19 files changed

+114
-10
lines changed

src/dune/context.ml

+10-5
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ let write_dot_dune_dir ~build_dir ~ocamlc ~ocaml_config_vars =
250250

251251
let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets
252252
~host_context ~host_toolchain ~profile ~fdo_target_exe
253-
~dynamically_linked_foreign_archives =
253+
~dynamically_linked_foreign_archives ~bisect_enabled =
254254
let prog_not_found_in_path prog =
255255
Utils.program_not_found prog ~context:name ~loc:None
256256
in
@@ -485,6 +485,7 @@ let create ~(kind : Kind.t) ~path ~env ~env_nodes ~name ~merlin ~targets
485485
; ccomp_type = Ocaml_config.ccomp_type ocfg
486486
; profile
487487
; ocaml_version = Ocaml_config.version_string ocfg
488+
; bisect_enabled
488489
}
489490
in
490491
if Option.is_some fdo_target_exe then
@@ -597,10 +598,10 @@ let extend_paths t ~env =
597598
Env.extend ~vars env
598599

599600
let default ~merlin ~env_nodes ~env ~targets ~fdo_target_exe
600-
~dynamically_linked_foreign_archives =
601+
~dynamically_linked_foreign_archives ~bisect_enabled =
601602
let path = Env.path env in
602603
create ~kind:Default ~path ~env ~env_nodes ~merlin ~targets ~fdo_target_exe
603-
~dynamically_linked_foreign_archives
604+
~dynamically_linked_foreign_archives ~bisect_enabled
604605

605606
let opam_version =
606607
let f opam =
@@ -631,7 +632,7 @@ let opam_version =
631632

632633
let create_for_opam ~root ~env ~env_nodes ~targets ~profile ~switch ~name
633634
~merlin ~host_context ~host_toolchain ~fdo_target_exe
634-
~dynamically_linked_foreign_archives =
635+
~dynamically_linked_foreign_archives ~bisect_enabled =
635636
let opam =
636637
match Memo.Lazy.force opam with
637638
| None -> Utils.program_not_found "opam" ~loc:None
@@ -682,6 +683,7 @@ let create_for_opam ~root ~env ~env_nodes ~targets ~profile ~switch ~name
682683
~kind:(Opam { root; switch })
683684
~profile ~targets ~path ~env ~env_nodes ~name ~merlin ~host_context
684685
~host_toolchain ~fdo_target_exe ~dynamically_linked_foreign_archives
686+
~bisect_enabled
685687

686688
let instantiate_context env (workspace : Workspace.t)
687689
~(context : Workspace.Context.t) ~host_context =
@@ -701,6 +703,7 @@ let instantiate_context env (workspace : Workspace.t)
701703
; loc = _
702704
; fdo_target_exe
703705
; dynamically_linked_foreign_archives
706+
; bisect_enabled
704707
} ->
705708
let merlin =
706709
workspace.merlin_context = Some (Workspace.Context.name context)
@@ -716,6 +719,7 @@ let instantiate_context env (workspace : Workspace.t)
716719
let env = extend_paths ~env paths in
717720
default ~env ~env_nodes ~profile ~targets ~name ~merlin ~host_context
718721
~host_toolchain ~fdo_target_exe ~dynamically_linked_foreign_archives
722+
~bisect_enabled
719723
| Opam
720724
{ base =
721725
{ targets
@@ -728,6 +732,7 @@ let instantiate_context env (workspace : Workspace.t)
728732
; loc = _
729733
; fdo_target_exe
730734
; dynamically_linked_foreign_archives
735+
; bisect_enabled
731736
}
732737
; switch
733738
; root
@@ -736,7 +741,7 @@ let instantiate_context env (workspace : Workspace.t)
736741
let env = extend_paths ~env paths in
737742
create_for_opam ~root ~env_nodes ~env ~profile ~switch ~name ~merlin
738743
~targets ~host_context ~host_toolchain:toolchain ~fdo_target_exe
739-
~dynamically_linked_foreign_archives
744+
~dynamically_linked_foreign_archives ~bisect_enabled
740745

741746
module Create = struct
742747
module Output = struct

src/dune/dune_file.ml

+39-1
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,24 @@ module Preprocess_map = struct
214214
List.fold_left (Preprocess.pps pp) ~init:acc ~f:(fun acc (loc, pp) ->
215215
Lib_name.Map.set acc pp loc))
216216
|> Lib_name.Map.foldi ~init:[] ~f:(fun pp loc acc -> (loc, pp) :: acc)
217+
218+
let add_bisect t =
219+
let bisect_ppx =
220+
let bisect_name = Lib_name.parse_string_exn (Loc.none, "bisect_ppx") in
221+
(Loc.none, bisect_name)
222+
in
223+
Per_module.map t ~f:(fun pp ->
224+
match pp with
225+
| Preprocess.No_preprocessing ->
226+
let loc = Loc.none in
227+
let pps = [ bisect_ppx ] in
228+
let flags = [] in
229+
let staged = false in
230+
Preprocess.Pps { loc; pps; flags; staged }
231+
| Preprocess.Pps { loc; pps; flags; staged } ->
232+
let pps = bisect_ppx :: pps in
233+
Preprocess.Pps { loc; pps; flags; staged }
234+
| _ -> pp (* TODO: decide if this is the correct behavior *) )
217235
end
218236

219237
module Lint = struct
@@ -359,6 +377,7 @@ module Buildable = struct
359377
; flags : Ocaml_flags.Spec.t
360378
; js_of_ocaml : Js_of_ocaml.t
361379
; allow_overlapping_dependencies : bool
380+
; bisect_ppx : bool
362381
}
363382

364383
let decode ~in_library ~allow_re_export =
@@ -424,6 +443,8 @@ module Buildable = struct
424443
field "js_of_ocaml" Js_of_ocaml.decode ~default:Js_of_ocaml.default
425444
and+ allow_overlapping_dependencies =
426445
field_b "allow_overlapping_dependencies"
446+
and+ bisect_ppx =
447+
field_b "bisect_ppx" ~check:(Dune_lang.Syntax.since Stanza.syntax (2, 5))
427448
and+ version = Dune_lang.Syntax.get_exn Stanza.syntax in
428449
let foreign_stubs =
429450
foreign_stubs
@@ -468,6 +489,7 @@ module Buildable = struct
468489
; flags
469490
; js_of_ocaml
470491
; allow_overlapping_dependencies
492+
; bisect_ppx
471493
}
472494

473495
let has_foreign t =
@@ -481,6 +503,12 @@ module Buildable = struct
481503
Per_module.get t.preprocess dummy_name
482504
else
483505
Preprocess.No_preprocessing
506+
507+
let preprocess t ~(lib_config: Lib_config.t) =
508+
if t.bisect_ppx && lib_config.bisect_enabled then
509+
Preprocess_map.add_bisect t.preprocess
510+
else
511+
t.preprocess
484512
end
485513

486514
module Public_lib = struct
@@ -1031,7 +1059,17 @@ module Library = struct
10311059
let synopsis = conf.synopsis in
10321060
let sub_systems = conf.sub_systems in
10331061
let ppx_runtime_deps = conf.ppx_runtime_libraries in
1034-
let pps = Preprocess_map.pps conf.buildable.preprocess in
1062+
let pps =
1063+
let pps_without_bisect = Preprocess_map.pps conf.buildable.preprocess in
1064+
if lib_config.bisect_enabled && conf.buildable.bisect_ppx then
1065+
let bisect_ppx =
1066+
let bisect_name = Lib_name.parse_string_exn (Loc.none, "bisect_ppx") in
1067+
(Loc.none, bisect_name)
1068+
in
1069+
bisect_ppx :: pps_without_bisect
1070+
else
1071+
pps_without_bisect
1072+
in
10351073
let virtual_deps = conf.virtual_deps in
10361074
let dune_version = Some conf.dune_version in
10371075
let implements = conf.implements in

src/dune/dune_file.mli

+4
Original file line numberDiff line numberDiff line change
@@ -98,13 +98,17 @@ module Buildable : sig
9898
; flags : Ocaml_flags.Spec.t
9999
; js_of_ocaml : Js_of_ocaml.t
100100
; allow_overlapping_dependencies : bool
101+
; bisect_ppx : bool
101102
}
102103

103104
(** Check if the buildable has any foreign stubs or archives. *)
104105
val has_foreign : t -> bool
105106

106107
(** Preprocessing specification used by all modules or [No_preprocessing] *)
107108
val single_preprocess : t -> Preprocess.t
109+
110+
(** Includes bisect_ppx if specified by [lib_config] *)
111+
val preprocess : t -> lib_config:Lib_config.t -> Preprocess_map.t
108112
end
109113

110114
module Public_lib : sig

src/dune/exe_rules.ml

+5-2
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,13 @@ let executables_rules ~sctx ~dir ~expander ~dir_contents ~scope ~compile_info
1515
let ml_sources = Dir_contents.ocaml dir_contents in
1616
Ml_sources.modules_of_executables ml_sources ~first_exe ~obj_dir
1717
in
18+
let ctx = SC.context sctx in
19+
let preprocess =
20+
Dune_file.Buildable.preprocess exes.buildable ~lib_config:ctx.lib_config
21+
in
1822
let pp =
1923
Preprocessing.make sctx ~dir ~dep_kind:Required ~scope ~expander
20-
~preprocess:exes.buildable.preprocess
24+
~preprocess
2125
~preprocessor_deps:exes.buildable.preprocessor_deps
2226
~lint:exes.buildable.lint ~lib_name:None
2327
in
@@ -44,7 +48,6 @@ let executables_rules ~sctx ~dir ~expander ~dir_contents ~scope ~compile_info
4448
(Module_name.to_string mod_name)
4549
])
4650
in
47-
let ctx = SC.context sctx in
4851
let explicit_js_mode = Dune_project.explicit_js_mode (Scope.project scope) in
4952
let linkages =
5053
let module L = Dune_file.Executables.Link_mode in

src/dune/lib_config.ml

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type t =
1414
; ccomp_type : Ocaml_config.Ccomp_type.t
1515
; profile : Profile.t
1616
; ocaml_version : string
17+
; bisect_enabled : bool
1718
}
1819

1920
let var_map =

src/dune/lib_config.mli

+1
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ type t =
1414
; ccomp_type : Ocaml_config.Ccomp_type.t
1515
; profile : Profile.t
1616
; ocaml_version : string
17+
; bisect_enabled : bool
1718
}
1819

1920
val allowed_in_enabled_if : (string * Dune_lang.Syntax.Version.t) list

src/dune/lib_rules.ml

+5-2
Original file line numberDiff line numberDiff line change
@@ -340,10 +340,14 @@ let cctx (lib : Library.t) ~sctx ~source_modules ~dir ~expander ~scope
340340
let flags = Super_context.ocaml_flags sctx ~dir lib.buildable in
341341
let obj_dir = Library.obj_dir ~dir lib in
342342
let vimpl = Virtual_rules.impl sctx ~lib ~scope in
343+
let ctx = Super_context.context sctx in
344+
let preprocess =
345+
Dune_file.Buildable.preprocess lib.buildable ~lib_config:ctx.lib_config
346+
in
343347
(* Preprocess before adding the alias module as it doesn't need preprocessing *)
344348
let pp =
345349
Preprocessing.make sctx ~dir ~dep_kind ~scope
346-
~preprocess:lib.buildable.preprocess ~expander
350+
~preprocess ~expander
347351
~preprocessor_deps:lib.buildable.preprocessor_deps
348352
~lint:lib.buildable.lint
349353
~lib_name:(Some (snd lib.name))
@@ -354,7 +358,6 @@ let cctx (lib : Library.t) ~sctx ~source_modules ~dir ~expander ~scope
354358
let modules = Vimpl.impl_modules vimpl modules in
355359
let requires_compile = Lib.Compile.direct_requires compile_info in
356360
let requires_link = Lib.Compile.requires_link compile_info in
357-
let ctx = Super_context.context sctx in
358361
let dynlink =
359362
Dynlink_supported.get lib.dynlink ctx.supports_shared_libraries
360363
in

src/dune/workspace.ml

+8
Original file line numberDiff line numberDiff line change
@@ -49,6 +49,7 @@ module Context = struct
4949
; paths : (string * Ordered_set_lang.t) list
5050
; fdo_target_exe : Path.t option
5151
; dynamically_linked_foreign_archives : bool
52+
; bisect_enabled : bool
5253
}
5354

5455
let to_dyn = Dyn.Encoder.opaque
@@ -64,6 +65,7 @@ module Context = struct
6465
; paths
6566
; fdo_target_exe
6667
; dynamically_linked_foreign_archives
68+
; bisect_enabled
6769
} t =
6870
Profile.equal profile t.profile
6971
&& List.equal Target.equal targets t.targets
@@ -77,6 +79,7 @@ module Context = struct
7779
&& Option.equal Path.equal fdo_target_exe t.fdo_target_exe
7880
&& Bool.equal dynamically_linked_foreign_archives
7981
t.dynamically_linked_foreign_archives
82+
&& Bool.equal bisect_enabled t.bisect_enabled
8083

8184
let fdo_suffix t =
8285
match t.fdo_target_exe with
@@ -133,6 +136,9 @@ module Context = struct
133136
field "paths" ~default:[]
134137
( Dune_lang.Syntax.since Stanza.syntax (1, 12)
135138
>>> map ~f (repeat (pair (located string) Ordered_set_lang.decode)) )
139+
and+ bisect_enabled =
140+
field ~default:false "bisect_enabled"
141+
(Dune_lang.Syntax.since syntax (2, 5) >>> bool)
136142
and+ loc = loc in
137143
Option.iter host_context ~f:(fun _ ->
138144
match targets with
@@ -153,6 +159,7 @@ module Context = struct
153159
; paths
154160
; fdo_target_exe
155161
; dynamically_linked_foreign_archives
162+
; bisect_enabled
156163
}
157164
end
158165

@@ -293,6 +300,7 @@ module Context = struct
293300
; paths = []
294301
; fdo_target_exe = None
295302
; dynamically_linked_foreign_archives = true
303+
; bisect_enabled = false
296304
}
297305
end
298306

src/dune/workspace.mli

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ module Context : sig
2828
will be built with all foreign archives statically linked into
2929
the runtime system. *)
3030
; dynamically_linked_foreign_archives : bool
31+
; bisect_enabled : bool
3132
}
3233
end
3334

test/blackbox-tests/dune.inc

+10
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,14 @@
4646
test-cases/bin-eager-deps
4747
(progn (run dune-cram run run.t) (diff? run.t run.t.corrected)))))
4848

49+
(rule
50+
(alias bisect-ppx)
51+
(deps (package dune) (source_tree test-cases/bisect-ppx))
52+
(action
53+
(chdir
54+
test-cases/bisect-ppx
55+
(progn (run dune-cram run run.t) (diff? run.t run.t.corrected)))))
56+
4957
(rule
5058
(alias block-strings)
5159
(deps (package dune) (source_tree test-cases/block-strings))
@@ -2458,6 +2466,7 @@
24582466
(alias all-promotions)
24592467
(alias bad-alias-error)
24602468
(alias bin-eager-deps)
2469+
(alias bisect-ppx)
24612470
(alias block-strings)
24622471
(alias byte-code-only)
24632472
(alias byte_complete)
@@ -2750,6 +2759,7 @@
27502759
(alias all-promotions)
27512760
(alias bad-alias-error)
27522761
(alias bin-eager-deps)
2762+
(alias bisect-ppx)
27532763
(alias block-strings)
27542764
(alias byte-code-only)
27552765
(alias byte_complete)

test/blackbox-tests/gen_tests.ml

+1
Original file line numberDiff line numberDiff line change
@@ -255,6 +255,7 @@ let exclusions =
255255
~additional_deps:[ Sexp.strings [ "package"; "dune-configurator" ] ]
256256
; make "mdx-stanza" ~external_deps:true
257257
; make "toplevel-integration" ~external_deps:true
258+
; make "bisect-ppx"
258259
]
259260
|> String_map.of_list_map_exn ~f:(fun (test : Test.t) -> (test.path, test))
260261

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
(library
2+
(name hello)
3+
(modules hello)
4+
(bisect_ppx))
5+
6+
(executable
7+
(name tester)
8+
(modules tester)
9+
(libraries hello))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
(lang dune 2.5)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(lang dune 2.5)
2+
(context (default (bisect_enabled false)))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
(lang dune 2.5)
2+
(context (default (bisect_enabled true)))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
let run () = print_endline "Hello, world!"
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
Test that bisect_ppx is enabled and produces *.coverage file.
2+
$ dune exec --root . ./tester.exe
3+
Hello, world!
4+
$ dune exec bisect-ppx-report -- html
5+
Error: no coverage files given on command line or found
6+
[1]
7+
$ dune exec --root . ./tester.exe --workspace dune-workspace.dev
8+
Hello, world!
9+
$ dune exec bisect-ppx-report -- html
10+
Info: found coverage files in './'
11+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
let () =
2+
Hello.run ()

test/expect-tests/findlib_tests.ml

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ let findlib =
2828
; ccomp_type = Other "gcc"
2929
; profile = Profile.Dev
3030
; ocaml_version = "4.02.3"
31+
; bisect_enabled = false
3132
}
3233
in
3334
Findlib.create ~stdlib_dir:cwd ~paths:[ db_path ]

0 commit comments

Comments
 (0)