dune/src/file_tree.ml

68 lines
1.4 KiB
OCaml
Raw Normal View History

open! Import
module Dir = struct
type t =
{ path : Path.t
; files : String_set.t
; sub_dirs : t String_map.t
}
let path t = t.path
let files t = t.files
let sub_dirs t = t.sub_dirs
let rec fold t ~init ~f =
let init = f t init in
String_map.fold t.sub_dirs ~init ~f:(fun ~key:_ ~data:t acc ->
fold t ~init:acc ~f)
end
type t =
{ root : Dir.t
; dirs : Dir.t Path.Map.t
}
let root t = t.root
let ignore_file = function
| ""
| "_build"
| ".git"
| ".hg"
| "_darcs"
| "." -> true
| fn -> fn.[0] = '.' && fn.[1] = '#'
let load path =
let rec walk path : Dir.t =
let files, sub_dirs =
Path.readdir path
|> List.filter ~f:(fun fn ->
not (ignore_file fn))
|> List.partition_map ~f:(fun fn ->
let path = Path.relative path fn in
if Path.exists path && Path.is_directory path then
Inr (fn, walk path)
else
Inl fn)
in
{ path
; files = String_set.of_list files
; sub_dirs = String_map.of_alist_exn sub_dirs
}
in
let root = walk path in
let dirs =
Dir.fold root ~init:Path.Map.empty ~f:(fun dir acc ->
Path.Map.add acc ~key:dir.path ~data:dir)
in
{ root
; dirs
}
let fold t ~init ~f =
Path.Map.fold t.dirs ~init ~f:(fun ~key:_ ~data:dir acc -> f dir acc)
let find_dir t path =
Path.Map.find path t.dirs