- Add `--verbose`/`-v` flag; gate all diagnostic stderr output behind it - Add `--no-uuid`, `--no-source`, `--no-location`, `--no-description`, `--no-conference-url` flags to suppress individual INFO lines - Add `--sort` option (`asc`, `desc`, `original`) replacing hardcoded descending sort - Add `--source` option to override calendar name (single-file only) - Introduce `Config` module with global `ref` flags set at startup from CLI args - Add `Utils.warn` helper that writes to stderr only when `Config.verbose` is set - Normalise all diagnostic messages to a consistent format (`Warning: ... (UID: ...)`) - Remove `debug_print_of_recurrence_and_skip`; inline skip at each call site - Fix `add_common_part` to always emit a trailing `\\\n ` continuation line
83 lines
2.7 KiB
OCaml
83 lines
2.7 KiB
OCaml
open Cmdliner
|
|
open Cmdliner.Term.Syntax
|
|
|
|
let version_string () =
|
|
match Build_info.V1.version () with
|
|
| None -> "dev"
|
|
| Some v -> Build_info.V1.Version.to_string v
|
|
|
|
let files =
|
|
let doc = "Files to process" in
|
|
Arg.(non_empty & pos_all string [] & info [] ~docv:"FILE" ~doc)
|
|
|
|
let timezone =
|
|
let doc = "Target timezone for output (e.g. Europe/Rome). Defaults to local timezone." in
|
|
Arg.(value & opt (some string) None & info [ "timezone"; "z" ] ~docv:"TZ" ~doc)
|
|
|
|
let verbose =
|
|
let doc = "Print diagnostic messages (skipped events, unsupported recurrences, etc.) on stderr." in
|
|
Arg.(value & flag & info [ "verbose"; "v" ] ~doc)
|
|
|
|
let no_uuid =
|
|
let doc = "Omit the INFO line with the event UID from output." in
|
|
Arg.(value & flag & info [ "no-uuid" ] ~doc)
|
|
|
|
let no_source =
|
|
let doc = "Omit the INFO line with the calendar source name from output." in
|
|
Arg.(value & flag & info [ "no-source" ] ~doc)
|
|
|
|
let no_location =
|
|
let doc = "Omit the INFO line with the event location from output." in
|
|
Arg.(value & flag & info [ "no-location" ] ~doc)
|
|
|
|
let no_description =
|
|
let doc = "Omit the INFO line with the event description from output." in
|
|
Arg.(value & flag & info [ "no-description" ] ~doc)
|
|
|
|
let no_conference_url =
|
|
let doc = "Omit the INFO line with the conference URL from output." in
|
|
Arg.(value & flag & info [ "no-conference-url" ] ~doc)
|
|
|
|
type sort_order = Asc | Desc | Original
|
|
|
|
let sort_order_enum = [ ("asc", Asc); ("desc", Desc); ("original", Original) ]
|
|
|
|
let sort =
|
|
let doc = "Output sort order by date: $(b,desc) (default), $(b,asc), or $(b,none) (file order)." in
|
|
Arg.(value & opt (enum sort_order_enum) Desc & info [ "sort" ] ~docv:"ORDER" ~doc)
|
|
|
|
let source =
|
|
let doc = "Override the calendar source name used in INFO lines. Only valid when processing a single file." in
|
|
Arg.(value & opt (some string) None & info [ "source" ] ~docv:"NAME" ~doc)
|
|
|
|
type cli_args = {
|
|
tz : string option;
|
|
verbose : bool;
|
|
no_uuid : bool;
|
|
no_source : bool;
|
|
no_location : bool;
|
|
no_description : bool;
|
|
no_conference_url : bool;
|
|
sort : sort_order;
|
|
source : string option;
|
|
}
|
|
|
|
let main_command f =
|
|
let doc = "Convert iCalendar files to remind format" in
|
|
let man = [] in
|
|
Cmd.make (Cmd.info "ical2rem" ~version:(version_string ()) ~doc ~man)
|
|
@@
|
|
let+ files = files
|
|
and+ tz = timezone
|
|
and+ verbose = verbose
|
|
and+ no_uuid = no_uuid
|
|
and+ no_source = no_source
|
|
and+ no_location = no_location
|
|
and+ no_description = no_description
|
|
and+ no_conference_url = no_conference_url
|
|
and+ sort = sort
|
|
and+ source = source in
|
|
f { tz; verbose; no_uuid; no_source; no_location; no_description; no_conference_url; sort; source } files
|
|
|
|
let main f = Cmd.eval @@ main_command f
|