package pplumbing

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file log_cli.ml

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
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
module Log_level = struct
  type t = Logs.level option

  let all : t list =
    [ None
    ; Some Logs.App
    ; Some Logs.Error
    ; Some Logs.Warning
    ; Some Logs.Info
    ; Some Logs.Debug
    ]
  ;;

  let to_string : t -> string = function
    | None -> "quiet"
    | Some level ->
      (match level with
       | App -> "app"
       | Error -> "error"
       | Warning -> "warning"
       | Info -> "info"
       | Debug -> "debug")
  ;;
end

module Config = struct
  let logs_level_arg =
    let open Command.Std in
    let+ verbose_count =
      Arg.flag_count
        [ "verbose"; "v" ]
        ~doc:"Increase verbosity. Repeatable, but more than twice does not bring more"
    and+ verbosity =
      Arg.named_opt
        [ "verbosity" ]
        (Param.enumerated (module Log_level))
        ~docv:"LEVEL"
        ~doc:"Be more or less verbose. Takes over $(b,v)."
    and+ quiet =
      Arg.flag [ "quiet"; "q" ] ~doc:"Be quiet. Takes over $(b,v) and $(b,--verbosity)"
    in
    if quiet
    then None
    else (
      match verbosity with
      | Some verbosity -> verbosity
      | None ->
        (match verbose_count with
         | 0 -> Some Logs.Warning
         | 1 -> Some Logs.Info
         | _ -> Some Logs.Debug))
  ;;

  module Fmt_style_renderer = struct
    type t = Fmt.style_renderer option

    let all = [ None; Some `Ansi_tty; Some `None ]

    let to_string = function
      | None -> "auto"
      | Some `Ansi_tty -> "always"
      | Some `None -> "never"
    ;;
  end

  let fmt_style_renderer_arg =
    let open Command.Std in
    Arg.named_with_default
      [ "color" ]
      (Param.enumerated (module Fmt_style_renderer))
      ~default:None
      ~docv:"WHEN"
      ~doc:"Colorize the output"
  ;;

  type t =
    { logs_level : Logs.level option
    ; fmt_style_renderer : Fmt.style_renderer option
    ; warn_error : bool
    }

  let default =
    { logs_level = Some Logs.Warning; fmt_style_renderer = None; warn_error = false }
  ;;

  let create
        ?(logs_level = default.logs_level)
        ?(fmt_style_renderer = default.fmt_style_renderer)
        ?(warn_error = default.warn_error)
        ()
    =
    { logs_level; fmt_style_renderer; warn_error }
  ;;

  let logs_level t = t.logs_level
  let fmt_style_renderer t = t.fmt_style_renderer
  let warn_error t = t.warn_error

  let arg =
    let open Command.Std in
    let+ warn_error = Arg.flag [ "warn-error" ] ~doc:"treat warnings as errors"
    and+ logs_level = logs_level_arg
    and+ fmt_style_renderer = fmt_style_renderer_arg in
    { logs_level; fmt_style_renderer; warn_error }
  ;;

  let to_args { logs_level; fmt_style_renderer; warn_error } =
    List.concat
      [ (match logs_level with
         | None -> [ "--quiet" ]
         | Some level ->
           (match level with
            | App -> [ "--verbosity"; "app" ]
            | Error -> [ "--verbosity"; "error" ]
            | Warning -> []
            | Info -> [ "--verbosity"; "info" ]
            | Debug -> [ "--verbosity"; "debug" ]))
      ; (match fmt_style_renderer with
         | None -> []
         | Some `Ansi_tty -> [ "--color"; "always" ]
         | Some `None -> [ "--color"; "never" ])
      ; (if warn_error then [ "--warn-error" ] else [])
      ]
  ;;
end

let setup_log ~(config : Config.t) =
  Fmt_tty.setup_std_outputs ?style_renderer:config.fmt_style_renderer ();
  let () =
    Err.Private.style_renderer
    := match config.fmt_style_renderer with
       | Some `None -> `None
       | None | Some `Ansi_tty -> `Auto
  in
  Logs.set_level config.logs_level;
  let () =
    Err.Private.set_logs_level
      ~get:(fun () ->
        match Logs.level () with
        | None | Some App -> Quiet
        | Some Error -> Error
        | Some Warning -> Warning
        | Some Info -> Info
        | Some Debug -> Debug)
      ~set:(fun level ->
        (Logs.set_level
           (match level with
            | Quiet -> None
            | Error -> Some Error
            | Warning -> Some Warning
            | Info -> Some Info
            | Debug -> Some Debug) [@coverage off]))
  in
  Logs.set_reporter (Logs_fmt.reporter ())
;;

let setup_config ~config =
  setup_log ~config;
  Err.Private.warn_error := config.warn_error;
  Err.Private.set_logs_counts ~err_count:Logs.err_count ~warn_count:Logs.warn_count;
  ()
;;

let set_config () =
  let open Command.Std in
  let+ config = Config.arg in
  setup_config ~config
;;
OCaml

Innovation. Community. Security.