Class: Ukiryu::Environment
- Inherits:
-
Object
- Object
- Ukiryu::Environment
- Defined in:
- lib/ukiryu/environment.rb
Overview
Environment represents a set of environment variables for command execution.
This class provides an immutable, functional-style interface for managing environment variables. All write operations return a new Environment instance, preserving the original.
Usage
Create from various sources:
env = Environment.system # Empty environment
env = Environment.from_env # Inherit current process ENV
env = Environment.new({ 'PATH' => '...' }) # From hash
Manipulate immutably:
new_env = env.set('VAR', 'value')
new_env = env.delete('VAR')
new_env = env.merge(other_env)
PATH utilities (Unix-style colon separator):
new_env = env.prepend_path('/new/bin')
new_env = env.append_path('/new/bin')
new_env = env.remove_path('/old/bin')
Convert to hash for execution:
hash = env.to_h
Constant Summary collapse
- SEPARATOR =
':'
Class Method Summary collapse
-
.from_env ⇒ Environment
Create an environment that inherits from the current process ENV.
-
.system ⇒ Environment
Create an empty environment (no inherited variables).
Instance Method Summary collapse
-
#==(other) ⇒ Boolean
Equality check.
-
#[](key) ⇒ String?
Get a value from the environment.
-
#append_path(additions) ⇒ Environment
Append one or more directories to PATH.
-
#delete(key) ⇒ Environment
Delete a variable.
-
#hash ⇒ Integer
Hash representation for hashing (e.g., use in Hash as key).
-
#initialize(env = {}) ⇒ Environment
constructor
Create a new Environment instance.
-
#inspect ⇒ String
String representation for debugging.
-
#key?(key) ⇒ Boolean
Check if a key exists in the environment.
-
#keys ⇒ Array<String>
Get all keys in the environment.
-
#merge(other) ⇒ Environment
Merge another environment or hash.
-
#path_array ⇒ Array<String>
Get the PATH as an array.
-
#path_contains?(directory) ⇒ Boolean
Check if PATH contains a directory.
-
#prepend_path(additions) ⇒ Environment
Prepend one or more directories to PATH.
-
#remove_path(directory) ⇒ Environment
Remove a directory from PATH.
-
#set(key, value) ⇒ Environment
Set or update a variable.
-
#to_h ⇒ Hash{String => String}
Convert to a plain hash (for execution).
Constructor Details
#initialize(env = {}) ⇒ Environment
Create a new Environment instance
37 38 39 |
# File 'lib/ukiryu/environment.rb', line 37 def initialize(env = {}) @env = env.dup.freeze end |
Class Method Details
.from_env ⇒ Environment
Create an environment that inherits from the current process ENV
51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 |
# File 'lib/ukiryu/environment.rb', line 51 def self.from_env # On Windows, ENV.to_h might not include PATH due to case sensitivity # issues. Ensure PATH is always included by explicitly checking for it. env_hash = ENV.to_h.dup # Ensure PATH is included (check case-insensitively on Windows) unless env_hash.key?('PATH') # Look for Path, path, etc. on Windows ENV.each_key do |key| if key.upcase == 'PATH' env_hash['PATH'] = ENV[key] break end end end new(env_hash) end |
.system ⇒ Environment
Create an empty environment (no inherited variables)
44 45 46 |
# File 'lib/ukiryu/environment.rb', line 44 def self.system new({}) end |
Instance Method Details
#==(other) ⇒ Boolean
Equality check
198 199 200 201 202 |
# File 'lib/ukiryu/environment.rb', line 198 def ==(other) return false unless other.is_a?(Environment) @env == other.instance_variable_get(:@env) end |
#[](key) ⇒ String?
Get a value from the environment
74 75 76 |
# File 'lib/ukiryu/environment.rb', line 74 def [](key) @env[key.to_s] end |
#append_path(additions) ⇒ Environment
Append one or more directories to PATH
Handles Unix-style colon-separated PATH. Directories are added to the end of PATH, so existing directories take precedence.
150 151 152 153 154 155 156 |
# File 'lib/ukiryu/environment.rb', line 150 def append_path(additions) additions_arr = Array(additions) additions_str = additions_arr.join(SEPARATOR) existing = @env['PATH'] || '' new_path = existing.empty? ? additions_str : "#{existing}#{SEPARATOR}#{additions_str}" self.class.new(@env.merge('PATH' => new_path)) end |
#delete(key) ⇒ Environment
Delete a variable
113 114 115 116 117 |
# File 'lib/ukiryu/environment.rb', line 113 def delete(key) new_env = @env.dup new_env.delete(key.to_s) self.class.new(new_env) end |
#hash ⇒ Integer
Hash representation for hashing (e.g., use in Hash as key)
214 215 216 |
# File 'lib/ukiryu/environment.rb', line 214 def hash @env.hash end |
#inspect ⇒ String
String representation for debugging
207 208 209 |
# File 'lib/ukiryu/environment.rb', line 207 def inspect "#<Ukiryu::Environment keys=#{@env.keys.size}>" end |
#key?(key) ⇒ Boolean
Check if a key exists in the environment
82 83 84 |
# File 'lib/ukiryu/environment.rb', line 82 def key?(key) @env.key?(key.to_s) end |
#keys ⇒ Array<String>
Get all keys in the environment
89 90 91 |
# File 'lib/ukiryu/environment.rb', line 89 def keys @env.keys end |
#merge(other) ⇒ Environment
Merge another environment or hash
123 124 125 126 |
# File 'lib/ukiryu/environment.rb', line 123 def merge(other) other_hash = other.is_a?(Environment) ? other.to_h : other self.class.new(@env.merge(other_hash)) end |
#path_array ⇒ Array<String>
Get the PATH as an array
190 191 192 |
# File 'lib/ukiryu/environment.rb', line 190 def path_array (@env['PATH'] || '').split(SEPARATOR) end |
#path_contains?(directory) ⇒ Boolean
Check if PATH contains a directory
181 182 183 184 185 |
# File 'lib/ukiryu/environment.rb', line 181 def path_contains?(directory) return false unless @env['PATH'] @env['PATH'].split(SEPARATOR).include?(directory) end |
#prepend_path(additions) ⇒ Environment
Prepend one or more directories to PATH
Handles Unix-style colon-separated PATH. Directories are added to the beginning of PATH, so they are searched first.
135 136 137 138 139 140 141 |
# File 'lib/ukiryu/environment.rb', line 135 def prepend_path(additions) additions_arr = Array(additions) additions_str = additions_arr.join(SEPARATOR) existing = @env['PATH'] || '' new_path = existing.empty? ? additions_str : "#{additions_str}#{SEPARATOR}#{existing}" self.class.new(@env.merge('PATH' => new_path)) end |
#remove_path(directory) ⇒ Environment
Remove a directory from PATH
Removes all occurrences of the specified directory from PATH. Uses prefix matching to handle cases like removing ‘/opt’ which should also remove ‘/opt/bin’, ‘/opt/local/bin’, etc.
166 167 168 169 170 171 172 173 174 175 |
# File 'lib/ukiryu/environment.rb', line 166 def remove_path(directory) existing = @env['PATH'] || '' # Remove trailing slash for consistent comparison dir = directory.end_with?('/') ? directory[0..-2] : directory path_parts = existing.split(SEPARATOR).reject do |part| part == dir || part.start_with?("#{dir}/") end new_path = path_parts.join(SEPARATOR) self.class.new(@env.merge('PATH' => new_path)) end |
#set(key, value) ⇒ Environment
Set or update a variable
105 106 107 |
# File 'lib/ukiryu/environment.rb', line 105 def set(key, value) self.class.new(@env.merge(key.to_s => value.to_s)) end |
#to_h ⇒ Hash{String => String}
Convert to a plain hash (for execution)
96 97 98 |
# File 'lib/ukiryu/environment.rb', line 96 def to_h @env.dup end |