Include generated files when looking for odig doc files
This commit is contained in:
parent
75335af4bc
commit
331b9dc14e
|
@ -166,8 +166,12 @@ anyway.
|
||||||
*** Odig conventions
|
*** Odig conventions
|
||||||
|
|
||||||
Jbuilder follows the [[http://erratique.ch/software/odig][odig]] conventions and automatically installs any
|
Jbuilder follows the [[http://erratique.ch/software/odig][odig]] conventions and automatically installs any
|
||||||
README*, CHANGE* and LICENSE* files in the same directory as the
|
README*, CHANGE*, HISTORY* and LICENSE* files in the same directory as
|
||||||
=<package>.opam= file to a location where odig will find them.
|
the =<package>.opam= file to a location where odig will find them.
|
||||||
|
|
||||||
|
Note that this include files present in the source tree as well as
|
||||||
|
generated files. So for instance a changelog generated by a rule will
|
||||||
|
be automatically installed as well.
|
||||||
|
|
||||||
** jbuild
|
** jbuild
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
open Import
|
||||||
|
open Build.Repr
|
||||||
|
|
||||||
|
module Pset = Path.Set
|
||||||
|
module Pmap = Path.Map
|
||||||
|
module Vspec = Build.Vspec
|
||||||
|
|
||||||
|
module Target = struct
|
||||||
|
type t =
|
||||||
|
| Normal of Path.t
|
||||||
|
| Vfile : _ Vspec.t -> t
|
||||||
|
|
||||||
|
let path = function
|
||||||
|
| Normal p -> p
|
||||||
|
| Vfile (Vspec.T (p, _)) -> p
|
||||||
|
|
||||||
|
let paths ts =
|
||||||
|
List.fold_left ts ~init:Pset.empty ~f:(fun acc t ->
|
||||||
|
Pset.add (path t) acc)
|
||||||
|
end
|
||||||
|
|
||||||
|
let deps t ~all_targets_by_dir =
|
||||||
|
let rec loop : type a b. (a, b) t -> Pset.t -> Pset.t = fun t acc ->
|
||||||
|
match t with
|
||||||
|
| Arr _ -> acc
|
||||||
|
| Prim _ -> acc
|
||||||
|
| Store_vfile _ -> acc
|
||||||
|
| Compose (a, b) -> loop a (loop b acc)
|
||||||
|
| First t -> loop t acc
|
||||||
|
| Second t -> loop t acc
|
||||||
|
| Split (a, b) -> loop a (loop b acc)
|
||||||
|
| Fanout (a, b) -> loop a (loop b acc)
|
||||||
|
| Paths fns -> Pset.union fns acc
|
||||||
|
| Vpath (Vspec.T (fn, _)) -> Pset.add fn acc
|
||||||
|
| Paths_glob (dir, re) -> begin
|
||||||
|
match Pmap.find dir (Lazy.force all_targets_by_dir) with
|
||||||
|
| None -> Pset.empty
|
||||||
|
| Some targets ->
|
||||||
|
Pset.filter targets ~f:(fun path ->
|
||||||
|
Re.execp re (Path.basename path))
|
||||||
|
end
|
||||||
|
| Dyn_paths t -> loop t acc
|
||||||
|
| Record_lib_deps _ -> acc
|
||||||
|
| Fail _ -> acc
|
||||||
|
in
|
||||||
|
loop (Build.repr t) Pset.empty
|
||||||
|
|
||||||
|
let lib_deps =
|
||||||
|
let rec loop : type a b. (a, b) t -> Build.lib_deps Pmap.t -> Build.lib_deps Pmap.t
|
||||||
|
= fun t acc ->
|
||||||
|
match t with
|
||||||
|
| Arr _ -> acc
|
||||||
|
| Prim _ -> acc
|
||||||
|
| Store_vfile _ -> acc
|
||||||
|
| Compose (a, b) -> loop a (loop b acc)
|
||||||
|
| First t -> loop t acc
|
||||||
|
| Second t -> loop t acc
|
||||||
|
| Split (a, b) -> loop a (loop b acc)
|
||||||
|
| Fanout (a, b) -> loop a (loop b acc)
|
||||||
|
| Paths _ -> acc
|
||||||
|
| Vpath _ -> acc
|
||||||
|
| Paths_glob _ -> acc
|
||||||
|
| Dyn_paths t -> loop t acc
|
||||||
|
| Record_lib_deps (dir, deps) ->
|
||||||
|
let data =
|
||||||
|
match Pmap.find dir acc with
|
||||||
|
| None -> deps
|
||||||
|
| Some others -> Build.merge_lib_deps deps others
|
||||||
|
in
|
||||||
|
Pmap.add acc ~key:dir ~data
|
||||||
|
| Fail _ -> acc
|
||||||
|
in
|
||||||
|
fun t -> loop (Build.repr t) Pmap.empty
|
||||||
|
|
||||||
|
let targets =
|
||||||
|
let rec loop : type a b. (a, b) t -> Target.t list -> Target.t list = fun t acc ->
|
||||||
|
match t with
|
||||||
|
| Arr _ -> acc
|
||||||
|
| Prim { targets; _ } ->
|
||||||
|
List.fold_left targets ~init:acc ~f:(fun acc fn -> Target.Normal fn :: acc)
|
||||||
|
| Store_vfile spec -> Vfile spec :: acc
|
||||||
|
| Compose (a, b) -> loop a (loop b acc)
|
||||||
|
| First t -> loop t acc
|
||||||
|
| Second t -> loop t acc
|
||||||
|
| Split (a, b) -> loop a (loop b acc)
|
||||||
|
| Fanout (a, b) -> loop a (loop b acc)
|
||||||
|
| Paths _ -> acc
|
||||||
|
| Vpath _ -> acc
|
||||||
|
| Paths_glob _ -> acc
|
||||||
|
| Dyn_paths t -> loop t acc
|
||||||
|
| Record_lib_deps _ -> acc
|
||||||
|
| Fail _ -> acc
|
||||||
|
in
|
||||||
|
fun t -> loop (Build.repr t) []
|
|
@ -0,0 +1,23 @@
|
||||||
|
open Import
|
||||||
|
|
||||||
|
module Target : sig
|
||||||
|
type t =
|
||||||
|
| Normal of Path.t
|
||||||
|
| Vfile : _ Build.Vspec.t -> t
|
||||||
|
|
||||||
|
val path : t -> Path.t
|
||||||
|
val paths : t list -> Path.Set.t
|
||||||
|
end
|
||||||
|
|
||||||
|
val deps
|
||||||
|
: (_, _) Build.t
|
||||||
|
-> all_targets_by_dir:Path.Set.t Path.Map.t Lazy.t
|
||||||
|
-> Path.Set.t
|
||||||
|
|
||||||
|
val lib_deps
|
||||||
|
: (_, _) Build.t
|
||||||
|
-> Build.lib_deps Path.Map.t
|
||||||
|
|
||||||
|
val targets
|
||||||
|
: (_, _) Build.t
|
||||||
|
-> Target.t list
|
|
@ -130,19 +130,7 @@ let wait_for_file t fn ~targeting =
|
||||||
(String.concat ~sep:"\n--> "
|
(String.concat ~sep:"\n--> "
|
||||||
(List.map loop ~f:Path.to_string))
|
(List.map loop ~f:Path.to_string))
|
||||||
|
|
||||||
module Target = struct
|
module Target = Build_interpret.Target
|
||||||
type t =
|
|
||||||
| Normal of Path.t
|
|
||||||
| Vfile : _ Vspec.t -> t
|
|
||||||
|
|
||||||
let path = function
|
|
||||||
| Normal p -> p
|
|
||||||
| Vfile (Vspec.T (p, _)) -> p
|
|
||||||
|
|
||||||
let paths ts =
|
|
||||||
List.fold_left ts ~init:Pset.empty ~f:(fun acc t ->
|
|
||||||
Pset.add (path t) acc)
|
|
||||||
end
|
|
||||||
|
|
||||||
let get_file : type a. t -> Path.t -> a File_kind.t -> a File_spec.t = fun t fn kind ->
|
let get_file : type a. t -> Path.t -> a File_kind.t -> a File_spec.t = fun t fn kind ->
|
||||||
match Hashtbl.find t.files fn with
|
match Hashtbl.find t.files fn with
|
||||||
|
@ -154,82 +142,8 @@ let get_file : type a. t -> Path.t -> a File_kind.t -> a File_spec.t = fun t fn
|
||||||
let save_vfile (type a) (module K : Vfile_kind.S with type t = a) fn x =
|
let save_vfile (type a) (module K : Vfile_kind.S with type t = a) fn x =
|
||||||
K.save x ~filename:(Path.to_string fn)
|
K.save x ~filename:(Path.to_string fn)
|
||||||
|
|
||||||
module Build_interpret = struct
|
module Build_exec = struct
|
||||||
include Build.Repr
|
open Build.Repr
|
||||||
|
|
||||||
let deps t ~all_targets_by_dir =
|
|
||||||
let rec loop : type a b. (a, b) t -> Pset.t -> Pset.t = fun t acc ->
|
|
||||||
match t with
|
|
||||||
| Arr _ -> acc
|
|
||||||
| Prim _ -> acc
|
|
||||||
| Store_vfile _ -> acc
|
|
||||||
| Compose (a, b) -> loop a (loop b acc)
|
|
||||||
| First t -> loop t acc
|
|
||||||
| Second t -> loop t acc
|
|
||||||
| Split (a, b) -> loop a (loop b acc)
|
|
||||||
| Fanout (a, b) -> loop a (loop b acc)
|
|
||||||
| Paths fns -> Pset.union fns acc
|
|
||||||
| Vpath (Vspec.T (fn, _)) -> Pset.add fn acc
|
|
||||||
| Paths_glob (dir, re) -> begin
|
|
||||||
match Pmap.find dir (Lazy.force all_targets_by_dir) with
|
|
||||||
| None -> Pset.empty
|
|
||||||
| Some targets ->
|
|
||||||
Pset.filter targets ~f:(fun path ->
|
|
||||||
Re.execp re (Path.basename path))
|
|
||||||
end
|
|
||||||
| Dyn_paths t -> loop t acc
|
|
||||||
| Record_lib_deps _ -> acc
|
|
||||||
| Fail _ -> acc
|
|
||||||
in
|
|
||||||
loop t Pset.empty
|
|
||||||
|
|
||||||
let lib_deps =
|
|
||||||
let rec loop : type a b. (a, b) t -> Build.lib_deps Pmap.t -> Build.lib_deps Pmap.t
|
|
||||||
= fun t acc ->
|
|
||||||
match t with
|
|
||||||
| Arr _ -> acc
|
|
||||||
| Prim _ -> acc
|
|
||||||
| Store_vfile _ -> acc
|
|
||||||
| Compose (a, b) -> loop a (loop b acc)
|
|
||||||
| First t -> loop t acc
|
|
||||||
| Second t -> loop t acc
|
|
||||||
| Split (a, b) -> loop a (loop b acc)
|
|
||||||
| Fanout (a, b) -> loop a (loop b acc)
|
|
||||||
| Paths _ -> acc
|
|
||||||
| Vpath _ -> acc
|
|
||||||
| Paths_glob _ -> acc
|
|
||||||
| Dyn_paths t -> loop t acc
|
|
||||||
| Record_lib_deps (dir, deps) ->
|
|
||||||
let data =
|
|
||||||
match Pmap.find dir acc with
|
|
||||||
| None -> deps
|
|
||||||
| Some others -> Build.merge_lib_deps deps others
|
|
||||||
in
|
|
||||||
Pmap.add acc ~key:dir ~data
|
|
||||||
| Fail _ -> acc
|
|
||||||
in
|
|
||||||
fun t -> loop t Pmap.empty
|
|
||||||
|
|
||||||
let targets =
|
|
||||||
let rec loop : type a b. (a, b) t -> Target.t list -> Target.t list = fun t acc ->
|
|
||||||
match t with
|
|
||||||
| Arr _ -> acc
|
|
||||||
| Prim { targets; _ } ->
|
|
||||||
List.fold_left targets ~init:acc ~f:(fun acc fn -> Target.Normal fn :: acc)
|
|
||||||
| Store_vfile spec -> Vfile spec :: acc
|
|
||||||
| Compose (a, b) -> loop a (loop b acc)
|
|
||||||
| First t -> loop t acc
|
|
||||||
| Second t -> loop t acc
|
|
||||||
| Split (a, b) -> loop a (loop b acc)
|
|
||||||
| Fanout (a, b) -> loop a (loop b acc)
|
|
||||||
| Paths _ -> acc
|
|
||||||
| Vpath _ -> acc
|
|
||||||
| Paths_glob _ -> acc
|
|
||||||
| Dyn_paths t -> loop t acc
|
|
||||||
| Record_lib_deps _ -> acc
|
|
||||||
| Fail _ -> acc
|
|
||||||
in
|
|
||||||
fun t -> loop t []
|
|
||||||
|
|
||||||
let exec bs t x ~targeting =
|
let exec bs t x ~targeting =
|
||||||
let rec exec
|
let rec exec
|
||||||
|
@ -271,7 +185,7 @@ module Build_interpret = struct
|
||||||
| Record_lib_deps _ -> return x
|
| Record_lib_deps _ -> return x
|
||||||
| Fail { fail } -> fail ()
|
| Fail { fail } -> fail ()
|
||||||
in
|
in
|
||||||
exec t x
|
exec (Build.repr t) x
|
||||||
end
|
end
|
||||||
|
|
||||||
let add_spec t fn spec ~allow_override =
|
let add_spec t fn spec ~allow_override =
|
||||||
|
@ -288,12 +202,11 @@ let create_file_specs t targets rule ~allow_override =
|
||||||
|
|
||||||
module Pre_rule = struct
|
module Pre_rule = struct
|
||||||
type t =
|
type t =
|
||||||
{ build : (unit, unit) Build.Repr.t
|
{ build : (unit, unit) Build.t
|
||||||
; targets : Target.t list
|
; targets : Target.t list
|
||||||
}
|
}
|
||||||
|
|
||||||
let make build =
|
let make build =
|
||||||
let build = Build.repr build in
|
|
||||||
{ build
|
{ build
|
||||||
; targets = Build_interpret.targets build
|
; targets = Build_interpret.targets build
|
||||||
}
|
}
|
||||||
|
@ -335,7 +248,7 @@ let compile_rule t ~all_targets_by_dir ?(allow_override=false) pre_rule =
|
||||||
all_unit
|
all_unit
|
||||||
(Pset.fold deps ~init:[] ~f:(fun fn acc -> wait_for_file t fn ~targeting :: acc))
|
(Pset.fold deps ~init:[] ~f:(fun fn acc -> wait_for_file t fn ~targeting :: acc))
|
||||||
>>= fun () ->
|
>>= fun () ->
|
||||||
Build_interpret.exec t build () ~targeting
|
Build_exec.exec t build () ~targeting
|
||||||
) in
|
) in
|
||||||
let rule =
|
let rule =
|
||||||
{ Rule.
|
{ Rule.
|
||||||
|
|
|
@ -1466,6 +1466,19 @@ module Gen(P : Params) = struct
|
||||||
| Installation |
|
| Installation |
|
||||||
+-----------------------------------------------------------------+ *)
|
+-----------------------------------------------------------------+ *)
|
||||||
|
|
||||||
|
let known_targets_by_dir_so_far =
|
||||||
|
List.fold_left !all_rules ~init:Path.Map.empty ~f:(fun acc rule ->
|
||||||
|
List.fold_left (Build_interpret.targets rule) ~init:acc ~f:(fun acc target ->
|
||||||
|
let path = Build_interpret.Target.path target in
|
||||||
|
let dir = Path.parent path in
|
||||||
|
let fn = Path.basename path in
|
||||||
|
let files =
|
||||||
|
match Path.Map.find dir acc with
|
||||||
|
| None -> String_set.singleton fn
|
||||||
|
| Some set -> String_set.add fn set
|
||||||
|
in
|
||||||
|
Path.Map.add acc ~key:dir ~data:files))
|
||||||
|
|
||||||
let lib_install_files ~dir (lib : Library.t) =
|
let lib_install_files ~dir (lib : Library.t) =
|
||||||
let byte = List.mem Mode.Byte ~set:lib.modes in
|
let byte = List.mem Mode.Byte ~set:lib.modes in
|
||||||
let native = List.mem Mode.Native ~set:lib.modes in
|
let native = List.mem Mode.Native ~set:lib.modes in
|
||||||
|
@ -1526,8 +1539,9 @@ module Gen(P : Params) = struct
|
||||||
])
|
])
|
||||||
|> List.map ~f:(Install.Entry.make Lib)
|
|> List.map ~f:(Install.Entry.make Lib)
|
||||||
|
|
||||||
let odig_doc_file_re =
|
let is_odig_doc_file fn =
|
||||||
Re.(compile (alt [str "README"; str "LICENSE"; str "CHANGE"; str "HISTORY"]))
|
List.exists [ "README"; "LICENSE"; "CHANGE"; "HISTORY"]
|
||||||
|
~f:(fun prefix -> String.is_prefix fn ~prefix)
|
||||||
|
|
||||||
let install_file package =
|
let install_file package =
|
||||||
let entries =
|
let entries =
|
||||||
|
@ -1550,9 +1564,14 @@ module Gen(P : Params) = struct
|
||||||
in
|
in
|
||||||
let entries =
|
let entries =
|
||||||
let root_listing = File_tree.Dir.files (File_tree.root P.file_tree) in
|
let root_listing = File_tree.Dir.files (File_tree.root P.file_tree) in
|
||||||
String_set.fold root_listing ~init:entries ~f:(fun fn acc ->
|
let root_targets =
|
||||||
if Re.execp odig_doc_file_re fn then
|
match Path.Map.find ctx.build_dir known_targets_by_dir_so_far with
|
||||||
Install.Entry.make Doc (Path.relative Path.root fn) :: acc
|
| None -> root_listing
|
||||||
|
| Some set -> String_set.union root_listing set
|
||||||
|
in
|
||||||
|
String_set.fold root_targets ~init:entries ~f:(fun fn acc ->
|
||||||
|
if is_odig_doc_file fn then
|
||||||
|
Install.Entry.make Doc (Path.relative ctx.build_dir fn) :: acc
|
||||||
else
|
else
|
||||||
acc)
|
acc)
|
||||||
in
|
in
|
||||||
|
|
Loading…
Reference in New Issue