Support version stanzas in dune-project files

This commit is contained in:
Jeremie Dimino 2018-05-02 16:55:18 +01:00 committed by Jérémie Dimino
parent 8d4e1904a2
commit db91543e3f
7 changed files with 64 additions and 31 deletions

View File

@ -131,6 +131,15 @@ Sets the name of the project:
(name <name>) (name <name>)
version
-------
Sets the version of the project:
.. code:: scheme
(version <version>)
<package>.opam files <package>.opam files
==================== ====================
@ -185,25 +194,21 @@ defined in the workspace. While Jbuilder itself makes no use of version
numbers, it can be use by external tools such as numbers, it can be use by external tools such as
`ocamlfind <http://projects.camlcity.org/projects/findlib.html>`__. `ocamlfind <http://projects.camlcity.org/projects/findlib.html>`__.
Jbuilder determines the version of a package by first looking in the Jbuilder determines the version of a package by trying the following
``<package>.opam`` for a ``version`` variable. If not found, it will try methods in order:
to read the first line of a version file in the same directory as the
``<package>.opam`` file. The version file is any file whose name is, in
order in which they are looked for:
- ``<package>.version`` - it looks in the ``<package>.opam`` file for a ``version`` variable
- ``version`` - it looks for a ``<package>.version`` file in the same directory and
- ``VERSION`` reads the first line
- it looks for the version specified in the ``dune-project`` if present
- it looks for a ``version`` file and reads the first line
- it looks for a ``VERSION`` file and reads the first line
The version file can be generated by a user rule. ``<package>.version``, ``version`` and ``VERSION`` files may be
generated.
If the version can't be determined, Jbuilder just won't assign one. If the version can't be determined, Jbuilder just won't assign one.
Note that if you are using `Topkg <https://github.com/dbuenzli/topkg>`__
as well in your project, you shouldn't manually set a version in your
``<package>.opam`` file or write/generate on of the file listed above.
See the section about :ref:`using-topkg` for more details.
Odig conventions Odig conventions
---------------- ----------------

View File

@ -2,7 +2,8 @@ open Import
open Sexp.Of_sexp open Sexp.Of_sexp
type t = type t =
{ name : string { name : string
; version : string option
} }
let filename = "dune-project" let filename = "dune-project"
@ -32,7 +33,8 @@ let parse ~dir =
record record
(lang >>= fun Dune_0_1 -> (lang >>= fun Dune_0_1 ->
name ~dir >>= fun name -> name ~dir >>= fun name ->
return { name }) field_o "version" string >>= fun version ->
return { name; version })
let load ~dir = let load ~dir =
let fname = Path.relative dir filename in let fname = Path.relative dir filename in

View File

@ -3,7 +3,8 @@
open Import open Import
type t = type t =
{ name : string { name : string
; version : string option
} }
val load : dir:Path.t -> t val load : dir:Path.t -> t

View File

@ -44,6 +44,15 @@ module Gen(P : Install_params) = struct
>>> Build.write_file_dyn >>> Build.write_file_dyn
(lib_dune_file ~dir:(Lib.src_dir lib) ~name:(Lib.name lib))) (lib_dune_file ~dir:(Lib.src_dir lib) ~name:(Lib.name lib)))
let version_from_dune_project (pkg : Package.t) =
let dir = Path.append (SC.build_dir sctx) pkg.path in
let scope = Scope.info (SC.find_scope_by_dir sctx dir) in
scope.version
type version_method =
| File of string
| From_dune_project
let init_meta () = let init_meta () =
SC.libs_by_package sctx SC.libs_by_package sctx
|> Package.Name.Map.iter ~f:(fun ((pkg : Package.t), libs) -> |> Package.Name.Map.iter ~f:(fun ((pkg : Package.t), libs) ->
@ -63,18 +72,25 @@ module Gen(P : Install_params) = struct
let rec loop = function let rec loop = function
| [] -> Build.return None | [] -> Build.return None
| candidate :: rest -> | candidate :: rest ->
let p = Path.relative path candidate in match candidate with
Build.if_file_exists p | File fn ->
~then_:(Build.lines_of p let p = Path.relative path fn in
>>^ function Build.if_file_exists p
| ver :: _ -> Some ver ~then_:(Build.lines_of p
| _ -> Some "") >>^ function
~else_:(loop rest) | ver :: _ -> Some ver
| _ -> Some "")
~else_:(loop rest)
| From_dune_project ->
match version_from_dune_project pkg with
| None -> loop rest
| Some _ as x -> Build.return x
in in
loop loop
[ (Package.Name.to_string pkg.name) ^ ".version" [ File ((Package.Name.to_string pkg.name) ^ ".version")
; "version" ; From_dune_project
; "VERSION" ; File "version"
; File "VERSION"
] ]
in in
Super_context.Pkg_version.set sctx pkg get Super_context.Pkg_version.set sctx pkg get

View File

@ -92,15 +92,17 @@ module Scope_info = struct
{ name : Name.t { name : Name.t
; packages : Package.t Package.Name.Map.t ; packages : Package.t Package.Name.Map.t
; root : Path.t ; root : Path.t
; version : string option
} }
let anonymous = let anonymous =
{ name = None { name = None
; packages = Package.Name.Map.empty ; packages = Package.Name.Map.empty
; root = Path.root ; root = Path.root
; version = None
} }
let make = function let make ?version = function
| [] -> anonymous | [] -> anonymous
| pkg :: rest as pkgs -> | pkg :: rest as pkgs ->
let name = let name =
@ -114,6 +116,7 @@ module Scope_info = struct
Package.Name.Map.of_list_exn (List.map pkgs ~f:(fun pkg -> Package.Name.Map.of_list_exn (List.map pkgs ~f:(fun pkg ->
pkg.Package.name, pkg)) pkg.Package.name, pkg))
; root ; root
; version
} }
let package_listing packages = let package_listing packages =

View File

@ -28,9 +28,10 @@ module Scope_info : sig
scope. *) scope. *)
; packages : Package.t Package.Name.Map.t ; packages : Package.t Package.Name.Map.t
; root : Path.t ; root : Path.t
; version : string option
} }
val make : Package.t list -> t val make : ?version:string -> Package.t list -> t
(** The anonymous represent the scope at the root of the workspace (** The anonymous represent the scope at the root of the workspace
when the root of the workspace contains no [<package>.opam] when the root of the workspace contains no [<package>.opam]

View File

@ -275,12 +275,17 @@ let load ?extra_ignored_subtrees ?(ignore_promoted_rules=false) () =
match scope, project with match scope, project with
| None, None -> assert false | None, None -> assert false
| Some _, None -> scope | Some _, None -> scope
| None, Some { name } -> | None, Some { name; version } ->
Some { name = Some name Some { name = Some name
; packages = Package.Name.Map.empty ; packages = Package.Name.Map.empty
; root = path ; root = path
; version
} }
| Some scope, Some { name } -> Some { scope with name = Some name }) | Some scope, Some { name; version } ->
Some { scope with
name = Some name
; version
})
in in
let scopes = let scopes =