My agentic slop goes here. Not intended for anyone else!
1(** XDG Base Directory Specification support with Eio capabilities 2 3 This library provides an OCaml implementation of the XDG Base Directory 4 Specification with Eio filesystem integration. The XDG specification defines 5 standard locations for user-specific and system-wide application files, 6 helping to keep user home directories clean and organized. 7 8 The specification is available at: 9 {{:https://specifications.freedesktop.org/basedir-spec/latest/} XDG Base Directory Specification} 10 11 {b Key Concepts:} 12 13 The XDG specification defines several types of directories: 14 - {b User directories}: Store user-specific files (config, data, cache, state, runtime) 15 - {b System directories}: Store system-wide files shared across users 16 - {b Precedence}: User directories take precedence over system directories 17 - {b Application isolation}: Each application gets its own subdirectory 18 19 {b Environment Variable Precedence:} 20 21 This library follows a three-level precedence system: 22 + Application-specific variables (e.g., [MYAPP_CONFIG_DIR]) - highest priority 23 + XDG standard variables (e.g., [XDG_CONFIG_HOME]) 24 + Default paths (e.g., [$HOME/.config]) - lowest priority 25 26 This allows fine-grained control over directory locations without affecting 27 other XDG-compliant applications. 28 29 {b Directory Creation:} 30 31 All directories are automatically created with appropriate permissions (0o755) 32 when accessed, except for runtime directories which require stricter permissions 33 as per the specification. 34 35 @see <https://specifications.freedesktop.org/basedir-spec/latest/> XDG Base Directory Specification *) 36 37(** The main XDG context type containing all directory paths for an application. 38 39 A value of type [t] represents the complete XDG directory structure for a 40 specific application, including both user-specific and system-wide directories. 41 All paths are resolved at creation time and are absolute paths within the 42 Eio filesystem. *) 43type t 44 45(** XDG directory types for specifying which directories an application needs. 46 47 These polymorphic variants allow applications to declare which XDG directories 48 they use, enabling runtime systems to only provide the requested directories. *) 49type dir = [ 50 | `Config (** User configuration files *) 51 | `Cache (** User-specific cached data *) 52 | `Data (** User-specific application data *) 53 | `State (** User-specific state data (logs, history, etc.) *) 54 | `Runtime (** User-specific runtime files (sockets, pipes, etc.) *) 55] 56 57(** {1 Exceptions} *) 58 59(** Exception raised when XDG environment variables contain invalid paths. 60 61 The XDG specification requires all paths in environment variables to be 62 absolute. This exception is raised when a relative path is found. *) 63exception Invalid_xdg_path of string 64 65(** {1 Construction} *) 66 67(** [create fs app_name] creates an XDG context for the given application. 68 69 This function initializes the complete XDG directory structure for your application, 70 resolving all paths according to the environment variables and creating directories 71 as needed. 72 73 @param fs The Eio filesystem providing filesystem access 74 @param app_name The name of your application (used as subdirectory name) 75 76 {b Path Resolution:} 77 78 For each directory type, the following precedence is used: 79 + Application-specific environment variable (e.g., [MYAPP_CONFIG_DIR]) 80 + XDG standard environment variable (e.g., [XDG_CONFIG_HOME]) 81 + Default path as specified in the XDG specification 82 83 {b Example:} 84 {[ 85 let xdg = Xdge.create env#fs "myapp" in 86 let config = Xdge.config_dir xdg in 87 (* config is now <fs:$HOME/.config/myapp> or the overridden path *) 88 ]} 89 90 All directories are created with permissions 0o755 if they don't exist, 91 except for runtime directories which are created with 0o700 permissions and 92 validated according to the XDG specification. 93 94 @raise Invalid_xdg_path if any environment variable contains a relative path *) 95val create : Eio.Fs.dir_ty Eio.Path.t -> string -> t 96 97(** {1 Accessors} *) 98 99(** [app_name t] returns the application name used when creating this XDG context. 100 101 This is the name that was passed to {!create} and is used as the subdirectory 102 name within each XDG base directory. *) 103val app_name : t -> string 104 105(** {1 Base Directories} *) 106 107(** [config_dir t] returns the path to user-specific configuration files. 108 109 {b Purpose:} Store user preferences, settings, and configuration files. 110 Configuration files should be human-readable when possible. 111 112 {b Environment Variables:} 113 - [${APP_NAME}_CONFIG_DIR]: Application-specific override (highest priority) 114 - [XDG_CONFIG_HOME]: XDG standard variable 115 - Default: [$HOME/.config/{app_name}] 116 117 @see <https://specifications.freedesktop.org/basedir-spec/latest/#variables> XDG_CONFIG_HOME specification *) 118val config_dir : t -> Eio.Fs.dir_ty Eio.Path.t 119 120(** [data_dir t] returns the path to user-specific data files. 121 122 {b Purpose:} Store persistent application data that should be preserved 123 across application restarts and system reboots. This data is typically 124 not modified by users directly. 125 126 {b Environment Variables:} 127 - [${APP_NAME}_DATA_DIR]: Application-specific override (highest priority) 128 - [XDG_DATA_HOME]: XDG standard variable 129 - Default: [$HOME/.local/share/{app_name}] 130 131 {b Example Files:} 132 - Application databases 133 - User-generated content (documents, projects) 134 - Downloaded resources 135 - Application plugins or extensions 136 137 @see <https://specifications.freedesktop.org/basedir-spec/latest/#variables> XDG_DATA_HOME specification *) 138val data_dir : t -> Eio.Fs.dir_ty Eio.Path.t 139 140(** [cache_dir t] returns the path to user-specific cache files. 141 142 {b Purpose:} Store non-essential cached data that can be regenerated 143 if deleted. The application should remain functional if this directory 144 is cleared, though performance may be temporarily impacted. 145 146 {b Environment Variables:} 147 - [${APP_NAME}_CACHE_DIR]: Application-specific override (highest priority) 148 - [XDG_CACHE_HOME]: XDG standard variable 149 - Default: [$HOME/.cache/{app_name}] 150 151 {b Example Files:} 152 - Downloaded thumbnails and previews 153 - Compiled bytecode or object files 154 - Network response caches 155 - Temporary computation results 156 157 Users may clear cache directories to free disk space, so 158 always check for cache validity and be prepared to regenerate data. 159 160 @see <https://specifications.freedesktop.org/basedir-spec/latest/#variables> XDG_CACHE_HOME specification *) 161val cache_dir : t -> Eio.Fs.dir_ty Eio.Path.t 162 163(** [state_dir t] returns the path to user-specific state files. 164 165 {b Purpose:} Store persistent state data that should be preserved between 166 application restarts but is not important enough to be user data. This 167 includes application state that can be regenerated but would impact the 168 user experience if lost. 169 170 {b Environment Variables:} 171 - [${APP_NAME}_STATE_DIR]: Application-specific override (highest priority) 172 - [XDG_STATE_HOME]: XDG standard variable 173 - Default: [$HOME/.local/state/{app_name}] 174 175 {b Example Files:} 176 - Application history (recently used files, command history) 177 - Current application state (window positions, open tabs) 178 - Logs and journal files 179 - Undo/redo history 180 181 {b Comparison with other directories:} 182 - Unlike cache: State should persist between reboots 183 - Unlike data: State can be regenerated (though inconvenient) 184 - Unlike config: State changes frequently during normal use 185 186 @see <https://specifications.freedesktop.org/basedir-spec/latest/#variables> XDG_STATE_HOME specification *) 187val state_dir : t -> Eio.Fs.dir_ty Eio.Path.t 188 189(** [runtime_dir t] returns the path to user-specific runtime files. 190 191 {b Purpose:} Store runtime files such as sockets, named pipes, and 192 process IDs. These files are only valid for the duration of the user's 193 login session. 194 195 {b Environment Variables:} 196 - [${APP_NAME}_RUNTIME_DIR]: Application-specific override (highest priority) 197 - [XDG_RUNTIME_DIR]: XDG standard variable 198 - Default: None (returns [None] if not set) 199 200 {b Required Properties (per specification):} 201 - Owned by the user with access mode 0700 202 - Bound to the user login session lifetime 203 - Located on a local filesystem (not networked) 204 - Fully-featured by the OS (supporting proper locking, etc.) 205 206 {b Example Files:} 207 - Unix domain sockets 208 - Named pipes (FIFOs) 209 - Lock files 210 - Small process communication files 211 212 This may return [None] if no suitable runtime directory 213 is available. Applications should handle this gracefully, perhaps by 214 falling back to [/tmp] with appropriate security measures. 215 216 @see <https://specifications.freedesktop.org/basedir-spec/latest/#variables> XDG_RUNTIME_DIR specification *) 217val runtime_dir : t -> Eio.Fs.dir_ty Eio.Path.t option 218 219(** {1 System Directories} *) 220 221(** [config_dirs t] returns search paths for system-wide configuration files. 222 223 {b Purpose:} Provide a search path for configuration files that are 224 shared between multiple users. Files in user-specific {!config_dir} 225 take precedence over these system directories. 226 227 {b Environment Variables:} 228 - [${APP_NAME}_CONFIG_DIRS]: Application-specific override (highest priority) 229 - [XDG_CONFIG_DIRS]: XDG standard variable (colon-separated list) 230 - Default: [[/etc/xdg/{app_name}]] 231 232 {b Search Order:} 233 Directories are ordered by preference, with earlier entries taking 234 precedence over later ones. When looking for a configuration file, 235 search {!config_dir} first, then each directory in this list. 236 237 @see <https://specifications.freedesktop.org/basedir-spec/latest/#variables> XDG_CONFIG_DIRS specification *) 238val config_dirs : t -> Eio.Fs.dir_ty Eio.Path.t list 239 240(** [data_dirs t] returns search paths for system-wide data files. 241 242 {b Purpose:} Provide a search path for data files that are shared 243 between multiple users. Files in user-specific {!data_dir} take 244 precedence over these system directories. 245 246 {b Environment Variables:} 247 - [${APP_NAME}_DATA_DIRS]: Application-specific override (highest priority) 248 - [XDG_DATA_DIRS]: XDG standard variable (colon-separated list) 249 - Default: [[/usr/local/share/{app_name}; /usr/share/{app_name}]] 250 251 {b Search Order:} 252 Directories are ordered by preference, with earlier entries taking 253 precedence over later ones. When looking for a data file, search 254 {!data_dir} first, then each directory in this list. 255 256 {b Example Files:} 257 - Application icons and themes 258 - Desktop files 259 - Shared application resources 260 - Documentation files 261 - Default templates 262 263 @see <https://specifications.freedesktop.org/basedir-spec/latest/#variables> XDG_DATA_DIRS specification *) 264val data_dirs : t -> Eio.Fs.dir_ty Eio.Path.t list 265 266(** {1 File Search} *) 267 268(** [find_config_file t filename] searches for a configuration file following XDG precedence. 269 270 This function searches for the given filename in the user configuration directory 271 first, then in system configuration directories in order of preference. 272 Files that are inaccessible (due to permissions, non-existence, etc.) are 273 silently skipped as per the XDG specification. 274 275 @param t The XDG context 276 @param filename The name of the file to search for 277 @return [Some path] if found, [None] if not found in any directory 278 279 {b Search Order:} 280 1. User config directory ({!config_dir}) 281 2. System config directories ({!config_dirs}) in preference order 282 283 *) 284val find_config_file : t -> string -> Eio.Fs.dir_ty Eio.Path.t option 285 286(** [find_data_file t filename] searches for a data file following XDG precedence. 287 288 This function searches for the given filename in the user data directory 289 first, then in system data directories in order of preference. 290 Files that are inaccessible (due to permissions, non-existence, etc.) are 291 silently skipped as per the XDG specification. 292 293 @param t The XDG context 294 @param filename The name of the file to search for 295 @return [Some path] if found, [None] if not found in any directory 296 297 {b Search Order:} 298 1. User data directory ({!data_dir}) 299 2. System data directories ({!data_dirs}) in preference order 300 301 *) 302val find_data_file : t -> string -> Eio.Fs.dir_ty Eio.Path.t option 303 304(** {1 Pretty Printing} *) 305 306(** [pp ?brief ?sources ppf t] pretty prints the XDG directory configuration. 307 308 @param brief If [true], prints a compact one-line summary (default: [false]) 309 @param sources If [true], shows the source of each directory value, 310 indicating whether it came from defaults, environment 311 variables, or command line (default: [false]) 312 @param ppf The formatter to print to 313 @param t The XDG context to print 314 315 {b Output formats:} 316 - Normal: Multi-line detailed view of all directories 317 - Brief: Single line showing app name and key directories 318 - With sources: Adds annotations showing where each path came from 319 *) 320val pp : ?brief:bool -> ?sources:bool -> Format.formatter -> t -> unit 321 322(** {1 Cmdliner Integration} *) 323 324module Cmd : sig 325 (** The type of the outer XDG context *) 326 type xdg_t = t 327 (** Cmdliner integration for XDG directory configuration. 328 329 This module provides integration with the Cmdliner library, 330 allowing XDG directories to be configured via command-line arguments 331 while respecting the precedence of environment variables. *) 332 333 (** Type of XDG configuration gathered from command-line and environment. 334 335 This contains all XDG directory paths along with their sources, 336 as determined by command-line arguments and environment variables. *) 337 type t 338 339 (** [term app_name fs ?dirs ()] creates a Cmdliner term for XDG directory configuration. 340 341 This function generates a Cmdliner term that handles XDG directory 342 configuration through both command-line flags and environment variables, 343 and directly returns the XDG context. Only command-line flags for the 344 requested directories are generated. 345 346 @param app_name The application name (used for environment variable prefixes) 347 @param fs The Eio filesystem to use for path resolution 348 @param dirs List of directories to include flags for (default: all directories) 349 350 {b Generated Command-line Flags:} 351 Only the flags for requested directories are generated: 352 - [--config-dir DIR]: Override configuration directory (if [`Config] in dirs) 353 - [--data-dir DIR]: Override data directory (if [`Data] in dirs) 354 - [--cache-dir DIR]: Override cache directory (if [`Cache] in dirs) 355 - [--state-dir DIR]: Override state directory (if [`State] in dirs) 356 - [--runtime-dir DIR]: Override runtime directory (if [`Runtime] in dirs) 357 358 {b Environment Variable Precedence:} 359 For each directory type, the following precedence applies: 360 + Command-line flag (e.g., [--config-dir]) - if enabled 361 + Application-specific variable (e.g., [MYAPP_CONFIG_DIR]) 362 + XDG standard variable (e.g., [XDG_CONFIG_HOME]) 363 + Default value 364 *) 365 val term : string -> Eio.Fs.dir_ty Eio.Path.t -> 366 ?dirs:dir list -> 367 unit -> (xdg_t * t) Cmdliner.Term.t 368 369 (** [cache_term app_name] creates a Cmdliner term that provides just the cache 370 directory path as a string, respecting XDG precedence. 371 372 This is a convenience function for applications that only need cache 373 directory configuration. It returns the resolved cache directory path 374 directly as a string, suitable for use in other Cmdliner terms. 375 376 @param app_name The application name (used for environment variable prefixes) 377 378 {b Generated Command-line Flag:} 379 - [--cache-dir DIR]: Override cache directory 380 381 {b Environment Variable Precedence:} 382 + Command-line flag ([--cache-dir]) 383 + Application-specific variable (e.g., [MYAPP_CACHE_DIR]) 384 + XDG standard variable ([XDG_CACHE_HOME]) 385 + Default value ([$HOME/.cache/{app_name}]) 386 *) 387 val cache_term : string -> string Cmdliner.Term.t 388 389 (** [env_docs app_name] generates documentation for environment variables. 390 391 Returns a formatted string documenting all environment variables that 392 affect XDG directory configuration for the given application. This is 393 useful for generating man pages or help text. 394 395 @param app_name The application name 396 @return A formatted documentation string 397 398 {b Included Information:} 399 - Configuration precedence rules 400 - Application-specific environment variables 401 - XDG standard environment variables 402 - Default values for each directory type 403 *) 404 val env_docs : string -> string 405 406 (** [pp ppf config] pretty prints a Cmdliner configuration. 407 408 This function formats the configuration showing each directory path 409 along with its source, which is helpful for debugging configuration 410 issues or displaying the current configuration to users. 411 412 @param ppf The formatter to print to 413 @param config The configuration to print *) 414 val pp : Format.formatter -> t -> unit 415end