Include generated files when looking for odig doc files

This commit is contained in:
Jeremie Dimino 2017-02-23 14:16:29 +00:00
parent 75335af4bc
commit 331b9dc14e
5 changed files with 153 additions and 100 deletions

View File

@ -166,8 +166,12 @@ anyway.
*** Odig conventions
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
=<package>.opam= file to a location where odig will find them.
README*, CHANGE*, HISTORY* and LICENSE* files in the same directory as
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

94
src/build_interpret.ml Normal file
View File

@ -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) []

23
src/build_interpret.mli Normal file
View File

@ -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

View File

@ -130,19 +130,7 @@ let wait_for_file t fn ~targeting =
(String.concat ~sep:"\n--> "
(List.map loop ~f:Path.to_string))
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
module Target = Build_interpret.Target
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
@ -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 =
K.save x ~filename:(Path.to_string fn)
module Build_interpret = struct
include 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 []
module Build_exec = struct
open Build.Repr
let exec bs t x ~targeting =
let rec exec
@ -271,7 +185,7 @@ module Build_interpret = struct
| Record_lib_deps _ -> return x
| Fail { fail } -> fail ()
in
exec t x
exec (Build.repr t) x
end
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
type t =
{ build : (unit, unit) Build.Repr.t
{ build : (unit, unit) Build.t
; targets : Target.t list
}
let make build =
let build = Build.repr build in
{ 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
(Pset.fold deps ~init:[] ~f:(fun fn acc -> wait_for_file t fn ~targeting :: acc))
>>= fun () ->
Build_interpret.exec t build () ~targeting
Build_exec.exec t build () ~targeting
) in
let rule =
{ Rule.

View File

@ -1466,6 +1466,19 @@ module Gen(P : Params) = struct
| 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 byte = List.mem Mode.Byte ~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)
let odig_doc_file_re =
Re.(compile (alt [str "README"; str "LICENSE"; str "CHANGE"; str "HISTORY"]))
let is_odig_doc_file fn =
List.exists [ "README"; "LICENSE"; "CHANGE"; "HISTORY"]
~f:(fun prefix -> String.is_prefix fn ~prefix)
let install_file package =
let entries =
@ -1550,9 +1564,14 @@ module Gen(P : Params) = struct
in
let entries =
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 ->
if Re.execp odig_doc_file_re fn then
Install.Entry.make Doc (Path.relative Path.root fn) :: acc
let root_targets =
match Path.Map.find ctx.build_dir known_targets_by_dir_so_far with
| 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
acc)
in