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
open Astring
type stanza = string option
type t = string list
let stanza v = Some (String.trim v)
let stanzaf fmt = Fmt.kstr stanza fmt
let v x : t =
List.fold_left
(fun acc -> function None -> acc | Some f -> f :: acc)
[] (List.rev x)
let pp_list pp = Fmt.(list ~sep:(any "\n\n") pp)
let pp ppf (t : t) = Fmt.pf ppf "%a" (pp_list Fmt.string) t
let to_string t = Fmt.to_to_string pp t ^ "\n"
let compact_list ?(indent = 2) field ppf l =
let all = Buffer.create 1024 in
let line = Buffer.create 70 in
let sep = "\n" ^ String.v ~len:indent (fun _ -> ' ') in
let first_char = ref true in
let first_line = ref true in
let flush () =
Buffer.add_buffer all line;
Buffer.clear line;
Buffer.add_string line sep;
first_line := false
in
List.iter
(fun w ->
let max = if !first_line then 75 - indent - String.length field else 75 in
let wn = String.length w in
if wn >= 40 || Buffer.length line + wn >= max then flush ();
if not !first_char then Buffer.add_char line ' ';
first_char := false;
Buffer.add_string line w)
l;
flush ();
Fmt.pf ppf "%s" (Buffer.contents all)
let config_rule ~config_ml_file ~packages =
let pkgs =
match packages with
| [] -> ""
| pkgs ->
let pkgs =
List.fold_left
(fun acc pkg ->
let pkgs = String.Set.of_list (Package.libraries pkg) in
String.Set.union pkgs acc)
String.Set.empty pkgs
|> String.Set.elements
in
String.concat ~sep:" " pkgs
in
let rename_config_file =
let config_ml_file = Fpath.base config_ml_file in
let ext = Fpath.get_ext config_ml_file in
let name = Fpath.rem_ext config_ml_file |> Fpath.to_string in
if name = "config" then []
else
[
stanzaf "(rule (copy# %s config%s))"
(Fpath.to_string config_ml_file)
ext;
]
in
let contents =
stanzaf
{|
(executable
(name config)
(modules config)
(flags :standard -warn-error -A)
(libraries %s))
|}
pkgs
in
v (rename_config_file @ [ contents ])
let base ~packages ~config_ml_file =
let dune_base = config_rule ~config_ml_file ~packages in
let disable_conflicting_directories = "(data_only_dirs duniverse dist)" in
disable_conflicting_directories :: dune_base
let base_project = [ stanza "(lang dune 2.9)" ]
let base_workspace = v [ stanza "(lang dune 2.9)\n(context default)" ]