Skip to content

Commit

Permalink
Merge pull request #2696 from nojb/top_level_old_name
Browse files Browse the repository at this point in the history
Allow top-level libraries in `old_public_name`
  • Loading branch information
nojb authored Oct 16, 2019
2 parents f8d9ecf + 8482631 commit 3843510
Show file tree
Hide file tree
Showing 23 changed files with 878 additions and 126 deletions.
7 changes: 7 additions & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,13 @@
stanza as well as the `(foreign_stubs ...)` and `(foreign_archives ...)` fields.
(#2659, RFC #2650, @snowleopard)

- Add (deprecated_package_names) field to (package) declaration in
dune-project. The names declared here can be used in the (old_public_name)
field of (deprecated_library_name) stanza. These names are interpreted as
library names (not prefixed by a package name) and appropiate redirections are
setup in their META files. This feaure is meant to migrate old libraries which
do not follow Dune's convention of prefixing libraries with the package
name. (#2696, @nojb)

1.11.4 (09/10/2019)
-------------------
Expand Down
14 changes: 14 additions & 0 deletions doc/dune-files.rst
Original file line number Diff line number Diff line change
Expand Up @@ -237,6 +237,11 @@ It contains the following fields:

- ``(tags <tags>)`` are the list of tags for the package

- ``(deprecated_package_names <name list>)`` is a list of names that can be used
with the :ref:`deprecated-library-name` stanza to migrate legacy libraries
from other build systems which do not follow Dune's convention of prefixing
the public name of the library with the package name.

The list of dependencies ``<dep-specification>`` is modeled after opam's own
language: The syntax is as a list of the following elements:

Expand Down Expand Up @@ -494,6 +499,8 @@ JavaScript output.

See :ref:`jsoo` for more information.

.. _deprecated-library-name:

deprecated_library_name
-----------------------

Expand All @@ -512,6 +519,13 @@ dependencies, it will be transparently replaced by the new name. Note
that it is not necessary for the new name to exist at definition time
as it is only resolved at the point where the old name is used.

The ``old_public_name`` can also be one of the names declared in the
``deprecated_package_names`` field of the package declaration in
``dune-project`` file. In this case, the "old" library is understood to be a
library whose name is not prefixed by the package name. Such a library cannot be
defined in Dune, but other build systems allow it and this feature is meant to
help migration from those systems.

executable
----------

Expand Down
5 changes: 3 additions & 2 deletions src/dune/dialect.ml
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,11 @@ module File_kind = struct
[ ("kind", Ml_kind.to_dyn kind)
; ("extension", string extension)
; ( "preprocess"
, option (pair Loc.to_dyn Action_dune_lang.to_dyn) preprocess )
, option (fun (_, x) -> Action_dune_lang.to_dyn x) preprocess )
; ( "format"
, option
(triple Loc.to_dyn Action_dune_lang.to_dyn (list string))
(fun (_, x, y) ->
pair Action_dune_lang.to_dyn (list string) (x, y))
format )
]
end
Expand Down
83 changes: 55 additions & 28 deletions src/dune/dune_file.ml
Original file line number Diff line number Diff line change
Expand Up @@ -598,27 +598,42 @@ module Public_lib = struct

let name t = snd t.name

let make project ((_, s) as loc_name) =
let package t = t.package

let make ?(allow_deprecated_names = false) project ((_, s) as loc_name) =
let pkg, rest = Lib_name.split s in
Result.map (Pkg.resolve project pkg) ~f:(fun pkg ->
{ package = pkg
; sub_dir =
( if rest = [] then
None
let x =
if not allow_deprecated_names then
None
else
List.find_map
(Package.Name.Map.values (Dune_project.packages project))
~f:(fun ({ deprecated_package_names; _ } as package) ->
if Package.Name.Map.mem deprecated_package_names pkg then
Some { package; sub_dir = None; name = loc_name }
else
Some (String.concat rest ~sep:"/") )
; name = loc_name
})

let public_name_field =
None)
in
match x with
| Some x -> Ok x
| None ->
Result.map (Pkg.resolve project pkg) ~f:(fun pkg ->
{ package = pkg
; sub_dir =
( if rest = [] then
None
else
Some (String.concat rest ~sep:"/") )
; name = loc_name
})

let decode ?allow_deprecated_names () =
map_validate
(let+ project = Dune_project.get_exn ()
and+ loc_name = field_o "public_name" (located Lib_name.decode) in
and+ loc_name = located Lib_name.decode in
(project, loc_name))
~f:(fun (project, loc_name) ->
match loc_name with
| None -> Ok None
| Some x -> Result.map (make project x) ~f:Option.some)
make ?allow_deprecated_names project loc_name)
end

module Mode_conf = struct
Expand Down Expand Up @@ -808,7 +823,7 @@ module Library = struct
(let+ buildable = Buildable.decode ~in_library:true ~allow_re_export:true
and+ loc = loc
and+ name = field_o "name" Lib_name.Local.decode_loc
and+ public = Public_lib.public_name_field
and+ public = field_o "public_name" (Public_lib.decode ())
and+ synopsis = field_o "synopsis" string
and+ install_c_headers =
field "install_c_headers" (repeat string) ~default:[]
Expand Down Expand Up @@ -1918,7 +1933,7 @@ module Coq = struct
fields
(let+ name = field "name" Lib_name.Local.decode_loc
and+ loc = loc
and+ public = Public_lib.public_name_field
and+ public = field_o "public_name" (Public_lib.decode ())
and+ synopsis = field_o "synopsis" string
and+ flags = Ordered_set_lang.Unexpanded.field "flags"
and+ modules = modules_field "modules"
Expand Down Expand Up @@ -2113,26 +2128,38 @@ module Include_subdirs = struct
end

module Deprecated_library_name = struct
module Old_public_name = struct
type t =
{ deprecated : bool
; public : Public_lib.t
}

let decode =
let+ public = Public_lib.decode ~allow_deprecated_names:true () in
let deprecated =
not
(Package.Name.equal
(Lib_name.package_name (Public_lib.name public))
(Public_lib.package public).name)
in
{ deprecated; public }
end

type t =
{ loc : Loc.t
; project : Dune_project.t
; old_public_name : Public_lib.t
; new_public_name : Lib_name.t
; old_public_name : Old_public_name.t
; new_public_name : Loc.t * Lib_name.t
}

let decode =
fields
(let+ loc = loc
and+ project = Dune_project.get_exn ()
and+ old_public_name =
map_validate
(let+ project = Dune_project.get_exn ()
and+ loc_name =
field "old_public_name" (located Lib_name.decode)
in
(project, loc_name))
~f:(fun (project, loc_name) -> Public_lib.make project loc_name)
and+ new_public_name = field "new_public_name" Lib_name.decode in
and+ old_public_name = field "old_public_name" Old_public_name.decode
and+ new_public_name =
field "new_public_name" (located Lib_name.decode)
in
{ loc; project; old_public_name; new_public_name })
end

Expand Down
13 changes: 11 additions & 2 deletions src/dune/dune_file.mli
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,8 @@ module Public_lib : sig
}

val name : t -> Lib_name.t

val package : t -> Package.t
end

module Mode_conf : sig
Expand Down Expand Up @@ -464,11 +466,18 @@ module Include_subdirs : sig
end

module Deprecated_library_name : sig
module Old_public_name : sig
type t =
{ deprecated : bool
; public : Public_lib.t
}
end

type t =
{ loc : Loc.t
; project : Dune_project.t
; old_public_name : Public_lib.t
; new_public_name : Lib_name.t
; old_public_name : Old_public_name.t
; new_public_name : Loc.t * Lib_name.t
}
end

Expand Down
43 changes: 43 additions & 0 deletions src/dune/dune_package.ml
Original file line number Diff line number Diff line change
Expand Up @@ -194,6 +194,14 @@ module Lib = struct
let wrapped t = Option.map t.modules ~f:Modules.wrapped

let info dp = dp.info

let to_dyn { info; modules; main_module_name } =
let open Dyn.Encoder in
record
[ ("info", Lib_info.to_dyn Path.to_dyn info)
; ("modules", option Modules.to_dyn modules)
; ("main_module_name", option Module_name.to_dyn main_module_name)
]
end

module Deprecated_library_name = struct
Expand All @@ -218,6 +226,13 @@ module Deprecated_library_name = struct
[ field "old_public_name" Lib_name.encode old_public_name
; field "new_public_name" Lib_name.encode new_public_name
]

let to_dyn { loc = _; old_public_name; new_public_name } =
let open Dyn.Encoder in
record
[ ("old_public_name", Lib_name.to_dyn old_public_name)
; ("new_public_name", Lib_name.to_dyn new_public_name)
]
end

module Entry = struct
Expand All @@ -242,6 +257,13 @@ module Entry = struct
, let+ x = Deprecated_library_name.decode in
Deprecated_library_name x )
]

let to_dyn x =
let open Dyn.Encoder in
match x with
| Library lib -> constr "Library" [ Lib.to_dyn lib ]
| Deprecated_library_name lib ->
constr "Deprecated_library_name" [ Deprecated_library_name.to_dyn lib ]
end

type t =
Expand Down Expand Up @@ -304,6 +326,15 @@ let encode ~dune_version { entries; name; version; dir } =
in
prepend_version ~dune_version (List.concat [ sexp; entries ])

let to_dyn { entries; name; version; dir } =
let open Dyn.Encoder in
record
[ ("entries", list Entry.to_dyn entries)
; ("name", Package.Name.to_dyn name)
; ("version", option string version)
; ("dir", Path.to_dyn dir)
]

module Or_meta = struct
type nonrec t =
| Use_meta
Expand All @@ -326,4 +357,16 @@ module Or_meta = struct

let load p =
Vfile.load p ~f:(fun lang -> decode ~lang ~dir:(Path.parent_exn p))

let pp ~dune_version ppf t =
let t = encode ~dune_version t in
Format.fprintf ppf "%a@."
(Fmt.list ~pp_sep:Fmt.nl Dune_lang.Deprecated.pp)
t

let to_dyn x =
let open Dyn.Encoder in
match x with
| Use_meta -> constr "Use_meta" []
| Dune_package t -> constr "Dune_package" [ to_dyn t ]
end
13 changes: 13 additions & 0 deletions src/dune/dune_package.mli
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,8 @@ module Lib : sig
-> main_module_name:Module_name.t option
-> modules:Modules.t option
-> t

val to_dyn : t Dyn.Encoder.t
end

module Deprecated_library_name : sig
Expand All @@ -30,6 +32,8 @@ module Deprecated_library_name : sig
; old_public_name : Lib_name.t
; new_public_name : Lib_name.t
}

val to_dyn : t Dyn.Encoder.t
end

module Entry : sig
Expand All @@ -40,6 +44,8 @@ module Entry : sig
val name : t -> Lib_name.t

val version : t -> string option

val to_dyn : t Dyn.Encoder.t
end

type t =
Expand All @@ -49,12 +55,19 @@ type t =
; dir : Path.t
}

val to_dyn : t Dyn.Encoder.t

module Or_meta : sig
type nonrec t =
| Use_meta
| Dune_package of t

val encode : dune_version:Dune_lang.Syntax.Version.t -> t -> Dune_lang.t list

val pp :
dune_version:Dune_lang.Syntax.Version.t -> Format.formatter -> t -> unit

val load : Dpath.t -> t

val to_dyn : t Dyn.Encoder.t
end
21 changes: 21 additions & 0 deletions src/dune/dune_project.ml
Original file line number Diff line number Diff line change
Expand Up @@ -725,6 +725,26 @@ let parse ~dir ~lang ~opam_packages ~file =
name
]
| _, _ -> () );
let package_defined_twice name loc1 loc2 =
User_error.raise
[ Pp.textf "Package name %s is defined twice:"
(Package.Name.to_string name)
; Pp.textf "- %s" (Loc.to_file_colon_line loc1)
; Pp.textf "- %s" (Loc.to_file_colon_line loc2)
]
in
let deprecated_package_names =
List.fold_left packages ~init:Package.Name.Map.empty
~f:(fun acc { Package.deprecated_package_names; _ } ->
Package.Name.Map.union acc deprecated_package_names
~f:package_defined_twice)
in
List.iter packages ~f:(fun p ->
match
Package.Name.Map.find deprecated_package_names p.Package.name
with
| None -> ()
| Some loc -> package_defined_twice p.Package.name loc p.loc);
match
Package.Name.Map.of_list_map packages ~f:(fun p -> (p.name, p))
with
Expand Down Expand Up @@ -870,6 +890,7 @@ let load ~dir ~files ~infer_from_opam_files =
; description = None
; kind = Opam
; tags = []
; deprecated_package_names = Package.Name.Map.empty
})
in
(name, (loc, pkg)) :: acc)
Expand Down
Loading

0 comments on commit 3843510

Please sign in to comment.