class SugarCane::CLI::Parser

Provides a specification for the command line interface that drives documentation, parsing, and default values.

Attributes

stdout[R]

Public Class Methods

new(stdout = $stdout) click to toggle source
# File lib/sugarcane/cli/parser.rb, line 21
def initialize(stdout = $stdout)
  @stdout = stdout

  add_banner
  add_user_defined_checks

  SugarCane.default_checks.each do |check|
    add_check_options(check)
  end
  add_checks_shortcut

  add_cane_options

  add_version
  add_help
end
parse(*args) click to toggle source
# File lib/sugarcane/cli/parser.rb, line 17
def self.parse(*args)
  new.parse(*args)
end

Public Instance Methods

add_banner() click to toggle source
# File lib/sugarcane/cli/parser.rb, line 68
      def add_banner
        parser.banner = <<-BANNER
Usage: sugarcane [options]

Default options are loaded from a .sugarcane file in the current directory.

BANNER
      end
add_cane_options() click to toggle source
# File lib/sugarcane/cli/parser.rb, line 115
def add_cane_options
  add_option %w(--max-violations VALUE),
    "Max allowed violations", default: 0, cast: :to_i

  add_option %w(--editor PROGRAM), "Text editor to use", default: nil

  add_option %w(--json),
    "output as json", default: false

  add_option %w(--report),
    "output a report", default: false

  add_option %w(--parallel),
    "Use all processors. Slower on small projects, faster on large.",
      cast: ->(x) { x }

  add_option %w(--color),
    "Colorize output", default: false

  parser.separator ""
end
add_check_options(check) click to toggle source
# File lib/sugarcane/cli/parser.rb, line 92
def add_check_options(check)
  check.options.each do |key, data|
    cli_key  = key.to_s.tr('_', '-')
    opts     = data[1] || {}
    variable = opts[:variable] || "VALUE"
    defaults = opts[:default] || []

    if opts[:type] == Array
      parser.on("--#{cli_key} #{variable}", Array, data[0]) do |opts|
        (options[key.to_sym] ||= []) << opts
      end
    else
      if [*defaults].length > 0
        add_option ["--#{cli_key}", variable], *data
      else
        add_option ["--#{cli_key}"], *data
      end
    end
  end

  parser.separator ""
end
add_checks_shortcut() click to toggle source
# File lib/sugarcane/cli/parser.rb, line 137
def add_checks_shortcut
  description = "Apply all checks to given file"
  parser.on("-f", "--all FILE", description) do |f|
    # This is a bit of a hack, but provides a really useful UI for
    # dealing with single files. Let's see how it evolves.
    options[:abc_glob] = f
    options[:style_glob] = f
    options[:doc_glob] = f
  end
end
add_help() click to toggle source
# File lib/sugarcane/cli/parser.rb, line 155
def add_help
  parser.on_tail("-h", "--help", "Show this message") do
    stdout.puts parser
    raise OptionsHandled
  end
end
add_option(option, description, opts={}) click to toggle source
# File lib/sugarcane/cli/parser.rb, line 162
def add_option(option, description, opts={})
  option_key = option[0].gsub('--', '').tr('-', '_').to_sym
  default    = opts[:default]
  cast       = opts[:cast] || ->(x) { x }

  if default
    description += " (default: %s)" % default
  end

  parser.on(option.join(' '), description) do |v|
    options[option_key] = cast.to_proc.call(v)
    options.delete(opts[:clobber])
  end
end
add_user_defined_checks() click to toggle source
# File lib/sugarcane/cli/parser.rb, line 77
def add_user_defined_checks
  description = "Load a Ruby file containing user-defined checks"
  parser.on("-r", "--require FILE", description) do |f|
    load(f)
  end

  description = "Use the given user-defined check"
  parser.on("-c", "--check CLASS", description) do |c|
    check = Kernel.const_get(c)
    options[:checks] << check
    add_check_options(check)
  end
  parser.separator ""
end
add_version() click to toggle source
# File lib/sugarcane/cli/parser.rb, line 148
def add_version
  parser.on_tail("-v", "--version", "Show version") do
    stdout.puts SugarCane::VERSION
    raise OptionsHandled
  end
end
get_default_options() click to toggle source
# File lib/sugarcane/cli/parser.rb, line 49
def get_default_options
  # Right now, read_options_from_file can't just be called on
  # both because if the second one doesn't exist the defaults for
  # non-existent values will override what's already read
  if SugarCane::File.exists? './.sugarcane'
    read_options_from_file './.sugarcane'
  else
    read_options_from_file './.cane'
  end
end
options() click to toggle source
# File lib/sugarcane/cli/parser.rb, line 177
def options
  @options ||= {
    checks: SugarCane.default_checks
  }
end
parse(args, ret = true) click to toggle source
# File lib/sugarcane/cli/parser.rb, line 38
def parse(args, ret = true)
  parser.parse!(get_default_options + args)
  SugarCane::CLI.default_options.merge(options)
rescue OptionParser::InvalidOption, OptionParser::AmbiguousOption
  args = %w(--help)
  ret = false
  retry
rescue OptionsHandled
  ret
end
parser() click to toggle source
# File lib/sugarcane/cli/parser.rb, line 183
def parser
  @parser ||= OptionParser.new
end
read_options_from_file(file) click to toggle source
# File lib/sugarcane/cli/parser.rb, line 60
def read_options_from_file(file)
  if SugarCane::File.exists?(file)
    SugarCane::File.contents(file).split(/\s+/m)
  else
    []
  end
end