forked from
anil.recoil.org/monopam
Monorepo management for opam overlays
1(*---------------------------------------------------------------------------
2 Copyright (c) 2026 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6(** Daily changes with per-day-per-repo structure.
7
8 This module provides an immutable data structure for loading and querying
9 daily changes from per-day-per-repo JSON files. Files are named
10 [<repo>-<YYYY-MM-DD>.json] and contain timestamped entries for real-time
11 tracking. *)
12
13(** {1 Types} *)
14
15type commit_range = { from_hash : string; to_hash : string; count : int }
16(** Commit range information. *)
17
18type entry = {
19 repository : string;
20 hour : int;
21 timestamp : Ptime.t;
22 summary : string;
23 changes : string list;
24 commit_range : commit_range;
25 contributors : string list;
26 repo_url : string option;
27}
28(** A single timestamped changelog entry. *)
29
30type day = {
31 repository : string;
32 date : string;
33 entries : entry list; (** Sorted by timestamp ascending. *)
34}
35(** All entries for a single repository on a single day. *)
36
37module String_map : Map.S with type key = string
38(** String-keyed map type. *)
39
40type t = {
41 by_repo : day list String_map.t;
42 (** Map from repository name to list of days. *)
43 by_date : day list String_map.t;
44 (** Map from date (YYYY-MM-DD) to list of days across repos. *)
45 all_entries : entry list; (** All entries sorted by timestamp ascending. *)
46}
47(** Immutable collection of all loaded daily changes. *)
48
49(** {1 Construction} *)
50
51val empty : t
52(** Empty daily changes structure. *)
53
54val load_all : fs:_ Eio.Path.t -> changes_dir:Fpath.t -> t
55(** [load_all ~fs ~changes_dir] loads all [<repo>-<YYYY-MM-DD>.json] files from
56 the changes directory and returns an immutable structure for querying. *)
57
58(** {1 Querying} *)
59
60val since : t -> Ptime.t -> entry list
61(** [since t timestamp] returns all entries with timestamp after [timestamp],
62 sorted by timestamp ascending. *)
63
64val for_repo : t -> string -> day list
65(** [for_repo t repo] returns all days for the given repository, sorted by date
66 descending. *)
67
68val for_date : t -> string -> day list
69(** [for_date t date] returns all days (across repos) for the given date. *)
70
71val repos : t -> string list
72(** [repos t] returns list of all repository names with changes. *)
73
74val dates : t -> string list
75(** [dates t] returns list of all dates with changes, sorted descending. *)
76
77(** {1 File Discovery} *)
78
79val list_repos : fs:_ Eio.Path.t -> changes_dir:Fpath.t -> string list
80(** [list_repos ~fs ~changes_dir] returns all repository names that have daily
81 change files. *)
82
83val list_dates :
84 fs:_ Eio.Path.t -> changes_dir:Fpath.t -> repo:string -> string list
85(** [list_dates ~fs ~changes_dir ~repo] returns all dates for which the given
86 repository has change files. *)
87
88(** {1 Loading Individual Files} *)
89
90val load_repo_day :
91 fs:_ Eio.Path.t ->
92 changes_dir:Fpath.t ->
93 repo:string ->
94 date:string ->
95 entry list
96(** [load_repo_day ~fs ~changes_dir ~repo ~date] loads entries for a specific
97 repo and date. Returns empty list if file doesn't exist. *)
98
99val load_repo_all :
100 fs:_ Eio.Path.t -> changes_dir:Fpath.t -> repo:string -> entry list
101(** [load_repo_all ~fs ~changes_dir ~repo] loads all entries for a repository
102 across all dates. *)
103
104val entries_since :
105 fs:_ Eio.Path.t -> changes_dir:Fpath.t -> since:Ptime.t -> entry list
106(** [entries_since ~fs ~changes_dir ~since] returns all entries created after
107 the given timestamp, useful for real-time updates. *)