XDG library path support for OCaml via Eio capabilities
linux macos ocaml xdg
at main 16 kB view raw
1Test with default directories: 2 3 $ export HOME=./test_home 4 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 5 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 6 $ ./xdg_example.exe 7 === Cmdliner Config === 8 XDG config: 9 10 === XDG Directories === 11 XDG directories for 'xdg_example': 12 User directories: 13 config: <fs:./test_home/./test_home/.config/xdg_example> [default] 14 data: <fs:./test_home/./test_home/.local/share/xdg_example> [default] 15 cache: <fs:./test_home/./test_home/.cache/xdg_example> [default] 16 state: <fs:./test_home/./test_home/.local/state/xdg_example> [default] 17 runtime: <none> [default] 18 System directories: 19 config_dirs: [<fs:/etc/xdg/xdg_example>] 20 data_dirs: [<fs:/usr/local/share/xdg_example>; <fs:/usr/share/xdg_example>] 21 22No command-line args or env vars are set, so all directories use defaults. 23Config shows empty (no overrides), and directories show [default] source. User 24directories follow XDG spec: ~/.config, ~/.local/share, ~/.cache, 25~/.local/state. Runtime dir is <none> since XDG_RUNTIME_DIR has no default. 26System dirs use XDG spec defaults: /etc/xdg for config, /usr/{local/,}share for 27data. 28 29Test with all command line arguments specified 30 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 31 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 32 $ ./xdg_example.exe \ 33 > --config-dir ./test-config \ 34 > --data-dir ./test-data \ 35 > --cache-dir ./test-cache \ 36 > --state-dir ./test-state \ 37 > --runtime-dir ./test-runtime 38 === Cmdliner Config === 39 XDG config: 40 config_dir: ./test-config [cmdline] 41 data_dir: ./test-data [cmdline] 42 cache_dir: ./test-cache [cmdline] 43 state_dir: ./test-state [cmdline] 44 runtime_dir: ./test-runtime [cmdline] 45 46 === XDG Directories === 47 XDG directories for 'xdg_example': 48 User directories: 49 config: <fs:./test_home/./test-config> [cmdline] 50 data: <fs:./test_home/./test-data> [cmdline] 51 cache: <fs:./test_home/./test-cache> [cmdline] 52 state: <fs:./test_home/./test-state> [cmdline] 53 runtime: <fs:./test_home/./test-runtime> [cmdline] 54 System directories: 55 config_dirs: [<fs:/etc/xdg/xdg_example>] 56 data_dirs: [<fs:/usr/local/share/xdg_example>; <fs:/usr/share/xdg_example>] 57 58All user directories are overridden by command-line arguments, showing 59[cmdline] as the source. The config section shows all overrides with their 60values and [cmdline] sources. System directories remain at their defaults since 61they cannot be overridden by user directories command-line options. 62 63Test with environment variables (app-specific) 64 $ XDG_EXAMPLE_CONFIG_DIR=./env-config \ 65 > XDG_EXAMPLE_DATA_DIR=./env-data \ 66 > XDG_EXAMPLE_CACHE_DIR=./env-cache \ 67 > XDG_EXAMPLE_STATE_DIR=./env-state \ 68 > XDG_EXAMPLE_RUNTIME_DIR=./env-runtime \ 69 > ./xdg_example.exe 70 === Cmdliner Config === 71 XDG config: 72 config_dir: ./env-config [env(XDG_EXAMPLE_CONFIG_DIR)] 73 data_dir: ./env-data [env(XDG_EXAMPLE_DATA_DIR)] 74 cache_dir: ./env-cache [env(XDG_EXAMPLE_CACHE_DIR)] 75 state_dir: ./env-state [env(XDG_EXAMPLE_STATE_DIR)] 76 runtime_dir: ./env-runtime [env(XDG_EXAMPLE_RUNTIME_DIR)] 77 78 === XDG Directories === 79 XDG directories for 'xdg_example': 80 User directories: 81 config: <fs:./test_home/./env-config> [env(XDG_EXAMPLE_CONFIG_DIR)] 82 data: <fs:./test_home/./env-data> [env(XDG_EXAMPLE_DATA_DIR)] 83 cache: <fs:./test_home/./env-cache> [env(XDG_EXAMPLE_CACHE_DIR)] 84 state: <fs:./test_home/./env-state> [env(XDG_EXAMPLE_STATE_DIR)] 85 runtime: <fs:./test_home/./env-runtime> [env(XDG_EXAMPLE_RUNTIME_DIR)] 86 System directories: 87 config_dirs: [<fs:/etc/xdg/xdg_example>] 88 data_dirs: [<fs:/usr/local/share/xdg_example>; <fs:/usr/share/xdg_example>] 89 90App-specific environment variables (XDG_EXAMPLE_*) override the defaults. The 91source correctly shows [env(XDG_EXAMPLE_*)] for each variable. These 92app-specific variables take precedence over XDG standard variables when both 93are available, allowing per-application customization. 94 95Test with standard XDG environment variables: 96 97 $ XDG_CONFIG_HOME=/tmp/xdge/xdg-config \ 98 > XDG_DATA_HOME=/tmp/xdge/xdg-data \ 99 > XDG_CACHE_HOME=/tmp/xdge/xdg-cache \ 100 > XDG_STATE_HOME=/tmp/xdge/xdg-state \ 101 > XDG_RUNTIME_DIR=/tmp/xdge/xdg-runtime \ 102 > ./xdg_example.exe 103 === Cmdliner Config === 104 XDG config: 105 config_dir: /tmp/xdge/xdg-config [env(XDG_CONFIG_HOME)] 106 data_dir: /tmp/xdge/xdg-data [env(XDG_DATA_HOME)] 107 cache_dir: /tmp/xdge/xdg-cache [env(XDG_CACHE_HOME)] 108 state_dir: /tmp/xdge/xdg-state [env(XDG_STATE_HOME)] 109 runtime_dir: /tmp/xdge/xdg-runtime [env(XDG_RUNTIME_DIR)] 110 111 === XDG Directories === 112 XDG directories for 'xdg_example': 113 User directories: 114 config: <fs:/tmp/xdge/xdg-config> [env(XDG_CONFIG_HOME)] 115 data: <fs:/tmp/xdge/xdg-data> [env(XDG_DATA_HOME)] 116 cache: <fs:/tmp/xdge/xdg-cache> [env(XDG_CACHE_HOME)] 117 state: <fs:/tmp/xdge/xdg-state> [env(XDG_STATE_HOME)] 118 runtime: <fs:/tmp/xdge/xdg-runtime> [env(XDG_RUNTIME_DIR)] 119 System directories: 120 config_dirs: [<fs:/etc/xdg/xdg_example>] 121 data_dirs: [<fs:/usr/local/share/xdg_example>; <fs:/usr/share/xdg_example>] 122 123Standard XDG environment variables (XDG_*_HOME, XDG_RUNTIME_DIR) override the 124defaults. The source correctly shows [env(XDG_*)] for each variable. Note that 125the user directories use the raw paths from env vars (not app-specific subdirs) 126since XDG_CONFIG_HOME etc. are intended to be the base directories for the 127user. 128 129Test command line overrides environment variables: 130 131 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 132 $ XDG_EXAMPLE_CONFIG_DIR=./env-config \ 133 > ./xdg_example.exe --config-dir ./cli-config 134 === Cmdliner Config === 135 XDG config: 136 config_dir: ./cli-config [cmdline] 137 138 === XDG Directories === 139 XDG directories for 'xdg_example': 140 User directories: 141 config: <fs:./test_home/./cli-config> [cmdline] 142 data: <fs:./test_home/./test_home/.local/share/xdg_example> [default] 143 cache: <fs:./test_home/./test_home/.cache/xdg_example> [default] 144 state: <fs:./test_home/./test_home/.local/state/xdg_example> [default] 145 runtime: <none> [default] 146 System directories: 147 config_dirs: [<fs:/etc/xdg/xdg_example>] 148 data_dirs: [<fs:/usr/local/share/xdg_example>; <fs:/usr/share/xdg_example>] 149 150Command-line arguments have highest precedence, overriding environment 151variables. Only config_dir is shown in the config section since it is the only 152one explicitly set. The config_dir shows [cmdline] source while other 153directories fall back to defaults, demonstrating the precedence hierarchy: of 154cmdline then app env vars then XDG env vars then defaults. 155 156Test mixed environment variable precedence (app-specific overrides XDG 157standard): 158 159 $ export HOME=./test_home 160 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 161 $ XDG_CONFIG_HOME=/tmp/xdge/xdg-config \ 162 > XDG_EXAMPLE_CONFIG_DIR=./app-config \ 163 > XDG_DATA_HOME=/tmp/xdge/xdg-data \ 164 > XDG_EXAMPLE_DATA_DIR=./app-data \ 165 > ./xdg_example.exe 166 === Cmdliner Config === 167 XDG config: 168 config_dir: ./app-config [env(XDG_EXAMPLE_CONFIG_DIR)] 169 data_dir: ./app-data [env(XDG_EXAMPLE_DATA_DIR)] 170 171 === XDG Directories === 172 XDG directories for 'xdg_example': 173 User directories: 174 config: <fs:./test_home/./app-config> [env(XDG_EXAMPLE_CONFIG_DIR)] 175 data: <fs:./test_home/./app-data> [env(XDG_EXAMPLE_DATA_DIR)] 176 cache: <fs:./test_home/./test_home/.cache/xdg_example> [default] 177 state: <fs:./test_home/./test_home/.local/state/xdg_example> [default] 178 runtime: <none> [default] 179 System directories: 180 config_dirs: [<fs:/etc/xdg/xdg_example>] 181 data_dirs: [<fs:/usr/local/share/xdg_example>; <fs:/usr/share/xdg_example>] 182 183Demonstrates app-specific environment variables taking precedence over XDG 184standard ones. Both XDG_CONFIG_HOME and XDG_EXAMPLE_CONFIG_DIR are set, but the 185app-specific one wins. Same for data directories. Cache, state, and runtime 186fall back to defaults since no variables are set for them. 187 188Test partial environment variable override: 189 190 $ export HOME=./test_home 191 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 192 $ XDG_EXAMPLE_CONFIG_DIR=./app-config \ 193 > XDG_DATA_HOME=/tmp/xdge/xdg-data \ 194 > XDG_CACHE_HOME=/tmp/xdge/xdg-cache \ 195 > ./xdg_example.exe 196 === Cmdliner Config === 197 XDG config: 198 config_dir: ./app-config [env(XDG_EXAMPLE_CONFIG_DIR)] 199 data_dir: /tmp/xdge/xdg-data [env(XDG_DATA_HOME)] 200 cache_dir: /tmp/xdge/xdg-cache [env(XDG_CACHE_HOME)] 201 202 === XDG Directories === 203 XDG directories for 'xdg_example': 204 User directories: 205 config: <fs:./test_home/./app-config> [env(XDG_EXAMPLE_CONFIG_DIR)] 206 data: <fs:/tmp/xdge/xdg-data> [env(XDG_DATA_HOME)] 207 cache: <fs:/tmp/xdge/xdg-cache> [env(XDG_CACHE_HOME)] 208 state: <fs:./test_home/./test_home/.local/state/xdg_example> [default] 209 runtime: <none> [default] 210 System directories: 211 config_dirs: [<fs:/etc/xdg/xdg_example>] 212 data_dirs: [<fs:/usr/local/share/xdg_example>; <fs:/usr/share/xdg_example>] 213 214Shows mixed sources working together. Config uses app-specific env var (highest 215priority among env vars), data and cache use XDG standard env vars (no 216app-specific ones set), and state uses default (no env vars set). Each 217directory gets its value from the highest-priority available source. 218 219Test command line overrides mixed environment variables: 220 221 $ export HOME=./test_home 222 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 223 $ XDG_CONFIG_HOME=/tmp/xdge/xdg-config \ 224 > XDG_EXAMPLE_CONFIG_DIR=./app-config \ 225 > ./xdg_example.exe --config-dir ./cli-config 226 === Cmdliner Config === 227 XDG config: 228 config_dir: ./cli-config [cmdline] 229 230 === XDG Directories === 231 XDG directories for 'xdg_example': 232 User directories: 233 config: <fs:./test_home/./cli-config> [cmdline] 234 data: <fs:./test_home/./test_home/.local/share/xdg_example> [default] 235 cache: <fs:./test_home/./test_home/.cache/xdg_example> [default] 236 state: <fs:./test_home/./test_home/.local/state/xdg_example> [default] 237 runtime: <none> [default] 238 System directories: 239 config_dirs: [<fs:/etc/xdg/xdg_example>] 240 data_dirs: [<fs:/usr/local/share/xdg_example>; <fs:/usr/share/xdg_example>] 241 242Command-line argument overrides both types of environment variables. Even 243though both XDG_CONFIG_HOME and XDG_EXAMPLE_CONFIG_DIR are set, the 244--config-dir flag takes precedence and shows [cmdline] source. Other 245directories fall back to defaults since no other command-line args are 246provided. 247 248Test empty environment variable handling: 249 $ export HOME=./test_home 250 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 251 $ XDG_EXAMPLE_CONFIG_DIR="" \ 252 > XDG_CONFIG_HOME=/tmp/xdge/xdg-config \ 253 > ./xdg_example.exe 254 === Cmdliner Config === 255 XDG config: 256 config_dir: /tmp/xdge/xdg-config [env(XDG_CONFIG_HOME)] 257 258 === XDG Directories === 259 XDG directories for 'xdg_example': 260 User directories: 261 config: <fs:/tmp/xdge/xdg-config> [env(XDG_CONFIG_HOME)] 262 data: <fs:./test_home/./test_home/.local/share/xdg_example> [default] 263 cache: <fs:./test_home/./test_home/.cache/xdg_example> [default] 264 state: <fs:./test_home/./test_home/.local/state/xdg_example> [default] 265 runtime: <none> [default] 266 System directories: 267 config_dirs: [<fs:/etc/xdg/xdg_example>] 268 data_dirs: [<fs:/usr/local/share/xdg_example>; <fs:/usr/share/xdg_example>] 269 270When an app-specific env var is empty (""), it falls back to the XDG standard 271variable. XDG_EXAMPLE_CONFIG_DIR="" is ignored, so XDG_CONFIG_HOME is used 272instead, correctly showing [env(XDG_CONFIG_HOME)] as the source. This behavior 273ensures that empty app-specific variables do not override useful XDG standard 274settings. 275 276Test system directory environment variables: 277 278 $ export HOME=./test_home 279 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 280 $ XDG_CONFIG_DIRS=/tmp/xdge/sys1:/tmp/xdge/sys2 \ 281 > XDG_DATA_DIRS=/tmp/xdge/data1:/tmp/xdge/data2 \ 282 > ./xdg_example.exe 283 === Cmdliner Config === 284 XDG config: 285 286 === XDG Directories === 287 XDG directories for 'xdg_example': 288 User directories: 289 config: <fs:./test_home/./test_home/.config/xdg_example> [default] 290 data: <fs:./test_home/./test_home/.local/share/xdg_example> [default] 291 cache: <fs:./test_home/./test_home/.cache/xdg_example> [default] 292 state: <fs:./test_home/./test_home/.local/state/xdg_example> [default] 293 runtime: <none> [default] 294 System directories: 295 config_dirs: [<fs:/tmp/xdge/sys1/xdg_example>; 296 <fs:/tmp/xdge/sys2/xdg_example>] 297 data_dirs: [<fs:/tmp/xdge/data1/xdg_example>; 298 <fs:/tmp/xdge/data2/xdg_example>] 299 300XDG_CONFIG_DIRS and XDG_DATA_DIRS environment variables override the default 301system directories. The colon-separated paths are parsed and the app name is 302appended to each path. User directories remain at defaults since no user-level 303overrides are provided. System directory env vars only affect the system 304directories, not user directories. 305 306Test _path functions do not create directories but can access files within them: 307 308 $ export HOME=/tmp/xdge/xdg_path_test 309 $ mkdir -p /tmp/xdge/xdg_path_test 310 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 311 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 312Create config subdirectory manually and write a test file: 313 $ mkdir -p "/tmp/xdge/xdg_path_test/.config/path_test/profiles" 314 $ echo "test profile content" > "/tmp/xdge/xdg_path_test/.config/path_test/profiles/default.json" 315Create data subdirectory manually and write a test file: 316 $ mkdir -p "/tmp/xdge/xdg_path_test/.local/share/path_test/databases" 317 $ echo "test database content" > "/tmp/xdge/xdg_path_test/.local/share/path_test/databases/main.db" 318Create cache subdirectory manually and write a test file: 319 $ mkdir -p "/tmp/xdge/xdg_path_test/.cache/path_test/thumbnails" 320 $ echo "test cache content" > "/tmp/xdge/xdg_path_test/.cache/path_test/thumbnails/thumb1.png" 321Create state subdirectory manually and write a test file: 322 $ mkdir -p "/tmp/xdge/xdg_path_test/.local/state/path_test/logs" 323 $ echo "test log content" > "/tmp/xdge/xdg_path_test/.local/state/path_test/logs/app.log" 324 325Now test that we can read the files through the XDG _path functions: 326 $ ./test_paths.exe 327 config file content: test profile content 328 data file content: test database content 329 cache file content: test cache content 330 state file content: test log content 331 332This test verifies that the _path functions return correct paths that can be used to access 333files within XDG subdirectories, without the functions automatically creating those directories. 334 335Test path resolution with --show-paths: 336 337Test with a preset HOME to verify correct path resolution: 338 $ export HOME=./home_testuser 339 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 340 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 341 $ ./xdg_example.exe --show-paths 342 config_dir: ./home_testuser/./home_testuser/.config/xdg_example 343 data_dir: ./home_testuser/./home_testuser/.local/share/xdg_example 344 cache_dir: ./home_testuser/./home_testuser/.cache/xdg_example 345 state_dir: ./home_testuser/./home_testuser/.local/state/xdg_example 346 runtime_dir: <none> 347 config_dirs: /etc/xdg/xdg_example 348 data_dirs: /usr/local/share/xdg_example:/usr/share/xdg_example 349 350Test with environment variables set: 351 $ export HOME=./home_testuser 352 $ export XDG_CONFIG_HOME=/tmp/xdge/config 353 $ export XDG_DATA_HOME=/tmp/xdge/data 354 $ export XDG_CACHE_HOME=/tmp/xdge/cache 355 $ export XDG_STATE_HOME=/tmp/xdge/state 356 $ export XDG_CONFIG_DIRS=/tmp/xdge/config1:/tmp/xdge/config2 357 $ export XDG_DATA_DIRS=/tmp/xdge/data1:/tmp/xdge/data2 358 $ ./xdg_example.exe --show-paths 359 config_dir: /tmp/xdge/config 360 data_dir: /tmp/xdge/data 361 cache_dir: /tmp/xdge/cache 362 state_dir: /tmp/xdge/state 363 runtime_dir: <none> 364 config_dirs: /tmp/xdge/config1/xdg_example:/tmp/xdge/config2/xdg_example 365 data_dirs: /tmp/xdge/data1/xdg_example:/tmp/xdge/data2/xdg_example 366 367Test with command-line overrides: 368 $ export HOME=./home_testuser 369 $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 370 $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 371 $ ./xdg_example.exe --show-paths --config-dir ./override/config --data-dir ./override/data 372 config_dir: ./home_testuser/./override/config 373 data_dir: ./home_testuser/./override/data 374 cache_dir: ./home_testuser/./home_testuser/.cache/xdg_example 375 state_dir: ./home_testuser/./home_testuser/.local/state/xdg_example 376 runtime_dir: <none> 377 config_dirs: /etc/xdg/xdg_example 378 data_dirs: /usr/local/share/xdg_example:/usr/share/xdg_example 379