(** Read package data from day10's html directory *)
let list_package_names ~html_dir =
let p_dir = Filename.concat html_dir "p" in
if Sys.file_exists p_dir && Sys.is_directory p_dir then
Sys.readdir p_dir
|> Array.to_list
|> List.filter (fun name ->
let path = Filename.concat p_dir name in
Sys.is_directory path)
|> List.sort String.compare
else
[]
let compare_versions v1 v2 =
(* Simple version comparison - compare segments numerically where possible *)
let parse v =
String.split_on_char '.' v
|> List.map (fun s -> try `Int (int_of_string s) with _ -> `Str s)
in
let rec cmp l1 l2 = match l1, l2 with
| [], [] -> 0
| [], _ -> -1
| _, [] -> 1
| `Int a :: t1, `Int b :: t2 ->
let c = Int.compare a b in if c <> 0 then c else cmp t1 t2
| `Str a :: t1, `Str b :: t2 ->
let c = String.compare a b in if c <> 0 then c else cmp t1 t2
| `Int _ :: _, `Str _ :: _ -> -1
| `Str _ :: _, `Int _ :: _ -> 1
in
cmp (parse v2) (parse v1) (* Descending order *)
let list_package_versions ~html_dir ~name =
let pkg_dir = Filename.concat (Filename.concat html_dir "p") name in
if Sys.file_exists pkg_dir && Sys.is_directory pkg_dir then
Sys.readdir pkg_dir
|> Array.to_list
|> List.filter (fun version ->
let path = Filename.concat pkg_dir version in
Sys.is_directory path)
|> List.sort compare_versions
else
[]
let list_packages ~html_dir =
list_package_names ~html_dir
|> List.concat_map (fun name ->
list_package_versions ~html_dir ~name
|> List.map (fun version -> (name, version)))
let package_has_docs ~html_dir ~name ~version =
let path = Filename.concat html_dir
(Filename.concat "p" (Filename.concat name version)) in
Sys.file_exists path && Sys.is_directory path
let docs_path ~name ~version =
Printf.sprintf "/docs/p/%s/%s/" name version