csc360-a1-shell/ruby/shell/cli.rb
Sami Samhuri 4f4e97475b
[ruby] Modernize Ruby shell parsing and expansion, add C compat test mode (#4)
Replace Ruby's old wordexp-like command splitting with a tokenizer and
parser that understands ; and && while honoring quotes and nesting.

Implement richer expansions for command substitution, arithmetic,
parameter defaults (${var:-...}), brace expansion, and escaped
dollar/backtick behavior via shared quote-state handling.

Expand the test suite with parser/expansion edge cases, escaping
parity checks, builtin usage validation, and job-control refresh tests.

Keep C green by adding a compat test profile for c/Makefile test and
by returning nonzero on builtin failures in -c mode, including clearer
`bg` usage output.
2026-02-07 15:18:41 -08:00

67 lines
1.5 KiB
Ruby

require "shell/colours"
require "shell/logger"
require "shell/repl"
module Shell
class CLI
include Colours
attr_reader :logger, :options, :repl
def initialize(logger: nil, repl: nil)
@logger = logger || Logger.instance
@options = {}
@repl = repl || REPL.new(logger: @logger)
@repl.precmd_hook = -> { print_logs }
end
def run(args: nil)
@options = parse_options(args || ARGV)
logger.verbose "Options: #{options.inspect}"
if options[:command]
logger.verbose "Executing command: #{options[:command]}"
print_logs
status = repl.process_command(options[:command])
print_logs
exit status
elsif $stdin.isatty
repl.start(options: options)
end
end
def parse_options(args)
options = {
verbose: false
}
while (arg = args.shift)
case arg
when "-c"
options[:command] = args.shift
if options[:command].nil?
warn "ERROR: expected string after -c"
exit 1
end
when "-v", "--verbose"
options[:verbose] = true
else
logger.warn "#{red("[ERROR]")} Unknown argument: #{arg}"
exit 1
end
end
options
end
def print_logs
logger.logs.each do |log|
message = "#{log.message}#{CLEAR}"
case log.level
when :verbose
warn message if options[:verbose]
else
warn message
end
end
logger.clear
end
end
end