Skip to content

Instantly share code, notes, and snippets.

@sagotch
Created August 18, 2021 13:14
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sagotch/766d830aa8383a383cba200c62ceb1fc to your computer and use it in GitHub Desktop.
Save sagotch/766d830aa8383a383cba200c62ceb1fc to your computer and use it in GitHub Desktop.
let read_lines p =
let rec loop () = match input_line p with
| exception End_of_file -> close_in p ; []
| line -> line :: loop ()
in loop ()
let process cmd =
let (stdout, _, stderr) as p =
Unix.open_process_full cmd (Unix.environment ())
in
let out = read_lines stdout in
let err = read_lines stderr in
ignore @@ Unix.close_process_full p ;
out, err
module Either = struct type ('a, 'b) t = Left of 'a | Right of 'b end
let partition_map p l =
let rec part left right = function
| [] -> (List.rev left, List.rev right)
| x :: l ->
begin match p x with
| Some (Either.Left v) -> part (v :: left) right l
| Some (Either.Right v) -> part left (v :: right) l
| None -> part left right l
end
in
part [] [] l
let () =
let ic = open_in ".depend" in
let lines = read_lines ic in
close_in ic ;
let dune_root = List.hd lines in
let out = List.tl lines in
let root = dune_root ^ "/_build/default/lib/" in
let opam_swich_prefix = Sys.getenv "OPAM_SWITCH_PREFIX" in
let opam_swich_prefix_lib = opam_swich_prefix ^ "/lib/" in
let aux fn =
let aux prefix =
if String.length fn > String.length prefix
&& String.sub fn 0 (String.length prefix) = prefix
then Some (String.sub fn (String.length prefix) (String.length fn - String.length prefix))
else None
in
match aux opam_swich_prefix_lib with
| Some x -> Some (`opam x)
| None -> match aux root with
| Some x -> Some (`root x)
| None -> None
in
let directories0, files0 =
partition_map begin fun s ->
try Scanf.sscanf s {|#directory "%[^"]";;|} (fun s -> match aux s with Some s -> Some (Either.Left s) | _ -> None)
with _ ->
try Scanf.sscanf s {|#load "%[^"]";;|} (fun s -> match aux s with Some s -> Some (Either.Right s) | _ -> None)
with _ -> failwith s
end out
in
let directories0 = (`opam "ocaml") :: directories0 in
let directories =
List.map begin function
| `opam d -> opam_swich_prefix_lib ^ d
| `root d -> root ^ d
end directories0
in
let cmas, cmis =
List.fold_right begin fun x (cmas, cmis) -> match x with
| `opam fn ->
let aux fn = opam_swich_prefix_lib ^ fn in
let cmas = aux fn :: cmas in
let cmi = aux (Filename.remove_extension fn ^ ".cmi") in
let cmis = if Sys.file_exists cmi then cmi :: cmis else cmis in
(cmas, cmis)
| `root fn ->
let cma = root ^ fn in
let cmas = cma :: cmas in
let dir = dune_root ^ "/_build/install/default/lib/geneweb/" ^ Filename.(dirname fn |> basename) in
let cmis =
Array.fold_left begin fun cmis s ->
if Filename.check_suffix (Filename.concat dir s) "cmi"
then (Filename.concat dir s) :: cmis
else cmis
end cmis (Sys.readdir dir)
in
(cmas, cmis)
end files0 ([], [])
in
let cmis =
let select =
let pref = opam_swich_prefix_lib ^ "ocaml/stdlib__" in
let len = String.length pref in
fun s -> String.length s > len && String.sub s 0 len = pref
in
Array.fold_left begin fun cmis s ->
let fname = Filename.concat (opam_swich_prefix_lib ^ "ocaml/") s in
if Filename.check_suffix fname "cmi" && select fname then fname :: cmis
else cmis
end cmis (Sys.readdir (opam_swich_prefix_lib ^ "ocaml/"))
in
let cmis = (opam_swich_prefix_lib ^ "ocaml/stdlib.cmi") :: cmis in
let data = "data.ml" in
let out = open_out_bin data in
begin
Printf.fprintf out {|let directories=[||} ;
List.iter (Printf.fprintf out {|"%s";|}) directories ;
Printf.fprintf out {||];;|}
end ;
begin
Printf.fprintf out {|let cmas=[||} ;
List.iter (Printf.fprintf out {|"%s";|}) cmas ;
Printf.fprintf out {||];;|}
end ;
begin
Printf.fprintf out {|let cmis=[||} ;
List.iter begin fun src ->
Printf.fprintf out "\"%s\"," src ;
Printf.fprintf out "{marshal|" ;
Marshal.to_channel out (Cmi_format.read_cmi src) [] ;
Printf.fprintf out "|marshal};"
end cmis ;
Printf.fprintf out {||];;|}
end ;
begin
let b = Buffer.create 1024 in
let aux = List.iter (fun src -> Digest.file src |> Digest.to_hex |> Buffer.add_string b) in
aux cmis ;
aux cmas ;
Printf.fprintf out {|let md5="%s";;|} (Buffer.contents b |> Digest.string |> Digest.to_hex)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment