xdge - XDG Base Directory Specification for Eio#
This library implements the XDG Base Directory Specification for OCaml applications using the Eio effects-based I/O library.
What is XDG?#
The XDG Base Directory Specification defines standard locations for user-specific files on Unix-like systems, keeping home directories clean and organised:
- Config (
~/.config/app): User preferences and settings - Data (
~/.local/share/app): Persistent application data - Cache (
~/.cache/app): Non-essential cached data (safe to delete) - State (
~/.local/state/app): Logs, history, and runtime state - Runtime (
$XDG_RUNTIME_DIR/app): Sockets, pipes, and session-bound files
The specification also defines system-wide search paths (/etc/xdg,
/usr/share) and a precedence system using environment variables
(XDG_CONFIG_HOME, XDG_DATA_HOME, and so on).
Why Eio?#
Eio uses a capability-based approach to I/O where filesystem access must be explicitly passed to functions. This design aligns naturally with XDG directory management. For example:
(* Filesystem access is an explicit capability *)
let xdg = Xdge.v env#fs "myapp"
The capability model provides the benefit that code that needs filesystem
access must receive the fs capability, with no hidden global state or ambient
authority. The Eio.Path.t type returned by xdge encapsulates both the
filesystem capability and the path, preventing path traversal outside the
granted capability. Applications can restrict filesystem access by passing a
sandboxed fs capability, and xdge respects those boundaries.
Usage#
let () =
Eio_main.run @@ fun env ->
let xdg = Xdge.v env#fs "myapp" in
let config = Xdge.config_dir xdg in
let data = Xdge.data_dir xdg in
Fmt.pr "config: %a@." Eio.Path.pp config;
Fmt.pr "data: %a@." Eio.Path.pp data;
match Xdge.config_file xdg "settings.json" with
| Some path -> Fmt.pr "found settings.json at %a@." Eio.Path.pp path
| None -> Fmt.pr "no settings.json on the XDG search path@."
On a default Linux install with no XDG overrides the first three lines print:
config: <fs>/home/alice/.config/myapp
data: <fs>/home/alice/.local/share/myapp
Xdge.config_file walks $XDG_CONFIG_HOME, then each entry of
$XDG_CONFIG_DIRS (defaulting to /etc/xdg), returning the first hit:
1. /home/alice/.config/myapp/settings.json
2. /etc/xdg/myapp/settings.json
Equivalent paths on macOS follow the same precedence rules with
$HOME/Library/Application Support/myapp as the user default. Override
any layer by setting XDG_CONFIG_HOME, XDG_CONFIG_DIRS, etc.
Cmdliner integration#
For CLI applications, xdge provides a Cmdliner term that exposes
--config-dir, --data-dir, --cache-dir, --state-dir, and
--runtime-dir flags, with precedence:
--config-dir (CLI) > MYAPP_CONFIG_DIR > XDG_CONFIG_HOME > default
let () =
Eio_main.run @@ fun env ->
let _term = Xdge.Cmd.term "myapp" env#fs () in
()
Installation#
Install with opam:
$ opam install nox-xdge
If opam cannot find the package, it may not yet be released in the public
opam-repository. Add the overlay repository, then install it:
$ opam repo add samoht https://tangled.org/gazagnaire.org/opam-overlay.git
$ opam update
$ opam install nox-xdge
Licence#
ISC