XDG library path support for OCaml via Eio capabilities
linux macos ocaml xdg
at main 4.8 kB view raw
1(*--------------------------------------------------------------------------- 2 Copyright (c) 2025 Anil Madhavapeddy <anil@recoil.org>. All rights reserved. 3 SPDX-License-Identifier: ISC 4 ---------------------------------------------------------------------------*) 5 6let test_path_validation () = 7 Printf.printf "Testing XDG path validation...\n"; 8 (* Test absolute path validation for environment variables *) 9 let test_relative_path_rejection env_var relative_path = 10 Printf.printf "Testing rejection of relative path in %s...\n" env_var; 11 Unix.putenv env_var relative_path; 12 try 13 Eio_main.run @@ fun env -> 14 let _ = Xdge.create env#fs "test_validation" in 15 Printf.printf "ERROR: Should have rejected relative path\n"; 16 false 17 with 18 | Xdge.Invalid_xdg_path msg -> 19 Printf.printf "SUCCESS: Correctly rejected relative path: %s\n" msg; 20 true 21 | exn -> 22 Printf.printf "ERROR: Wrong exception: %s\n" (Printexc.to_string exn); 23 false 24 in 25 let old_config_home = Sys.getenv_opt "XDG_CONFIG_HOME" in 26 let old_data_dirs = Sys.getenv_opt "XDG_DATA_DIRS" in 27 let success1 = 28 test_relative_path_rejection "XDG_CONFIG_HOME" "relative/path" 29 in 30 let success2 = 31 test_relative_path_rejection "XDG_DATA_DIRS" "rel1:rel2:/abs/path" 32 in 33 (* Restore original env vars *) 34 (match old_config_home with 35 | Some v -> Unix.putenv "XDG_CONFIG_HOME" v 36 | None -> ( try Unix.putenv "XDG_CONFIG_HOME" "" with _ -> ())); 37 (match old_data_dirs with 38 | Some v -> Unix.putenv "XDG_DATA_DIRS" v 39 | None -> ( try Unix.putenv "XDG_DATA_DIRS" "" with _ -> ())); 40 success1 && success2 41 42let test_file_search () = 43 Printf.printf "\nTesting XDG file search...\n"; 44 Eio_main.run @@ fun env -> 45 let xdg = Xdge.create env#fs "search_test" in 46 (* Create test files *) 47 let config_file = Eio.Path.(Xdge.config_dir xdg / "test.conf") in 48 let data_file = Eio.Path.(Xdge.data_dir xdg / "test.dat") in 49 Eio.Path.save ~create:(`Or_truncate 0o644) config_file "config content"; 50 Eio.Path.save ~create:(`Or_truncate 0o644) data_file "data content"; 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 (match Xdge.find_data_file xdg "test.dat" with 58 | Some path -> 59 let content = Eio.Path.load path in 60 Printf.printf "Found data file: %s\n" (String.trim content) 61 | None -> Printf.printf "ERROR: Data file not found\n"); 62 (* Test non-existent file *) 63 match Xdge.find_config_file xdg "nonexistent.conf" with 64 | Some _ -> Printf.printf "ERROR: Should not have found nonexistent file\n" 65 | None -> Printf.printf "Correctly handled nonexistent file\n" 66 67let () = 68 (* Check if we should run validation tests *) 69 if Array.length Sys.argv > 1 && Sys.argv.(1) = "--validate" then ( 70 let validation_success = test_path_validation () in 71 test_file_search (); 72 if validation_success then 73 Printf.printf "\nAll path validation tests passed!\n" 74 else Printf.printf "\nSome validation tests failed!\n") 75 else 76 (* Run original simple functionality test *) 77 Eio_main.run @@ fun env -> 78 let xdg = Xdge.create env#fs "path_test" in 79 (* Test config subdirectory *) 80 let profiles_path = Eio.Path.(Xdge.config_dir xdg / "profiles") in 81 let profile_file = Eio.Path.(profiles_path / "default.json") in 82 (try 83 let content = Eio.Path.load profile_file in 84 Printf.printf "config file content: %s" (String.trim content) 85 with exn -> 86 Printf.printf "config file error: %s" (Printexc.to_string exn)); 87 (* Test data subdirectory *) 88 let db_path = Eio.Path.(Xdge.data_dir xdg / "databases") in 89 let db_file = Eio.Path.(db_path / "main.db") in 90 (try 91 let content = Eio.Path.load db_file in 92 Printf.printf "\ndata file content: %s" (String.trim content) 93 with exn -> 94 Printf.printf "\ndata file error: %s" (Printexc.to_string exn)); 95 (* Test cache subdirectory *) 96 let cache_path = Eio.Path.(Xdge.cache_dir xdg / "thumbnails") in 97 let cache_file = Eio.Path.(cache_path / "thumb1.png") in 98 (try 99 let content = Eio.Path.load cache_file in 100 Printf.printf "\ncache file content: %s" (String.trim content) 101 with exn -> 102 Printf.printf "\ncache file error: %s" (Printexc.to_string exn)); 103 (* Test state subdirectory *) 104 let logs_path = Eio.Path.(Xdge.state_dir xdg / "logs") in 105 let log_file = Eio.Path.(logs_path / "app.log") in 106 try 107 let content = Eio.Path.load log_file in 108 Printf.printf "\nstate file content: %s\n" (String.trim content) 109 with exn -> 110 Printf.printf "\nstate file error: %s\n" (Printexc.to_string exn)