Class: Cane::CLI::Parser

Inherits:
Object
  • Object
show all
Defined in:
lib/cane/cli/parser.rb

Overview

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

Defined Under Namespace

Classes: OptionsHandled

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(stdout = $stdout) ⇒ Parser

Returns a new instance of Parser.



22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/cane/cli/parser.rb', line 22

def initialize(stdout = $stdout)
  @stdout = stdout

  add_banner
  add_user_defined_checks

  Cane.default_checks.each do |check|
    add_check_options(check)
  end

  add_cane_options

  add_version
  add_help
end

Instance Attribute Details

#stdoutObject (readonly)

Returns the value of attribute stdout.



155
156
157
# File 'lib/cane/cli/parser.rb', line 155

def stdout
  @stdout
end

Class Method Details

.parse(*args) ⇒ Object



18
19
20
# File 'lib/cane/cli/parser.rb', line 18

def self.parse(*args)
  new.parse(*args)
end

Instance Method Details

#add_bannerObject



58
59
60
61
62
63
64
65
# File 'lib/cane/cli/parser.rb', line 58

def add_banner
  parser.banner = <<-BANNER
Usage: cane [options]

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

BANNER
end

#add_cane_optionsObject



105
106
107
108
109
110
111
112
113
114
# File 'lib/cane/cli/parser.rb', line 105

def add_cane_options
  add_option %w(--max-violations VALUE),
    "Max allowed violations", default: 0, cast: :to_i

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

  parser.separator ""
end

#add_check_options(check) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
# File 'lib/cane/cli/parser.rb', line 82

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_helpObject



123
124
125
126
127
128
# File 'lib/cane/cli/parser.rb', line 123

def add_help
  parser.on_tail("-h", "--help", "Show this message") do
    stdout.puts parser
    raise OptionsHandled
  end
end

#add_option(option, description, opts = {}) ⇒ Object



130
131
132
133
134
135
136
137
138
139
140
141
142
143
# File 'lib/cane/cli/parser.rb', line 130

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_checksObject



67
68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/cane/cli/parser.rb', line 67

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_versionObject



116
117
118
119
120
121
# File 'lib/cane/cli/parser.rb', line 116

def add_version
  parser.on_tail("-v", "--version", "Show version") do
    stdout.puts Cane::VERSION
    raise OptionsHandled
  end
end

#get_default_optionsObject



50
51
52
53
54
55
56
# File 'lib/cane/cli/parser.rb', line 50

def get_default_options
  if Cane::File.exists?('./.cane')
    Cane::File.contents('./.cane').split(/\s+/m)
  else
    []
  end
end

#optionsObject



145
146
147
148
149
# File 'lib/cane/cli/parser.rb', line 145

def options
  @options ||= {
    checks: Cane.default_checks
  }
end

#parse(args, ret = true) ⇒ Object



38
39
40
41
42
43
44
45
46
47
48
# File 'lib/cane/cli/parser.rb', line 38

def parse(args, ret = true)
  parser.parse!(get_default_options + args)

  Cane::CLI.default_options.merge(options)
rescue OptionParser::InvalidOption, OptionParser::AmbiguousOption
  args = %w(--help)
  ret = false
  retry
rescue OptionsHandled
  ret
end

#parserObject



151
152
153
# File 'lib/cane/cli/parser.rb', line 151

def parser
  @parser ||= OptionParser.new
end