console_runner 0.1.9 → 0.1.10
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
-
|