My aggregated monorepo of OCaml code, automaintained
1(*---------------------------------------------------------------------------
2 Copyright (c) 2026 Anil Madhavapeddy <anil@recoil.org>. All rights reserved.
3 SPDX-License-Identifier: ISC
4 ---------------------------------------------------------------------------*)
5
6(** Aggregated daily changes format.
7
8 This module provides types and JSON codecs for the aggregated daily changes
9 format stored in [.changes/YYYYMMDD.json] files. These files combine all
10 repository changes for a single day into a structured format suitable for
11 broadcasting. *)
12
13(** {1 Change Types} *)
14
15(** Classification of changes for grouping in broadcasts. *)
16type change_type =
17 | Feature (** New features or capabilities *)
18 | Bugfix (** Bug fixes *)
19 | Documentation (** Documentation updates *)
20 | Refactor (** Code refactoring *)
21 | New_library (** Initial import of a new library *)
22 | Unknown (** Unclassified changes *)
23
24val change_type_of_string : string -> change_type
25val string_of_change_type : change_type -> string
26
27(** {1 Entry Types} *)
28
29type commit_range = {
30 from_hash : string; (** Starting commit hash *)
31 to_hash : string; (** Ending commit hash *)
32 count : int; (** Number of commits in range *)
33}
34(** Commit range information. *)
35
36type entry = {
37 repository : string; (** Repository name *)
38 hour : int; (** Hour of day 0-23 for filtering *)
39 timestamp : Ptime.t; (** RFC3339 timestamp for precise ordering *)
40 summary : string; (** One-line summary of changes *)
41 changes : string list; (** List of change bullet points *)
42 commit_range : commit_range; (** Commits included *)
43 contributors : string list; (** Contributors to these changes *)
44 repo_url : string option; (** Optional repository URL *)
45 change_type : change_type; (** Classification of the change *)
46}
47(** A single repository's changes for the day. *)
48
49(** {1 Aggregated File Type} *)
50
51type t = {
52 date : string; (** ISO date YYYY-MM-DD *)
53 generated_at : Ptime.t; (** When this file was generated *)
54 git_head : string; (** Monorepo HEAD at generation time *)
55 entries : entry list; (** All repository entries for this day *)
56 authors : string list; (** All unique authors for this day *)
57}
58(** The complete aggregated daily changes file. *)
59
60(** {1 JSON Codecs} *)
61
62val jsont : t Jsont.t
63val entry_jsont : entry Jsont.t
64
65(** {1 File I/O} *)
66
67val load :
68 fs:_ Eio.Path.t -> changes_dir:Fpath.t -> date:string -> (t, string) result
69(** Load aggregated changes for a specific date. [date] should be in YYYY-MM-DD
70 format. *)
71
72val load_range :
73 fs:_ Eio.Path.t ->
74 changes_dir:Fpath.t ->
75 from_date:string ->
76 to_date:string ->
77 (t list, string) result
78(** Load all aggregated changes files in date range. Dates should be in
79 YYYY-MM-DD format. *)
80
81val latest : fs:_ Eio.Path.t -> changes_dir:Fpath.t -> (t option, string) result
82(** Load the most recent aggregated changes file. *)
83
84val save : fs:_ Eio.Path.t -> changes_dir:Fpath.t -> t -> (unit, string) result
85(** Save aggregated changes to the appropriate file. *)