diff --git a/doc/dune-files.rst b/doc/dune-files.rst index 3482d659148..e4a6aa861e1 100644 --- a/doc/dune-files.rst +++ b/doc/dune-files.rst @@ -887,6 +887,30 @@ instead of this stanza. For example: (dirs :standard \ ...) +.. _dune-vendored_dirs: + +vendored_dirs (since 1.11) +------------------------- + +Dune supports vendoring of other dune-based projects natively since simply +copying a project into a subdirectory of your own project will work. Simply +doing that has a few limitations though. You can workaround those by explicitly +marking such directories as containing vendored code. + +Example: + +.. code:: scheme + + (vendored_dirs vendor) + + +Dune will not resolve aliases in vendored directories meaning by default it will +not build all installable targets, run the test, format or lint the code located +in such a directory while still building the parts your project depend upon. +Libraries and executable in vendored directories will also be built with a ``-w +-a`` flag to suppress all warnings and prevent pollution of your build output. + + .. _include_subdirs: include_subdirs diff --git a/src/bootstrap.boot.ml b/src/bootstrap.boot.ml index dbed532f7ca..eafcb1fc283 100644 --- a/src/bootstrap.boot.ml +++ b/src/bootstrap.boot.ml @@ -1,5 +1,7 @@ open Stdune +let bootstrapping = true + let data_only_path p = match Path.Source.to_string p with | "test" | "example" -> true diff --git a/src/bootstrap.ml b/src/bootstrap.ml index 010ae7cbf83..13cdd4048a7 100644 --- a/src/bootstrap.ml +++ b/src/bootstrap.ml @@ -1 +1,3 @@ +let bootstrapping = false + let data_only_path _ = false diff --git a/src/bootstrap.mli b/src/bootstrap.mli index abdb9cb4074..6799a3df616 100644 --- a/src/bootstrap.mli +++ b/src/bootstrap.mli @@ -2,6 +2,9 @@ open Stdune +(** Whether we're currently bootstrapping [dune] *) +val bootstrapping : bool + (** Treat the following path as if it was declared as a data only path in a [dune] file. *) val data_only_path : Path.Source.t -> bool diff --git a/src/build_system.ml b/src/build_system.ml index ad7d010a8ee..1db0862c4f9 100644 --- a/src/build_system.ml +++ b/src/build_system.ml @@ -195,7 +195,7 @@ module Alias0 = struct let dep_rec_internal ~name ~dir ~ctx_dir = Build.lazy_no_targets (lazy ( - File_tree.Dir.fold dir ~traverse_ignored_dirs:false + File_tree.Dir.fold dir ~traverse:Sub_dirs.Status.Set.normal_only ~init:(Build.return true) ~f:(fun dir acc -> let path = Path.Build.append_source ctx_dir (File_tree.Dir.path dir) in @@ -1277,7 +1277,7 @@ and get_rule t path = let all_targets t = String.Map.to_list t.contexts |> List.fold_left ~init:Path.Build.Set.empty ~f:(fun acc (_, ctx) -> - File_tree.fold t.file_tree ~traverse_ignored_dirs:true ~init:acc + File_tree.fold t.file_tree ~traverse:Sub_dirs.Status.Set.all ~init:acc ~f:(fun dir acc -> match load_dir diff --git a/src/dune_load.ml b/src/dune_load.ml index 3cbc36a36dd..2747f45f81e 100644 --- a/src/dune_load.ml +++ b/src/dune_load.ml @@ -265,7 +265,9 @@ let interpret ~dir ~project ~ignore_promoted_rules let load ?(ignore_promoted_rules=false) ~ancestor_vcs () = let ftree = File_tree.load Path.Source.root ~ancestor_vcs in let projects = - File_tree.fold ftree ~traverse_ignored_dirs:false ~init:[] + File_tree.fold ftree + ~traverse:{data_only = false; vendored = true; normal = true} + ~init:[] ~f:(fun dir acc -> let p = File_tree.Dir.project dir in if Path.Source.equal diff --git a/src/file_tree.ml b/src/file_tree.ml index 8f052bccf6e..d9ef79f0553 100644 --- a/src/file_tree.ml +++ b/src/file_tree.ml @@ -91,7 +91,7 @@ let load_jbuild_ignore path = module Dir = struct type t = { path : Path.Source.t - ; ignored : bool + ; status : Sub_dirs.Status.t ; contents : contents Lazy.t ; project : Dune_project.t ; vcs : Vcs.t option @@ -103,9 +103,9 @@ module Dir = struct ; dune_file : Dune_file.t option } - let create ~project ~path ~ignored ~contents ~vcs = + let create ~project ~path ~status ~contents ~vcs = { path - ; ignored + ; status ; contents ; project ; vcs @@ -114,7 +114,8 @@ module Dir = struct let contents t = Lazy.force t.contents let path t = t.path - let ignored t = t.ignored + let ignored t = t.status = Data_only + let vendored t = t.status = Vendored let files t = (contents t).files let sub_dirs t = (contents t).sub_dirs @@ -135,13 +136,14 @@ module Dir = struct String.Map.foldi (sub_dirs t) ~init:Path.Source.Set.empty ~f:(fun s _ acc -> Path.Source.Set.add acc (Path.Source.relative t.path s)) - let rec fold t ~traverse_ignored_dirs ~init:acc ~f = - if not traverse_ignored_dirs && t.ignored then - acc - else + let rec fold t ~traverse ~init:acc ~f = + let must_traverse = Sub_dirs.Status.Map.find traverse t.status in + if must_traverse then let acc = f t acc in String.Map.fold (sub_dirs t) ~init:acc ~f:(fun t acc -> - fold t ~traverse_ignored_dirs ~init:acc ~f) + fold t ~traverse ~init:acc ~f) + else + acc let rec dyn_of_contents { files; sub_dirs; dune_file } = let open Dyn in @@ -152,11 +154,11 @@ module Dir = struct ; "project", Dyn.opaque ] - and to_dyn { path ; ignored ; contents = lazy contents ; project = _; vcs } = + and to_dyn { path ; status ; contents = lazy contents ; project = _; vcs } = let open Dyn in Record [ "path", Path.Source.to_dyn path - ; "ignored", Bool ignored + ; "status", Sub_dirs.Status.to_dyn status ; "contents", dyn_of_contents contents ; "vcs", Dyn.Encoder.option Vcs.to_dyn vcs ] @@ -223,11 +225,11 @@ let readdir path = let load ?(warn_when_seeing_jbuild_file=true) path ~ancestor_vcs = let open Result.O in - let rec walk path ~dirs_visited ~project:parent_project ~vcs ~data_only + let rec walk path ~dirs_visited ~project:parent_project ~vcs ~(dir_status : Sub_dirs.Status.t) : (_, _) Result.t = let+ { dirs; files } = readdir path in let project = - if data_only then + if dir_status = Data_only then parent_project else Option.value (Dune_project.load ~dir:path ~files) @@ -249,7 +251,7 @@ let load ?(warn_when_seeing_jbuild_file=true) path ~ancestor_vcs = in let contents = lazy ( let dune_file, sub_dirs = - if data_only then + if dir_status = Data_only then (None, Sub_dirs.default) else let dune_file, sub_dirs = @@ -257,10 +259,13 @@ let load ?(warn_when_seeing_jbuild_file=true) path ~ancestor_vcs = | [] -> (None, Sub_dirs.default) | [fn] -> let file = Path.Source.relative path fn in + let warn_about_jbuild = + warn_when_seeing_jbuild_file && dir_status <> Vendored + in if fn = "dune" then ignore (Dune_project.ensure_project_file_exists project : Dune_project.created_or_already_exist) - else if warn_when_seeing_jbuild_file then + else if warn_about_jbuild then (* DUNE2: turn this into an error *) User_warning.emit ~loc:(Loc.in_file (Path.source file)) [ Pp.text "jbuild files are deprecated, please \ @@ -300,14 +305,19 @@ let load ?(warn_when_seeing_jbuild_file=true) path ~ancestor_vcs = |> List.fold_left ~init:String.Map.empty ~f:(fun acc (fn, path, file) -> let status = if Bootstrap.data_only_path path then - Sub_dirs.Status.Ignored + Sub_dirs.Status.Or_ignored.Ignored else Sub_dirs.status sub_dirs ~dir:fn in match status with | Ignored -> acc - | Normal | Data_only -> - let data_only = data_only || status = Data_only in + | Status status -> + let dir_status : Sub_dirs.Status.t = + match dir_status, status with + | Data_only, _ -> Data_only + | Vendored, Normal -> Vendored + | _, _ -> status + in let dirs_visited = if Sys.win32 then dirs_visited @@ -321,19 +331,19 @@ let load ?(warn_when_seeing_jbuild_file=true) path ~ancestor_vcs = (Path.Source.to_string_maybe_quoted path) ] in match - walk path ~dirs_visited ~project ~data_only ~vcs + walk path ~dirs_visited ~project ~dir_status ~vcs with | Ok dir -> String.Map.set acc fn dir | Error _ -> acc) in { Dir. files; sub_dirs; dune_file }) in - Dir.create ~path ~contents ~ignored:data_only ~project ~vcs + Dir.create ~path ~contents ~status:dir_status ~project ~vcs in match walk path ~dirs_visited:(File.Map.singleton (File.of_source_path path) path) - ~data_only:false + ~dir_status:Normal ~project:(Lazy.force Dune_project.anonymous) ~vcs:ancestor_vcs with @@ -382,11 +392,14 @@ let file_exists t path = let dir_exists t path = Option.is_some (find_dir t path) +let dir_is_vendored t path = + Option.map ~f:(fun dir -> Dir.vendored dir) (find_dir t path) + let files_recursively_in t ~prefix_with path = match find_dir t path with | None -> Path.Set.empty | Some dir -> - Dir.fold dir ~init:Path.Set.empty ~traverse_ignored_dirs:true + Dir.fold dir ~init:Path.Set.empty ~traverse:Sub_dirs.Status.Set.all ~f:(fun dir acc -> let path = Path.append_source prefix_with (Dir.path dir) in String.Set.fold (Dir.files dir) ~init:acc ~f:(fun fn acc -> diff --git a/src/file_tree.mli b/src/file_tree.mli index 1f31e4e6cef..3e28da50e99 100644 --- a/src/file_tree.mli +++ b/src/file_tree.mli @@ -42,11 +42,15 @@ module Dir : sig or [jbuild-ignore] file in one of its ancestor directories. *) val ignored : t -> bool + (** Whether this directory is vendored or sits within a vendored + directory *) + val vendored : t -> bool + val vcs : t -> Vcs.t option val fold : t - -> traverse_ignored_dirs:bool + -> traverse:Sub_dirs.Status.Set.t -> init:'a -> f:(t -> 'a -> 'a) -> 'a @@ -72,12 +76,12 @@ val load -> ancestor_vcs:Vcs.t option -> t -(** Passing [~traverse_ignored_dirs:true] to this functions causes the +(** Passing [~traverse_data_only_dirs:true] to this functions causes the whole source tree to be deeply scanned, including ignored sub-trees. *) val fold : t - -> traverse_ignored_dirs:bool + -> traverse:Sub_dirs.Status.Set.t -> init:'a -> f:(Dir.t -> 'a -> 'a) -> 'a @@ -99,6 +103,10 @@ val files_of : t -> Path.Source.t -> Path.Source.Set.t (** [true] iff the path is a directory *) val dir_exists : t -> Path.Source.t -> bool +(** [dir_is_vendored t path] tells whether [path] is a vendored directory. + Returns [None] if it doesn't describe a directory within [t]. *) +val dir_is_vendored : t -> Path.Source.t -> bool option + (** [true] iff the path is a file *) val file_exists : t -> Path.Source.t -> bool diff --git a/src/gen_rules.ml b/src/gen_rules.ml index 3f9121d5453..a148b0a9cef 100644 --- a/src/gen_rules.ml +++ b/src/gen_rules.ml @@ -161,7 +161,8 @@ module Gen(P : sig val sctx : Super_context.t end) = struct in let allow_approx_merlin = let dune_project = Scope.project scope in - Dune_project.allow_approx_merlin dune_project in + let dir_is_vendored = Super_context.dir_is_vendored sctx src_dir in + dir_is_vendored || Dune_project.allow_approx_merlin dune_project in Option.iter (Merlin.merge_all ~allow_approx_merlin merlins) ~f:(fun m -> let more_src_dirs = diff --git a/src/merlin.ml b/src/merlin.ml index 712fae6e32e..91de0e3e191 100644 --- a/src/merlin.ml +++ b/src/merlin.ml @@ -37,7 +37,7 @@ module Preprocess = struct if Action_dune_lang.compare_no_locs a1 a2 <> Ordering.Eq then warn_dropped_pp loc ~allow_approx_merlin ~reason:"this action preprocessor is not equivalent to other \ - preproocessor specifications."; + preprocessor specifications."; Action (loc, a1) | Pps _, Action (loc, _) | Action (loc, _), Pps _ -> diff --git a/src/ocaml_flags.ml b/src/ocaml_flags.ml index eb669cd3843..1fd8099311e 100644 --- a/src/ocaml_flags.ml +++ b/src/ocaml_flags.ml @@ -26,6 +26,9 @@ let dev_mode_warnings = let default_warnings = "-40" +let vendored_warnings = + ["-w"; "-a"] + let default_flags ~profile = if profile = "dev" then [ "-w"; dev_mode_warnings ^ default_warnings @@ -99,6 +102,8 @@ let append_common t flags = {t with common = t.common >>^ fun l -> l @ flags} let prepend_common flags t = {t with common = t.common >>^ fun l -> flags @ l} +let with_vendored_warnings t = append_common t vendored_warnings + let common t = t.common let dump t = diff --git a/src/ocaml_flags.mli b/src/ocaml_flags.mli index a47d915c411..5ce5426a821 100644 --- a/src/ocaml_flags.mli +++ b/src/ocaml_flags.mli @@ -29,6 +29,8 @@ val get_for_cm : t -> cm_kind:Cm_kind.t -> (unit, string list) Build.t val append_common : t -> string list -> t val prepend_common : string list -> t -> t +val with_vendored_warnings : t -> t + val common : t -> (unit, string list) Build.t val dump : t -> (unit, Dune_lang.t list) Build.t diff --git a/src/sub_dirs.ml b/src/sub_dirs.ml index 064f10f8f76..66aadbea391 100644 --- a/src/sub_dirs.ml +++ b/src/sub_dirs.ml @@ -1,9 +1,51 @@ open! Stdune -type 'set t = - { dirs : 'set - ; data_only : 'set - } +module Status = struct + type t = Data_only | Normal | Vendored + + module Map = struct + type 'a t = + { data_only : 'a + ; vendored : 'a + ; normal : 'a + } + + let find {data_only; vendored; normal} = function + | Data_only -> data_only + | Vendored -> vendored + | Normal -> normal + end + + let to_dyn t = + let open Dyn in + match t with + | Data_only -> Variant ("Data_only", []) + | Vendored -> Variant ("Vendored", []) + | Normal -> Variant ("Normal", []) + + module Or_ignored = struct + type nonrec t = Ignored | Status of t + end + + module Set = struct + open Map + type t = bool Map.t + + let all = {data_only = true; vendored = true; normal = true} + let normal_only = {data_only = false; vendored = false; normal = true} + end +end + +let status { Status.Map.normal; data_only ; vendored } + ~dir : Status.Or_ignored.t = + match String.Set.mem normal dir + , String.Set.mem data_only dir + , String.Set.mem vendored dir with + | true, false, false -> Status Normal + | true, false, true -> Status Vendored + | true, true, _ -> Status Data_only + | false, false, _ -> Ignored + | false, true, _ -> assert false let default = let standard_dirs = @@ -11,44 +53,51 @@ let default = | "" -> false | s -> s.[0] <> '.' && s.[0] <> '_') in - { dirs = standard_dirs + { Status.Map. + normal = standard_dirs ; data_only = Predicate_lang.empty + ; vendored = Predicate_lang.empty } -let make ~dirs ~data_only ~ignored_sub_dirs = - let dirs = Option.value dirs ~default:default.dirs in +let make ~dirs ~data_only ~ignored_sub_dirs ~vendored_dirs = + let normal = Option.value dirs ~default:default.normal in let data_only = let data_only = Option.value data_only ~default:default.data_only in Predicate_lang.union (data_only :: ignored_sub_dirs) in - { dirs ; data_only } + let vendored = Option.value vendored_dirs ~default:default.vendored in + { Status.Map. normal ; data_only ; vendored } -let add_data_only_dirs t ~dirs = - { t with data_only = - Predicate_lang.union - [t.data_only; (Predicate_lang.of_string_set dirs)] } +let add_data_only_dirs (t : _ Status.Map.t) ~dirs = + { t with + Status.Map. + data_only = + Predicate_lang.union + [t.data_only; Predicate_lang.of_string_set dirs] } -let eval t ~dirs = - let dirs = Predicate_lang.filter t.dirs ~standard:default.dirs dirs in - let data_only = - Predicate_lang.filter t.data_only ~standard:default.data_only dirs - |> String.Set.of_list - in - let dirs = String.Set.of_list dirs in - { dirs - ; data_only - } - -module Status = struct - type t = Ignored | Data_only | Normal -end - -let status t ~dir = - match String.Set.mem t.dirs dir, String.Set.mem t.data_only dir with - | true, false -> Status.Normal - | true, true -> Data_only - | false, false -> Ignored - | false, true -> assert false +let eval (t : _ Status.Map.t) ~dirs = + let normal = Predicate_lang.filter t.normal ~standard:default.normal dirs in + let to_set ~standard pred = + String.Set.of_list (Predicate_lang.filter pred ~standard dirs) in + let data_only = to_set ~standard:default.data_only t.data_only in + let vendored = + to_set ~standard:default.vendored t.vendored in + let both_vendored_and_data = String.Set.inter data_only vendored in + match String.Set.choose both_vendored_and_data with + | None -> + let normal = String.Set.of_list normal in + { Status.Map. + normal + ; data_only + ; vendored + } + | Some dir -> + User_error.raise + [ Pp.textf + "Directory %s was marked as vendored and data_only, \ + it can't be marked as both." + dir + ] let decode = let open Stanza.Decoder in @@ -86,10 +135,21 @@ let decode = Syntax.since Stanza.syntax (1, 6) >>> Predicate_lang.decode in + let vendored_dirs = + let decode = + if Bootstrap.bootstrapping then + let pred = Predicate_lang.of_pred (fun _ -> true) in + Dune_lang.Decoder.(map ~f:(fun () -> pred) (keyword "*")) + else + Predicate_lang.decode + in + located (Syntax.since Stanza.syntax (1, 11) >>> decode) + in let decode = let+ dirs = field_o "dirs" (located plang) and+ data_only = field_o "data_only_dirs" (located plang) and+ ignored_sub_dirs = multi_field "ignored_subdirs" ignored_sub_dirs + and+ vendored_dirs = field_o "vendored_dirs" vendored_dirs and+ rest = leftover_fields in match data_only, dirs, ignored_sub_dirs with @@ -104,7 +164,8 @@ let decode = | _ -> let dirs = Option.map ~f:snd dirs in let data_only = Option.map ~f:snd data_only in - ( make ~dirs ~data_only ~ignored_sub_dirs + let vendored_dirs = Option.map ~f:snd vendored_dirs in + ( make ~dirs ~data_only ~ignored_sub_dirs ~vendored_dirs , rest ) in diff --git a/src/sub_dirs.mli b/src/sub_dirs.mli index e6082946766..65165761c43 100644 --- a/src/sub_dirs.mli +++ b/src/sub_dirs.mli @@ -1,23 +1,46 @@ open Stdune -type 'set t = private - { dirs : 'set - ; data_only : 'set - } - module Status : sig - type t = Ignored | Data_only | Normal + type t = Data_only | Normal | Vendored + + val to_dyn : t -> Dyn.t + + module Or_ignored : sig + type nonrec t = Ignored | Status of t + end + + module Map : sig + type status + type 'a t = + { data_only : 'a + ; vendored : 'a + ; normal : 'a + } + + val find : 'a t -> status -> 'a + end with type status := t + + module Set : sig + type t = bool Map.t + + val all : t + val normal_only : t + end end -val default : Predicate_lang.t t +val default : Predicate_lang.t Status.Map.t val add_data_only_dirs - : Predicate_lang.t t + : Predicate_lang.t Status.Map.t -> dirs:String.Set.t - -> Predicate_lang.t t + -> Predicate_lang.t Status.Map.t -val eval : Predicate_lang.t t -> dirs:string list -> String.Set.t t +val eval + : Predicate_lang.t Status.Map.t + -> dirs:string list + -> String.Set.t Status.Map.t -val status : String.Set.t t -> dir:string -> Status.t +val status : String.Set.t Status.Map.t -> dir:string -> Status.Or_ignored.t -val decode : (Predicate_lang.t t * Dune_lang.Ast.t list) Stanza.Decoder.t +val decode + : (Predicate_lang.t Status.Map.t * Dune_lang.Ast.t list) Stanza.Decoder.t diff --git a/src/super_context.ml b/src/super_context.ml index 2112a0b446e..9083ca348ec 100644 --- a/src/super_context.ml +++ b/src/super_context.ml @@ -268,13 +268,30 @@ let partial_expand sctx ~dep_kind ~targets_written_by_user ~map_exe let partial = Action_unexpanded.partial_expand t ~expander ~map_exe in (partial, acc) +let dir_is_vendored t src_dir = + Option.value ~default:false (File_tree.dir_is_vendored t.file_tree src_dir) + +let build_dir_is_vendored t build_dir = + let opt = + let open Option.O in + let+ src_dir = Path.Build.drop_build_context build_dir in + dir_is_vendored t src_dir + in + Option.value ~default:false opt + let ocaml_flags t ~dir (x : Dune_file.Buildable.t) = - let t = t.env_context in - let expander = Env.expander t ~dir in - Ocaml_flags.make - ~spec:x.flags - ~default:(Env.ocaml_flags t ~dir) - ~eval:(Expander.expand_and_eval_set expander) + let expander = Env.expander t.env_context ~dir in + let flags = + Ocaml_flags.make + ~spec:x.flags + ~default:(Env.ocaml_flags t.env_context ~dir) + ~eval:(Expander.expand_and_eval_set expander) + in + let dir_is_vendored = build_dir_is_vendored t dir in + if dir_is_vendored then + Ocaml_flags.with_vendored_warnings flags + else + flags let c_flags t ~dir ~expander ~flags = let t = t.env_context in diff --git a/src/super_context.mli b/src/super_context.mli index 8853918d040..9e203df1c82 100644 --- a/src/super_context.mli +++ b/src/super_context.mli @@ -69,6 +69,9 @@ val dump_env : t -> dir:Path.Build.t -> (unit, Dune_lang.t list) Build.t val find_scope_by_dir : t -> Path.Build.t -> Scope.t val find_scope_by_name : t -> Dune_project.Name.t -> Scope.t +(** Tells whether the given source directory is marked as vendored *) +val dir_is_vendored : t -> Path.Source.t -> bool + val add_rule : t -> ?sandbox:bool diff --git a/src/upgrader.ml b/src/upgrader.ml index dcd5ec71021..69b88f1663c 100644 --- a/src/upgrader.ml +++ b/src/upgrader.ml @@ -371,8 +371,8 @@ let upgrade ft = ; to_edit = [] } in - File_tree.fold ft ~traverse_ignored_dirs:false ~init:() ~f:(fun dir () -> - upgrade_dir todo dir); + File_tree.fold ft ~traverse:Sub_dirs.Status.Set.normal_only ~init:() + ~f:(fun dir () -> upgrade_dir todo dir); let git = lazy ( match Bin.which ~path:(Env.path Env.initial) "git" with | Some x -> x diff --git a/src/utop.ml b/src/utop.ml index 7e8a26bfd73..09f1fe063f0 100644 --- a/src/utop.ml +++ b/src/utop.ml @@ -26,7 +26,7 @@ let libs_under_dir sctx ~db ~dir = (let open Option.O in let* dir = Path.drop_build_context dir in let+ dir = File_tree.find_dir (Super_context.file_tree sctx) dir in - File_tree.Dir.fold dir ~traverse_ignored_dirs:true + File_tree.Dir.fold dir ~traverse:Sub_dirs.Status.Set.all ~init:[] ~f:(fun dir acc -> let dir = Path.Build.append_source (Super_context.build_dir sctx) diff --git a/test/blackbox-tests/dune.inc b/test/blackbox-tests/dune.inc index 30066b08617..2bb6422b093 100644 --- a/test/blackbox-tests/dune.inc +++ b/test/blackbox-tests/dune.inc @@ -1542,6 +1542,14 @@ test-cases/variants-wrong-external-declaration (progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected))))) +(alias + (name vendor) + (deps (package dune) (source_tree test-cases/vendor)) + (action + (chdir + test-cases/vendor + (progn (run %{exe:cram.exe} -test run.t) (diff? run.t run.t.corrected))))) + (alias (name vlib) (deps (package dune) (source_tree test-cases/vlib)) @@ -1787,6 +1795,7 @@ (alias variants-multi-project) (alias variants-only-package) (alias variants-wrong-external-declaration) + (alias vendor) (alias vlib) (alias vlib-default-impl) (alias vlib-wrong-default-impl) @@ -1957,6 +1966,7 @@ (alias variants-multi-project) (alias variants-only-package) (alias variants-wrong-external-declaration) + (alias vendor) (alias vlib) (alias vlib-default-impl) (alias vlib-wrong-default-impl) diff --git a/test/blackbox-tests/test-cases/vendor/conflicts-with-data-only/dir/dune b/test/blackbox-tests/test-cases/vendor/conflicts-with-data-only/dir/dune new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/blackbox-tests/test-cases/vendor/conflicts-with-data-only/dune b/test/blackbox-tests/test-cases/vendor/conflicts-with-data-only/dune new file mode 100644 index 00000000000..066527c4328 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/conflicts-with-data-only/dune @@ -0,0 +1,3 @@ +(vendored_dirs *) + +(data_only_dirs *) diff --git a/test/blackbox-tests/test-cases/vendor/conflicts-with-data-only/dune-project b/test/blackbox-tests/test-cases/vendor/conflicts-with-data-only/dune-project new file mode 100644 index 00000000000..0636ab6acf4 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/conflicts-with-data-only/dune-project @@ -0,0 +1 @@ +(lang dune 1.11) diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/dune-project b/test/blackbox-tests/test-cases/vendor/duniverse/dune-project new file mode 100644 index 00000000000..0636ab6acf4 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/dune-project @@ -0,0 +1 @@ +(lang dune 1.11) diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/dune b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/dune new file mode 100644 index 00000000000..806de809491 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/dune @@ -0,0 +1 @@ +(vendored_dirs *) diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/dune-project b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/dune-project new file mode 100644 index 00000000000..bc29044968d --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/dune-project @@ -0,0 +1,2 @@ +(lang dune 1.10) +(name vendored) diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/lib/dune b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/lib/dune new file mode 100644 index 00000000000..ff43b81c072 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/lib/dune @@ -0,0 +1,2 @@ +(library + (public_name vendored)) diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/lib/vendored.ml b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/lib/vendored.ml new file mode 100644 index 00000000000..3282b724e89 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/lib/vendored.ml @@ -0,0 +1 @@ +let say_hello () = Printf.printf "Hello from vendored lib!\n" diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/tests/dune b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/tests/dune new file mode 100644 index 00000000000..424d13f6598 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/tests/dune @@ -0,0 +1,3 @@ +(test + (name test) + (libraries vendored)) diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/tests/test.ml b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/tests/test.ml new file mode 100644 index 00000000000..a1d72716532 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/tests/test.ml @@ -0,0 +1 @@ +let () = Vendored.say_hello () diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/vendored.opam b/test/blackbox-tests/test-cases/vendor/duniverse/duniverse/vendored/vendored.opam new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/lib/dune b/test/blackbox-tests/test-cases/vendor/duniverse/lib/dune new file mode 100644 index 00000000000..73ad23b414b --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/lib/dune @@ -0,0 +1,3 @@ +(library + (public_name main) + (libraries vendored)) diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/lib/main.ml b/test/blackbox-tests/test-cases/vendor/duniverse/lib/main.ml new file mode 100644 index 00000000000..03f3828cacc --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/lib/main.ml @@ -0,0 +1,3 @@ +let _ = Vendored.say_hello + +let say_hello () = Printf.printf "Hello from main lib!\n" diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/main.opam b/test/blackbox-tests/test-cases/vendor/duniverse/main.opam new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/tests/dune b/test/blackbox-tests/test-cases/vendor/duniverse/tests/dune new file mode 100644 index 00000000000..b4a9ad42806 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/tests/dune @@ -0,0 +1,3 @@ +(test + (name test) + (libraries main)) diff --git a/test/blackbox-tests/test-cases/vendor/duniverse/tests/test.ml b/test/blackbox-tests/test-cases/vendor/duniverse/tests/test.ml new file mode 100644 index 00000000000..0a29d9c1105 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/duniverse/tests/test.ml @@ -0,0 +1 @@ +let () = Main.say_hello () diff --git a/test/blackbox-tests/test-cases/vendor/from-1-11/dune b/test/blackbox-tests/test-cases/vendor/from-1-11/dune new file mode 100644 index 00000000000..806de809491 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/from-1-11/dune @@ -0,0 +1 @@ +(vendored_dirs *) diff --git a/test/blackbox-tests/test-cases/vendor/from-1-11/dune-project b/test/blackbox-tests/test-cases/vendor/from-1-11/dune-project new file mode 100644 index 00000000000..42c0c167431 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/from-1-11/dune-project @@ -0,0 +1 @@ +(lang dune 1.10) diff --git a/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/dune b/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/dune new file mode 100644 index 00000000000..67b077aef4a --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/dune @@ -0,0 +1,6 @@ +(alias + (name inaccurate-merlins-are-ok) + (deps vendored/a.ml) + (action (echo "There should be no inaccurate .merlin warning above!"))) + +(vendored_dirs vendored) diff --git a/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/dune-project b/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/dune-project new file mode 100644 index 00000000000..0636ab6acf4 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/dune-project @@ -0,0 +1 @@ +(lang dune 1.11) diff --git a/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/vendored/a.ml b/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/vendored/a.ml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/vendored/b.ml b/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/vendored/b.ml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/vendored/dune b/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/vendored/dune new file mode 100644 index 00000000000..134706f4c7b --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/inaccurate-merlin/vendored/dune @@ -0,0 +1,9 @@ +(library + (name a) + (modules a) + (preprocess (action (bash "some_command")))) + +(library + (name b) + (modules b) + (preprocess (action (bash "some_other_command")))) diff --git a/test/blackbox-tests/test-cases/vendor/jbuild-files/dune b/test/blackbox-tests/test-cases/vendor/jbuild-files/dune new file mode 100644 index 00000000000..75359159337 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/jbuild-files/dune @@ -0,0 +1,6 @@ +(alias + (name jbuild-are-ok) + (deps vendored/lib.cmxa) + (action (echo "There should be no jbuild warning above!"))) + +(vendored_dirs vendored) diff --git a/test/blackbox-tests/test-cases/vendor/jbuild-files/dune-project b/test/blackbox-tests/test-cases/vendor/jbuild-files/dune-project new file mode 100644 index 00000000000..0636ab6acf4 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/jbuild-files/dune-project @@ -0,0 +1 @@ +(lang dune 1.11) diff --git a/test/blackbox-tests/test-cases/vendor/jbuild-files/vendored/jbuild b/test/blackbox-tests/test-cases/vendor/jbuild-files/vendored/jbuild new file mode 100644 index 00000000000..20b3f6191f3 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/jbuild-files/vendored/jbuild @@ -0,0 +1 @@ +(library ((name lib))) diff --git a/test/blackbox-tests/test-cases/vendor/jbuild-files/vendored/lib.ml b/test/blackbox-tests/test-cases/vendor/jbuild-files/vendored/lib.ml new file mode 100644 index 00000000000..e69de29bb2d diff --git a/test/blackbox-tests/test-cases/vendor/run.t b/test/blackbox-tests/test-cases/vendor/run.t new file mode 100644 index 00000000000..7982477864e --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/run.t @@ -0,0 +1,48 @@ +Vendored directories should be traversed to find targets so that they are built when they are depend upon + + $ dune build --root duniverse + Entering directory 'duniverse' + +Aliases should not be resolved in vendored sub directories + + $ dune runtest --root duniverse + Entering directory 'duniverse' + test alias tests/runtest + Hello from main lib! + +When compiling vendored code, all warnings should be disabled + + $ dune build --root warnings @no-warnings-please + Entering directory 'warnings' + There should be no OCaml warning above! + +Dune will not warn about jbuild files within vendored directories + + $ dune build --root jbuild-files @jbuild-are-ok + Entering directory 'jbuild-files' + There should be no jbuild warning above! + +Dune will not warn about generating inaccurate .merlin files within vendored directories + + $ dune build --root inaccurate-merlin @inaccurate-merlins-are-ok + Entering directory 'inaccurate-merlin' + There should be no inaccurate .merlin warning above! + +The vendored_dirs stanza is available from version 1.11 of the dune language + + $ dune build --root from-1-11 + Entering directory 'from-1-11' + File "dune", line 1, characters 0-17: + 1 | (vendored_dirs *) + ^^^^^^^^^^^^^^^^^ + Error: 'vendored_dirs' is only available since version 1.11 of the dune + language + [1] + +The same directory cannot be marked as both vendored and data-only + + $ dune build --root conflicts-with-data-only + Entering directory 'conflicts-with-data-only' + Error: Directory dir was marked as vendored and data_only, it can't be marked + as both. + [1] diff --git a/test/blackbox-tests/test-cases/vendor/warnings/dune b/test/blackbox-tests/test-cases/vendor/warnings/dune new file mode 100644 index 00000000000..55e794d9a9e --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/warnings/dune @@ -0,0 +1,6 @@ +(alias + (name no-warnings-please) + (deps vendored/lib.cmxa) + (action (echo "There should be no OCaml warning above!"))) + +(vendored_dirs vendored) diff --git a/test/blackbox-tests/test-cases/vendor/warnings/dune-project b/test/blackbox-tests/test-cases/vendor/warnings/dune-project new file mode 100644 index 00000000000..0636ab6acf4 --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/warnings/dune-project @@ -0,0 +1 @@ +(lang dune 1.11) diff --git a/test/blackbox-tests/test-cases/vendor/warnings/vendored/dune b/test/blackbox-tests/test-cases/vendor/warnings/vendored/dune new file mode 100644 index 00000000000..4ce22d14f6c --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/warnings/vendored/dune @@ -0,0 +1,2 @@ +(library + (name lib)) diff --git a/test/blackbox-tests/test-cases/vendor/warnings/vendored/lib.ml b/test/blackbox-tests/test-cases/vendor/warnings/vendored/lib.ml new file mode 100644 index 00000000000..39ac22eefcf --- /dev/null +++ b/test/blackbox-tests/test-cases/vendor/warnings/vendored/lib.ml @@ -0,0 +1,2 @@ +let do_something = function + | [] -> () diff --git a/vendor/dune b/vendor/dune new file mode 100644 index 00000000000..806de809491 --- /dev/null +++ b/vendor/dune @@ -0,0 +1 @@ +(vendored_dirs *)