module Travis::CLI

def command(name)

def command(name)
  const_name = command_name(name)
  constant   = CLI.const_get(const_name) if const_name =~ (/^[A-Z][A-Za-z]+$/) && const_defined?(const_name)
  if command? constant
    constant
  else
    warn "unknown command #{name}"
    exit 1
  end
end

def command?(constant)

def command?(constant)
  constant.is_a? Class and constant < Command and !constant.abstract?
end

def command_name(name)

def command_name(name)
  case name
  when nil, '-h', '-?' then 'Help'
  when '-v'            then 'Version'
  when /^--/           then command_name(name[2..])
  else name.split('-').map(&:capitalize).join
  end
end

def commands

def commands
  CLI.constants.map { |n| try_const_get(n) }.select { |c| command? c }
end

def dummy_io

def dummy_io
  return StringIO.new unless defined? IO::NULL && IO::NULL
  File.open(IO::NULL, 'w')
end

def preparse(unparsed, args = [], opts = {})

can't use flatten as it will flatten hashes
def preparse(unparsed, args = [], opts = {})
  case unparsed
  when Hash  then opts.merge! unparsed
  when Array then unparsed.each { |e| preparse(e, args, opts) }
  else args << unparsed.to_s
  end
  [args, opts]
end

def run(*args)

def run(*args)
  args, opts = preparse(args)
  name       = args.shift unless args.empty?
  command    = command(name).new(opts)
  command.parse(args)
  command.execute
end

def silent

def silent
  stderr = $stderr
  $stderr = dummy_io
  stdout = $stdout
  $stdout = dummy_io
  yield
ensure
  $stderr = stderr if stderr
  $stdout = stdout if stdout
end

def try_const_get(name)

def try_const_get(name)
  CLI.const_get(name)
rescue Exception
end