File: fmt.ml

package info (click to toggle)
ocaml-dune 3.20.2-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 33,564 kB
  • sloc: ml: 175,178; asm: 28,570; ansic: 5,251; sh: 1,096; lisp: 625; makefile: 148; python: 125; cpp: 48; javascript: 10
file content (67 lines) | stat: -rw-r--r-- 2,169 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
open Import

let doc = "Format source code."

let man =
  [ `S "DESCRIPTION"
  ; `P
      {|$(b,dune fmt) runs the formatter on the source code. The formatter is
        automatically selected. ocamlformat is used to format OCaml source code
        ( *.ml and *.mli files) and refmt is used to format Reason source code
        ( *.re and *.rei files).|}
  ; `Blocks Common.help_secs
  ]
;;

let lock_ocamlformat () =
  if Lazy.force Lock_dev_tool.is_enabled
  then
    (* Note that generating the ocamlformat lockdir here means
       that it will be created when a user runs `dune fmt` but not
       when a user runs `dune build @fmt`. It's important that
       this logic remain outside of `dune build`, as `dune
       build` is intended to only build targets, and generating
       a lockdir is not building a target. *)
    Lock_dev_tool.lock_dev_tool Ocamlformat |> Memo.run
  else Fiber.return ()
;;

let run_fmt_command ~(common : Common.t) ~config =
  let open Fiber.O in
  let once () =
    let* () = lock_ocamlformat () in
    let request (setup : Import.Main.build_system) =
      let dir = Path.(relative root) (Common.prefix_target common ".") in
      Alias.in_dir ~name:Dune_rules.Alias.fmt ~recursive:true ~contexts:setup.contexts dir
      |> Alias.request
    in
    Build.run_build_system ~common ~request
    >>| function
    | Ok () -> ()
    | Error `Already_reported -> raise Dune_util.Report_error.Already_reported
  in
  Scheduler.go_with_rpc_server ~common ~config once
;;

let command =
  let term =
    let+ builder = Common.Builder.term
    and+ no_promote =
      Arg.(
        value
        & flag
        & info
            [ "preview" ]
            ~doc:
              "Just print the changes that would be made without actually applying them. \
               This takes precedence over auto-promote as that flag is assumed for this \
               command.")
    in
    let builder =
      Common.Builder.set_promote builder (if no_promote then Never else Automatically)
    in
    let common, config = Common.init builder in
    run_fmt_command ~common ~config
  in
  Cmd.v (Cmd.info "fmt" ~doc ~man ~envs:Common.envs) term
;;