package ortac-dune

  1. Overview
  2. Docs

Source file wrapper.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
open Utils

type config = {
  interface_file : string;
  package_name : string option;
  ocaml_output : string option;
  dune_output : string option;
}

open Fmt

let get_optional proj suffix config =
  let default =
    str "%s_%s"
      Filename.(basename config.interface_file |> chop_extension)
      suffix
  in
  Option.value (proj config) ~default

let get_ocaml_output = get_optional (fun cfg -> cfg.ocaml_output) "wrapped.ml"

let get_name_output =
  get_optional
    (fun cfg ->
      match cfg.ocaml_output with
      | Some s -> Some (Filename.chop_extension s)
      | None -> None)
    "wrapped"

let get_intf_output =
  get_optional
    (fun cfg ->
      match cfg.ocaml_output with
      | Some s -> Some (Filename.chop_extension s ^ ".mli")
      | None -> None)
    "wrapped.mli"

let wrapper ppf _ = pf ppf "wrapper"

let msg ppf config =
  pf ppf
    "; This file is generated by ortac dune wrapper@\n\
     ; It contains the rules for generating a wrapper for %s@\n"
    config.interface_file

let package config =
  match config.package_name with
  | None -> []
  | Some s -> [ (fun ppf _ -> pf ppf "(package %s)" s) ]

let gen_ortac_lib ppf config =
  let gen_name = get_name_output config in
  let modules ppf _ = pf ppf "(modules %s)" gen_name in
  let name ppf _ = pf ppf "(name %s)" gen_name in
  let stanzas = [ name; modules ] @ package config in
  let library ppf = library ppf stanzas in
  stanza_rule library ppf config

let gen_copy_rule ppf config =
  let copy ppf =
    copy ppf
      [
        (fun ppf _ -> pf ppf "%s" "%{deps}");
        (fun ppf _ -> pf ppf "%s" "%{targets}");
      ]
  in
  let action ppf = action ppf (stanza copy) in
  let stanzas =
    [
      runtest;
      promote;
      targets get_intf_output;
      deps (fun c -> c.interface_file);
      action;
    ]
  in
  let rule ppf = rule ppf stanzas in
  stanza_rule rule ppf config

let gen_ortac_rule ppf config =
  let args = [ ortac; wrapper; with_deps ] in
  let run ppf = run ppf args in
  let ignore_err = ignore_err (stanza run) in
  let action ppf =
    action_with_env "ORTAC_ONLY_PLUGIN" "wrapper" ppf (with_target ignore_err)
  in
  let stanzas =
    [
      runtest;
      promote;
      targets get_ocaml_output;
      deps (fun cfg -> cfg.interface_file);
      action;
    ]
  in
  let rule ppf = rule ppf stanzas in
  stanza_rule rule ppf config

let gen_dune_rules ppf config =
  let rules = [ msg; gen_copy_rule; gen_ortac_rule; gen_ortac_lib ] in
  concat ~sep:cut rules ppf config
OCaml

Innovation. Community. Security.