Skip to content

Commit 9703fe6

Browse files
rleshchinskiyRoman Leshchinskiy
andauthored
Refactor Common.init (#8916)
* Refactor Common.init Previously, we would obtain a [Common.t] from [Common.term] but it would be only partially initialised, until we called [Common.init] on it. This seemed unnecessarily unsafe and also made some upcoming changes to tracing harder than they should be. This PR refactors things such that [Common.init] now takes a [Builder.t] (which was partially exposed but not really used externally before) and produces a [Common.t]. [Builder.t] encapsulates how Dune should be initialised and [Common.t] is the result of that initialisation. This seems cleaner. This also allows us to move some config settings into [Builder.t] which were previously sprinkled through the code. The upcoming tracing settings will be able to go in the same spot. Signed-off-by: Roman Leshchinskiy <[email protected]> * Fix dune init Signed-off-by: Roman Leshchinskiy <[email protected]> --------- Signed-off-by: Roman Leshchinskiy <[email protected]> Co-authored-by: Roman Leshchinskiy <[email protected]>
1 parent a3ed6d1 commit 9703fe6

34 files changed

+226
-198
lines changed

bin/build_cmd.ml

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -143,9 +143,9 @@ let runtest_info =
143143

144144
let runtest_term =
145145
let name_ = Arg.info [] ~docv:"DIR" in
146-
let+ common = Common.term
146+
let+ builder = Common.Builder.term
147147
and+ dirs = Arg.(value & pos_all string [ "." ] name_) in
148-
let config = Common.init common in
148+
let common, config = Common.init builder in
149149
let request (setup : Import.Main.build_system) =
150150
Action_builder.all_unit
151151
(List.map dirs ~f:(fun dir ->
@@ -180,14 +180,14 @@ let build =
180180
in
181181
let name_ = Arg.info [] ~docv:"TARGET" in
182182
let term =
183-
let+ common = Common.term
183+
let+ builder = Common.Builder.term
184184
and+ targets = Arg.(value & pos_all dep [] name_) in
185185
let targets =
186186
match targets with
187-
| [] -> [ Common.default_target common ]
187+
| [] -> [ Common.Builder.default_target builder ]
188188
| _ :: _ -> targets
189189
in
190-
let config = Common.init common in
190+
let common, config = Common.init builder in
191191
let request setup =
192192
Target.interpret_targets (Common.root common) config setup targets
193193
in
@@ -209,7 +209,7 @@ let fmt =
209209
]
210210
in
211211
let term =
212-
let+ common = Common.term
212+
let+ builder = Common.Builder.term
213213
and+ no_promote =
214214
Arg.(
215215
value
@@ -221,10 +221,10 @@ let fmt =
221221
This takes precedence over auto-promote as that flag is assumed for this \
222222
command.")
223223
in
224-
let common =
225-
Common.set_promote common (if no_promote then Never else Automatically)
224+
let builder =
225+
Common.Builder.set_promote builder (if no_promote then Never else Automatically)
226226
in
227-
let config = Common.init common in
227+
let common, config = Common.init builder in
228228
let request (setup : Import.Main.build_system) =
229229
let dir = Path.(relative root) (Common.prefix_target common ".") in
230230
Alias.in_dir ~name:Dune_rules.Alias.fmt ~recursive:true ~contexts:setup.contexts dir

bin/clean.ml

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,13 @@ let command =
99
]
1010
in
1111
let term =
12-
let+ common = Common.term in
13-
(* Pass [No_log_file] to prevent the log file from being created. Indeed, we
14-
are going to delete the whole build directory right after and that
15-
includes deleting the log file. Not only creating the log file would be
16-
useless but with some FS this also causes [dune clean] to fail (cf
12+
let+ builder = Common.Builder.term in
13+
(* Disable log file creation. Indeed, we are going to delete the whole build directory
14+
right after and that includes deleting the log file. Not only would creating the
15+
log file be useless but with some FS this also causes [dune clean] to fail (cf
1716
https://github.com/ocaml/dune/issues/2964). *)
18-
let _config = Common.init common ~log_file:No_log_file in
17+
let builder = Common.Builder.disable_log_file builder in
18+
let _common, _config = Common.init builder in
1919
Dune_util.Global_lock.lock_exn ~timeout:None;
2020
Dune_engine.Target_promotion.files_in_source_tree_to_delete ()
2121
|> Path.Source.Set.iter ~f:(fun p -> Path.unlink_no_err (Path.source p));

bin/common.ml

Lines changed: 83 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -554,6 +554,14 @@ let cache_debug_flags_term : Cache_debug_flags.t Term.t =
554554
value initial
555555
;;
556556

557+
module Action_runner = struct
558+
type t =
559+
| No
560+
| Yes of
561+
(Dune_lang.Dep_conf.t Dune_rpc_impl.Server.t
562+
-> (Dune_engine.Action_exec.input -> Dune_engine.Action_runner.t option) Staged.t)
563+
end
564+
557565
module Builder = struct
558566
type t =
559567
{ debug_dep_path : bool
@@ -594,9 +602,20 @@ module Builder = struct
594602
; root : string option
595603
; stats_trace_file : string option
596604
; stats_trace_extended : bool
605+
; allow_builds : bool
606+
; default_root_is_cwd : bool
607+
; action_runner : Action_runner.t
608+
; log_file : Dune_util.Log.File.t
597609
}
598610

599611
let set_root t root = { t with root = Some root }
612+
let forbid_builds t = { t with allow_builds = false; no_print_directory = true }
613+
let set_default_root_is_cwd t x = { t with default_root_is_cwd = x }
614+
let set_action_runner t x = { t with action_runner = x }
615+
let set_log_file t x = { t with log_file = x }
616+
let disable_log_file t = { t with log_file = No_log_file }
617+
let set_promote t v = { t with promote = Some v }
618+
let default_target t = t.default_target
600619

601620
(** Cmdliner documentation markup language
602621
(https://erratique.ch/software/cmdliner/doc/tool_man.html#doclang)
@@ -1023,6 +1042,10 @@ module Builder = struct
10231042
; root
10241043
; stats_trace_file
10251044
; stats_trace_extended
1045+
; allow_builds = true
1046+
; default_root_is_cwd = false
1047+
; action_runner = No
1048+
; log_file = Default
10261049
}
10271050
;;
10281051
end
@@ -1044,7 +1067,6 @@ let dump_memo_graph_file t = t.builder.dump_memo_graph_file
10441067
let dump_memo_graph_format t = t.builder.dump_memo_graph_format
10451068
let dump_memo_graph_with_timing t = t.builder.dump_memo_graph_with_timing
10461069
let file_watcher t = t.builder.file_watcher
1047-
let default_target t = t.builder.default_target
10481070
let prefix_target t s = t.root.reach_from_root_prefix ^ s
10491071

10501072
let rpc t =
@@ -1053,10 +1075,6 @@ let rpc t =
10531075
| `Allow rpc -> `Allow (Lazy.force rpc)
10541076
;;
10551077

1056-
let forbid_builds t =
1057-
{ t with rpc = `Forbid_builds; builder = { t.builder with no_print_directory = true } }
1058-
;;
1059-
10601078
let signal_watcher t =
10611079
match t.rpc with
10621080
| `Allow _ -> `Yes
@@ -1068,7 +1086,6 @@ let signal_watcher t =
10681086
let watch_exclusions t = t.builder.watch_exclusions
10691087
let stats t = t.stats
10701088
let insignificant_changes t = t.builder.insignificant_changes
1071-
let set_promote t v = { t with builder = { t.builder with promote = Some v } }
10721089

10731090
(* To avoid needless recompilations under Windows, where the case of
10741091
[Sys.getcwd] can vary between different invocations of [dune], normalize to
@@ -1134,13 +1151,67 @@ let print_entering_message c =
11341151
Console.print [ Pp.verbatim (sprintf "Leaving directory '%s'" dir) ]))
11351152
;;
11361153

1137-
let init ?action_runner ?log_file c =
1154+
(* CR-someday rleshchinskiy: The split between `build` and `init` seems quite arbitrary,
1155+
we should probably refactor that at some point. *)
1156+
let build (builder : Builder.t) =
1157+
let root =
1158+
Workspace_root.create
1159+
~default_is_cwd:builder.default_root_is_cwd
1160+
~specified_by_user:builder.root
1161+
in
1162+
let stats =
1163+
Option.map builder.stats_trace_file ~f:(fun f ->
1164+
let stats =
1165+
Dune_stats.create
1166+
~extended_build_job_info:builder.stats_trace_extended
1167+
(Out (open_out f))
1168+
in
1169+
Dune_stats.set_global stats;
1170+
stats)
1171+
in
1172+
let rpc =
1173+
if builder.allow_builds
1174+
then
1175+
`Allow
1176+
(lazy
1177+
(let registry =
1178+
match builder.watch with
1179+
| Yes _ -> `Add
1180+
| No -> `Skip
1181+
in
1182+
let lock_timeout =
1183+
match builder.watch with
1184+
| Yes Passive -> Some 1.0
1185+
| _ -> None
1186+
in
1187+
let action_runner = Dune_engine.Action_runner.Rpc_server.create () in
1188+
Dune_rpc_impl.Server.create
1189+
~lock_timeout
1190+
~registry
1191+
~root:root.dir
1192+
~handle:Dune_rules_rpc.register
1193+
~watch_mode_config:builder.watch
1194+
~parse_build:Dune_rules_rpc.parse_build
1195+
stats
1196+
action_runner))
1197+
else `Forbid_builds
1198+
in
1199+
if builder.store_digest_preimage then Dune_engine.Reversible_digest.enable ();
1200+
if builder.print_metrics
1201+
then (
1202+
Memo.Perf_counters.enable ();
1203+
Dune_metrics.enable ());
1204+
{ builder; root; rpc; stats }
1205+
;;
1206+
1207+
let init (builder : Builder.t) =
1208+
let c = build builder in
11381209
if c.root.dir <> Filename.current_dir_name then Sys.chdir c.root.dir;
11391210
Path.set_root (normalize_path (Path.External.cwd ()));
11401211
Path.Build.set_build_dir (Path.Outside_build_dir.of_string c.builder.build_dir);
11411212
(* Once we have the build directory set, initialise the logging. We can't do
11421213
this earlier, because the build log typically goes into [_build/log]. *)
1143-
Log.init () ?file:log_file;
1214+
Log.init () ~file:builder.log_file;
11441215
(* We need to print this before reading the workspace file, so that the editor
11451216
can interpret errors in the workspace file. *)
11461217
print_entering_message c;
@@ -1179,9 +1250,9 @@ let init ?action_runner ?log_file c =
11791250
in
11801251
Log.info [ Pp.textf "Shared cache: %s" (Config.Toggle.to_string config.cache_enabled) ];
11811252
let action_runner =
1182-
match action_runner with
1183-
| None -> None
1184-
| Some f ->
1253+
match builder.action_runner with
1254+
| No -> None
1255+
| Yes f ->
11851256
(match rpc c with
11861257
| `Forbid_builds -> Code_error.raise "action runners require building" []
11871258
| `Allow server -> Some (Staged.unstage @@ f server))
@@ -1240,7 +1311,7 @@ let init ?action_runner ?log_file c =
12401311
let stat = Gc.stat () in
12411312
let path = Path.external_ file in
12421313
Dune_util.Gc.serialize ~path stat);
1243-
config
1314+
c, config
12441315
;;
12451316

12461317
let footer =
@@ -1281,63 +1352,6 @@ let help_secs =
12811352
]
12821353
;;
12831354

1284-
let build (builder : Builder.t) ~default_root_is_cwd =
1285-
let root =
1286-
Workspace_root.create
1287-
~default_is_cwd:default_root_is_cwd
1288-
~specified_by_user:builder.root
1289-
in
1290-
let stats =
1291-
Option.map builder.stats_trace_file ~f:(fun f ->
1292-
let stats =
1293-
Dune_stats.create
1294-
~extended_build_job_info:builder.stats_trace_extended
1295-
(Out (open_out f))
1296-
in
1297-
Dune_stats.set_global stats;
1298-
stats)
1299-
in
1300-
let rpc =
1301-
`Allow
1302-
(lazy
1303-
(let registry =
1304-
match builder.watch with
1305-
| Yes _ -> `Add
1306-
| No -> `Skip
1307-
in
1308-
let lock_timeout =
1309-
match builder.watch with
1310-
| Yes Passive -> Some 1.0
1311-
| _ -> None
1312-
in
1313-
let action_runner = Dune_engine.Action_runner.Rpc_server.create () in
1314-
Dune_rpc_impl.Server.create
1315-
~lock_timeout
1316-
~registry
1317-
~root:root.dir
1318-
~handle:Dune_rules_rpc.register
1319-
~watch_mode_config:builder.watch
1320-
~parse_build:Dune_rules_rpc.parse_build
1321-
stats
1322-
action_runner))
1323-
in
1324-
if builder.store_digest_preimage then Dune_engine.Reversible_digest.enable ();
1325-
if builder.print_metrics
1326-
then (
1327-
Memo.Perf_counters.enable ();
1328-
Dune_metrics.enable ());
1329-
{ builder; root; rpc; stats }
1330-
;;
1331-
1332-
let term ~default_root_is_cwd =
1333-
let+ builder = Builder.term in
1334-
build builder ~default_root_is_cwd
1335-
;;
1336-
1337-
let term_with_default_root_is_cwd = term ~default_root_is_cwd:true
1338-
let term = term ~default_root_is_cwd:false
1339-
let build = build ~default_root_is_cwd:false
1340-
13411355
let envs =
13421356
Cmd.Env.
13431357
[ info

bin/common.mli

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@ val rpc
1414
| `Forbid_builds (** Promise not to build anything. For now, this isn't checked *)
1515
]
1616

17-
val forbid_builds : t -> t
1817
val signal_watcher : t -> [ `Yes | `No ]
1918
val watch_exclusions : t -> string list
2019
val stats : t -> Dune_stats.t option
@@ -24,23 +23,41 @@ val dump_memo_graph_format : t -> Dune_graph.Graph.File_format.t
2423
val dump_memo_graph_with_timing : t -> bool
2524
val watch : t -> Dune_rpc_impl.Watch_mode_config.t
2625
val file_watcher : t -> Dune_engine.Scheduler.Run.file_watcher
27-
val default_target : t -> Arg.Dep.t
2826
val prefix_target : t -> string -> string
2927
val insignificant_changes : t -> [ `React | `Ignore ]
3028

31-
(** [init] executes sequence of side-effecting actions to initialize Dune's
32-
working environment based on the options determined in a [Common.t]
33-
record.contents.
29+
module Action_runner : sig
30+
type t =
31+
| No
32+
| Yes of
33+
(Dune_lang.Dep_conf.t Dune_rpc_impl.Server.t
34+
-> (Dune_engine.Action_exec.input -> Dune_engine.Action_runner.t option) Staged.t)
35+
end
36+
37+
(** [Builder] describes how to initialize Dune. *)
38+
module Builder : sig
39+
type t
40+
41+
val set_root : t -> string -> t
42+
val forbid_builds : t -> t
43+
val set_default_root_is_cwd : t -> bool -> t
44+
val set_action_runner : t -> Action_runner.t -> t
45+
val set_log_file : t -> Dune_util.Log.File.t -> t
46+
val disable_log_file : t -> t
47+
val set_promote : t -> Dune_engine.Clflags.Promote.t -> t
48+
val default_target : t -> Arg.Dep.t
49+
val term : t Cmdliner.Term.t
50+
end
51+
52+
val build : Builder.t -> t
3453

35-
Return the final configuration, which is the same as the one returned in the
36-
[config] field of [Dune_rules.Workspace.workspace ()]) *)
37-
val init
38-
: ?action_runner:
39-
(Dune_lang.Dep_conf.t Dune_rpc_impl.Server.t
40-
-> (Dune_engine.Action_exec.input -> Dune_engine.Action_runner.t option) Staged.t)
41-
-> ?log_file:Dune_util.Log.File.t
42-
-> t
43-
-> Dune_config.t
54+
(** [init] creates a [Common.t] by executing a sequence of side-effecting actions to
55+
initialize Dune's working environment based on the options determined in the\
56+
[Builder.t].
57+
58+
Return the [Common.t] and the final configuration, which is the same as the one
59+
returned in the [config] field of [Dune_rules.Workspace.workspace ()]) *)
60+
val init : Builder.t -> t * Dune_config_file.Dune_config.t
4461

4562
(** [examples [("description", "dune cmd foo"); ...]] is an [EXAMPLES] manpage
4663
section of enumerated examples illustrating how to run the documented
@@ -54,10 +71,7 @@ val command_synopsis : string list -> Cmdliner.Manpage.block list
5471

5572
val help_secs : Cmdliner.Manpage.block list
5673
val footer : Cmdliner.Manpage.block
57-
val term : t Cmdliner.Term.t
58-
val term_with_default_root_is_cwd : t Cmdliner.Term.t
5974
val envs : Cmdliner.Cmd.Env.info list
60-
val set_promote : t -> Dune_engine.Clflags.Promote.t -> t
6175
val debug_backtraces : bool Cmdliner.Term.t
6276
val config_from_config_file : Dune_config.Partial.t Cmdliner.Term.t
6377
val display_term : Dune_config.Display.t option Cmdliner.Term.t
@@ -73,12 +87,3 @@ module Let_syntax : sig
7387
val ( let+ ) : 'a Cmdliner.Term.t -> ('a -> 'b) -> 'b Cmdliner.Term.t
7488
val ( and+ ) : 'a Cmdliner.Term.t -> 'b Cmdliner.Term.t -> ('a * 'b) Cmdliner.Term.t
7589
end
76-
77-
module Builder : sig
78-
type t
79-
80-
val set_root : t -> string -> t
81-
val term : t Cmdliner.Term.t
82-
end
83-
84-
val build : Builder.t -> t

0 commit comments

Comments
 (0)