From 306b4c80da1a44b28ef1a68550f36a042d39d9a0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ojeda=20B=C3=A4r?= Date: Fri, 11 Oct 2019 14:19:52 +0200 Subject: [PATCH 1/7] Add Lib.Resolve_result.to_dyn MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolás Ojeda Bär --- src/dune/lib.ml | 9 ++++ src/dune/lib.mli | 2 + src/dune/lib_info.ml | 118 ++++++++++++++++++++++++++++++++++++++++++ src/dune/lib_info.mli | 2 + src/dune/lib_kind.ml | 16 ++++++ src/dune/lib_kind.mli | 2 + 6 files changed, 149 insertions(+) diff --git a/src/dune/lib.ml b/src/dune/lib.ml index b35e3fdcca4..7a3b8e44068 100644 --- a/src/dune/lib.ml +++ b/src/dune/lib.ml @@ -1511,6 +1511,15 @@ module DB = struct | Found of Lib_info.external_ | Hidden of Lib_info.external_ * string | Redirect of db option * Lib_name.t + + let to_dyn x = + let open Dyn.Encoder in + match x with + | Not_found -> constr "Not_found" [] + | Found lib -> constr "Found" [ Lib_info.to_dyn Path.to_dyn lib ] + | Hidden (lib, s) -> + constr "Hidden" [ Lib_info.to_dyn Path.to_dyn lib; string s ] + | Redirect (_, name) -> constr "Redirect" [ Lib_name.to_dyn name ] end type t = db diff --git a/src/dune/lib.mli b/src/dune/lib.mli index d925fd89fb2..6728ff63406 100644 --- a/src/dune/lib.mli +++ b/src/dune/lib.mli @@ -147,6 +147,8 @@ module DB : sig | Found of Lib_info.external_ | Hidden of Lib_info.external_ * string | Redirect of t option * Lib_name.t + + val to_dyn : t Dyn.Encoder.t end (** Create a new library database. [resolve] is used to resolve library names diff --git a/src/dune/lib_info.ml b/src/dune/lib_info.ml index ce2d78af665..462474c21c7 100644 --- a/src/dune/lib_info.ml +++ b/src/dune/lib_info.ml @@ -4,16 +4,27 @@ module Inherited = struct type 'a t = | This of 'a | From of (Loc.t * Lib_name.t) + + let to_dyn f x = + let open Dyn.Encoder in + match x with + | This x -> constr "This" [ f x ] + | From (_, name) -> constr "From" [ Lib_name.to_dyn name ] end module Main_module_name = struct type t = Module_name.t option Inherited.t + + let to_dyn x = Inherited.to_dyn (Dyn.Encoder.option Module_name.to_dyn) x end module Special_builtin_support = struct module Build_info = struct type api_version = V1 + let api_version_to_dyn = function + | V1 -> Dyn.Encoder.constr "V1" [] + let supported_api_versions = [ (1, V1) ] type t = @@ -21,6 +32,13 @@ module Special_builtin_support = struct ; api_version : api_version } + let to_dyn { data_module; api_version } = + let open Dyn.Encoder in + record + [ ("data_module", string data_module) + ; ("api_version", api_version_to_dyn api_version) + ] + let decode = let open Dune_lang.Decoder in fields @@ -57,6 +75,12 @@ module Special_builtin_support = struct | Findlib_dynload | Build_info of Build_info.t + let to_dyn x = + let open Dyn.Encoder in + match x with + | Findlib_dynload -> constr "Findlib_dynload" [] + | Build_info info -> constr "Build_info" [ Build_info.to_dyn info ] + let decode = let open Dune_lang.Decoder in sum @@ -80,6 +104,14 @@ module Status = struct | Public of Dune_project.Name.t * Package.t | Private of Dune_project.t + let to_dyn x = + let open Dyn.Encoder in + match x with + | Installed -> constr "Installed" [] + | Public (name, package) -> + constr "Public" [ Dune_project.Name.to_dyn name; Package.to_dyn package ] + | Private proj -> constr "Private" [ Dune_project.to_dyn proj ] + let pp ppf t = Format.pp_print_string ppf ( match t with @@ -106,6 +138,12 @@ module Source = struct | Local | External of 'a + let to_dyn f x = + let open Dyn.Encoder in + match x with + | Local -> constr "Local" [] + | External x -> constr "External" [ f x ] + let map t ~f = match t with | Local -> Local @@ -117,6 +155,14 @@ module Enabled_status = struct | Normal | Optional | Disabled_because_of_enabled_if + + let to_dyn x = + let open Dyn.Encoder in + match x with + | Normal -> constr "Normal" [] + | Optional -> constr "Optional" [] + | Disabled_because_of_enabled_if -> + constr "Disabled_because_of_enabled_if" [] end type 'path t = @@ -312,3 +358,75 @@ let of_local = map ~f_path:Path.build ~f_obj_dir:Obj_dir.of_local let as_local_exn = map ~f_path:Path.as_in_build_dir_exn ~f_obj_dir:Obj_dir.as_local_exn + +let to_dyn path + { loc + ; name + ; kind + ; status + ; src_dir + ; orig_src_dir + ; obj_dir + ; version + ; synopsis + ; requires + ; main_module_name + ; foreign_objects + ; plugins + ; archives + ; ppx_runtime_deps + ; foreign_archives + ; jsoo_runtime + ; jsoo_archive + ; pps + ; enabled + ; virtual_deps + ; dune_version + ; sub_systems + ; virtual_ + ; implements + ; variant + ; known_implementations + ; default_implementation + ; modes + ; wrapped + ; special_builtin_support + } = + let open Dyn.Encoder in + let snd f (_, x) = f x in + record + [ ("loc", Loc.to_dyn loc) + ; ("name", Lib_name.to_dyn name) + ; ("kind", Lib_kind.to_dyn kind) + ; ("status", Status.to_dyn status) + ; ("src_dir", path src_dir) + ; ("orig_src_dir", option path orig_src_dir) + ; ("obj_dir", Obj_dir.to_dyn obj_dir) + ; ("version", option string version) + ; ("synopsis", option string synopsis) + ; ("archives", Mode.Dict.to_dyn (list path) archives) + ; ("plugins", Mode.Dict.to_dyn (list path) plugins) + ; ("foreign_objects", Source.to_dyn (list path) foreign_objects) + ; ("foreign_archives", Mode.Dict.to_dyn (list path) foreign_archives) + ; ("jsoo_runtime", list path jsoo_runtime) + ; ("jsoo_archive", option path jsoo_archive) + ; ("requires", list Lib_dep.to_dyn requires) + ; ("ppx_runtime_deps", list (snd Lib_name.to_dyn) ppx_runtime_deps) + ; ("pps", list (snd Lib_name.to_dyn) pps) + ; ("enabled", Enabled_status.to_dyn enabled) + ; ("virtual_deps", list (snd Lib_name.to_dyn) virtual_deps) + ; ("dune_version", option Dune_lang.Syntax.Version.to_dyn dune_version) + ; ("sub_systems", Sub_system_name.Map.to_dyn Dyn.Encoder.opaque sub_systems) + ; ("virtual_", option (Source.to_dyn Modules.to_dyn) virtual_) + ; ("implements", option (snd Lib_name.to_dyn) implements) + ; ("variant", option Variant.to_dyn variant) + ; ( "known_implementation" + , Variant.Map.to_dyn (snd Lib_name.to_dyn) known_implementations ) + ; ( "default_implementation" + , option (snd Lib_name.to_dyn) default_implementation ) + ; ("wrapped", option (Inherited.to_dyn Wrapped.to_dyn) wrapped) + ; ("main_module_name", Main_module_name.to_dyn main_module_name) + ; ("modes", Mode.Dict.Set.to_dyn modes) + ; ( "special_builtin_support" + , option Special_builtin_support.to_dyn special_builtin_support ) + ] diff --git a/src/dune/lib_info.mli b/src/dune/lib_info.mli index f943ad614d7..6cae4c84242 100644 --- a/src/dune/lib_info.mli +++ b/src/dune/lib_info.mli @@ -185,3 +185,5 @@ val create : -> wrapped:Wrapped.t Inherited.t option -> special_builtin_support:Special_builtin_support.t option -> 'a t + +val to_dyn : 'path Dyn.Encoder.t -> 'path t Dyn.Encoder.t diff --git a/src/dune/lib_kind.ml b/src/dune/lib_kind.ml index 7a646c0bbd0..a346414c773 100644 --- a/src/dune/lib_kind.ml +++ b/src/dune/lib_kind.ml @@ -7,6 +7,11 @@ module Ppx_args = struct ; value : String_with_vars.t } + let to_dyn x = + let open Dyn.Encoder in + record + [ ("name", string x.name); ("value", String_with_vars.to_dyn x.value) ] + let decode = let open Dune_lang.Decoder in let* () = Dune_lang.Syntax.since Stanza.syntax (1, 10) in @@ -28,6 +33,10 @@ module Ppx_args = struct type t = { cookies : Cookie.t list } + let to_dyn { cookies } = + let open Dyn.Encoder in + record [ ("cookies", list Cookie.to_dyn cookies) ] + let decode = let open Dune_lang.Decoder in let args = @@ -46,6 +55,13 @@ type t = | Ppx_deriver of Ppx_args.t | Ppx_rewriter of Ppx_args.t +let to_dyn x = + let open Dyn.Encoder in + match x with + | Normal -> constr "Normal" [] + | Ppx_deriver args -> constr "Ppx_deriver" [ Ppx_args.to_dyn args ] + | Ppx_rewriter args -> constr "Ppx_rewriter" [ Ppx_args.to_dyn args ] + let decode = let open Dune_lang.Decoder in sum diff --git a/src/dune/lib_kind.mli b/src/dune/lib_kind.mli index ef31b75219f..2988735ef46 100644 --- a/src/dune/lib_kind.mli +++ b/src/dune/lib_kind.mli @@ -14,4 +14,6 @@ type t = | Ppx_deriver of Ppx_args.t | Ppx_rewriter of Ppx_args.t +val to_dyn : t Stdune.Dyn.Encoder.t + include Dune_lang.Conv.S with type t := t From a19fac2b9a87d2529df4f74c1a5981d9507723e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ojeda=20B=C3=A4r?= Date: Mon, 14 Oct 2019 14:19:42 +0200 Subject: [PATCH 2/7] Add Dune_package.{to_dyn,Or_meta.pp} MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolás Ojeda Bär --- src/dune/dialect.ml | 4 ++-- src/dune/dune_package.ml | 42 +++++++++++++++++++++++++++++++++++++++ src/dune/dune_package.mli | 11 ++++++++++ 3 files changed, 55 insertions(+), 2 deletions(-) diff --git a/src/dune/dialect.ml b/src/dune/dialect.ml index 9ca3c1e6923..24863cb0a24 100644 --- a/src/dune/dialect.ml +++ b/src/dune/dialect.ml @@ -14,10 +14,10 @@ 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 diff --git a/src/dune/dune_package.ml b/src/dune/dune_package.ml index 0893f97cb2f..4d520f41b3a 100644 --- a/src/dune/dune_package.ml +++ b/src/dune/dune_package.ml @@ -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 @@ -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 @@ -242,6 +257,14 @@ 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 = @@ -304,6 +327,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 @@ -326,4 +358,14 @@ 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 diff --git a/src/dune/dune_package.mli b/src/dune/dune_package.mli index 15ca51bd0f0..08500fc4db5 100644 --- a/src/dune/dune_package.mli +++ b/src/dune/dune_package.mli @@ -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 @@ -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 @@ -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 = @@ -49,12 +55,17 @@ 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 From 92abcafa7e2352ad3514889acf67594dca5ae2e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ojeda=20B=C3=A4r?= Date: Wed, 9 Oct 2019 19:03:00 +0200 Subject: [PATCH 3/7] Add (deprecated_package_names ...) field MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolás Ojeda Bär --- src/dune/dune_file.ml | 83 +++++++++++------ src/dune/dune_file.mli | 13 ++- src/dune/dune_package.mli | 4 +- src/dune/dune_project.ml | 21 +++++ src/dune/gen_meta.ml | 21 +++-- src/dune/gen_meta.mli | 1 + src/dune/install_rules.ml | 187 +++++++++++++++++++++++++++++++------- src/dune/lib.ml | 88 +++++++++--------- src/dune/lib.mli | 2 +- src/dune/opam_create.ml | 1 + src/dune/package.ml | 29 +++++- src/dune/package.mli | 3 + src/dune/scope.ml | 16 ++-- src/dune/super_context.ml | 10 +- 14 files changed, 353 insertions(+), 126 deletions(-) diff --git a/src/dune/dune_file.ml b/src/dune/dune_file.ml index fb41b02861c..f4bf032fbcc 100644 --- a/src/dune/dune_file.ml +++ b/src/dune/dune_file.ml @@ -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 @@ -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:[] @@ -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" @@ -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 diff --git a/src/dune/dune_file.mli b/src/dune/dune_file.mli index 115daded83d..81d23ac46d5 100644 --- a/src/dune/dune_file.mli +++ b/src/dune/dune_file.mli @@ -119,6 +119,8 @@ module Public_lib : sig } val name : t -> Lib_name.t + + val package : t -> Package.t end module Mode_conf : sig @@ -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 diff --git a/src/dune/dune_package.mli b/src/dune/dune_package.mli index 08500fc4db5..3c37ee1dbd1 100644 --- a/src/dune/dune_package.mli +++ b/src/dune/dune_package.mli @@ -63,7 +63,9 @@ module Or_meta : sig | 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 pp : + dune_version:Dune_lang.Syntax.Version.t -> Format.formatter -> t -> unit val load : Dpath.t -> t diff --git a/src/dune/dune_project.ml b/src/dune/dune_project.ml index 9b749983e46..0e9cfc28d5e 100644 --- a/src/dune/dune_project.ml +++ b/src/dune/dune_project.ml @@ -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 @@ -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) diff --git a/src/dune/gen_meta.ml b/src/dune/gen_meta.ml index c5c1b006feb..f1285adb1bf 100644 --- a/src/dune/gen_meta.ml +++ b/src/dune/gen_meta.ml @@ -142,7 +142,7 @@ let gen_lib pub_name lib ~version = ] ) ] -let gen ~package ~version entries = +let gen ~package ~version ?(add_directory_entry = true) entries = let version = match version with | None -> [] @@ -155,10 +155,13 @@ let gen ~package ~version entries = let name = Lib.Local.info lib |> Lib_info.name in let pub_name = Pub_name.parse name in (pub_name, gen_lib pub_name (Lib.Local.to_lib lib) ~version) - | Deprecated_library_name d -> - ( Pub_name.parse (snd d.old_public_name.name) - , version @ [ requires (Lib_name.Set.singleton d.new_public_name) ] - )) + | Deprecated_library_name + { old_public_name = { public = old_public_name; _ } + ; new_public_name = _, new_public_name + ; _ + } -> + ( Pub_name.parse (Dune_file.Public_lib.name old_public_name) + , version @ [ requires (Lib_name.Set.singleton new_public_name) ] )) in let pkgs = List.map pkgs ~f:(fun (pn, meta) -> @@ -179,7 +182,13 @@ let gen ~package ~version entries = |> String.Map.to_list |> List.map ~f:(fun (name, pkgs) -> let pkg = loop name pkgs in - Package { pkg with entries = directory name :: pkg.entries }) + let pkg = + if add_directory_entry then + { pkg with entries = directory name :: pkg.entries } + else + pkg + in + Package pkg) in { name = Some (Lib_name.of_string_exn ~loc:None name) ; entries = entries @ subs diff --git a/src/dune/gen_meta.mli b/src/dune/gen_meta.mli index 7e75efc972d..f953801a095 100644 --- a/src/dune/gen_meta.mli +++ b/src/dune/gen_meta.mli @@ -5,5 +5,6 @@ open! Import val gen : package:string -> version:string option + -> ?add_directory_entry:bool -> Super_context.Lib_entry.t list -> Meta.t diff --git a/src/dune/install_rules.ml b/src/dune/install_rules.ml index 14fb076721c..0faaf1f1489 100644 --- a/src/dune/install_rules.ml +++ b/src/dune/install_rules.ml @@ -11,6 +11,10 @@ module Package_paths = struct let meta_file (ctx : Context.t) pkg = Path.Build.append_source ctx.build_dir (Package.meta_file pkg) + let deprecated_meta_file (ctx : Context.t) pkg name = + Path.Build.append_source ctx.build_dir + (Package.deprecated_meta_file pkg name) + let build_dir (ctx : Context.t) (pkg : Package.t) = Path.Build.append_source ctx.build_dir pkg.path @@ -18,6 +22,10 @@ module Package_paths = struct Path.Build.relative (build_dir ctx pkg) (Package.Name.to_string pkg.name ^ ".dune-package") + let deprecated_dune_package_file ctx pkg name = + Path.Build.relative (build_dir ctx pkg) + (Package.Name.to_string name ^ ".dune-package") + let meta_template ctx pkg = Path.Build.extend_basename (meta_file ctx pkg) ~suffix:".template" end @@ -170,17 +178,40 @@ end = struct let dune_package_file = Package_paths.dune_package_file ctx pkg in + let deprecated_meta_and_dune_files = + List.concat_map + (Package.Name.Map.to_list pkg.deprecated_package_names) + ~f:(fun (name, _) -> + let meta_file = + Package_paths.deprecated_meta_file ctx pkg name + in + let dune_package_file = + Package_paths.deprecated_dune_package_file ctx pkg name + in + [ ( None + , Install.Entry.make Lib_root meta_file + ~dst: + ( Package.Name.to_string name + ^ "/" ^ Findlib.meta_fn ) ) + ; ( None + , Install.Entry.make Lib_root dune_package_file + ~dst: + ( Package.Name.to_string name + ^ "/" ^ Dune_package.fn ) ) + ]) + in (None, Install.Entry.make Lib meta_file ~dst:Findlib.meta_fn) :: ( None , Install.Entry.make Lib dune_package_file ~dst:Dune_package.fn ) :: ( match pkg.kind with - | Dune false -> [] + | Dune false -> deprecated_meta_and_dune_files | Dune true | Opam -> let opam_file = Package_paths.opam_file ctx pkg in - [ (None, Install.Entry.make Lib opam_file ~dst:"opam") ] ) + (None, Install.Entry.make Lib opam_file ~dst:"opam") + :: deprecated_meta_and_dune_files ) in String.Set.fold files ~init ~f:(fun fn acc -> if is_odig_doc_file fn then @@ -262,6 +293,18 @@ let gen_dune_package sctx pkg = let dune_version = Dune_lang.Syntax.greatest_supported_version Stanza.syntax in + let lib_entries = Super_context.lib_entries_of_package sctx pkg.name in + let deprecated_dune_packages = + List.filter_map lib_entries ~f:(function + | Super_context.Lib_entry.Deprecated_library_name + ( { old_public_name = { deprecated = true; public = old_public_name } + ; _ + } as t ) -> + Some + (Lib_name.package_name (Dune_file.Public_lib.name old_public_name), t) + | _ -> None) + |> Package.Name.Map.of_list_multi + in let action = let gen_dune_package () = let dune_package = @@ -273,38 +316,49 @@ let gen_dune_package sctx pkg = Path.Build.L.relative pkg_root subdir in let entries = - Super_context.lib_entries_of_package sctx pkg.name - |> List.map ~f:(function - | Super_context.Lib_entry.Deprecated_library_name d -> - Dune_package.Entry.Deprecated_library_name - { loc = d.loc - ; old_public_name = snd d.old_public_name.name - ; new_public_name = d.new_public_name - } - | Library lib -> - let dir_contents = - let info = Lib.Local.info lib in - let dir = Lib_info.src_dir info in - Dir_contents.get sctx ~dir - in - let obj_dir = Lib.Local.obj_dir lib in - let lib = Lib.Local.to_lib lib in - let name = Lib.name lib in - let foreign_objects = - let dir = Obj_dir.obj_dir obj_dir in - Dir_contents.foreign_sources_of_library dir_contents ~name - |> Foreign.Sources.object_files ~dir - ~ext_obj:ctx.lib_config.ext_obj - |> List.map ~f:Path.build - in - let modules = - Dir_contents.modules_of_library dir_contents ~name - in - Library + List.filter_map lib_entries ~f:(function + | Super_context.Lib_entry.Deprecated_library_name + { old_public_name = { deprecated = true; _ }; _ } -> + None + | Super_context.Lib_entry.Deprecated_library_name + { old_public_name = + { public = old_public_name; deprecated = false } + ; new_public_name = _, new_public_name + ; loc + ; _ + } -> + Some + (Dune_package.Entry.Deprecated_library_name + { loc + ; old_public_name = + Dune_file.Public_lib.name old_public_name + ; new_public_name + }) + | Library lib -> + let dir_contents = + let info = Lib.Local.info lib in + let dir = Lib_info.src_dir info in + Dir_contents.get sctx ~dir + in + let obj_dir = Lib.Local.obj_dir lib in + let lib = Lib.Local.to_lib lib in + let name = Lib.name lib in + let foreign_objects = + let dir = Obj_dir.obj_dir obj_dir in + Dir_contents.foreign_sources_of_library dir_contents ~name + |> Foreign.Sources.object_files ~dir + ~ext_obj:ctx.lib_config.ext_obj + |> List.map ~f:Path.build + in + let modules = + Dir_contents.modules_of_library dir_contents ~name + in + Some + (Library (Result.ok_exn (Lib.to_dune_lib lib ~dir:(Path.build (lib_root lib)) - ~modules ~foreign_objects))) + ~modules ~foreign_objects)))) in Dune_package.Or_meta.Dune_package { Dune_package.version = pkg.version @@ -321,10 +375,43 @@ let gen_dune_package sctx pkg = ~then_:(Build.return Dune_package.Or_meta.Use_meta) ~else_:(Build.delayed gen_dune_package) in - Dune_package.Or_meta.encode ~dune_version pkg - |> Format.asprintf "%a@." - (Fmt.list ~pp_sep:Fmt.nl Dune_lang.Deprecated.pp)) + Format.asprintf "%a" (Dune_package.Or_meta.pp ~dune_version) pkg) in + Package.Name.Map.iteri pkg.deprecated_package_names ~f:(fun name _ -> + let dune_pkg = + let entries = + match Package.Name.Map.find deprecated_dune_packages name with + | None -> [] + | Some entries -> + List.map entries + ~f:(fun { Dune_file.Deprecated_library_name.old_public_name = + { public = old_public_name; _ } + ; new_public_name = _, new_public_name + ; loc + ; _ + } + -> + let old_public_name = + Dune_file.Public_lib.name old_public_name + in + Dune_package.Entry.Deprecated_library_name + { loc; old_public_name; new_public_name }) + in + { Dune_package.version = pkg.version + ; name + ; entries + ; dir = + Path.build + (Config.local_install_lib_dir ~context:ctx.name ~package:name) + } + in + Build.write_file + (Package_paths.deprecated_dune_package_file ctx pkg + dune_pkg.Dune_package.name) + (Format.asprintf "%a" + (Dune_package.Or_meta.pp ~dune_version) + (Dune_package.Or_meta.Dune_package dune_pkg)) + |> Super_context.add_rule sctx ~dir:ctx.build_dir); Super_context.add_rule sctx ~dir:ctx.build_dir action let init_meta_and_dune_package sctx ~dir = @@ -333,6 +420,21 @@ let init_meta_and_dune_package sctx ~dir = |> Scope.project |> Dune_project.packages |> Package.Name.Map.iter ~f:(fun (pkg : Package.t) -> let entries = Super_context.lib_entries_of_package sctx pkg.name in + let deprecated_packages, entries = + List.partition_map entries ~f:(function + | Super_context.Lib_entry.Deprecated_library_name + { old_public_name = + { deprecated = true + ; public = { sub_dir = None; name = _, name; _ } + } + ; _ + } as entry -> + Left (Lib_name.package_name name, entry) + | entry -> Right entry) + in + let deprecated_packages = + Package.Name.Map.of_list_multi deprecated_packages + in let meta = Package_paths.meta_file ctx pkg in let meta_template = Path.build (Package_paths.meta_template ctx pkg) @@ -394,7 +496,22 @@ let init_meta_and_dune_package sctx ~dir = Format.pp_close_box ppf (); Format.pp_print_flush ppf (); Buffer.contents buf) - |> Build.write_file_dyn meta)) + |> Build.write_file_dyn meta); + Package.Name.Map.iteri pkg.deprecated_package_names ~f:(fun name _ -> + let meta = Package_paths.deprecated_meta_file ctx pkg name in + Super_context.add_rule sctx ~dir:ctx.build_dir + ( (let meta = + let entries = + match Package.Name.Map.find deprecated_packages name with + | None -> [] + | Some entries -> entries + in + Gen_meta.gen + ~package:(Package.Name.to_string pkg.name) + ~version:pkg.version entries ~add_directory_entry:false + in + Format.asprintf "@[%a@,@]" Meta.pp meta.entries) + |> Build.write_file meta ))) let symlink_installed_artifacts_to_build_install sctx (entries : (Loc.t option * Path.Build.t Install.Entry.t) list) diff --git a/src/dune/lib.ml b/src/dune/lib.ml index 7a3b8e44068..57585abf136 100644 --- a/src/dune/lib.ml +++ b/src/dune/lib.ml @@ -332,7 +332,7 @@ and resolve_result = | Not_found | Found of Lib_info.external_ | Hidden of Lib_info.external_ * string - | Redirect of db option * Lib_name.t + | Redirect of db option * (Loc.t * Lib_name.t) type lib = t @@ -1088,7 +1088,7 @@ end = struct let resolve_name db name ~stack = match db.resolve name with - | Redirect (db', name') -> ( + | Redirect (db', (_, name')) -> ( let db' = Option.value db' ~default:db in match find_internal db' name' ~stack with | St_initializing _ as x -> x @@ -1510,7 +1510,7 @@ module DB = struct | Not_found | Found of Lib_info.external_ | Hidden of Lib_info.external_ * string - | Redirect of db option * Lib_name.t + | Redirect of db option * (Loc.t * Lib_name.t) let to_dyn x = let open Dyn.Encoder in @@ -1519,7 +1519,7 @@ module DB = struct | Found lib -> constr "Found" [ Lib_info.to_dyn Path.to_dyn lib ] | Hidden (lib, s) -> constr "Hidden" [ Lib_info.to_dyn Path.to_dyn lib; string s ] - | Redirect (_, name) -> constr "Redirect" [ Lib_name.to_dyn name ] + | Redirect (_, (_, name)) -> constr "Redirect" [ Lib_name.to_dyn name ] end type t = db @@ -1558,7 +1558,7 @@ module DB = struct | Hidden _ -> assert false | Found x -> x - | Redirect (_, name') -> ( + | Redirect (_, (_, name')) -> ( match Lib_name.Map.find libmap name' with | Some (Found x) -> x | _ -> assert false )) @@ -1614,9 +1614,13 @@ module DB = struct List.concat_map stanzas ~f:(fun stanza -> match (stanza : Library_related_stanza.t) with | External_variant _ -> [] - | Deprecated_library_name x -> - [ ( Dune_file.Public_lib.name x.old_public_name - , Redirect (None, x.new_public_name) ) + | Deprecated_library_name + { old_public_name = { public = old_public_name; _ } + ; new_public_name + ; _ + } -> + [ ( Dune_file.Public_lib.name old_public_name + , Redirect (None, new_public_name) ) ] | Library (dir, (conf : Dune_file.Library.t)) -> ( (* In the [implements] field of library stanzas, the user might use @@ -1659,41 +1663,38 @@ module DB = struct [ (name, Found info) ] else [ (name, Found info) - ; (Lib_name.of_local conf.name, Redirect (None, name)) + ; (Lib_name.of_local conf.name, Redirect (None, p.name)) ] )) - |> Lib_name.Map.of_list - |> function - | Ok x -> x - | Error (name, _, _) -> ( - match - List.filter_map stanzas ~f:(function - | Library (_, conf) -> - if - Lib_name.equal name (Lib_name.of_local conf.name) - || - match conf.public with - | None -> false - | Some p -> Lib_name.equal name (Dune_file.Public_lib.name p) - then - Some conf.buildable.loc - else - None - | Deprecated_library_name x -> - Option.some_if - (Lib_name.equal name - (Dune_file.Public_lib.name x.old_public_name)) - x.loc - | External_variant _ -> None) - with - | [] - | [ _ ] -> - assert false - | loc1 :: loc2 :: _ -> - User_error.raise - [ Pp.textf "Library %s is defined twice:" (Lib_name.to_string name) - ; Pp.textf "- %s" (Loc.to_file_colon_line loc1) - ; Pp.textf "- %s" (Loc.to_file_colon_line loc2) - ] ) + |> Lib_name.Map.of_list_reducei ~f:(fun name v1 v2 -> + let res = + match (v1, v2) with + | Found info1, Found info2 -> + Error (Lib_info.loc info1, Lib_info.loc info2) + | Found info, Redirect (None, (loc, _)) + | Redirect (None, (loc, _)), Found info -> + Error (loc, Lib_info.loc info) + | Redirect (None, (loc1, lib1)), Redirect (None, (loc2, lib2)) + -> + if Lib_name.equal lib1 lib2 then + Ok v1 + else + Error (loc1, loc2) + | _ -> + Code_error.raise + "create_from_stanzas produced unexpected result" + [ ("v1", Resolve_result.to_dyn v1) + ; ("v2", Resolve_result.to_dyn v2) + ] + in + match res with + | Ok x -> x + | Error (loc1, loc2) -> + User_error.raise + [ Pp.textf "Library %s is defined twice:" + (Lib_name.to_string name) + ; Pp.textf "- %s" (Loc.to_file_colon_line loc1) + ; Pp.textf "- %s" (Loc.to_file_colon_line loc2) + ]) in (* We need to check that [external_variant] stanzas are correct, i.e. contain valid [virtual_library] fields now since this is the last time @@ -1710,7 +1711,8 @@ module DB = struct ~resolve:(fun name -> match Findlib.find findlib name with | Ok (Library pkg) -> Found (Dune_package.Lib.info pkg) - | Ok (Deprecated_library_name d) -> Redirect (None, d.new_public_name) + | Ok (Deprecated_library_name d) -> + Redirect (None, (Loc.none, d.new_public_name)) | Error e -> ( match e with | Not_found -> diff --git a/src/dune/lib.mli b/src/dune/lib.mli index 6728ff63406..b9f4da55fcc 100644 --- a/src/dune/lib.mli +++ b/src/dune/lib.mli @@ -146,7 +146,7 @@ module DB : sig | Not_found | Found of Lib_info.external_ | Hidden of Lib_info.external_ * string - | Redirect of t option * Lib_name.t + | Redirect of t option * (Loc.t * Lib_name.t) val to_dyn : t Dyn.Encoder.t end diff --git a/src/dune/opam_create.ml b/src/dune/opam_create.ml index 10f8a1498db..5830e01d765 100644 --- a/src/dune/opam_create.ml +++ b/src/dune/opam_create.ml @@ -47,6 +47,7 @@ let package_fields ; kind = _ ; tags ; loc = _ + ; deprecated_package_names = _ } ~project = let open Opam_file.Create in let tags = diff --git a/src/dune/package.ml b/src/dune/package.ml index 583a0602251..ff3d15e4a82 100644 --- a/src/dune/package.ml +++ b/src/dune/package.ml @@ -246,6 +246,7 @@ type t = ; version : string option ; kind : Kind.t ; tags : string list + ; deprecated_package_names : Loc.t Name.Map.t } (* Package name are globally unique, so we can reasonably expect that there @@ -263,7 +264,26 @@ let decode ~dir = and+ depends = field ~default:[] "depends" (repeat Dependency.decode) and+ conflicts = field ~default:[] "conflicts" (repeat Dependency.decode) and+ depopts = field ~default:[] "depopts" (repeat Dependency.decode) - and+ tags = field "tags" (enter (repeat string)) ~default:[] in + and+ tags = field "tags" (enter (repeat string)) ~default:[] + and+ deprecated_package_names = + field ~default:[] "deprecated_package_names" + ( Dune_lang.Syntax.since Stanza.syntax (2, 0) + >>> repeat (located Name.decode) ) + in + let deprecated_package_names = + match + Name.Map.of_list_map deprecated_package_names ~f:(fun (loc, s) -> + (s, loc)) + with + | Ok x -> x + | Error (name, (loc1, _), (loc2, _)) -> + User_error.raise + [ Pp.textf "Deprecated package name %s is declared twice:" + (Name.to_string name) + ; Pp.textf "- %s" (Loc.to_file_colon_line loc1) + ; Pp.textf "- %s" (Loc.to_file_colon_line loc2) + ] + in { name ; loc ; synopsis @@ -275,6 +295,7 @@ let decode ~dir = ; version = None ; kind = Dune false ; tags + ; deprecated_package_names } let to_dyn @@ -289,6 +310,7 @@ let to_dyn ; kind ; tags ; loc = _ + ; deprecated_package_names } = let open Dyn.Encoder in record @@ -302,6 +324,8 @@ let to_dyn ; ("kind", Kind.to_dyn kind) ; ("tags", list string tags) ; ("version", option string version) + ; ( "deprecated_package_names" + , Name.Map.to_dyn Loc.to_dyn deprecated_package_names ) ] let opam_file t = Path.Source.relative t.path (Name.opam_fn t.name) @@ -309,3 +333,6 @@ let opam_file t = Path.Source.relative t.path (Name.opam_fn t.name) let meta_file t = Path.Source.relative t.path (Name.meta_fn t.name) let file ~dir ~name = Path.relative dir (Name.to_string name ^ opam_ext) + +let deprecated_meta_file t name = + Path.Source.relative t.path (Name.meta_fn name) diff --git a/src/dune/package.mli b/src/dune/package.mli index 7eec9210e4e..e54a74595bd 100644 --- a/src/dune/package.mli +++ b/src/dune/package.mli @@ -81,6 +81,7 @@ type t = ; version : string option ; kind : Kind.t ; tags : string list + ; deprecated_package_names : Loc.t Name.Map.t } val file : dir:Path.t -> name:Name.t -> Path.t @@ -91,6 +92,8 @@ val opam_file : t -> Path.Source.t val meta_file : t -> Path.Source.t +val deprecated_meta_file : t -> Name.t -> Path.Source.t + val to_dyn : t -> Dyn.t val hash : t -> int diff --git a/src/dune/scope.ml b/src/dune/scope.ml index 8ab733e53ce..cfaa06b2a2b 100644 --- a/src/dune/scope.ml +++ b/src/dune/scope.ml @@ -41,14 +41,14 @@ module DB = struct type redirect_to = | Project of Dune_project.t - | Name of Lib_name.t + | Name of (Loc.t * Lib_name.t) let resolve t public_libs name : Lib.DB.Resolve_result.t = match Lib_name.Map.find public_libs name with | None -> Not_found | Some (Project project) -> let scope = find_by_project (Fdecl.get t) project in - Redirect (Some scope.db, name) + Redirect (Some scope.db, (Loc.none, name)) | Some (Name name) -> Redirect (None, name) let public_libs t ~stdlib_dir ~installed_libs stanzas = @@ -60,10 +60,13 @@ module DB = struct Some (Dune_file.Public_lib.name p, Project project) | Library _ -> None | External_variant _ -> None - | Deprecated_library_name x -> + | Deprecated_library_name + { old_public_name = { public = old_public_name; _ } + ; new_public_name + ; _ + } -> Some - ( Dune_file.Public_lib.name x.old_public_name - , Name x.new_public_name )) + (Dune_file.Public_lib.name old_public_name, Name new_public_name)) |> Lib_name.Map.of_list |> function | Ok x -> x @@ -72,7 +75,8 @@ module DB = struct List.filter_map stanzas ~f:(fun stanza -> match stanza with | Library (_, { buildable = { loc; _ }; public = Some p; _ }) - | Deprecated_library_name { loc; old_public_name = p; _ } -> + | Deprecated_library_name + { loc; old_public_name = { public = p; _ }; _ } -> Option.some_if (name = Dune_file.Public_lib.name p) loc | _ -> None) with diff --git a/src/dune/super_context.ml b/src/dune/super_context.ml index 0a1b4ce979a..352b1d39708 100644 --- a/src/dune/super_context.ml +++ b/src/dune/super_context.ml @@ -27,7 +27,9 @@ module Lib_entry = struct let name = function | Library lib -> Lib.Local.to_lib lib |> Lib.name - | Deprecated_library_name d -> snd d.old_public_name.name + | Deprecated_library_name + { old_public_name = { public = old_public_name; _ }; _ } -> + Dune_file.Public_lib.name old_public_name end type t = @@ -525,8 +527,10 @@ let create ~(context : Context.t) ?host ~projects ~packages ~stanzas ( pub.package.name , Lib_entry.Library (Option.value_exn (Lib.Local.of_lib lib)) ) :: acc ) - | Dune_file.Deprecated_library_name d -> - ( d.old_public_name.package.name + | Dune_file.Deprecated_library_name + ({ old_public_name = { public = old_public_name; _ }; _ } as d) + -> + ( (Dune_file.Public_lib.package old_public_name).name , Lib_entry.Deprecated_library_name d ) :: acc | _ -> acc) From 90d2cd03318c62636e148ba2ad9006e2af6aeb56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ojeda=20B=C3=A4r?= Date: Tue, 8 Oct 2019 23:41:56 +0200 Subject: [PATCH 4/7] Add test MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolás Ojeda Bär --- .../test-cases/deprecated-library-name/run.t | 300 ++++++++++++++++++ 1 file changed, 300 insertions(+) diff --git a/test/blackbox-tests/test-cases/deprecated-library-name/run.t b/test/blackbox-tests/test-cases/deprecated-library-name/run.t index 761f3b7bb68..1ae02cf380b 100644 --- a/test/blackbox-tests/test-cases/deprecated-library-name/run.t +++ b/test/blackbox-tests/test-cases/deprecated-library-name/run.t @@ -93,3 +93,303 @@ that wasn't found: Error: Library "a" not found. Hint: try: dune external-lib-deps --missing c/prog.exe [1] + +Test that we can migrate top-level libraries +-------------------------------------------- + + $ mkdir d + +First the motivating case. + + $ cat >d/dune-project < (lang dune 2.0) + > (package (name menhir) (deprecated_package_names menhirLib menhirSdk dummy)) + > EOF + + $ cat >d/dune < (rule (with-stdout-to lib.ml (progn))) + > (library + > (name menhirLib) + > (public_name menhir.lib) + > (modules lib)) + > (deprecated_library_name + > (old_public_name menhirLib) + > (new_public_name menhir.lib)) + > (rule (with-stdout-to sdk.ml (echo "let version = ()"))) + > (library + > (name menhirSdk) + > (public_name menhir.sdk) + > (modules sdk)) + > (deprecated_library_name + > (old_public_name menhirSdk) + > (new_public_name menhir.sdk)) + > EOF + + $ cd d && dune build --root . @install + + $ find d/_build/install/default -name 'META' | sort + d/_build/install/default/lib/dummy/META + d/_build/install/default/lib/menhir/META + d/_build/install/default/lib/menhirLib/META + d/_build/install/default/lib/menhirSdk/META + + $ cat d/_build/install/default/lib/dummy/META + + + $ cat d/_build/install/default/lib/menhirLib/META + requires = "menhir.lib" + $ cat d/_build/install/default/lib/menhirSdk/META + requires = "menhir.sdk" + + $ find d/_build/install/default -name 'dune-package' | sort + d/_build/install/default/lib/dummy/dune-package + d/_build/install/default/lib/menhir/dune-package + d/_build/install/default/lib/menhirLib/dune-package + d/_build/install/default/lib/menhirSdk/dune-package + + $ cat d/_build/install/default/lib/dummy/dune-package + (lang dune 2.0) + (name dummy) + + $ cat d/_build/install/default/lib/menhirLib/dune-package + (lang dune 2.0) + (name menhirLib) + (deprecated_library_name + (old_public_name menhirLib) + (new_public_name menhir.lib)) + + $ cat d/_build/install/default/lib/menhirSdk/dune-package + (lang dune 2.0) + (name menhirSdk) + (deprecated_library_name + (old_public_name menhirSdk) + (new_public_name menhir.sdk)) + + +Check that we can use the short name in library dependencies. + + $ cat >>d/dune < (rule (with-stdout-to use.ml (echo "let _ = MenhirSdk.Sdk.version"))) + > (library + > (name foo) + > (public_name menhir.foo) + > (libraries menhirSdk menhirLib) + > (modules use)) + > EOF + + $ cd d && dune build --root . @all + +Checks that we can migrate top-level libraries across packages. + + $ cat >d/dune-project < (lang dune 2.0) + > (package (name p) (deprecated_package_names top1 top2)) + > (package (name q)) + > EOF + + $ cat >d/dune < (rule (with-stdout-to foo.ml (progn))) + > (library + > (name foo) + > (public_name q.bar) + > (modules foo)) + > (deprecated_library_name + > (old_public_name top1) + > (new_public_name q.bar)) + > EOF + + $ cd d && dune build --root . @install + + $ cat d/_build/install/default/lib/top1/META + requires = "q.bar" + +Check that we can do it when the name of the new library is the same as the +old public name: + + $ cat >d/dune < (rule (with-stdout-to bar.ml (progn))) + > (library + > (name top2) + > (public_name q.top2) + > (modules bar)) + > (deprecated_library_name + > (old_public_name top2) + > (new_public_name q.top2)) + > EOF + + $ cd d && dune build --root . @all + + $ cat d/_build/install/default/lib/top2/META + requires = "q.top2" + +We check that there is an error when there is an actual ambiguity: + + $ cat >d/dune < (rule (with-stdout-to bar.ml (progn))) + > (rule (with-stdout-to bar2.ml (progn))) + > (library + > (name top2) + > (public_name q.top2) + > (modules bar)) + > (library + > (name top3) + > (public_name q.top3) + > (modules bar2)) + > (deprecated_library_name + > (old_public_name top2) + > (new_public_name q.top3)) + > EOF + + $ cd d && dune build --root . @all + Error: Library top2 is defined twice: + - dune:13 + - dune:5 + [1] + +Another case of ambiguity: + + $ cat >d/dune-project < (lang dune 2.0) + > (package (name p)) + > (package (name q) (deprecated_package_names p)) + > EOF + + $ cat >d/dune < (rule (with-stdout-to bar.ml (progn))) + > (library + > (name p) + > (public_name p) + > (modules bar)) + > (deprecated_library_name + > (old_public_name p) + > (new_public_name p)) + > EOF + + $ cd d && dune build --root . --display=short @all + Error: Package name p is defined twice: + - dune-project:3 + - dune-project:2 + [1] + +Qualified, deprecated old_public_name: + + $ cat >d/dune-project < (lang dune 2.0) + > (package (name p) (deprecated_package_names q)) + > EOF + + $ cat >d/dune < (rule (with-stdout-to bar.ml (progn))) + > (library + > (name p) + > (public_name p) + > (modules bar)) + > (deprecated_library_name + > (old_public_name q.foo) + > (new_public_name p)) + > EOF + + $ cd d && dune build --root . @all + + $ find d/_build/install/default -name 'META' | sort + d/_build/install/default/lib/p/META + d/_build/install/default/lib/q/META + + $ cat d/_build/install/default/lib/q/META + package "foo" ( + requires = "p" + ) + + $ find d/_build/install/default -name 'dune-package' | sort + d/_build/install/default/lib/p/dune-package + d/_build/install/default/lib/q/dune-package + + $ cat d/_build/install/default/lib/q/dune-package + (lang dune 2.0) + (name q) + (deprecated_library_name (old_public_name q.foo) (new_public_name p)) + +Two libraries redirecting to the same library: + + $ cat >d/dune-project < (lang dune 2.0) + > (package (name p) (deprecated_package_names q)) + > EOF + + $ cat >d/dune < (rule (with-stdout-to bar.ml (progn))) + > (library + > (name p) + > (public_name p) + > (modules bar)) + > (deprecated_library_name + > (old_public_name q.foo) + > (new_public_name p)) + > (deprecated_library_name + > (old_public_name q.bar) + > (new_public_name p)) + > EOF + + $ cd d && dune build --root . @all + + $ find d/_build/install/default -name 'META' | sort + d/_build/install/default/lib/p/META + d/_build/install/default/lib/q/META + + $ cat d/_build/install/default/lib/q/META + package "bar" ( + requires = "p" + ) + package "foo" ( + requires = "p" + ) + + $ find d/_build/install/default -name 'dune-package' | sort + d/_build/install/default/lib/p/dune-package + d/_build/install/default/lib/q/dune-package + + $ cat d/_build/install/default/lib/q/dune-package + (lang dune 2.0) + (name q) + (deprecated_library_name (old_public_name q.bar) (new_public_name p)) + (deprecated_library_name (old_public_name q.foo) (new_public_name p)) + +Check that we can use deprecated packages from within the same project and +across projects. + + $ mkdir -p d/p/a d/p/b + + $ cat >d/p/a/dune-project < (lang dune 2.0) + > (package (name a) (deprecated_package_names aa)) + > EOF + + $ cat >d/p/b/dune-project < (lang dune 2.0) + > (package (name b)) + > EOF + + $ cat >d/p/a/dune < (rule (with-stdout-to empty1.ml (progn))) + > (rule (with-stdout-to empty2.ml (progn))) + > (deprecated_library_name + > (old_public_name aa.foo) + > (new_public_name a.p)) + > (library + > (name p) + > (public_name a.p) + > (modules empty1)) + > (library + > (name q) + > (libraries aa.foo) + > (modules empty2)) + > EOF + + $ cat >d/p/b/dune < (rule (with-stdout-to empty.ml (progn))) + > (library + > (name b) + > (libraries aa.foo)) + > EOF + + $ cd d/p && dune build --root . @all From c2b0965959afa5a81f7a1f6d08c90d63228e90ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ojeda=20B=C3=A4r?= Date: Fri, 11 Oct 2019 14:46:04 +0200 Subject: [PATCH 5/7] Update CHANGES.md MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolás Ojeda Bär --- CHANGES.md | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index c1fdb9e10b6..f89d9930939 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -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) ------------------- From d978e318cd445f028d14601fe9c21362a161c4c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ojeda=20B=C3=A4r?= Date: Fri, 11 Oct 2019 14:56:07 +0200 Subject: [PATCH 6/7] Update manual MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolás Ojeda Bär --- doc/dune-files.rst | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/doc/dune-files.rst b/doc/dune-files.rst index 91d59dcd9be..932de2e4ded 100644 --- a/doc/dune-files.rst +++ b/doc/dune-files.rst @@ -237,6 +237,11 @@ It contains the following fields: - ``(tags )`` are the list of tags for the package +- ``(deprecated_package_names )`` 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 ```` is modeled after opam's own language: The syntax is as a list of the following elements: @@ -494,6 +499,8 @@ JavaScript output. See :ref:`jsoo` for more information. +.. _deprecated-library-name: + deprecated_library_name ----------------------- @@ -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 ---------- From 84826314b962c1c86ce4c218b5de7f212eeef32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Nicol=C3=A1s=20Ojeda=20B=C3=A4r?= Date: Wed, 16 Oct 2019 14:59:11 +0200 Subject: [PATCH 7/7] make fmt MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Nicolás Ojeda Bär --- src/dune/dialect.ml | 3 ++- src/dune/dune_package.ml | 31 ++++++++++++++++--------------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/src/dune/dialect.ml b/src/dune/dialect.ml index 24863cb0a24..f3370a39920 100644 --- a/src/dune/dialect.ml +++ b/src/dune/dialect.ml @@ -17,7 +17,8 @@ module File_kind = struct , option (fun (_, x) -> Action_dune_lang.to_dyn x) preprocess ) ; ( "format" , option - (fun (_, x, y) -> pair Action_dune_lang.to_dyn (list string) (x, y)) + (fun (_, x, y) -> + pair Action_dune_lang.to_dyn (list string) (x, y)) format ) ] end diff --git a/src/dune/dune_package.ml b/src/dune/dune_package.ml index 4d520f41b3a..9e9ad4c218e 100644 --- a/src/dune/dune_package.ml +++ b/src/dune/dune_package.ml @@ -195,12 +195,12 @@ module Lib = struct let info dp = dp.info - let to_dyn { info ; modules ; main_module_name } = + 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 + [ ("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 @@ -230,8 +230,8 @@ module Deprecated_library_name = struct 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 + [ ("old_public_name", Lib_name.to_dyn old_public_name) + ; ("new_public_name", Lib_name.to_dyn new_public_name) ] end @@ -261,10 +261,9 @@ module Entry = struct let to_dyn x = let open Dyn.Encoder in match x with - | Library lib -> - constr "Library" [Lib.to_dyn lib] + | Library lib -> constr "Library" [ Lib.to_dyn lib ] | Deprecated_library_name lib -> - constr "Deprecated_library_name" [Deprecated_library_name.to_dyn lib] + constr "Deprecated_library_name" [ Deprecated_library_name.to_dyn lib ] end type t = @@ -330,10 +329,10 @@ let encode ~dune_version { entries; name; version; dir } = 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 + [ ("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 @@ -361,11 +360,13 @@ module Or_meta = struct 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 + 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] + | Dune_package t -> constr "Dune_package" [ to_dyn t ] end