Skip to content

Commit 43300d3

Browse files
committed
avoid command line parsing in a the middle of a library
1 parent cc1de11 commit 43300d3

File tree

5 files changed

+69
-74
lines changed

5 files changed

+69
-74
lines changed

bin/ocamlformat-rpc/main.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,6 @@ let info =
7373
Cmd.info "ocamlformat-rpc" ~version:Ocamlformat_lib.Version.current ~doc
7474
~man
7575

76-
let rpc_main_t = Term.(const Ocamlformat_rpc.run $ const ())
76+
let rpc_main_t = Term.(const (Ocamlformat_rpc.run ~global_conf:None) $ const ())
7777

7878
let () = Stdlib.exit @@ Cmd.eval_result (Cmd.v info rpc_main_t)

bin/ocamlformat/main.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ let run_action action =
8787
| Print_config conf -> Conf.print_config conf ; Ok ()
8888
;;
8989

90-
match Bin_conf.action () with
90+
match Cmdliner.Cmd.eval_value Bin_conf.term with
9191
| Ok (`Ok action) -> (
9292
match run_action action with
9393
| Ok () -> Stdlib.exit 0

lib-rpc-server/ocamlformat_rpc.ml

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,10 @@ let run_config conf c =
6262
in
6363
update conf c
6464

65-
let run_path path =
65+
let run_path ~global_conf path =
6666
match
6767
Bin_conf.build_config ~enable_outside_detected_project:false ~root:None
68-
~file:path ~is_stdin:false
68+
~file:path ~is_stdin:false ?global_conf ()
6969
with
7070
| Ok _ as ok -> ok
7171
| Error e -> Error (`Path_error e)
@@ -93,9 +93,9 @@ let run_format conf x =
9393
; format Expression
9494
; format Use_file ]
9595

96-
let run_format_with_args {Rpc.path; config} conf x =
96+
let run_format_with_args ~global_conf {Rpc.path; config} conf x =
9797
let open Result in
98-
Option.value_map path ~default:(Ok conf) ~f:run_path
98+
Option.value_map path ~default:(Ok conf) ~f:(run_path ~global_conf)
9999
>>= fun conf ->
100100
Option.value_map config ~default:(Ok conf) ~f:(fun c -> run_config conf c)
101101
>>= fun conf -> run_format conf x
@@ -124,7 +124,8 @@ let handle_error e output =
124124
| `Config_error e -> handle_config_error e output
125125
| `Path_error e -> handle_path_error e output
126126

127-
let rec rpc_main = function
127+
let rpc_main ~global_conf v =
128+
let rec rpc_main = function
128129
| Waiting_for_version -> (
129130
match Protocol.Init.read_input stdin with
130131
| `Halt -> Ok ()
@@ -146,7 +147,7 @@ let rec rpc_main = function
146147
| `Unknown | `Error _ -> rpc_main state
147148
| `Format x ->
148149
let conf =
149-
match run_format_with_args Rpc.empty_args conf x with
150+
match run_format_with_args ~global_conf Rpc.empty_args conf x with
150151
| Ok (`Format formatted) ->
151152
Protocol.V1.output stdout (`Format formatted) ;
152153
conf
@@ -169,7 +170,7 @@ let rec rpc_main = function
169170
| `Unknown | `Error _ -> rpc_main state
170171
| `Format (x, format_args) ->
171172
let conf =
172-
match run_format_with_args format_args conf x with
173+
match run_format_with_args ~global_conf format_args conf x with
173174
| Ok (`Format formatted) ->
174175
Protocol.V2.output stdout (`Format (formatted, format_args)) ;
175176
conf
@@ -178,8 +179,10 @@ let rec rpc_main = function
178179
conf
179180
in
180181
rpc_main (Version_defined (v, conf)) ) )
182+
in
183+
rpc_main v
181184

182-
let run () =
185+
let run ~global_conf () =
183186
Stdio.In_channel.set_binary_mode stdin true ;
184187
Stdio.Out_channel.set_binary_mode stdout true ;
185-
rpc_main Waiting_for_version
188+
rpc_main ~global_conf Waiting_for_version

lib/bin_conf/Bin_conf.ml

Lines changed: 51 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -48,8 +48,6 @@ let default =
4848
; ocp_indent_config= false
4949
; config= [] }
5050

51-
let global_conf = ref default
52-
5351
let info =
5452
let doc = "A tool to format OCaml code." in
5553
let man =
@@ -355,11 +353,6 @@ let global_term =
355353
in
356354
term
357355

358-
let set_global_term =
359-
declare_option
360-
~set:(fun conf_modif -> global_conf := conf_modif default)
361-
global_term
362-
363356
(** Do not escape from [build_config] *)
364357
exception Conf_error of string
365358

@@ -392,7 +385,7 @@ let update_from_ocp_indent c loc (oic : IndentConfig.t) =
392385
; match_indent_nested= elt @@ convert_threechoices oic.i_strict_with }
393386
}
394387

395-
let read_config_file ?version_check ?disable_conf_attrs conf = function
388+
let read_config_file ?version_check ?disable_conf_attrs ~ignore_invalid_options conf = function
396389
| File_system.Ocp_indent file -> (
397390
let filename = Fpath.to_string file in
398391
try
@@ -415,7 +408,7 @@ let read_config_file ?version_check ?disable_conf_attrs conf = function
415408
(ocp_indent_conf, conf, errors)
416409
with
417410
| Invalid_argument e
418-
when !global_conf.ignore_invalid_options ->
411+
when ignore_invalid_options ->
419412
warn ~loc "%s" e ;
420413
(ocp_indent_conf, conf, errors)
421414
| Invalid_argument e ->
@@ -444,7 +437,7 @@ let read_config_file ?version_check ?disable_conf_attrs conf = function
444437
line
445438
with
446439
| Ok conf -> (conf, errors)
447-
| Error _ when !global_conf.ignore_invalid_options ->
440+
| Error _ when ignore_invalid_options ->
448441
warn ~loc "ignoring invalid options %S" line ;
449442
(conf, errors)
450443
| Error e -> (conf, e :: errors) )
@@ -505,7 +498,12 @@ let is_in_listing_file ~listings ~filename =
505498
warn ~loc "%s. Ignoring file." err ;
506499
None )
507500

508-
let update_using_env conf =
501+
type global_conf =
502+
{ apply_cli : t -> t
503+
; current : t
504+
}
505+
506+
let update_using_env ~global_conf conf =
509507
let f (config, errors) (name, value) =
510508
match
511509
Decl.update Conf.options ~config ~from:`Env ~name ~value ~inline:false
@@ -514,48 +512,34 @@ let update_using_env conf =
514512
| Error e -> (config, e :: errors)
515513
in
516514
let conf, errors =
517-
List.fold_left !global_conf.config ~init:(conf, []) ~f
515+
List.fold_left global_conf.current.config ~init:(conf, []) ~f
518516
in
519517
match List.rev errors with
520518
| [] -> conf
521519
| l -> failwith_user_errors ~from:"OCAMLFORMAT environment variable" l
522520

523-
let global_lib_term =
524-
Term.(
525-
const (fun conf_modif lib_conf ->
526-
let new_global = conf_modif {!global_conf with lib_conf} in
527-
global_conf := new_global ;
528-
new_global.lib_conf )
529-
$ global_term )
530-
531-
let global_lib_term_eval =
532-
lazy
533-
(let discard = Format.make_formatter (fun _ _ _ -> ()) ignore in
534-
Cmd.eval_value ~err:discard ~help:discard (Cmd.v info global_lib_term)
535-
)
536-
537-
let update_using_cmdline config =
538-
match Lazy.force global_lib_term_eval with
539-
| Ok (`Ok conf_modif) -> conf_modif config
540-
| Error _ | Ok (`Version | `Help) -> config
541-
542-
let build_config ~enable_outside_detected_project ~root ~file ~is_stdin =
521+
let update_using_cmdline ~global_conf config =
522+
let t = global_conf.apply_cli { default with lib_conf = config } in
523+
t.lib_conf, { global_conf with current = t }
524+
525+
let build_config ~enable_outside_detected_project ~root ~file ~is_stdin ~global_conf =
543526
let vfile = Fpath.v file in
544527
let file_abs = Fpath.(vfile |> to_absolute |> normalize) in
545528
let fs =
546529
File_system.make ~enable_outside_detected_project
547-
~disable_conf_files:!global_conf.disable_conf_files
548-
~ocp_indent_config:!global_conf.ocp_indent_config ~root ~file:file_abs
530+
~disable_conf_files:global_conf.current.disable_conf_files
531+
~ocp_indent_config:global_conf.current.ocp_indent_config ~root ~file:file_abs
549532
in
550533
(* [version-check] can be modified by cmdline (evaluated last) but could
551534
lead to errors when parsing the .ocamlformat files (evaluated first).
552535
Similarly, [disable-conf-attrs] could lead to incorrect config. *)
553-
let forward_conf =
536+
let forward_conf, global_conf =
554537
let read_config_file =
555538
read_config_file ~version_check:false ~disable_conf_attrs:false
556539
in
557-
List.fold fs.configuration_files ~init:Conf.default ~f:read_config_file
558-
|> update_using_env |> update_using_cmdline
540+
List.fold fs.configuration_files ~init:Conf.default
541+
~f:(read_config_file ~ignore_invalid_options:global_conf.current.ignore_invalid_options)
542+
|> update_using_env ~global_conf |> update_using_cmdline ~global_conf
559543
in
560544
let conf =
561545
let opr_opts =
@@ -565,10 +549,12 @@ let build_config ~enable_outside_detected_project ~root ~file ~is_stdin =
565549
in
566550
{Conf.default with opr_opts}
567551
in
568-
let conf =
569-
List.fold fs.configuration_files ~init:conf ~f:read_config_file
570-
|> update_using_env |> update_using_cmdline
552+
let conf, global_conf =
553+
List.fold fs.configuration_files ~init:conf
554+
~f:(read_config_file ~ignore_invalid_options:global_conf.current.ignore_invalid_options)
555+
|> update_using_env ~global_conf |> update_using_cmdline ~global_conf
571556
in
557+
let _ = global_conf in
572558
if
573559
(not is_stdin)
574560
&& (not (File_system.has_ocamlformat_file fs))
@@ -603,11 +589,11 @@ let build_config ~enable_outside_detected_project ~root ~file ~is_stdin =
603589
{f with disable= {f.disable with v= not f.disable.v}} )
604590
| None -> conf
605591

606-
let build_config ~enable_outside_detected_project ~root ~file ~is_stdin =
592+
let build_config ~enable_outside_detected_project ~root ~file ~is_stdin ?(global_conf = { current = default; apply_cli = Fn.id }) () =
607593
try
608594
let conf, warn_now =
609595
collect_warnings (fun () ->
610-
build_config ~enable_outside_detected_project ~root ~file ~is_stdin )
596+
build_config ~enable_outside_detected_project ~root ~file ~is_stdin ~global_conf )
611597
in
612598
if not conf.opr_opts.quiet.v then warn_now () ;
613599
Ok conf
@@ -625,19 +611,19 @@ let ( let* ) = Result.( >>= )
625611

626612
let ( let+ ) = Result.( >>| )
627613

628-
let make_action ~enable_outside_detected_project ~root action inputs =
614+
let make_action ~enable_outside_detected_project ~root action inputs ~global_conf =
629615
let make_file ?name kind file =
630616
let name = Option.value ~default:file name in
631617
let+ conf =
632618
build_config ~enable_outside_detected_project ~root ~file:name
633-
~is_stdin:false
619+
~is_stdin:false ~global_conf ()
634620
in
635621
{kind; name; file= File file; conf}
636622
in
637623
let make_stdin ?(name = "<standard input>") kind =
638624
let+ conf =
639625
build_config ~enable_outside_detected_project ~root ~file:name
640-
~is_stdin:false
626+
~is_stdin:false ~global_conf ()
641627
in
642628
{kind; name; file= Stdin; conf}
643629
in
@@ -669,7 +655,8 @@ let make_action ~enable_outside_detected_project ~root action inputs =
669655
(File_system.root_ocamlformat_file ~root |> Fpath.to_string, true)
670656
in
671657
let+ conf =
672-
build_config ~enable_outside_detected_project ~root ~file ~is_stdin
658+
build_config ~enable_outside_detected_project ~root ~file ~is_stdin ~global_conf
659+
()
673660
in
674661
Print_config conf
675662
| (`No_action | `Output _ | `Inplace | `Check), `No_input ->
@@ -692,8 +679,8 @@ let make_action ~enable_outside_detected_project ~root action inputs =
692679
let+ inputs = make_inputs inputs in
693680
Check inputs
694681

695-
let validate_inputs () =
696-
match (!global_conf.inputs, !global_conf.kind, !global_conf.name) with
682+
let validate_inputs ~global_conf =
683+
match (global_conf.inputs, global_conf.kind, global_conf.name) with
697684
| [], _, _ -> Ok `No_input
698685
| [Stdin], None, None ->
699686
Error
@@ -728,36 +715,39 @@ let validate_inputs () =
728715
|> Result.all
729716
|> Result.map ~f:(fun files -> `Several_files files)
730717

731-
let validate_action () =
718+
let validate_action ~global_conf () =
732719
match
733720
List.filter_map
734721
~f:(fun s -> s)
735-
[ Option.map ~f:(fun o -> (`Output o, "--output")) !global_conf.output
736-
; Option.some_if !global_conf.inplace (`Inplace, "--inplace")
737-
; Option.some_if !global_conf.check (`Check, "--check")
738-
; Option.some_if !global_conf.print_config
722+
[ Option.map ~f:(fun o -> (`Output o, "--output")) global_conf.output
723+
; Option.some_if global_conf.inplace (`Inplace, "--inplace")
724+
; Option.some_if global_conf.check (`Check, "--check")
725+
; Option.some_if global_conf.print_config
739726
(`Print_config, "--print-config") ]
740727
with
741728
| [] -> Ok `No_action
742729
| [(action, _)] -> Ok action
743730
| (_, a1) :: (_, a2) :: _ ->
744731
Error (Printf.sprintf "Cannot specify %s with %s" a1 a2)
745732

746-
let validate () =
733+
let validate ~global_conf =
747734
let root =
748-
Option.map !global_conf.root
735+
Option.map global_conf.current.root
749736
~f:Fpath.(fun x -> v x |> to_absolute |> normalize)
750737
in
751738
let enable_outside_detected_project =
752-
!global_conf.enable_outside_detected_project && Option.is_none root
739+
global_conf.current.enable_outside_detected_project && Option.is_none root
753740
in
754741
match
755-
let* action = validate_action () in
756-
let* inputs = validate_inputs () in
757-
make_action ~enable_outside_detected_project ~root action inputs
742+
let* action = validate_action ~global_conf:global_conf.current () in
743+
let* inputs = validate_inputs ~global_conf:global_conf.current in
744+
make_action ~enable_outside_detected_project ~root action inputs ~global_conf
758745
with
759746
| Error e -> `Error (false, e)
760747
| Ok action -> `Ok action
761748

762-
let action () =
763-
Cmd.eval_value (Cmd.v info Term.(ret (const validate $ set_global_term)))
749+
let term =
750+
Cmd.v info
751+
Term.(ret (Syntax.(
752+
let+ apply_cli = global_term in
753+
validate ~global_conf:{ apply_cli; current = apply_cli default })))

lib/bin_conf/Bin_conf.mli

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,14 @@
99
(* *)
1010
(**************************************************************************)
1111

12+
type global_conf
1213
val build_config :
1314
enable_outside_detected_project:bool
1415
-> root:Fpath.t option
1516
-> file:string
1617
-> is_stdin:bool
18+
-> ?global_conf:global_conf
19+
-> unit
1720
-> (Ocamlformat_lib.Conf.t, string) Result.t
1821

1922
type file = Stdin | File of string
@@ -35,5 +38,4 @@ type action =
3538
| Print_config of Ocamlformat_lib.Conf.t
3639
(** Print the configuration and exit. *)
3740

38-
val action :
39-
unit -> (action Cmdliner.Cmd.eval_ok, Cmdliner.Cmd.eval_error) Result.t
41+
val term : action Cmdliner.Cmd.t

0 commit comments

Comments
 (0)