lib/cli/kit/executor.rb in cli-kit-3.0.0.pre vs lib/cli/kit/executor.rb in cli-kit-3.0.0

- old
+ new

@@ -2,85 +2,53 @@ require 'English' module CLI module Kit class Executor - def initialize( - tool_name:, command_registry:, error_handler:, log_file: nil - ) - @tool_name = tool_name - @command_registry = command_registry - @error_handler = error_handler + def initialize(log_file:) @log_file = log_file end + def call(command, command_name, args) + with_traps { with_logging { command.call(args, command_name) } } + end + + private + def with_logging(&block) return yield unless @log_file CLI::UI.log_output_to(@log_file, &block) end - def commands_and_aliases - @command_registry.command_names + @command_registry.aliases.keys - end - - def trap_signals - trap('QUIT') do - z = caller - CLI::UI.raw do - STDERR.puts('SIGQUIT: quit') - STDERR.puts(z) + def with_traps + twrap('QUIT', method(:quit_handler)) do + twrap('INFO', method(:info_handler)) do + yield end - exit 1 end - trap('INFO') do - z = caller - CLI::UI.raw do - STDERR.puts('SIGINFO:') - STDERR.puts(z) - # Thread.list.map { |t| t.backtrace } - end - end end - def call(command, command_name, args) - trap_signals - with_logging do - @error_handler.handle_abort do - if command.nil? - command_not_found(command_name) - raise CLI::Kit::AbortSilent # Already output message - end - command.call(args, command_name) - CLI::Kit::EXIT_SUCCESS # unless an exception was raised - end - end + def twrap(signal, handler) + prev_handler = trap(signal, handler) + yield + ensure + trap(signal, prev_handler) end - def command_not_found(name) - CLI::UI::Frame.open("Command not found", color: :red, timing: false) do - STDERR.puts(CLI::UI.fmt("{{command:#{@tool_name} #{name}}} was not found")) + def quit_handler(_sig) + z = caller + CLI::UI.raw do + $stderr.puts('SIGQUIT: quit') + $stderr.puts(z) end + exit(CLI::Kit::EXIT_FAILURE_BUT_NOT_BUG) + end - cmds = commands_and_aliases - if cmds.all? { |cmd| cmd.is_a?(String) } - possible_matches = cmds.min_by(2) do |cmd| - CLI::Kit::Levenshtein.distance(cmd, name) - end - - # We don't want to match against any possible command - # so reject anything that is too far away - possible_matches.reject! do |possible_match| - CLI::Kit::Levenshtein.distance(possible_match, name) > 3 - end - - # If we have any matches left, tell the user - if possible_matches.any? - CLI::UI::Frame.open("{{bold:Did you mean?}}", timing: false, color: :blue) do - possible_matches.each do |possible_match| - STDERR.puts CLI::UI.fmt("{{command:#{@tool_name} #{possible_match}}}") - end - end - end + def info_handler(_sig) + z = caller + CLI::UI.raw do + $stderr.puts('SIGINFO:') + $stderr.puts(z) end end end end end