Class: Ace::LLM::Atoms::XDGDirectoryResolver
- Inherits:
-
Object
- Object
- Ace::LLM::Atoms::XDGDirectoryResolver
- Defined in:
- lib/ace/llm/atoms/xdg_directory_resolver.rb
Overview
XDGDirectoryResolver provides XDG Base Directory Specification compliant directory resolution for cache and data storage. This atom has no dependencies on other parts of this gem.
Constant Summary collapse
- APP_NAME =
Application name used in directory paths
"ace-llm"- XDG_CACHE_HOME =
Environment variable names
"XDG_CACHE_HOME"- XDG_CONFIG_HOME =
"XDG_CONFIG_HOME"- XDG_DATA_HOME =
"XDG_DATA_HOME"- HOME =
"HOME"- DEFAULT_DIR_PERMISSIONS =
Default directory permissions
0o700
Class Method Summary collapse
-
.cache_directory(env_reader = ENV) ⇒ String
Resolve XDG-compliant cache directory path.
-
.cache_subdirectory(cache_type, env_reader = ENV) ⇒ String
Get cache subdirectory path for specific cache type.
-
.config_directory(env_reader = ENV) ⇒ String
Resolve XDG-compliant config directory path.
-
.data_directory(env_reader = ENV) ⇒ String
Resolve XDG-compliant data directory path.
-
.ensure_cache_subdirectory(cache_type, env_reader = ENV, permissions = DEFAULT_DIR_PERMISSIONS) ⇒ String
Resolve and ensure cache subdirectory exists.
-
.ensure_directory(directory, permissions = DEFAULT_DIR_PERMISSIONS) ⇒ String
Ensure directory exists with proper permissions.
-
.safe_directory_path?(path) ⇒ Boolean
Validate directory path for security.
Instance Method Summary collapse
-
#cache_directory ⇒ String
Instance method to get cache directory.
-
#cache_subdirectory(cache_type) ⇒ String
Instance method to get cache subdirectory.
-
#config_directory ⇒ String
Instance method to get config directory.
-
#data_directory ⇒ String
Instance method to get data directory.
-
#ensure_cache_subdirectory(cache_type, permissions = DEFAULT_DIR_PERMISSIONS) ⇒ String
Instance method to ensure cache subdirectory exists.
-
#ensure_directory(directory, permissions = DEFAULT_DIR_PERMISSIONS) ⇒ String
Instance method to ensure directory exists.
-
#initialize(env_reader = ENV) ⇒ XDGDirectoryResolver
constructor
Instance methods for non-static usage.
Constructor Details
#initialize(env_reader = ENV) ⇒ XDGDirectoryResolver
Instance methods for non-static usage
142 143 144 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 142 def initialize(env_reader = ENV) @env_reader = env_reader end |
Class Method Details
.cache_directory(env_reader = ENV) ⇒ String
Resolve XDG-compliant cache directory path
28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 28 def self.cache_directory(env_reader = ENV) xdg_cache_home = env_reader[XDG_CACHE_HOME] home_dir = env_reader[HOME] # Use XDG_CACHE_HOME if set and non-empty cache_base = if xdg_cache_home && !xdg_cache_home.strip.empty? File.(xdg_cache_home.strip) elsif home_dir && !home_dir.strip.empty? # Fall back to ~/.cache if HOME is available File.(".cache", home_dir.strip) else # Last resort: use current directory File.(".cache") end File.join(cache_base, APP_NAME) end |
.cache_subdirectory(cache_type, env_reader = ENV) ⇒ String
Get cache subdirectory path for specific cache type
102 103 104 105 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 102 def self.cache_subdirectory(cache_type, env_reader = ENV) base_cache_dir = cache_directory(env_reader) File.join(base_cache_dir, cache_type.to_s) end |
.config_directory(env_reader = ENV) ⇒ String
Resolve XDG-compliant config directory path
49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 49 def self.config_directory(env_reader = ENV) xdg_config_home = env_reader[XDG_CONFIG_HOME] home_dir = env_reader[HOME] # Use XDG_CONFIG_HOME if set and non-empty config_base = if xdg_config_home && !xdg_config_home.strip.empty? File.(xdg_config_home.strip) elsif home_dir && !home_dir.strip.empty? # Fall back to ~/.config if HOME is available File.(".config", home_dir.strip) else # Last resort: use current directory File.(".config") end File.join(config_base, APP_NAME) end |
.data_directory(env_reader = ENV) ⇒ String
Resolve XDG-compliant data directory path
70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 70 def self.data_directory(env_reader = ENV) xdg_data_home = env_reader[XDG_DATA_HOME] home_dir = env_reader[HOME] # Use XDG_DATA_HOME if set and non-empty data_base = if xdg_data_home && !xdg_data_home.strip.empty? File.(xdg_data_home.strip) elsif home_dir && !home_dir.strip.empty? # Fall back to ~/.local/share if HOME is available File.(".local/share", home_dir.strip) else # Last resort: use current directory File.(".local/share") end File.join(data_base, APP_NAME) end |
.ensure_cache_subdirectory(cache_type, env_reader = ENV, permissions = DEFAULT_DIR_PERMISSIONS) ⇒ String
Resolve and ensure cache subdirectory exists
112 113 114 115 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 112 def self.ensure_cache_subdirectory(cache_type, env_reader = ENV, = DEFAULT_DIR_PERMISSIONS) subdir_path = cache_subdirectory(cache_type, env_reader) ensure_directory(subdir_path, ) end |
.ensure_directory(directory, permissions = DEFAULT_DIR_PERMISSIONS) ⇒ String
Ensure directory exists with proper permissions
93 94 95 96 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 93 def self.ensure_directory(directory, = DEFAULT_DIR_PERMISSIONS) FileUtils.mkdir_p(directory, mode: ) directory end |
.safe_directory_path?(path) ⇒ Boolean
Validate directory path for security
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 120 def self.safe_directory_path?(path) return false if path.nil? || path.empty? # Reject paths with null bytes (security concern) return false if path.include?("\0") # Reject paths with parent directory traversal attempts return false if path.include?("..") # Must be absolute path after expansion begin = File.(path) pathname = Pathname.new() return false unless pathname.absolute? rescue return false end true end |
Instance Method Details
#cache_directory ⇒ String
Instance method to get cache directory
148 149 150 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 148 def cache_directory self.class.cache_directory(@env_reader) end |
#cache_subdirectory(cache_type) ⇒ String
Instance method to get cache subdirectory
175 176 177 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 175 def cache_subdirectory(cache_type) self.class.cache_subdirectory(cache_type, @env_reader) end |
#config_directory ⇒ String
Instance method to get config directory
154 155 156 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 154 def config_directory self.class.config_directory(@env_reader) end |
#data_directory ⇒ String
Instance method to get data directory
160 161 162 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 160 def data_directory self.class.data_directory(@env_reader) end |
#ensure_cache_subdirectory(cache_type, permissions = DEFAULT_DIR_PERMISSIONS) ⇒ String
Instance method to ensure cache subdirectory exists
183 184 185 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 183 def ensure_cache_subdirectory(cache_type, = DEFAULT_DIR_PERMISSIONS) self.class.ensure_cache_subdirectory(cache_type, @env_reader, ) end |
#ensure_directory(directory, permissions = DEFAULT_DIR_PERMISSIONS) ⇒ String
Instance method to ensure directory exists
168 169 170 |
# File 'lib/ace/llm/atoms/xdg_directory_resolver.rb', line 168 def ensure_directory(directory, = DEFAULT_DIR_PERMISSIONS) self.class.ensure_directory(directory, ) end |