Skip to content

Add support for x-maintenance-intent in dune-project #11274

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 5 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions doc/changes/11274.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
- Support for opam `(maintenance_intent ...)` in dune-project (#11274, @art-w)
2 changes: 2 additions & 0 deletions doc/howto/opam-file-generation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -81,13 +81,15 @@ For example, if your opam file looks like:
"conduit-async" { >= "1.0.3" }
"async" { >= "v0.10.0" }
]
x-maintenance-intent: [ "(latest)" ]

You can express this as::

(source (github mirage/ocaml-cohttp))
(license ISC)
(authors "Anil Madhavapeddy" "Rudi Grinberg")
(maintainers "[email protected]")
(maintenance_intent "(latest)")

(package
(name cohttp-async)
Expand Down
13 changes: 13 additions & 0 deletions doc/reference/dune-project/generate_opam_files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,19 @@ defined in the project:
"Jane Doe <[email protected]>"
"John Doe <[email protected]>")

.. _maintenance_intent:
.. describe:: (maintenance_intent <strings>)

.. versionadded:: 3.18

Specify the `opam maintenance intent <https://github.com/ocaml/opam-repository/blob/master/governance/policies/archiving.md#specification-of-the-x--fields-used-in-the-archiving-process>`__.

Example:

.. code:: dune

(maintenance_intent "(latest)")

.. describe:: (source ...)

.. versionadded:: 1.7
Expand Down
7 changes: 7 additions & 0 deletions doc/reference/dune-project/package.rst
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,13 @@ package

The same as (and takes precedences over) the corresponding global field.

.. describe:: (maintenance_intent ...)

.. versionadded:: 3.18

The same as (and takes precedences over) the corresponding global field.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you add a link to the global field? The global field has the links to the documentation which is nice, so being able to go there directly without having to search for it would be useful.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there any way to link to an anchor with rst?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Leonidas-from-XIV for uniformity, I don't think this is what we want. If you look above, there is no link to global.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@art-w No, I don't think so, at least not easily. I think the other file would need to define a named reference at the location where the field is defined and we would need to link to that. Or use a plugin which automatically creates these anchors. If you find an easier way, I'd love to know about it, it does feel like an odd omission in reST/RTD.

@maiste I understand your uniformity argument but I think it should not prevent us from making the documentation easier to navigate. I think it is always better to add a link (and we could do that for other fields that allow overriding as well, or say "all the fields are overrides of the global, link here", though that's not really true as you can't have global depends)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, my argument makes more sense regarding the code than the documentation. I'm fine with both in the end 😄

See :doc:`the global field for details </reference/dune-project/generate_opam_files>`.

.. describe:: (source ...)

.. versionadded:: 2.0
Expand Down
11 changes: 9 additions & 2 deletions src/dune_config_file/dune_config_file.ml
Original file line number Diff line number Diff line change
Expand Up @@ -20,21 +20,27 @@ module Dune_config = struct
type t =
{ authors : string list option
; maintainers : string list option
; maintenance_intent : string list option
; license : string list option
}

let decode =
fields
(let+ authors = field_o "authors" (repeat string)
and+ maintainers = field_o "maintainers" (repeat string)
and+ maintenance_intent = field_o "maintenance_intent" (repeat string)
and+ license = field_o "license" (repeat string) in
{ authors; maintainers; license })
{ authors; maintainers; maintenance_intent; license })
;;

let to_dyn t =
let f = Dyn.(option (list string)) in
Dyn.record
[ "authors", f t.authors; "maintainers", f t.maintainers; "license", f t.license ]
[ "authors", f t.authors
; "maintainers", f t.maintainers
; "maintenance_intent", f t.maintenance_intent
; "license", f t.license
]
;;
end

Expand Down Expand Up @@ -359,6 +365,7 @@ module Dune_config = struct
; project_defaults =
{ authors = Some [ "Author Name <[email protected]>" ]
; maintainers = Some [ "Maintainer Name <[email protected]>" ]
; maintenance_intent = None
; license = Some [ "LICENSE" ]
}
; experimental = []
Expand Down
1 change: 1 addition & 0 deletions src/dune_config_file/dune_config_file.mli
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ module Dune_config : sig
type t =
{ authors : string list option
; maintainers : string list option
; maintenance_intent : string list option
; license : string list option
}

Expand Down
61 changes: 56 additions & 5 deletions src/dune_lang/package_info.ml
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ type t =
; bug_reports : string option
; documentation : string option
; maintainers : string list option
; maintenance_intent : string list option
}

let source t = t.source
Expand All @@ -29,6 +30,7 @@ let bug_reports t =

let documentation t = t.documentation
let maintainers t = t.maintainers
let maintenance_intent t = t.maintenance_intent

let empty =
{ source = None
Expand All @@ -38,6 +40,7 @@ let empty =
; bug_reports = None
; documentation = None
; maintainers = None
; maintenance_intent = None
}
;;

Expand All @@ -54,10 +57,20 @@ let example ~authors ~maintainers ~license =
(* homepage and bug_reports are inferred from the source *)
; homepage = None
; bug_reports = None
; maintenance_intent = None
}
;;

let to_dyn { source; license; authors; homepage; bug_reports; documentation; maintainers }
let to_dyn
{ source
; license
; authors
; homepage
; bug_reports
; documentation
; maintainers
; maintenance_intent
}
=
let open Dyn in
record
Expand All @@ -67,18 +80,28 @@ let to_dyn { source; license; authors; homepage; bug_reports; documentation; mai
; "documentation", (option string) documentation
; "bug_reports", (option string) bug_reports
; "maintainers", option (list string) maintainers
; "maintenance_intent", option (list string) maintenance_intent
; "authors", option (list string) authors
]
;;

let encode_fields
{ source; authors; license; homepage; documentation; bug_reports; maintainers }
{ source
; authors
; license
; homepage
; documentation
; bug_reports
; maintainers
; maintenance_intent
}
=
let open Encoder in
record_fields
[ field_o "source" Source_kind.encode source
; field_l "authors" string (Option.value ~default:[] authors)
; field_l "maintainers" string (Option.value ~default:[] maintainers)
; field_l "maintenance_intent" string (Option.value ~default:[] maintenance_intent)
; field_l "license" string (Option.value ~default:[] license)
; field_o "homepage" string homepage
; field_o "documentation" string documentation
Expand Down Expand Up @@ -109,8 +132,18 @@ let decode ?since () =
field_o "bug_reports" (Syntax.since Stanza.syntax (v (1, 10)) >>> string)
and+ maintainers =
field_o "maintainers" (Syntax.since Stanza.syntax (v (1, 10)) >>> repeat string)
and+ maintenance_intent =
field_o "maintenance_intent" (Syntax.since Stanza.syntax (v (3, 18)) >>> repeat string)
in
{ source; authors; license; homepage; documentation; bug_reports; maintainers }
{ source
; authors
; license
; homepage
; documentation
; bug_reports
; maintainers
; maintenance_intent
}
;;

let superpose t1 t2 =
Expand All @@ -126,9 +159,27 @@ let superpose t1 t2 =
; documentation = f t1.documentation t2.documentation
; bug_reports = f t1.bug_reports t2.bug_reports
; maintainers = f t1.maintainers t2.maintainers
; maintenance_intent = f t1.maintenance_intent t2.maintenance_intent
}
;;

let create ~maintainers ~authors ~homepage ~bug_reports ~documentation ~license ~source =
{ maintainers; authors; homepage; bug_reports; documentation; license; source }
let create
~maintainers
~maintenance_intent
~authors
~homepage
~bug_reports
~documentation
~license
~source
=
{ maintainers
; authors
; homepage
; bug_reports
; documentation
; license
; source
; maintenance_intent
}
;;
2 changes: 2 additions & 0 deletions src/dune_lang/package_info.mli
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ val homepage : t -> string option
val bug_reports : t -> string option
val documentation : t -> string option
val maintainers : t -> string list option
val maintenance_intent : t -> string list option

(** example package info (used for project initialization ) *)
val example
Expand All @@ -28,6 +29,7 @@ val superpose : t -> t -> t

val create
: maintainers:string list option
-> maintenance_intent:string list option
-> authors:string list option
-> homepage:string option
-> bug_reports:string option
Expand Down
1 change: 1 addition & 0 deletions src/dune_pkg/opam_file.ml
Original file line number Diff line number Diff line change
Expand Up @@ -260,6 +260,7 @@ let load_opam_file_with_contents ~contents:opam_file_string file name =
let info =
Dune_lang.Package_info.create
~maintainers:(get_many "maintainer")
~maintenance_intent:(get_many "x-maintenance-intent")
~authors:(get_many "authors")
~homepage:(get_one "homepage")
~bug_reports:(get_one "bug-reports")
Expand Down
10 changes: 10 additions & 0 deletions src/dune_rules/opam_create.ml
Original file line number Diff line number Diff line change
Expand Up @@ -196,6 +196,15 @@ let insert_odoc_dep depends =
loop [] depends
;;

let maintenance_intent dune_version info =
if dune_version < (3, 18)
then None
else (
match Package_info.maintenance_intent info with
| None -> Some [ "(latest)" ]
| x -> x)
;;

let opam_fields project (package : Package.t) =
let dune_version = Dune_project.dune_version project in
let package_name = Package.name package in
Expand Down Expand Up @@ -228,6 +237,7 @@ let opam_fields project (package : Package.t) =
in
let list_fields =
[ "maintainer", Package_info.maintainers info
; "x-maintenance-intent", maintenance_intent dune_version info
; "authors", Package_info.authors info
; ( "license"
, match Package_info.license info with
Expand Down
10 changes: 6 additions & 4 deletions test/blackbox-tests/test-cases/config-project-defaults.t
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,11 @@ generated 'dune-project' file.

$ touch dune-config
$ cat >dune-config <<EOF
> (lang dune 3.17)
> (lang dune 3.18)
> (project_defaults
> (authors AuthorTest)
> (maintainers MaintainerTest)
> (maintenance_intent "(latest)")
> (license MIT))
> EOF

Expand All @@ -33,11 +34,12 @@ Change the version of the config file to one which does not support the

$ sed -i -e '1s|.*|(lang dune 3.16)|' dune-config
$ dune init proj test_proj1 --config-file=dune-config
File "$TESTCASE_ROOT/dune-config", lines 2-5, characters 0-85:
File "$TESTCASE_ROOT/dune-config", lines 2-6, characters 0-118:
2 | (project_defaults
3 | (authors AuthorTest)
4 | (maintainers MaintainerTest)
5 | (license MIT))
5 | (maintenance_intent "(latest)")
6 | (license MIT))
Error: 'project_defaults' is only available since version 3.17 of the dune
language. Please update your dune config file to have (lang dune 3.17).
[1]
Expand All @@ -47,7 +49,7 @@ Change the version of the config file to one which does not support the
Check to ensure that the default values are used when optional stanzas are
removed/not used.

$ sed -i -e '3,5c\
$ sed -i -e '3,6c\
> )' dune-config
$ dune init proj test_proj1 --config-file=dune-config
Entering directory 'test_proj1'
Expand Down
2 changes: 2 additions & 0 deletions test/blackbox-tests/test-cases/dune-init.t/run.t
Original file line number Diff line number Diff line change
Expand Up @@ -403,6 +403,7 @@ And the opam file will be generated as expected
]
]
dev-repo: "git+https://github.com/username/reponame.git"
x-maintenance-intent: ["(latest)"]

We can build and run the resulting executable:

Expand Down Expand Up @@ -513,6 +514,7 @@ And the opam file will be generated as expected
]
]
dev-repo: "git+https://github.com/username/reponame.git"
x-maintenance-intent: ["(latest)"]

And we we can run the tests:

Expand Down
13 changes: 9 additions & 4 deletions test/blackbox-tests/test-cases/dune-project-meta/override.t
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
Package information fields can be overridden per-package:

$ cat >dune-project <<EOF
> (lang dune 2.5)
> (lang dune 3.18)
> (name foo)
> (version 1.0.0)
> (source (github mirage/ocaml-cohttp))
> (license ISC)
> (authors "Anil Madhavapeddy" "Rudi Grinberg")
> (homepage https://my.home.page)
> (maintenance_intent "(none)")
> ;
> (generate_opam_files true)
> ;
Expand All @@ -16,7 +17,9 @@ Package information fields can be overridden per-package:
> (version 1.0.1)
> (source (github mirage/foo))
> (license MIT)
> (authors "Foo" "Bar"))
> (authors "Foo" "Bar")
> (maintenance_intent "0.9" "1.0.1")
> (allow_empty))
> EOF

$ dune build @install
Expand All @@ -30,10 +33,11 @@ Package information fields can be overridden per-package:
homepage: "https://my.home.page"
bug-reports: "https://github.com/mirage/foo/issues"
depends: [
"dune" {>= "2.5"}
"dune" {>= "3.18"}
"odoc" {with-doc}
]
build: [
["dune" "subst"] {pinned}
["dune" "subst"] {dev}
[
"dune"
"build"
Expand All @@ -47,3 +51,4 @@ Package information fields can be overridden per-package:
]
]
dev-repo: "git+https://github.com/mirage/foo.git"
x-maintenance-intent: ["0.9" "1.0.1"]
Loading
Loading