My agentic slop goes here. Not intended for anyone else!

more

Changed files
+117 -24
stack
xdge
+1 -1
stack/xdge/example/xdg_example.ml
···
let info = Cmdliner.Cmd.info "xdg_example" ~version:"1.0" ~doc ~man in
Eio_main.run
@@ fun env ->
-
let create_xdg_term = Xdge.Cmd.term app_name env#fs in
+
let create_xdg_term = Xdge.Cmd.term app_name env#fs () in
let main_term = Term.(const run $ create_xdg_term) in
let cmd = Cmdliner.Cmd.v info main_term in
exit @@ Cmdliner.Cmd.eval cmd
+52 -3
stack/xdge/lib/xdge.ml
···
; runtime_dir : string with_source
}
-
let term app_name fs =
+
let term app_name fs
+
?(config=true) ?(data=true) ?(cache=true) ?(state=true) ?(runtime=true) () =
let open Cmdliner in
let app_upper = String.uppercase_ascii app_name in
let show_paths =
let doc = "Show only the resolved directory paths without formatting" in
Arg.(value & flag & info [ "show-paths" ] ~doc)
in
-
let make_dir_arg name env_suffix xdg_var default_path =
+
let make_dir_arg ~enabled name env_suffix xdg_var default_path =
+
if not enabled then
+
(* Return a term that always gives the environment-only result *)
+
Term.(const (fun () ->
+
let app_env = app_upper ^ "_" ^ env_suffix in
+
match Sys.getenv_opt app_env with
+
| Some v when v <> "" -> { value = Some v; source = Env app_env }
+
| Some _ | None ->
+
(match Sys.getenv_opt xdg_var with
+
| Some v -> { value = Some v; source = Env xdg_var }
+
| None -> { value = None; source = Default }))
+
$ const ())
+
else
let app_env = app_upper ^ "_" ^ env_suffix in
let doc =
match default_path with
···
let home_prefix = "\\$HOME" in
let config_dir =
make_dir_arg
+
~enabled:config
"config"
"CONFIG_DIR"
"XDG_CONFIG_HOME"
···
in
let data_dir =
make_dir_arg
+
~enabled:data
"data"
"DATA_DIR"
"XDG_DATA_HOME"
···
in
let cache_dir =
make_dir_arg
+
~enabled:cache
"cache"
"CACHE_DIR"
"XDG_CACHE_HOME"
···
in
let state_dir =
make_dir_arg
+
~enabled:state
"state"
"STATE_DIR"
"XDG_STATE_HOME"
(Some (home_prefix ^ "/.local/state/" ^ app_name))
in
-
let runtime_dir = make_dir_arg "runtime" "RUNTIME_DIR" "XDG_RUNTIME_DIR" None in
+
let runtime_dir = make_dir_arg ~enabled:runtime "runtime" "RUNTIME_DIR" "XDG_RUNTIME_DIR" None in
Term.(
const
(fun
···
$ cache_dir
$ state_dir
$ runtime_dir)
+
;;
+
+
let cache_term app_name =
+
let open Cmdliner in
+
let app_upper = String.uppercase_ascii app_name in
+
let app_env = app_upper ^ "_CACHE_DIR" in
+
let xdg_var = "XDG_CACHE_HOME" in
+
let home = Sys.getenv "HOME" in
+
let default_path = home ^ "/.cache/" ^ app_name in
+
+
let doc =
+
Printf.sprintf
+
"Override cache directory. Can also be set with %s or %s. Default: %s"
+
app_env xdg_var default_path
+
in
+
+
let arg = Arg.(value & opt string default_path & info ["cache-dir"; "c"] ~docv:"DIR" ~doc) in
+
+
Term.(const (fun cmdline_val ->
+
(* Check command line first *)
+
if cmdline_val <> default_path then
+
cmdline_val
+
else
+
(* Then check app-specific env var *)
+
match Sys.getenv_opt app_env with
+
| Some v when v <> "" -> v
+
| _ ->
+
(* Then check XDG env var *)
+
match Sys.getenv_opt xdg_var with
+
| Some v when v <> "" -> v ^ "/" ^ app_name
+
| _ -> default_path
+
) $ arg)
;;
let env_docs app_name =
+64 -20
stack/xdge/lib/xdge.mli
···
as determined by command-line arguments and environment variables. *)
type t
-
(** [term app_name fs] creates a Cmdliner term for XDG directory configuration.
-
-
This function generates a Cmdliner term that handles all XDG directory
+
(** [term app_name fs ?config ?data ?cache ?state ?runtime ()] creates a
+
Cmdliner term for XDG directory configuration.
+
+
This function generates a Cmdliner term that handles XDG directory
configuration through both command-line flags and environment variables,
-
and directly returns the XDG context.
-
+
and directly returns the XDG context. Individual directory flags can be
+
disabled by passing [false] for the corresponding optional parameter.
+
@param app_name The application name (used for environment variable prefixes)
@param fs The Eio filesystem to use for path resolution
-
+
@param config Include [--config-dir] flag (default: true)
+
@param data Include [--data-dir] flag (default: true)
+
@param cache Include [--cache-dir] flag (default: true)
+
@param state Include [--state-dir] flag (default: true)
+
@param runtime Include [--runtime-dir] flag (default: true)
+
{b Generated Command-line Flags:}
-
- [--config-dir DIR]: Override configuration directory
-
- [--data-dir DIR]: Override data directory
-
- [--cache-dir DIR]: Override cache directory
-
- [--state-dir DIR]: Override state directory
-
- [--runtime-dir DIR]: Override runtime directory
-
+
Only the flags for enabled directories are generated:
+
- [--config-dir DIR]: Override configuration directory (if [config=true])
+
- [--data-dir DIR]: Override data directory (if [data=true])
+
- [--cache-dir DIR]: Override cache directory (if [cache=true])
+
- [--state-dir DIR]: Override state directory (if [state=true])
+
- [--runtime-dir DIR]: Override runtime directory (if [runtime=true])
+
{b Environment Variable Precedence:}
For each directory type, the following precedence applies:
-
+ Command-line flag (e.g., [--config-dir])
+
+ Command-line flag (e.g., [--config-dir]) - if enabled
+ Application-specific variable (e.g., [MYAPP_CONFIG_DIR])
+ XDG standard variable (e.g., [XDG_CONFIG_HOME])
+ Default value
-
-
{b Example:}
+
+
{b Example - All directories:}
{[
let open Cmdliner in
-
let main (xdg, _config) =
-
(* use xdg directly *)
-
in
-
let xdg_term = Cmd.term "myapp" env#fs in
+
let xdg_term = Cmd.term "myapp" env#fs () in
+
let main_term = Term.(const main $ xdg_term $ other_args) in
+
(* ... *)
+
]}
+
+
{b Example - Only cache directory:}
+
{[
+
let open Cmdliner in
+
let xdg_term = Cmd.term "myapp" env#fs
+
~config:false ~data:false ~state:false ~runtime:false () in
let main_term = Term.(const main $ xdg_term $ other_args) in
(* ... *)
]} *)
-
val term : string -> Eio.Fs.dir_ty Eio.Path.t -> (xdg_t * t) Cmdliner.Term.t
+
val term : string -> Eio.Fs.dir_ty Eio.Path.t ->
+
?config:bool -> ?data:bool -> ?cache:bool -> ?state:bool -> ?runtime:bool ->
+
unit -> (xdg_t * t) Cmdliner.Term.t
+
+
(** [cache_term app_name] creates a Cmdliner term that provides just the cache
+
directory path as a string, respecting XDG precedence.
+
+
This is a convenience function for applications that only need cache
+
directory configuration. It returns the resolved cache directory path
+
directly as a string, suitable for use in other Cmdliner terms.
+
+
@param app_name The application name (used for environment variable prefixes)
+
+
{b Generated Command-line Flag:}
+
- [--cache-dir DIR]: Override cache directory
+
+
{b Environment Variable Precedence:}
+
+ Command-line flag ([--cache-dir])
+
+ Application-specific variable (e.g., [MYAPP_CACHE_DIR])
+
+ XDG standard variable ([XDG_CACHE_HOME])
+
+ Default value ([$HOME/.cache/{app_name}])
+
+
{b Example:}
+
{[
+
let cache_dir_term = Xdge.Cmd.cache_term "myapp" in
+
let main cache_dir other_args =
+
(* use cache_dir as a string path *)
+
in
+
let main_term = Term.(const main $ cache_dir_term $ other_args) in
+
]} *)
+
val cache_term : string -> string Cmdliner.Term.t
(** [env_docs app_name] generates documentation for environment variables.