Skip to content

Commit 61387c5

Browse files
authored
track opam file metadata in dune-project and rewrite opam files (#2017)
track opam file metadata in dune-project and rewrite opam files
2 parents ea9080d + ca0f643 commit 61387c5

40 files changed

+1235
-181
lines changed

CHANGES.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,10 @@ unreleased
2525
to produce targets that are present in the source tree. This has
2626
been a warning for long enough (#2068, @diml)
2727

28+
- Add more opam metadata and use it to generate corrections to the .opam files
29+
in the source. This allows the user to partially specify opam metadata in the
30+
the dune-project file. (#2017, @avsm, @jonludlam)
31+
2832
1.9.1 (11/04/2019)
2933
------------------
3034

doc/index.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ Welcome to dune's documentation!
2222
configurator
2323
menhir
2424
jsoo
25+
opam
2526
variants
2627
formatting
2728
coq

doc/opam.rst

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
****
2+
opam
3+
****
4+
5+
opam_ is the official package manager for OCaml, and dune offers some
6+
integration with it.
7+
8+
Generating opam files
9+
=====================
10+
11+
Dune is able to use metadata specified in the ``dune-project`` file to cross
12+
reference it with the information in the user written ``.opam`` file. To enable
13+
this integration, a user needs to add an ``(opam ..)`` field to the dune-project
14+
file.
15+
16+
The fields that dune uses for this purpose are:
17+
18+
- ``(license <name>)`` - Specified the license of the project
19+
20+
- ``(authors <authors>)`` - A list of authors
21+
22+
- ``(source <source>)`` - where the source is specified two ways:
23+
``(github <user/repo>)`` or ``(uri <uri>)``
24+
25+
To enable dune suggesting corrections to the opam stanza, the user must specify
26+
an ``(opam <fields>)`` with the fields:
27+
28+
- ``(tags <tags>)`` - Specify the list of tags for all packages
29+
- ``(depends <dep-specification>)`` - The list of dependencies shared by all opam packages
30+
in this dune project
31+
- ``(conflicts <dep-specification>)`` - The list of conflicts shared by all opam
32+
packages in this dune project
33+
- ``(package <package>)`` - the list of packages in this project and their
34+
individual metadata.
35+
36+
The list of dependencies ``<dep-specification>`` is modeled after opam's own
37+
language: The syntax is as a list of the following elements:
38+
39+
.. code::
40+
op := '=' | '<' | '>' | '<>' | '>=' | '<='
41+
42+
stage := :with_test | :build | :dev
43+
44+
constr := (<op> <version>)
45+
46+
logop := or | and
47+
48+
dep := (name <stage>)
49+
| (name <constr>)
50+
| (name (<logop> (<stage> | <constr>)*))
51+
52+
dep-specification = dep+
53+
54+
The `(package <package>)` field contains the fields:
55+
56+
- ``(name <string>)`` is the name of the package
57+
58+
- ``(synopsis <string>)`` is a short package description
59+
60+
- ``(description <string>)`` is a longer package description
61+
62+
- ``(depends <dep-specification>)`` are package specific dependencies
63+
64+
- ``(conflicts <dep-specification)`` are package specific conflicts
65+
66+
Here's a complete example of a dune file with opam metadata specification:
67+
68+
.. code:: scheme
69+
70+
(lang dune 1.10)
71+
(name cohttp)
72+
(source (github mirage/ocaml-cohttp))
73+
(license ISC)
74+
(authors "Anil Madhavapeddy" "Rudi Grinberg")
75+
76+
(opam
77+
(tags org:mirage org:dune)
78+
(depends
79+
(ocaml (>= 4.06.0))
80+
(cohttp (>= 1.0.0)))
81+
(package
82+
(name cohttp)
83+
(synopsis "An OCaml library for HTTP clients and servers")
84+
(description "A longer description")
85+
(depends
86+
(alcotest :with-test)
87+
(dune (and :build (> 1.5)))
88+
(foo (and :dev (> 1.5) (< 2.0)))
89+
(uri (>= 1.9.0))
90+
(uri (< 2.0.0))
91+
(fieldslib (> v0.12))
92+
(fieldslib (< v0.13))))
93+
(package
94+
(name cohttp-async)
95+
(synopsis "HTTP client and server for the Async library")
96+
(description "A _really_ long description")
97+
(depends
98+
(cohttp (>= 1.0.2))
99+
(conduit-async (>= 1.0.3))
100+
(async (>= v0.10.0))
101+
(async (< v0.12)))))
102+
103+
.. _opam: https://opam.ocaml.org/

dune-project

Lines changed: 36 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,38 @@
1-
(lang dune 1.8)
1+
(lang dune 1.10)
22
(name dune)
33

4-
(implicit_transitive_deps false)
4+
(implicit_transitive_deps false)
5+
6+
(license MIT)
7+
(authors "Jane Street Group, LLC <opensource@janestreet.com>")
8+
(source (github ocaml/dune))
9+
10+
(opam
11+
(package
12+
(name dune)
13+
(depends
14+
(ocaml (>= 4.02))
15+
base-unix
16+
base-threads)
17+
(conflicts
18+
(jbuilder (<> "transition"))
19+
(odoc (< 1.3.0)))
20+
(synopsis "Fast, portable and opinionated build system")
21+
(description "
22+
dune is a build system that was designed to simplify the release of
23+
Jane Street packages. It reads metadata from \"dune\" files following a
24+
very simple s-expression syntax.
25+
26+
dune is fast, it has very low-overhead and support parallel builds on
27+
all platforms. It has no system dependencies, all you need to build
28+
dune and packages using dune is OCaml. You don't need or make or bash
29+
as long as the packages themselves don't use bash explicitly.
30+
31+
dune supports multi-package development by simply dropping multiple
32+
repositories into the same directory.
33+
34+
It also supports multi-context builds, such as building against
35+
several opam roots/switches simultaneously. This helps maintaining
36+
packages across several versions of OCaml and gives cross-compilation
37+
for free.
38+
")))

dune.opam

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@ conflicts: [
2121
"jbuilder" {!= "transition"}
2222
"odoc" {< "1.3.0"}
2323
]
24-
2524
synopsis: "Fast, portable and opinionated build system"
2625
description: """
2726
dune is a build system that was designed to simplify the release of

example/sample-projects/hello_world/hello_world.opam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ dev-repo: "git+https://github.com/SpongeBob/hello_world.git"
88
license: "Apache-2.0"
99
build: [
1010
["dune" "build" "-p" name "-j" jobs]
11-
]
11+
]

example/sample-projects/with-configure-step/myproject.opam

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ dev-repo: "git+https://github.com/SpongeBob/myproject.git"
88
license: "Apache-2.0"
99
build: [
1010
["dune" "build" "-p" name "-j" jobs]
11-
]
11+
]

src/blang.ml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,16 @@ module Op = struct
1515
| (Neq | Lt | Lte) , Lt
1616
| (Neq | Gt | Gte) , Gt -> true
1717
| _, _ -> false
18+
19+
let to_dyn =
20+
let open Dyn.Encoder in
21+
function
22+
| Eq -> string "Eq"
23+
| Gt -> string "Gt"
24+
| Gte -> string "Gte"
25+
| Lte -> string "Lte"
26+
| Lt -> string "Lt"
27+
| Neq -> string "Neq"
1828
end
1929

2030
type t =
@@ -43,3 +53,52 @@ let rec eval t ~dir ~f =
4353
let x = String_with_vars.expand x ~mode:Many ~dir ~f
4454
and y = String_with_vars.expand y ~mode:Many ~dir ~f in
4555
Op.eval op (Value.L.compare_vals ~dir x y)
56+
57+
let rec to_dyn =
58+
let open Dyn.Encoder in
59+
function
60+
| Const b -> constr "Const" [bool b]
61+
| Expr e -> constr "Expr" [via_sexp String_with_vars.to_sexp e]
62+
| And t -> constr "And" (List.map ~f:to_dyn t)
63+
| Or t -> constr "Or" (List.map ~f:to_dyn t)
64+
| Compare (o, s1, s2) ->
65+
constr "Compare"
66+
[ Op.to_dyn o
67+
; via_sexp String_with_vars.to_sexp s1
68+
; via_sexp String_with_vars.to_sexp s2
69+
]
70+
71+
let ops =
72+
[ "=", Op.Eq
73+
; ">=", Gte
74+
; "<=", Lt
75+
; ">", Gt
76+
; "<", Lt
77+
; "<>", Neq
78+
]
79+
80+
let decode =
81+
let open Stanza.Decoder in
82+
let ops =
83+
List.map ops ~f:(fun (name, op) ->
84+
( name
85+
, (let+ x = String_with_vars.decode
86+
and+ y = String_with_vars.decode
87+
in
88+
Compare (op, x, y))))
89+
in
90+
let decode =
91+
fix begin fun t ->
92+
if_list
93+
~then_:(
94+
[ "or", repeat t >>| (fun x -> Or x)
95+
; "and", repeat t >>| (fun x -> And x)
96+
] @ ops
97+
|> sum)
98+
~else_:(String_with_vars.decode >>| fun v -> Expr v)
99+
end
100+
in
101+
let+ () = Syntax.since Stanza.syntax (1, 1)
102+
and+ decode = decode
103+
in
104+
decode

src/blang.mli

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,9 @@ val true_ : t
2222
val eval
2323
: t
2424
-> dir:Path.t
25-
-> f:Value.t list option String_with_vars.expander
25+
-> f:Value.t list option String_with_vars.expander
2626
-> bool
27+
28+
val to_dyn : t -> Dyn.t
29+
30+
val decode : t Stanza.Decoder.t

src/dune_file.ml

Lines changed: 0 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -319,43 +319,6 @@ module Preprocess = struct
319319
]))
320320
end
321321

322-
module Blang = struct
323-
include Blang
324-
325-
let ops =
326-
[ "=", Op.Eq
327-
; ">=", Gte
328-
; "<=", Lt
329-
; ">", Gt
330-
; "<", Lt
331-
; "<>", Neq
332-
]
333-
334-
let decode =
335-
let ops =
336-
List.map ops ~f:(fun (name, op) ->
337-
( name
338-
, (let+ x = String_with_vars.decode
339-
and+ y = String_with_vars.decode
340-
in
341-
Compare (op, x, y))))
342-
in
343-
let decode =
344-
fix begin fun t ->
345-
if_list
346-
~then_:(
347-
[ "or", repeat t >>| (fun x -> Or x)
348-
; "and", repeat t >>| (fun x -> And x)
349-
] @ ops
350-
|> sum)
351-
~else_:(String_with_vars.decode >>| fun v -> Expr v)
352-
end
353-
in
354-
let+ () = Syntax.since Stanza.syntax (1, 1)
355-
and+ decode = decode
356-
in
357-
decode
358-
end
359322

360323
let enabled_if =
361324
field "enabled_if" ~default:Blang.true_

0 commit comments

Comments
 (0)