Class: Simple::CLI::Runner
- Inherits:
-
Object
- Object
- Simple::CLI::Runner
show all
- Includes:
- Autocompletion
- Defined in:
- lib/simple/cli/runner.rb,
lib/simple/cli/runner.rb
Overview
A Runner object manages running a CLI application module with a set of string arguments (usually taken from ARGV)
Defined Under Namespace
Modules: Autocompletion
Classes: CommandHelp
Constant Summary
Autocompletion::AUTOCOMPLETE_SHELL_CODE, Autocompletion::CommandHelp, Autocompletion::DEFAULT_OPTIONS
Instance Attribute Summary collapse
Class Method Summary
collapse
Instance Method Summary
collapse
#autocomplete, #autocomplete_bash, #autocomplete_help, #autocomplete_subcommand_options, #autocomplete_subcommands, #completions, #filter_completions
Constructor Details
#initialize(app) ⇒ Runner
Returns a new instance of Runner.
22
23
24
|
# File 'lib/simple/cli/runner.rb', line 22
def initialize(app)
@app = app
end
|
Instance Attribute Details
#subcommand ⇒ Object
Returns the value of attribute subcommand.
35
36
37
|
# File 'lib/simple/cli/runner.rb', line 35
def subcommand
@subcommand
end
|
Class Method Details
.run(app, *args) ⇒ Object
18
19
20
|
# File 'lib/simple/cli/runner.rb', line 18
def self.run(app, *args)
new(app).run(*args)
end
|
Instance Method Details
#args_with_options(args) ⇒ Object
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
# File 'lib/simple/cli/runner.rb', line 107
def args_with_options(args)
r = []
options = {}
while (arg = args.shift)
case arg
when /^--(.*)=(.*)/ then options[$1.to_sym] = $2
when /^--no-(.*)/ then options[$1.to_sym] = false
when /^--(.*)/ then options[$1.to_sym] = true
else r << arg
end
end
r << options unless options.empty?
r
end
|
#binary_name ⇒ Object
145
146
147
|
# File 'lib/simple/cli/runner.rb', line 145
def binary_name
$0.gsub(/.*\//, "")
end
|
#command_to_string(sym) ⇒ Object
123
124
125
|
# File 'lib/simple/cli/runner.rb', line 123
def command_to_string(sym)
sym.to_s.tr("_", ":")
end
|
#commands ⇒ Object
131
132
133
|
# File 'lib/simple/cli/runner.rb', line 131
def commands
@app.public_instance_methods(false).grep(/^[_a-zA-Z0-9]+$/)
end
|
#do_help!(subcommand = nil) ⇒ Object
60
61
62
63
64
65
66
|
# File 'lib/simple/cli/runner.rb', line 60
def do_help!(subcommand = nil)
if !subcommand
help!
else
help_subcommand!(subcommand)
end
end
|
26
27
28
29
30
31
32
33
|
# File 'lib/simple/cli/runner.rb', line 26
def (args)
args.reject! do |arg|
case arg
when "--verbose", "-v" then logger.level = Logger::DEBUG
when "--quiet", "-q" then logger.level = Logger::WARN
end
end
end
|
#help! ⇒ Object
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
|
# File 'lib/simple/cli/runner.rb', line 149
def help!
command_helps = commands.inject({}) do |hsh, sym|
edoc = CommandHelp.new(@app, sym)
next hsh if !edoc.head && logger.level != ::Logger::DEBUG
hsh.update sym => help_for_command(sym)
end
max_length = command_helps.values.map(&:length).max
print_help_line = lambda do |cmd, description|
if description
STDERR.puts format(" %-#{max_length}s # %s", cmd, description)
else
STDERR.puts format(" %-#{max_length}s", cmd)
end
end
STDERR.puts "Usage:\n\n"
command_helps.keys.sort.each do |sym|
command_help = command_helps[sym]
edoc = CommandHelp.new(@app, sym)
print_help_line.call command_help, edoc.head
end
STDERR.puts "\n Default options include:\n\n DOC\n\n print_help_line.call \"\#{binary_name} [ --verbose | -v ]\", \"run on DEBUG log level\"\n print_help_line.call \"\#{binary_name} [ --quiet | -q ]\", \"run on WARN log level\"\n\n STDERR.puts <<~DOC\n\n Other commands:\n\n DOC\n\n print_help_line.call \"\#{binary_name} help [ subcommand ]\", \"print help on a specific subcommand\"\n print_help_line.call \"\#{binary_name} help -v\", \"show help for internal commands as well\"\n print_help_line.call \"\#{binary_name} help autocomplete\", \"print information on autocompletion.\"\n\n STDERR.puts \"\\n\"\n\n exit 1\nend\n"
|
#help_for_command(sym) ⇒ Object
135
136
137
138
139
140
141
142
143
|
# File 'lib/simple/cli/runner.rb', line 135
def help_for_command(sym)
if sym == "autocomplete"
autocomplete_help
return
end
cmd = string_to_command(sym)
CommandHelp.new(@app, cmd).interface(binary_name, cmd)
end
|
#help_subcommand!(subcommand) ⇒ Object
68
69
70
71
72
73
74
75
76
77
78
|
# File 'lib/simple/cli/runner.rb', line 68
def help_subcommand!(subcommand)
edoc = CommandHelp.new(@app, string_to_command(subcommand))
puts " \#{help_for_command(subcommand)}\n\n \#{edoc.full}\n MSG\n\n exit 1\nend\n"
|
#logger ⇒ Object
80
81
82
|
# File 'lib/simple/cli/runner.rb', line 80
def logger
Simple::CLI.logger
end
|
#on_exception(e) ⇒ Object
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
# File 'lib/simple/cli/runner.rb', line 84
def on_exception(e)
raise(e) if Simple::CLI.logger.level == Logger::DEBUG
verbosity_hint = "Backtraces are currently silenced. Run with --verbose to see backtraces."
case e
when ArgumentError
logger.error e.message
logger.warn verbosity_hint
if subcommand
help_subcommand! subcommand
else
help!
end
else
msg = e.message
msg += " (#{e.class.name})" unless $!.class.name == "RuntimeError"
logger.error msg
logger.warn verbosity_hint
exit 2
end
end
|
#run(*args) ⇒ Object
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
|
# File 'lib/simple/cli/runner.rb', line 37
def run(*args)
(args)
@instance = Object.new.extend(@app)
command_name = args.shift || help!
command = string_to_command(command_name)
if command == :help
do_help!(*args)
elsif command == :autocomplete
autocomplete(*args)
elsif command == :autocomplete_bash
autocomplete_bash(*args)
elsif commands.include?(command)
self.subcommand = command
@instance.run! command, *args_with_options(args)
else
help!
end
rescue StandardError => e
on_exception(e)
end
|
#string_to_command(s) ⇒ Object
127
128
129
|
# File 'lib/simple/cli/runner.rb', line 127
def string_to_command(s)
s.to_s.tr(":", "_").to_sym
end
|