this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

home

+349 -220
+4 -2
xdg-eio/example/xdg_example.ml
··· 1 - let run (xdg,cfg) = 1 + let run (xdg, cfg) = 2 2 Fmt.pr 3 3 "%a@.%a@.@.%a@.%a@." 4 4 Fmt.(styled `Bold string) ··· 9 9 "=== XDG Directories ===" 10 10 (Xdge.pp ~brief:false ~sources:true) 11 11 xdg 12 + ;; 12 13 13 14 open Cmdliner 14 15 ··· 27 28 ] 28 29 in 29 30 let info = Cmdliner.Cmd.info "xdg_example" ~version:"1.0" ~doc ~man in 30 - Eio_main.run @@ fun env -> 31 + Eio_main.run 32 + @@ fun env -> 31 33 let create_xdg_term = Xdge.Cmd.term app_name env#fs in 32 34 let main_term = Term.(const run $ create_xdg_term) in 33 35 let cmd = Cmdliner.Cmd.v info main_term in
+216 -127
xdg-eio/lib/xdge.ml
··· 27 27 let path_str = Eio.Path.native_exn base_path in 28 28 let stat = Eio.Path.stat ~follow:true base_path in 29 29 let current_perm = stat.perm land 0o777 in 30 - if current_perm <> 0o700 then 30 + if current_perm <> 0o700 31 + then 31 32 failwith 32 33 (Printf.sprintf 33 - "XDG_RUNTIME_DIR base directory %s has incorrect permissions: %o (must be 0700)" 34 + "XDG_RUNTIME_DIR base directory %s has incorrect permissions: %o (must be \ 35 + 0700)" 34 36 path_str 35 37 current_perm); 36 38 (* Check ownership - directory should be owned by current user *) 37 39 let uid = Unix.getuid () in 38 - if stat.uid <> Int64.of_int uid then 40 + if stat.uid <> Int64.of_int uid 41 + then 39 42 failwith 40 43 (Printf.sprintf 41 - "XDG_RUNTIME_DIR base directory %s not owned by current user (uid %d, owner %Ld)" 44 + "XDG_RUNTIME_DIR base directory %s not owned by current user (uid %d, owner \ 45 + %Ld)" 42 46 path_str 43 47 uid 44 - stat.uid); 48 + stat.uid) 45 49 (* TODO: Check that directory is on local filesystem (not networked). 46 50 This would require filesystem type detection which is OS-specific. *) 47 51 with 48 - | exn -> failwith (Printf.sprintf "Cannot validate XDG_RUNTIME_DIR: %s" (Printexc.to_string exn)) 52 + | exn -> 53 + failwith 54 + (Printf.sprintf "Cannot validate XDG_RUNTIME_DIR: %s" (Printexc.to_string exn)) 55 + ;; 49 56 50 57 let ensure_runtime_dir _fs app_runtime_path = 51 58 (* Base directory validation is done in resolve_runtime_dir, 52 59 so we just create the app subdirectory *) 53 60 ensure_dir app_runtime_path 61 + ;; 54 62 55 63 let get_home_dir fs = 56 64 let home_str = ··· 67 75 | _ -> failwith "Cannot determine home directory")) 68 76 in 69 77 Eio.Path.(fs / home_str) 78 + ;; 70 79 71 80 let make_env_var_name app_name suffix = String.uppercase_ascii app_name ^ "_" ^ suffix 72 81 73 82 exception Invalid_xdg_path of string 74 83 75 84 let validate_absolute_path context path = 76 - if Filename.is_relative path then 77 - raise (Invalid_xdg_path 78 - (Printf.sprintf "%s must be an absolute path, got: %s" context path)) 85 + if Filename.is_relative path 86 + then 87 + raise 88 + (Invalid_xdg_path 89 + (Printf.sprintf "%s must be an absolute path, got: %s" context path)) 90 + ;; 79 91 80 92 let resolve_path fs home_path base_path = 81 93 if Filename.is_relative base_path 82 94 then Eio.Path.(home_path / base_path) 83 95 else Eio.Path.(fs / base_path) 96 + ;; 84 97 85 98 (* Helper to resolve system directories (config_dirs or data_dirs) *) 86 - let resolve_system_dirs fs _home_path app_name override_suffix xdg_var default_paths = 99 + let resolve_system_dirs fs home_path app_name override_suffix xdg_var default_paths = 87 100 let override_var = make_env_var_name app_name override_suffix in 88 101 match Sys.getenv_opt override_var with 89 102 | Some dirs when dirs <> "" -> 90 103 String.split_on_char ':' dirs 91 104 |> List.filter (fun s -> s <> "") 92 105 |> List.filter_map (fun path -> 93 - try 94 - validate_absolute_path override_var path; 95 - Some (Eio.Path.(fs / path / app_name)) 96 - with Invalid_xdg_path _ -> None) 106 + try 107 + validate_absolute_path override_var path; 108 + Some Eio.Path.(resolve_path fs home_path path / app_name) 109 + with 110 + | Invalid_xdg_path _ -> None) 97 111 | Some _ | None -> 98 112 (match Sys.getenv_opt xdg_var with 99 113 | Some dirs when dirs <> "" -> 100 114 String.split_on_char ':' dirs 101 115 |> List.filter (fun s -> s <> "") 102 116 |> List.filter_map (fun path -> 103 - try 104 - validate_absolute_path xdg_var path; 105 - Some (Eio.Path.(fs / path / app_name)) 106 - with Invalid_xdg_path _ -> None) 117 + try 118 + validate_absolute_path xdg_var path; 119 + Some Eio.Path.(resolve_path fs home_path path / app_name) 120 + with 121 + | Invalid_xdg_path _ -> None) 107 122 | Some _ | None -> 108 - List.map (fun path -> Eio.Path.(fs / path / app_name)) default_paths) 123 + List.map 124 + (fun path -> Eio.Path.(resolve_path fs home_path path / app_name)) 125 + default_paths) 126 + ;; 109 127 110 128 (* Helper to resolve a user directory with override precedence *) 111 - let resolve_user_dir fs _home_path app_name xdg_ctx xdg_getter override_suffix = 129 + let resolve_user_dir fs home_path app_name xdg_ctx xdg_getter override_suffix = 112 130 let override_var = make_env_var_name app_name override_suffix in 113 131 match Sys.getenv_opt override_var with 114 - | Some dir when dir <> "" -> 132 + | Some dir when dir <> "" -> 115 133 validate_absolute_path override_var dir; 116 134 Eio.Path.(fs / dir / app_name), Env override_var 117 - | Some _ | None -> Eio.Path.(fs / xdg_getter xdg_ctx / app_name), Default 135 + | Some _ | None -> 136 + let xdg_base = xdg_getter xdg_ctx in 137 + let base_path = resolve_path fs home_path xdg_base in 138 + Eio.Path.(base_path / app_name), Default 139 + ;; 118 140 119 141 (* Helper to resolve runtime directory (special case since it can be None) *) 120 - let resolve_runtime_dir fs _home_path app_name xdg_ctx = 142 + let resolve_runtime_dir fs home_path app_name xdg_ctx = 121 143 let override_var = make_env_var_name app_name "RUNTIME_DIR" in 122 144 match Sys.getenv_opt override_var with 123 - | Some dir when dir <> "" -> 145 + | Some dir when dir <> "" -> 124 146 validate_absolute_path override_var dir; 125 147 (* Validate the base runtime directory has correct permissions *) 126 - let base_runtime_dir = Eio.Path.(fs / dir) in 148 + let base_runtime_dir = resolve_path fs home_path dir in 127 149 validate_runtime_base_dir base_runtime_dir; 128 - Some (Eio.Path.(fs / dir / app_name)), Env override_var 150 + Some Eio.Path.(base_runtime_dir / app_name), Env override_var 129 151 | Some _ | None -> 130 - (match Xdg.runtime_dir xdg_ctx with 131 - | Some base -> 132 - (* Validate the base runtime directory has correct permissions *) 133 - let base_runtime_dir = Eio.Path.(fs / base) in 134 - validate_runtime_base_dir base_runtime_dir; 135 - Some (Eio.Path.(fs / base / app_name)) 136 - | None -> None), Default 152 + ( (match Xdg.runtime_dir xdg_ctx with 153 + | Some base -> 154 + (* Validate the base runtime directory has correct permissions *) 155 + let base_runtime_dir = resolve_path fs home_path base in 156 + validate_runtime_base_dir base_runtime_dir; 157 + Some Eio.Path.(base_runtime_dir / app_name) 158 + | None -> None) 159 + , Default ) 160 + ;; 137 161 138 162 let validate_standard_xdg_vars () = 139 163 (* Validate standard XDG environment variables for absolute paths *) 140 - let xdg_vars = [ 141 - "XDG_CONFIG_HOME"; 142 - "XDG_DATA_HOME"; 143 - "XDG_CACHE_HOME"; 144 - "XDG_STATE_HOME"; 145 - "XDG_RUNTIME_DIR"; 146 - "XDG_CONFIG_DIRS"; 147 - "XDG_DATA_DIRS"; 148 - ] in 149 - List.iter (fun var -> 150 - match Sys.getenv_opt var with 151 - | Some value when value <> "" -> 152 - if String.contains value ':' then 153 - (* Colon-separated list - validate each part *) 154 - String.split_on_char ':' value 155 - |> List.filter (fun s -> s <> "") 156 - |> List.iter (fun path -> validate_absolute_path var path) 157 - else 158 - (* Single path *) 159 - validate_absolute_path var value 160 - | _ -> () 161 - ) xdg_vars 164 + let xdg_vars = 165 + [ "XDG_CONFIG_HOME" 166 + ; "XDG_DATA_HOME" 167 + ; "XDG_CACHE_HOME" 168 + ; "XDG_STATE_HOME" 169 + ; "XDG_RUNTIME_DIR" 170 + ; "XDG_CONFIG_DIRS" 171 + ; "XDG_DATA_DIRS" 172 + ] 173 + in 174 + List.iter 175 + (fun var -> 176 + match Sys.getenv_opt var with 177 + | Some value when value <> "" -> 178 + if String.contains value ':' 179 + then 180 + (* Colon-separated list - validate each part *) 181 + String.split_on_char ':' value 182 + |> List.filter (fun s -> s <> "") 183 + |> List.iter (fun path -> validate_absolute_path var path) 184 + else 185 + (* Single path *) 186 + validate_absolute_path var value 187 + | _ -> ()) 188 + xdg_vars 189 + ;; 162 190 163 191 let create fs app_name = 164 192 let fs = fs in ··· 221 249 ; config_dirs 222 250 ; data_dirs 223 251 } 252 + ;; 224 253 225 254 let app_name t = t.app_name 226 255 let config_dir t = t.config_dir ··· 248 277 search_dirs remaining_dirs) 249 278 in 250 279 search_dirs dirs 280 + ;; 251 281 252 282 let find_config_file t filename = 253 283 (* Search user config dir first, then system config dirs *) 254 284 find_file_in_dirs (t.config_dir :: t.config_dirs) filename 285 + ;; 255 286 256 287 let find_data_file t filename = 257 288 (* Search user data dir first, then system data dirs *) 258 289 find_file_in_dirs (t.data_dir :: t.data_dirs) filename 290 + ;; 259 291 260 292 let pp ?(brief = false) ?(sources = false) ppf t = 261 293 let pp_source ppf = function ··· 361 393 "data_dirs:" 362 394 pp_paths 363 395 t.data_dirs) 396 + ;; 364 397 365 398 module Cmd = struct 366 399 type xdg_t = t ··· 381 414 let term app_name fs = 382 415 let open Cmdliner in 383 416 let app_upper = String.uppercase_ascii app_name in 417 + let show_paths = 418 + let doc = "Show only the resolved directory paths without formatting" in 419 + Arg.(value & flag & info [ "show-paths" ] ~doc) 420 + in 384 421 let make_dir_arg name env_suffix xdg_var default_path = 385 422 let app_env = app_upper ^ "_" ^ env_suffix in 386 423 let doc = ··· 446 483 in 447 484 let runtime_dir = make_dir_arg "runtime" "RUNTIME_DIR" "XDG_RUNTIME_DIR" None in 448 485 Term.( 449 - const (fun config_dir_ws data_dir_ws cache_dir_ws state_dir_ws runtime_dir_ws -> 450 - let config = { config_dir = config_dir_ws; data_dir = data_dir_ws; cache_dir = cache_dir_ws; state_dir = state_dir_ws; runtime_dir = runtime_dir_ws } in 451 - let home_path = get_home_dir fs in 452 - let xdg_ctx = Xdg.create ~env:Sys.getenv_opt () in 453 - (* Helper to resolve directory from config with source tracking *) 454 - let resolve_from_config config_ws xdg_getter = 455 - match config_ws.value with 456 - | Some dir -> resolve_path fs home_path dir, config_ws.source 457 - | None -> 458 - let xdg_base = xdg_getter xdg_ctx in 459 - Eio.Path.(fs / xdg_base / app_name), config_ws.source 460 - in 461 - (* User directories *) 462 - let config_dir, config_dir_source = 463 - resolve_from_config config.config_dir Xdg.config_dir 464 - in 465 - let data_dir, data_dir_source = resolve_from_config config.data_dir Xdg.data_dir in 466 - let cache_dir, cache_dir_source = 467 - resolve_from_config config.cache_dir Xdg.cache_dir 468 - in 469 - let state_dir, state_dir_source = 470 - resolve_from_config config.state_dir Xdg.state_dir 471 - in 472 - (* Runtime directory *) 473 - let runtime_dir, runtime_dir_source = 474 - match config.runtime_dir.value with 475 - | Some dir -> Some (resolve_path fs home_path dir), config.runtime_dir.source 476 - | None -> 477 - ( Option.map 478 - (fun base -> Eio.Path.(fs / base / app_name)) 479 - (Xdg.runtime_dir xdg_ctx) 480 - , config.runtime_dir.source ) 481 - in 482 - (* System directories - reuse shared helper *) 483 - let config_dirs = 484 - resolve_system_dirs 485 - fs 486 - home_path 487 - app_name 488 - "CONFIG_DIRS" 489 - "XDG_CONFIG_DIRS" 490 - [ "/etc/xdg" ] 491 - in 492 - let data_dirs = 493 - resolve_system_dirs 494 - fs 495 - home_path 496 - app_name 497 - "DATA_DIRS" 498 - "XDG_DATA_DIRS" 499 - [ "/usr/local/share"; "/usr/share" ] 500 - in 501 - ensure_dir config_dir; 502 - ensure_dir data_dir; 503 - ensure_dir cache_dir; 504 - ensure_dir state_dir; 505 - Option.iter (ensure_runtime_dir fs) runtime_dir; 506 - { app_name 507 - ; config_dir 508 - ; config_dir_source 509 - ; data_dir 510 - ; data_dir_source 511 - ; cache_dir 512 - ; cache_dir_source 513 - ; state_dir 514 - ; state_dir_source 515 - ; runtime_dir 516 - ; runtime_dir_source 517 - ; config_dirs 518 - ; data_dirs 519 - }, config) 486 + const 487 + (fun 488 + show_paths_flag 489 + config_dir_ws 490 + data_dir_ws 491 + cache_dir_ws 492 + state_dir_ws 493 + runtime_dir_ws 494 + -> 495 + let config = 496 + { config_dir = config_dir_ws 497 + ; data_dir = data_dir_ws 498 + ; cache_dir = cache_dir_ws 499 + ; state_dir = state_dir_ws 500 + ; runtime_dir = runtime_dir_ws 501 + } 502 + in 503 + let home_path = get_home_dir fs in 504 + (* First validate all standard XDG environment variables *) 505 + validate_standard_xdg_vars (); 506 + let xdg_ctx = Xdg.create ~env:Sys.getenv_opt () in 507 + (* Helper to resolve directory from config with source tracking *) 508 + let resolve_from_config config_ws xdg_getter = 509 + match config_ws.value with 510 + | Some dir -> resolve_path fs home_path dir, config_ws.source 511 + | None -> 512 + let xdg_base = xdg_getter xdg_ctx in 513 + let base_path = resolve_path fs home_path xdg_base in 514 + Eio.Path.(base_path / app_name), config_ws.source 515 + in 516 + (* User directories *) 517 + let config_dir, config_dir_source = 518 + resolve_from_config config.config_dir Xdg.config_dir 519 + in 520 + let data_dir, data_dir_source = 521 + resolve_from_config config.data_dir Xdg.data_dir 522 + in 523 + let cache_dir, cache_dir_source = 524 + resolve_from_config config.cache_dir Xdg.cache_dir 525 + in 526 + let state_dir, state_dir_source = 527 + resolve_from_config config.state_dir Xdg.state_dir 528 + in 529 + (* Runtime directory *) 530 + let runtime_dir, runtime_dir_source = 531 + match config.runtime_dir.value with 532 + | Some dir -> Some (resolve_path fs home_path dir), config.runtime_dir.source 533 + | None -> 534 + ( Option.map 535 + (fun base -> 536 + let base_path = resolve_path fs home_path base in 537 + Eio.Path.(base_path / app_name)) 538 + (Xdg.runtime_dir xdg_ctx) 539 + , config.runtime_dir.source ) 540 + in 541 + (* System directories - reuse shared helper *) 542 + let config_dirs = 543 + resolve_system_dirs 544 + fs 545 + home_path 546 + app_name 547 + "CONFIG_DIRS" 548 + "XDG_CONFIG_DIRS" 549 + [ "/etc/xdg" ] 550 + in 551 + let data_dirs = 552 + resolve_system_dirs 553 + fs 554 + home_path 555 + app_name 556 + "DATA_DIRS" 557 + "XDG_DATA_DIRS" 558 + [ "/usr/local/share"; "/usr/share" ] 559 + in 560 + ensure_dir config_dir; 561 + ensure_dir data_dir; 562 + ensure_dir cache_dir; 563 + ensure_dir state_dir; 564 + Option.iter (ensure_runtime_dir fs) runtime_dir; 565 + let xdg = 566 + { app_name 567 + ; config_dir 568 + ; config_dir_source 569 + ; data_dir 570 + ; data_dir_source 571 + ; cache_dir 572 + ; cache_dir_source 573 + ; state_dir 574 + ; state_dir_source 575 + ; runtime_dir 576 + ; runtime_dir_source 577 + ; config_dirs 578 + ; data_dirs 579 + } 580 + in 581 + (* Handle --show-paths option *) 582 + if show_paths_flag 583 + then ( 584 + let print_path name path = 585 + match path with 586 + | None -> Printf.printf "%s: <none>\n" name 587 + | Some p -> Printf.printf "%s: %s\n" name (Eio.Path.native_exn p) 588 + in 589 + let print_paths name paths = 590 + match paths with 591 + | [] -> Printf.printf "%s: []\n" name 592 + | paths -> 593 + let paths_str = String.concat ":" (List.map Eio.Path.native_exn paths) in 594 + Printf.printf "%s: %s\n" name paths_str 595 + in 596 + print_path "config_dir" (Some config_dir); 597 + print_path "data_dir" (Some data_dir); 598 + print_path "cache_dir" (Some cache_dir); 599 + print_path "state_dir" (Some state_dir); 600 + print_path "runtime_dir" runtime_dir; 601 + print_paths "config_dirs" config_dirs; 602 + print_paths "data_dirs" data_dirs; 603 + Stdlib.exit 0); 604 + xdg, config) 605 + $ show_paths 520 606 $ config_dir 521 607 $ data_dir 522 608 $ cache_dir 523 609 $ state_dir 524 610 $ runtime_dir) 611 + ;; 525 612 526 613 let env_docs app_name = 527 614 let app_upper = String.uppercase_ascii app_name in ··· 574 661 app_name 575 662 app_name 576 663 app_name 664 + ;; 577 665 578 666 let pp ppf config = 579 667 let pp_source ppf = function ··· 620 708 config.state_dir 621 709 (pp_with_source "runtime_dir") 622 710 config.runtime_dir 623 - end 711 + ;; 712 + end
+84 -91
xdg-eio/test/test_paths.ml
··· 1 1 let test_path_validation () = 2 2 Printf.printf "Testing XDG path validation...\n"; 3 - 4 3 (* Test absolute path validation for environment variables *) 5 4 let test_relative_path_rejection env_var relative_path = 6 5 Printf.printf "Testing rejection of relative path in %s...\n" env_var; 7 6 Unix.putenv env_var relative_path; 8 7 try 9 - Eio_main.run @@ fun env -> 10 - let _ = Xdge.create env#fs "test_validation" in 11 - Printf.printf "ERROR: Should have rejected relative path\n"; 12 - false 8 + Eio_main.run 9 + @@ fun env -> 10 + let _ = Xdge.create env#fs "test_validation" in 11 + Printf.printf "ERROR: Should have rejected relative path\n"; 12 + false 13 13 with 14 14 | Xdge.Invalid_xdg_path msg -> 15 - Printf.printf "SUCCESS: Correctly rejected relative path: %s\n" msg; 16 - true 15 + Printf.printf "SUCCESS: Correctly rejected relative path: %s\n" msg; 16 + true 17 17 | exn -> 18 - Printf.printf "ERROR: Wrong exception: %s\n" (Printexc.to_string exn); 19 - false 18 + Printf.printf "ERROR: Wrong exception: %s\n" (Printexc.to_string exn); 19 + false 20 20 in 21 - 22 21 let old_config_home = Sys.getenv_opt "XDG_CONFIG_HOME" in 23 22 let old_data_dirs = Sys.getenv_opt "XDG_DATA_DIRS" in 24 - 25 23 let success1 = test_relative_path_rejection "XDG_CONFIG_HOME" "relative/path" in 26 24 let success2 = test_relative_path_rejection "XDG_DATA_DIRS" "rel1:rel2:/abs/path" in 27 - 28 25 (* Restore original env vars *) 29 - (match old_config_home with 30 - | Some v -> Unix.putenv "XDG_CONFIG_HOME" v 31 - | None -> (try Unix.putenv "XDG_CONFIG_HOME" ""; with _ -> ())); 26 + (match old_config_home with 27 + | Some v -> Unix.putenv "XDG_CONFIG_HOME" v 28 + | None -> 29 + (try Unix.putenv "XDG_CONFIG_HOME" "" with 30 + | _ -> ())); 32 31 (match old_data_dirs with 33 32 | Some v -> Unix.putenv "XDG_DATA_DIRS" v 34 - | None -> (try Unix.putenv "XDG_DATA_DIRS" ""; with _ -> ())); 35 - 33 + | None -> 34 + (try Unix.putenv "XDG_DATA_DIRS" "" with 35 + | _ -> ())); 36 36 success1 && success2 37 + ;; 37 38 38 39 let test_file_search () = 39 40 Printf.printf "\nTesting XDG file search...\n"; 40 - 41 - Eio_main.run @@ fun env -> 42 - let xdg = Xdge.create env#fs "search_test" in 43 - 44 - (* Create test files *) 45 - let config_file = Eio.Path.(Xdge.config_dir xdg / "test.conf") in 46 - let data_file = Eio.Path.(Xdge.data_dir xdg / "test.dat") in 47 - 48 - Eio.Path.save ~create:(`Or_truncate 0o644) config_file "config content"; 49 - Eio.Path.save ~create:(`Or_truncate 0o644) data_file "data content"; 50 - 51 - (* Test finding existing files *) 52 - (match Xdge.find_config_file xdg "test.conf" with 53 - | Some path -> 54 - let content = Eio.Path.load path in 55 - Printf.printf "Found config file: %s\n" (String.trim content) 56 - | None -> Printf.printf "ERROR: Config file not found\n"); 57 - 58 - (match Xdge.find_data_file xdg "test.dat" with 59 - | Some path -> 60 - let content = Eio.Path.load path in 61 - Printf.printf "Found data file: %s\n" (String.trim content) 62 - | None -> Printf.printf "ERROR: Data file not found\n"); 63 - 64 - (* Test non-existent file *) 65 - (match Xdge.find_config_file xdg "nonexistent.conf" with 66 - | Some _ -> Printf.printf "ERROR: Should not have found nonexistent file\n" 67 - | None -> Printf.printf "Correctly handled nonexistent file\n") 41 + Eio_main.run 42 + @@ fun env -> 43 + let xdg = Xdge.create env#fs "search_test" in 44 + (* Create test files *) 45 + let config_file = Eio.Path.(Xdge.config_dir xdg / "test.conf") in 46 + let data_file = Eio.Path.(Xdge.data_dir xdg / "test.dat") in 47 + Eio.Path.save ~create:(`Or_truncate 0o644) config_file "config content"; 48 + Eio.Path.save ~create:(`Or_truncate 0o644) data_file "data content"; 49 + (* Test finding existing files *) 50 + (match Xdge.find_config_file xdg "test.conf" with 51 + | Some path -> 52 + let content = Eio.Path.load path in 53 + Printf.printf "Found config file: %s\n" (String.trim content) 54 + | None -> Printf.printf "ERROR: Config file not found\n"); 55 + (match Xdge.find_data_file xdg "test.dat" with 56 + | Some path -> 57 + let content = Eio.Path.load path in 58 + Printf.printf "Found data file: %s\n" (String.trim content) 59 + | None -> Printf.printf "ERROR: Data file not found\n"); 60 + (* Test non-existent file *) 61 + match Xdge.find_config_file xdg "nonexistent.conf" with 62 + | Some _ -> Printf.printf "ERROR: Should not have found nonexistent file\n" 63 + | None -> Printf.printf "Correctly handled nonexistent file\n" 64 + ;; 68 65 69 66 let () = 70 67 (* Check if we should run validation tests *) 71 - if Array.length Sys.argv > 1 && Sys.argv.(1) = "--validate" then ( 68 + if Array.length Sys.argv > 1 && Sys.argv.(1) = "--validate" 69 + then ( 72 70 let validation_success = test_path_validation () in 73 71 test_file_search (); 74 - 75 - if validation_success then 76 - Printf.printf "\nAll path validation tests passed!\n" 77 - else 78 - Printf.printf "\nSome validation tests failed!\n" 79 - ) else ( 72 + if validation_success 73 + then Printf.printf "\nAll path validation tests passed!\n" 74 + else Printf.printf "\nSome validation tests failed!\n") 75 + else 80 76 (* Run original simple functionality test *) 81 - Eio_main.run @@ fun env -> 82 - let xdg = Xdge.create env#fs "path_test" in 83 - 84 - (* Test config subdirectory *) 85 - let profiles_path = Eio.Path.(Xdge.config_dir xdg / "profiles") in 86 - let profile_file = Eio.Path.(profiles_path / "default.json") in 87 - (try 88 - let content = Eio.Path.load profile_file in 89 - Printf.printf "config file content: %s" (String.trim content) 90 - with 91 - | exn -> Printf.printf "config file error: %s" (Printexc.to_string exn)); 92 - 93 - (* Test data subdirectory *) 94 - let db_path = Eio.Path.(Xdge.data_dir xdg / "databases") in 95 - let db_file = Eio.Path.(db_path / "main.db") in 96 - (try 97 - let content = Eio.Path.load db_file in 98 - Printf.printf "\ndata file content: %s" (String.trim content) 99 - with 100 - | exn -> Printf.printf "\ndata file error: %s" (Printexc.to_string exn)); 101 - 102 - (* Test cache subdirectory *) 103 - let cache_path = Eio.Path.(Xdge.cache_dir xdg / "thumbnails") in 104 - let cache_file = Eio.Path.(cache_path / "thumb1.png") in 105 - (try 106 - let content = Eio.Path.load cache_file in 107 - Printf.printf "\ncache file content: %s" (String.trim content) 108 - with 109 - | exn -> Printf.printf "\ncache file error: %s" (Printexc.to_string exn)); 110 - 111 - (* Test state subdirectory *) 112 - let logs_path = Eio.Path.(Xdge.state_dir xdg / "logs") in 113 - let log_file = Eio.Path.(logs_path / "app.log") in 114 - (try 115 - let content = Eio.Path.load log_file in 116 - Printf.printf "\nstate file content: %s\n" (String.trim content) 117 - with 118 - | exn -> Printf.printf "\nstate file error: %s\n" (Printexc.to_string exn)) 119 - ) 77 + Eio_main.run 78 + @@ fun env -> 79 + let xdg = Xdge.create env#fs "path_test" in 80 + (* Test config subdirectory *) 81 + let profiles_path = Eio.Path.(Xdge.config_dir xdg / "profiles") in 82 + let profile_file = Eio.Path.(profiles_path / "default.json") in 83 + (try 84 + let content = Eio.Path.load profile_file in 85 + Printf.printf "config file content: %s" (String.trim content) 86 + with 87 + | exn -> Printf.printf "config file error: %s" (Printexc.to_string exn)); 88 + (* Test data subdirectory *) 89 + let db_path = Eio.Path.(Xdge.data_dir xdg / "databases") in 90 + let db_file = Eio.Path.(db_path / "main.db") in 91 + (try 92 + let content = Eio.Path.load db_file in 93 + Printf.printf "\ndata file content: %s" (String.trim content) 94 + with 95 + | exn -> Printf.printf "\ndata file error: %s" (Printexc.to_string exn)); 96 + (* Test cache subdirectory *) 97 + let cache_path = Eio.Path.(Xdge.cache_dir xdg / "thumbnails") in 98 + let cache_file = Eio.Path.(cache_path / "thumb1.png") in 99 + (try 100 + let content = Eio.Path.load cache_file in 101 + Printf.printf "\ncache file content: %s" (String.trim content) 102 + with 103 + | exn -> Printf.printf "\ncache file error: %s" (Printexc.to_string exn)); 104 + (* Test state subdirectory *) 105 + let logs_path = Eio.Path.(Xdge.state_dir xdg / "logs") in 106 + let log_file = Eio.Path.(logs_path / "app.log") in 107 + try 108 + let content = Eio.Path.load log_file in 109 + Printf.printf "\nstate file content: %s\n" (String.trim content) 110 + with 111 + | exn -> Printf.printf "\nstate file error: %s\n" (Printexc.to_string exn) 112 + ;;
+45
xdg-eio/test/xdg.t
··· 353 353 This test verifies that the _path functions return correct paths that can be used to access 354 354 files within XDG subdirectories, without the functions automatically creating those directories. 355 355 356 + Test path resolution with --show-paths: 357 + 358 + Test with a preset HOME to verify correct path resolution: 359 + $ export HOME=/home/testuser 360 + $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 361 + $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 362 + $ ../example/xdg_example.exe --show-paths 363 + config_dir: /home/testuser/.config/xdg_example 364 + data_dir: /home/testuser/.local/share/xdg_example 365 + cache_dir: /home/testuser/.cache/xdg_example 366 + state_dir: /home/testuser/.local/state/xdg_example 367 + runtime_dir: <none> 368 + config_dirs: /etc/xdg/xdg_example 369 + data_dirs: /usr/local/share/xdg_example:/usr/share/xdg_example 370 + 371 + Test with environment variables set: 372 + $ export HOME=/home/testuser 373 + $ export XDG_CONFIG_HOME=/custom/config 374 + $ export XDG_DATA_HOME=/custom/data 375 + $ export XDG_CACHE_HOME=/custom/cache 376 + $ export XDG_STATE_HOME=/custom/state 377 + $ export XDG_CONFIG_DIRS=/system/config1:/system/config2 378 + $ export XDG_DATA_DIRS=/system/data1:/system/data2 379 + $ ../example/xdg_example.exe --show-paths 380 + config_dir: /custom/config/xdg_example 381 + data_dir: /custom/data/xdg_example 382 + cache_dir: /custom/cache/xdg_example 383 + state_dir: /custom/state/xdg_example 384 + runtime_dir: <none> 385 + config_dirs: /system/config1/xdg_example:/system/config2/xdg_example 386 + data_dirs: /system/data1/xdg_example:/system/data2/xdg_example 387 + 388 + Test with command-line overrides: 389 + $ export HOME=/home/testuser 390 + $ unset XDG_CONFIG_HOME XDG_DATA_HOME XDG_CACHE_HOME XDG_STATE_HOME XDG_RUNTIME_DIR 391 + $ unset XDG_CONFIG_DIRS XDG_DATA_DIRS 392 + $ ../example/xdg_example.exe --show-paths --config-dir /override/config --data-dir /override/data 393 + config_dir: /override/config 394 + data_dir: /override/data 395 + cache_dir: /home/testuser/.cache/xdg_example 396 + state_dir: /home/testuser/.local/state/xdg_example 397 + runtime_dir: <none> 398 + config_dirs: /etc/xdg/xdg_example 399 + data_dirs: /usr/local/share/xdg_example:/usr/share/xdg_example 400 +