console_runner 0.1.9 → 0.1.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/lib/command_line_parser.rb +54 -0
- data/lib/console_runner.rb +3 -12
- data/lib/console_runner/version.rb +1 -1
- data/lib/method_parser.rb +76 -12
- metadata +3 -3
- data/lib/trollop_configurator.rb +0 -124
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 0061346daf03362eaa69986cb0333cbe5870e51d
|
4
|
+
data.tar.gz: e7ca879f56d7db7f1a6906975f120099447f59e3
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 900719815c752294a4face86d98397987450059710c6711dfee63bef07d9565a859d7e7e390555f42da111cbb07ffd4f7cfcc245989a4d22e4aadb845594a4b8
|
7
|
+
data.tar.gz: 478defb882bc32bf378a682413821399612070c831f8eb83b85c5a839448b59aa340056e3f3a31a06656d079ebae87bc83f51cc6226edc51e85cf4b51e7a0108
|
data/README.md
CHANGED
@@ -63,7 +63,7 @@ Or install it yourself as:
|
|
63
63
|
$ gem install console_runner
|
64
64
|
|
65
65
|
## FAQ
|
66
|
-
|
66
|
+
#### **Can I add documentation for my tool and customize help page content?**
|
67
67
|
Yes. Any text placed after `@runnable` tag will be displayed on the help page. You can add any additional information about how to use your tool there.
|
68
68
|
> **Tip**: You can use multi-line text as well
|
69
69
|
|
@@ -0,0 +1,54 @@
|
|
1
|
+
require 'trollop'
|
2
|
+
require 'method_parser'
|
3
|
+
|
4
|
+
# Parses command line and configure #Trollop
|
5
|
+
class CommandLineParser
|
6
|
+
attr_reader :method, :init_method
|
7
|
+
|
8
|
+
# Generate tool help menu.
|
9
|
+
# IMPORTANT! Should be executed before ARGV.shift
|
10
|
+
def initialize(file_parser)
|
11
|
+
@file_parser = file_parser
|
12
|
+
@sub_commands = @file_parser.runnable_methods.map { |m| m.name.to_s }
|
13
|
+
@parser = Trollop::Parser.new
|
14
|
+
@parser.banner(FileParser.select_runnable_tags(@file_parser.clazz).map { |t| (t.text + "\n") }.join("\n"))
|
15
|
+
@parser.stop_on @sub_commands
|
16
|
+
end
|
17
|
+
|
18
|
+
def run(action)
|
19
|
+
if %w(-h --help).include?(ARGV[0].strip)
|
20
|
+
Trollop::with_standard_exception_handling(@parser) { raise Trollop::HelpNeeded }
|
21
|
+
end
|
22
|
+
unless @sub_commands.include?(ARGV[0].strip)
|
23
|
+
raise ConsoleRunnerError, "You must provide one of available actions: #{@sub_commands.join ', '}"
|
24
|
+
end
|
25
|
+
|
26
|
+
@init_method = nil
|
27
|
+
@init_method = MethodParser.new(@file_parser.initialize_method) if @file_parser.initialize_method
|
28
|
+
@method = MethodParser.new action
|
29
|
+
[@init_method, @method].each do |method|
|
30
|
+
next unless method
|
31
|
+
method.trollop_opts.each { |a| @parser.opt(*a) }
|
32
|
+
cmd_opts = Trollop::with_standard_exception_handling @parser do
|
33
|
+
unless method.parameters.count.zero?
|
34
|
+
raise Trollop::HelpNeeded if ARGV.empty?
|
35
|
+
end
|
36
|
+
@parser.parse ARGV
|
37
|
+
end
|
38
|
+
given_attrs = cmd_opts.keys.select { |k| k.to_s.include? '_given' }.map { |k| k.to_s.gsub('_given', '').to_sym }
|
39
|
+
method.cmd_opts = cmd_opts.select { |k, _| given_attrs.include? k }
|
40
|
+
method.default_values.each do |k, v|
|
41
|
+
method.cmd_opts[k.to_sym] ||= v
|
42
|
+
end
|
43
|
+
method.required_parameters.each do |required_param|
|
44
|
+
next if method.options_group? required_param
|
45
|
+
unless method.cmd_opts[required_param.to_sym]
|
46
|
+
raise ConsoleRunnerError, "You must specify required parameter: #{required_param}"
|
47
|
+
end
|
48
|
+
end
|
49
|
+
ARGV.shift
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
data/lib/console_runner.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
require 'file_parser'
|
2
|
-
require '
|
2
|
+
require 'command_line_parser'
|
3
3
|
require 'runner'
|
4
4
|
require 'console_runner/version'
|
5
5
|
|
@@ -19,14 +19,12 @@ module ConsoleRunner
|
|
19
19
|
end
|
20
20
|
action = actions.first
|
21
21
|
action ||= file_parser.run_method
|
22
|
-
trol_config =
|
23
|
-
|
24
|
-
trol_config.parse_method action
|
22
|
+
trol_config = CommandLineParser.new(file_parser)
|
23
|
+
trol_config.run(action)
|
25
24
|
|
26
25
|
|
27
26
|
puts '======================================================='
|
28
27
|
puts 'Global options:'
|
29
|
-
puts trol_config.global_opts.map { |k, v| " #{k} = #{v}" }.join("\n")
|
30
28
|
if file_parser.initialize_method
|
31
29
|
puts "INIT: #{file_parser.initialize_method.name}"
|
32
30
|
puts 'INIT options:'
|
@@ -63,11 +61,4 @@ module ConsoleRunner
|
|
63
61
|
|
64
62
|
}
|
65
63
|
|
66
|
-
|
67
|
-
# raise ConsoleRunnerError, "#{clazz.name}#initialize method should be specified" unless initialize_method
|
68
|
-
#
|
69
|
-
# raise ConsoleRunnerError, "At least one method should be marked with @#{FileParser::RUNNABLE_TAG.to_s} tag.
|
70
|
-
# Also you may specify #run method and it will be executed by default.
|
71
|
-
# #run method don't need any code annotations as well." if runnable_methods.count == 0 unless run_method
|
72
|
-
|
73
64
|
end
|
data/lib/method_parser.rb
CHANGED
@@ -2,27 +2,84 @@
|
|
2
2
|
class MethodParser
|
3
3
|
attr_reader :method,
|
4
4
|
:name,
|
5
|
+
:parameters,
|
5
6
|
:param_tags, # All method parameters tags
|
6
|
-
:option_tags # Only options tags
|
7
|
+
:option_tags, # Only options tags
|
8
|
+
:trollop_opts,
|
9
|
+
:default_values,
|
10
|
+
:required_parameters
|
7
11
|
|
8
12
|
attr_accessor :cmd_opts
|
9
13
|
|
14
|
+
TYPES_MAPPINGS = {
|
15
|
+
'String' => :string,
|
16
|
+
'Integer' => :int,
|
17
|
+
'Fixnum' => :int,
|
18
|
+
'Float' => :float,
|
19
|
+
'Boolean' => :boolean,
|
20
|
+
'Array(String)' => :strings,
|
21
|
+
'Array(Integer)' => :ints,
|
22
|
+
'Array(Fixnum)' => :ints,
|
23
|
+
'Array(Float)' => :floats,
|
24
|
+
'Array(Boolean)' => :booleans
|
25
|
+
}.freeze
|
26
|
+
|
10
27
|
# @param [YARD::CodeObjects::MethodObject] method YARD method object to be parsed
|
11
28
|
def initialize(method)
|
12
|
-
@method
|
13
|
-
@name
|
14
|
-
@parameters
|
15
|
-
@
|
16
|
-
@
|
17
|
-
@
|
18
|
-
|
19
|
-
|
29
|
+
@method = method
|
30
|
+
@name = @method.name
|
31
|
+
@parameters = @method.parameters
|
32
|
+
@default_values = default_params
|
33
|
+
@param_tags = FileParser.select_param_tags @method
|
34
|
+
@option_tags = FileParser.select_option_tags @method
|
35
|
+
@required_parameters = @param_tags.select { |t| t.tag_name == 'param' }.map(&:name)
|
36
|
+
@cmd_opts = nil
|
37
|
+
same_params = param_tags_names & option_tags_names
|
38
|
+
unless same_params.count.zero?
|
20
39
|
raise(
|
21
40
|
ConsoleRunnerError,
|
22
41
|
"You have the same name for @param and @option attribute(s): #{same_params.join(', ')}.
|
23
42
|
Use different names to `console_runner` be able to run #{@name} method."
|
24
43
|
)
|
25
44
|
end
|
45
|
+
@trollop_opts = prepare_opts_for_trollop
|
46
|
+
end
|
47
|
+
|
48
|
+
def prepare_opts_for_trollop
|
49
|
+
result = []
|
50
|
+
param_tags.each do |tag|
|
51
|
+
tag_name = tag.name
|
52
|
+
tag_text = tag.text
|
53
|
+
tag_type = tag.type
|
54
|
+
if tag_type == "Hash"
|
55
|
+
options = option_tags.select { |t| t.name == tag.name }
|
56
|
+
if options.count > 0
|
57
|
+
options.each do |option|
|
58
|
+
option_name = option.pair.name.delete(':')
|
59
|
+
option_text = option.pair.text
|
60
|
+
option_type = option.pair.type
|
61
|
+
result << [
|
62
|
+
option_name.to_sym,
|
63
|
+
"(Ruby class: #{option_type}) " + option_text.to_s,
|
64
|
+
type: parse_type(option_type)
|
65
|
+
]
|
66
|
+
end
|
67
|
+
else
|
68
|
+
result << [
|
69
|
+
tag_name.to_sym,
|
70
|
+
"(Ruby class: #{tag_type}) " + tag_text.to_s,
|
71
|
+
type: parse_type(tag_type)
|
72
|
+
]
|
73
|
+
end
|
74
|
+
else
|
75
|
+
result << [
|
76
|
+
tag_name.to_sym,
|
77
|
+
"(Ruby class: #{tag_type}) " + tag_text.to_s,
|
78
|
+
type: parse_type(tag_type)
|
79
|
+
]
|
80
|
+
end
|
81
|
+
end
|
82
|
+
result
|
26
83
|
end
|
27
84
|
|
28
85
|
# Prepare
|
@@ -79,9 +136,18 @@ Use different names to `console_runner` be able to run #{@name} method."
|
|
79
136
|
option_tags.any? { |t| t.name == param_name }
|
80
137
|
end
|
81
138
|
|
139
|
+
|
140
|
+
private
|
141
|
+
|
142
|
+
def parse_type(yard_type)
|
143
|
+
result = TYPES_MAPPINGS[yard_type]
|
144
|
+
raise ConsoleRunnerError, "Unsupported YARD type: #{yard_type}" unless result
|
145
|
+
result
|
146
|
+
end
|
147
|
+
|
82
148
|
# @return [Hash] default values for parameters
|
83
149
|
def default_params
|
84
|
-
@parameters.map do |array|
|
150
|
+
@parameters.to_a.map do |array|
|
85
151
|
array.map do |a|
|
86
152
|
if a
|
87
153
|
['"', "'"].include?(a[0]) && ['"', "'"].include?(a[-1]) ? a[1..-2] : a
|
@@ -92,8 +158,6 @@ Use different names to `console_runner` be able to run #{@name} method."
|
|
92
158
|
end.to_h
|
93
159
|
end
|
94
160
|
|
95
|
-
private
|
96
|
-
|
97
161
|
# @return [Hash] options parameter as Hash
|
98
162
|
def option_as_hash(options_group_name)
|
99
163
|
result = {}
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: console_runner
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.10
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Yury Karpovich
|
8
8
|
autorequire:
|
9
9
|
bindir: exe
|
10
10
|
cert_chain: []
|
11
|
-
date: 2017-04-
|
11
|
+
date: 2017-04-13 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -157,13 +157,13 @@ files:
|
|
157
157
|
- bin/setup
|
158
158
|
- console_runner.gemspec
|
159
159
|
- exe/c_run
|
160
|
+
- lib/command_line_parser.rb
|
160
161
|
- lib/console_runner.rb
|
161
162
|
- lib/console_runner/version.rb
|
162
163
|
- lib/console_runner_error.rb
|
163
164
|
- lib/file_parser.rb
|
164
165
|
- lib/method_parser.rb
|
165
166
|
- lib/runner.rb
|
166
|
-
- lib/trollop_configurator.rb
|
167
167
|
homepage: https://github.com/yuri-karpovich/console_runner
|
168
168
|
licenses:
|
169
169
|
- MIT
|
data/lib/trollop_configurator.rb
DELETED
@@ -1,124 +0,0 @@
|
|
1
|
-
require 'trollop'
|
2
|
-
require 'method_parser'
|
3
|
-
|
4
|
-
# Parses command line and configure #Trollop
|
5
|
-
class TrollopConfigurator
|
6
|
-
attr_reader :global_opts, :method, :init_method
|
7
|
-
TYPES_MAPPINGS = {
|
8
|
-
'String' => :string,
|
9
|
-
'Integer' => :int,
|
10
|
-
'Fixnum' => :int,
|
11
|
-
'Float' => :float,
|
12
|
-
'Boolean' => :boolean,
|
13
|
-
'Array(String)' => :strings,
|
14
|
-
'Array(Integer)' => :ints,
|
15
|
-
'Array(Fixnum)' => :ints,
|
16
|
-
'Array(Float)' => :floats,
|
17
|
-
'Array(Boolean)' => :booleans
|
18
|
-
}.freeze
|
19
|
-
|
20
|
-
# Generate tool help menu.
|
21
|
-
# IMPORTANT! Should be executed before ARGV.shift
|
22
|
-
def initialize(file_parser)
|
23
|
-
runnable_methods = file_parser.runnable_methods
|
24
|
-
init_method = file_parser.initialize_method
|
25
|
-
clazz = runnable_methods.first.parent
|
26
|
-
sub_commands = runnable_methods.map { |m| m.name.to_s }
|
27
|
-
@parser = Trollop::Parser.new
|
28
|
-
@parser.banner(FileParser.select_runnable_tags(clazz).map { |t| (t.text + "\n") }.join("\n"))
|
29
|
-
@parser.stop_on sub_commands
|
30
|
-
|
31
|
-
if init_method
|
32
|
-
@init_method = MethodParser.new init_method
|
33
|
-
@init_method.param_tags.each do |tag|
|
34
|
-
tag_name = tag.name
|
35
|
-
tag_text = tag.text
|
36
|
-
tag_type = tag.type
|
37
|
-
if tag_type == "Hash"
|
38
|
-
options = option_tags.select { |t| t.name == tag.name }
|
39
|
-
if options.count > 0
|
40
|
-
options.each do |option|
|
41
|
-
option_name = option.pair.name.delete(':')
|
42
|
-
option_text = option.pair.text
|
43
|
-
option_type = option.pair.type
|
44
|
-
@parser.opt(option_name.to_sym, "(Ruby class: #{option_type}) " + option_text.to_s, type: TrollopConfigurator.parse_type(option_type))
|
45
|
-
end
|
46
|
-
else
|
47
|
-
@parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: TrollopConfigurator.parse_type(tag_type))
|
48
|
-
end
|
49
|
-
else
|
50
|
-
@parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: TrollopConfigurator.parse_type(tag_type))
|
51
|
-
end
|
52
|
-
end
|
53
|
-
end
|
54
|
-
|
55
|
-
@global_opts = Trollop::with_standard_exception_handling(@parser) do
|
56
|
-
begin
|
57
|
-
@parser.parse ARGV
|
58
|
-
rescue Trollop::CommandlineError => e
|
59
|
-
raise ConsoleRunnerError, "You must provide one of available actions: #{sub_commands.join ', '}" unless sub_commands.include?(ARGV[0])
|
60
|
-
raise e
|
61
|
-
end
|
62
|
-
end
|
63
|
-
|
64
|
-
if @init_method
|
65
|
-
given_attrs = @global_opts.keys.select { |k| k.to_s.include? '_given' }.map { |k| k.to_s.gsub('_given', '').to_sym }
|
66
|
-
@init_method.cmd_opts = @global_opts.select { |k, _| given_attrs.include? k }
|
67
|
-
end
|
68
|
-
end
|
69
|
-
|
70
|
-
# Parse method and configure #Trollop
|
71
|
-
def parse_method(method)
|
72
|
-
ARGV.shift
|
73
|
-
@method = MethodParser.new method
|
74
|
-
method_params_tags = @method.param_tags
|
75
|
-
|
76
|
-
method_params_tags.each do |tag|
|
77
|
-
tag_name = tag.name
|
78
|
-
tag_text = tag.text
|
79
|
-
tag_type = tag.type
|
80
|
-
if tag_type == "Hash"
|
81
|
-
options = @method.option_tags.select { |t| t.name == tag.name }
|
82
|
-
if options.count > 0
|
83
|
-
options.each do |option|
|
84
|
-
option_name = option.pair.name.delete(':')
|
85
|
-
option_text = option.pair.text
|
86
|
-
option_type = option.pair.type
|
87
|
-
@parser.opt(option_name.to_sym, "(Ruby class: #{option_type}) " + option_text.to_s, type: TrollopConfigurator.parse_type(option_type))
|
88
|
-
end
|
89
|
-
else
|
90
|
-
@parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: TrollopConfigurator.parse_type(tag_type))
|
91
|
-
end
|
92
|
-
else
|
93
|
-
@parser.opt(tag_name.to_sym, "(Ruby class: #{tag_type}) " + tag_text.to_s, type: TrollopConfigurator.parse_type(tag_type))
|
94
|
-
end
|
95
|
-
end
|
96
|
-
cmd_opts = Trollop::with_standard_exception_handling @parser do
|
97
|
-
unless method_params_tags.count.zero?
|
98
|
-
raise Trollop::HelpNeeded if ARGV.empty?
|
99
|
-
end
|
100
|
-
# show help screen
|
101
|
-
@parser.parse ARGV
|
102
|
-
end
|
103
|
-
given_attrs = cmd_opts.keys.select { |k| k.to_s.include? '_given' }.map { |k| k.to_s.gsub('_given', '').to_sym }
|
104
|
-
@method.cmd_opts = cmd_opts.select { |k, _| given_attrs.include? k }
|
105
|
-
@method.default_params.each do |k, v|
|
106
|
-
@method.cmd_opts[k.to_sym] ||= v
|
107
|
-
end
|
108
|
-
|
109
|
-
method_params_tags.select { |t| t.tag_name == 'param' }.map(&:name).each do |required_param|
|
110
|
-
next if @method.options_group? required_param
|
111
|
-
unless @method.cmd_opts[required_param.to_sym]
|
112
|
-
raise ConsoleRunnerError, "You must specify required parameter: #{required_param}"
|
113
|
-
end
|
114
|
-
end
|
115
|
-
end
|
116
|
-
|
117
|
-
def self.parse_type(yard_type)
|
118
|
-
result = TYPES_MAPPINGS[yard_type]
|
119
|
-
raise ConsoleRunnerError, "Unsupported YARD type: #{yard_type}" unless result
|
120
|
-
result
|
121
|
-
end
|
122
|
-
|
123
|
-
end
|
124
|
-
|