Module: Ukiryu::Shell
- Defined in:
- lib/ukiryu/shell.rb,
lib/ukiryu/shell/sh.rb,
lib/ukiryu/shell/cmd.rb,
lib/ukiryu/shell/zsh.rb,
lib/ukiryu/shell/base.rb,
lib/ukiryu/shell/bash.rb,
lib/ukiryu/shell/dash.rb,
lib/ukiryu/shell/fish.rb,
lib/ukiryu/shell/tcsh.rb,
lib/ukiryu/shell/registry.rb,
lib/ukiryu/shell/unix_base.rb,
lib/ukiryu/shell/powershell.rb,
lib/ukiryu/shell/instance_cache.rb
Overview
Shell detection and management
Provides EXPLICIT shell detection with no fallbacks. If shell cannot be determined, raises a clear error.
Shell types are grouped by platform compatibility:
-
‘unix` - All Unix-like shells (bash, zsh, fish, sh, dash, tcsh, ash, csh, ksh, + future shells)
-
‘windows` - cmd.exe only
-
‘powershell` - PowerShell Core on all platforms
Individual shell names are still supported for backward compatibility and are mapped to their appropriate platform group.
Defined Under Namespace
Classes: Base, Bash, Cmd, Dash, Fish, InstanceCache, PowerShell, Registry, Sh, Tcsh, UnixBase, Zsh
Constant Summary collapse
- PLATFORM_GROUPS =
Platform-grouped shell types (new schema v1)
%i[unix windows powershell].freeze
- INDIVIDUAL_SHELLS =
Individual shell types (backward compatibility)
%i[bash zsh fish sh dash tcsh powershell cmd].freeze
- VALID_SHELLS =
All valid shell types (platform groups + individual shells for backward compatibility)
(PLATFORM_GROUPS + INDIVIDUAL_SHELLS).freeze
- SHELL_TO_PLATFORM =
Map individual shells to their platform groups
{ bash: :unix, zsh: :unix, fish: :unix, sh: :unix, dash: :unix, tcsh: :unix, # ash, csh, ksh, nushell, elvish, etc. would also map to :unix powershell: :powershell, pwsh: :powershell, cmd: :windows }.freeze
- PLATFORM_TO_SHELLS =
Reverse map: platform groups to individual shells
{ unix: %i[bash zsh fish sh dash tcsh], windows: %i[cmd], powershell: %i[powershell pwsh] }.freeze
Class Attribute Summary collapse
-
.current_shell ⇒ Object
writeonly
Get or set the current shell (for explicit configuration).
Class Method Summary collapse
-
.all_valid ⇒ Array<Symbol>
Get list of all valid shells (platform groups + individual shells).
-
.available?(shell_sym) ⇒ Boolean
Check if a shell is available on the system.
-
.available_shells ⇒ Array<Symbol>
Get all shells available on the current system.
-
.class_for(name) ⇒ Class
Get shell class by name or platform group.
-
.detect ⇒ Symbol
Detect the current shell.
-
.executable_path(shell_sym) ⇒ String
Get shell executable path for the given shell name.
-
.from_string(str) ⇒ Symbol
Convert string to shell symbol or platform group.
-
.platform_group_for(shell_sym) ⇒ Symbol
Get the platform group for a given shell.
-
.register(name, shell_class) ⇒ Object
Register a custom shell class.
-
.reset ⇒ Object
private
Reset cached shell detection (mainly for testing).
-
.shell_class ⇒ Shell::Base
Get the shell class for the detected/configured shell.
-
.valid?(shell_sym) ⇒ Boolean
Check if a shell symbol is valid.
-
.valid_for_platform ⇒ Array<Symbol>
Get shells valid for current platform (returns platform groups).
Class Attribute Details
.current_shell=(value) ⇒ Object (writeonly)
Get or set the current shell (for explicit configuration)
103 104 105 |
# File 'lib/ukiryu/shell.rb', line 103 def current_shell=(value) @current_shell = value end |
Class Method Details
.all_valid ⇒ Array<Symbol>
Get list of all valid shells (platform groups + individual shells)
116 117 118 |
# File 'lib/ukiryu/shell.rb', line 116 def all_valid VALID_SHELLS.dup end |
.available?(shell_sym) ⇒ Boolean
Check if a shell is available on the system
194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 |
# File 'lib/ukiryu/shell.rb', line 194 def available?(shell_sym) # Platform groups return unix_shell_available? if shell_sym == :unix return powershell_available? if shell_sym == :powershell return Platform.windows? if shell_sym == :windows # Individual shells (backward compatibility) return false unless valid?(shell_sym) case shell_sym when :bash shell_available_on_unix?('bash') || bash_available_on_windows? when :zsh shell_available_on_unix?('zsh') when :fish shell_available_on_unix?('fish') when :sh shell_available_on_unix?('sh') when :dash shell_available_on_unix?('dash') when :tcsh shell_available_on_unix?('tcsh') when :pwsh powershell_available? else false end end |
.available_shells ⇒ Array<Symbol>
Get all shells available on the current system
226 227 228 |
# File 'lib/ukiryu/shell.rb', line 226 def available_shells VALID_SHELLS.select { |shell| available?(shell) } end |
.class_for(name) ⇒ Class
Get shell class by name or platform group
For platform groups, returns the most appropriate shell class:
-
:unix → Bash (most common Unix shell)
-
:windows → Cmd
-
:powershell → PowerShell
278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 |
# File 'lib/ukiryu/shell.rb', line 278 def class_for(name) # Check registry first (for custom shells) registered = Registry.lookup(name) return registered if registered # Built-in shells case name when :unix Bash # Most common Unix shell, all Unix shells share the same quoting rules when :windows Cmd when :powershell PowerShell when :bash Bash when :zsh Zsh when :fish Fish when :sh Sh when :dash Dash when :tcsh Tcsh when :pwsh PowerShell when :cmd Cmd else raise Ukiryu::Errors::UnknownShellError, "Unknown shell: #{name}" end end |
.detect ⇒ Symbol
Detect the current shell
234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 |
# File 'lib/ukiryu/shell.rb', line 234 def detect # Return explicitly configured shell if set return @current_shell if @current_shell # Check for test environment override (for CI testing with specific shells) test_shell = ENV['UKIRYU_TEST_SHELL'] return test_shell.to_sym if test_shell && valid?(test_shell.to_sym) # Detect based on platform and environment if Platform.windows? detect_windows_shell else detect_unix_shell end end |
.executable_path(shell_sym) ⇒ String
Get shell executable path for the given shell name
152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/ukiryu/shell.rb', line 152 def executable_path(shell_sym) return nil unless valid?(shell_sym) case shell_sym when :bash '/bin/bash' when :zsh '/bin/zsh' when :fish '/usr/bin/fish' when :sh '/bin/sh' when :dash '/bin/dash' when :tcsh '/bin/tcsh' when :powershell 'pwsh' # PowerShell Core when :cmd 'cmd' else raise ArgumentError, "Unknown shell: #{shell_sym}" end end |
.from_string(str) ⇒ Symbol
Convert string to shell symbol or platform group
182 183 184 185 186 187 188 |
# File 'lib/ukiryu/shell.rb', line 182 def from_string(str) shell_sym = str.to_s.downcase.to_sym return shell_sym if valid?(shell_sym) raise ArgumentError, "Invalid shell: #{str}. Valid: platform groups (#{PLATFORM_GROUPS.join(', ')}) or individual shells (#{INDIVIDUAL_SHELLS.join(', ')})" end |
.platform_group_for(shell_sym) ⇒ Symbol
Get the platform group for a given shell
136 137 138 139 140 141 142 143 144 145 |
# File 'lib/ukiryu/shell.rb', line 136 def platform_group_for(shell_sym) return shell_sym if PLATFORM_GROUPS.include?(shell_sym) unless SHELL_TO_PLATFORM.key?(shell_sym) raise ArgumentError, "Unknown shell: #{shell_sym}. Valid shells: #{VALID_SHELLS.join(', ')}" end SHELL_TO_PLATFORM[shell_sym] end |
.register(name, shell_class) ⇒ Object
Register a custom shell class
317 318 319 |
# File 'lib/ukiryu/shell.rb', line 317 def register(name, shell_class) Registry.register(name, shell_class) end |
.reset ⇒ Object
This method is part of a private API. You should avoid using this method if possible, as it may be removed or be changed in the future.
Reset cached shell detection (mainly for testing)
263 264 265 266 |
# File 'lib/ukiryu/shell.rb', line 263 def reset @current_shell = nil @shell_class = nil end |
.shell_class ⇒ Shell::Base
Get the shell class for the detected/configured shell
253 254 255 256 257 258 |
# File 'lib/ukiryu/shell.rb', line 253 def shell_class @shell_class ||= begin shell_name = detect class_for(shell_name) end end |
.valid?(shell_sym) ⇒ Boolean
Check if a shell symbol is valid
109 110 111 |
# File 'lib/ukiryu/shell.rb', line 109 def valid?(shell_sym) VALID_SHELLS.include?(shell_sym&.to_sym) end |
.valid_for_platform ⇒ Array<Symbol>
Get shells valid for current platform (returns platform groups)
123 124 125 126 127 128 129 |
# File 'lib/ukiryu/shell.rb', line 123 def valid_for_platform if Platform.windows? %i[windows powershell unix] # Windows can run all three types else %i[unix powershell] # Unix can run Unix shells and PowerShell Core end end |