optitron 0.2.1 → 0.2.2
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile.lock +1 -1
- data/lib/optitron/class_dsl.rb +15 -4
- data/lib/optitron/cli.rb +1 -2
- data/lib/optitron/help.rb +10 -6
- data/lib/optitron/option.rb +4 -1
- data/lib/optitron/parser.rb +17 -4
- data/lib/optitron/version.rb +1 -1
- data/spec/cli_spec.rb +7 -2
- data/spec/group_spec.rb +25 -0
- data/spec/option_spec.rb +4 -0
- metadata +5 -4
data/Gemfile.lock
CHANGED
data/lib/optitron/class_dsl.rb
CHANGED
@@ -109,6 +109,7 @@ class Optitron
|
|
109
109
|
@opts.clear if @opts
|
110
110
|
@args.clear if @args
|
111
111
|
@last_desc = nil
|
112
|
+
@last_group = nil
|
112
113
|
end
|
113
114
|
end
|
114
115
|
def optitron_parser
|
@@ -149,6 +150,10 @@ class Optitron
|
|
149
150
|
@last_desc = desc
|
150
151
|
end
|
151
152
|
|
153
|
+
def group(group)
|
154
|
+
@last_group = group
|
155
|
+
end
|
156
|
+
|
152
157
|
def opt(name, desc = nil, opts = nil)
|
153
158
|
@opts ||= []
|
154
159
|
@opts << [name, desc, opts]
|
@@ -198,14 +203,20 @@ class Optitron
|
|
198
203
|
if response.valid?
|
199
204
|
optitron_parser.target.params = response.params
|
200
205
|
args = response.args
|
201
|
-
|
202
|
-
|
206
|
+
parser_args = optitron_parser.commands.assoc(response.command).last.args
|
207
|
+
while (args.size < parser_args.size && !(parser_args[args.size].type == :greedy && parser_args[args.size].default.nil?))
|
208
|
+
args << parser_args[args.size].default
|
203
209
|
end
|
210
|
+
|
204
211
|
optitron_parser.target.send(response.command.to_sym, *response.args)
|
205
212
|
else
|
206
|
-
puts
|
213
|
+
puts optitron_parser.help
|
214
|
+
|
215
|
+
unless response.args.empty?
|
216
|
+
puts response.error_messages.join("\n")
|
217
|
+
end
|
207
218
|
end
|
208
219
|
end
|
209
220
|
end
|
210
221
|
end
|
211
|
-
end
|
222
|
+
end
|
data/lib/optitron/cli.rb
CHANGED
data/lib/optitron/help.rb
CHANGED
@@ -54,10 +54,8 @@ class Optitron
|
|
54
54
|
cmds.assoc(cmd_line) << help_line_for_opt(opt)
|
55
55
|
end
|
56
56
|
end
|
57
|
-
|
58
|
-
|
59
|
-
end
|
60
|
-
|
57
|
+
cmds.sort!{ |cmd1, cmd2| (cmd1[1].group || '') <=> (cmd2[1].group || '') }
|
58
|
+
opts_lines = @parser.options.map { |opt| help_line_for_opt(opt) }
|
61
59
|
args_lines = @parser.args.empty? ? nil : [@parser.args.map{|arg| help_line_for_arg(arg)}.join(' '), @parser.args.map{|arg| arg.desc}.join(', ')]
|
62
60
|
|
63
61
|
longest_line = 0
|
@@ -68,11 +66,17 @@ class Optitron
|
|
68
66
|
longest_line = [opts_lines.map{|o| o.first.size}.max, longest_line].max unless opts_lines.empty?
|
69
67
|
help_output = []
|
70
68
|
|
69
|
+
last_group = nil
|
70
|
+
|
71
71
|
unless cmds.empty?
|
72
72
|
help_output << "Commands\n\n" + cmds.map do |(cmd, *opts)|
|
73
73
|
cmd_text = ""
|
74
|
-
cmd_text << "%-#{longest_line}s " % cmd
|
75
74
|
cmd_obj = opts.shift
|
75
|
+
if last_group != cmd_obj.group
|
76
|
+
cmd_text << "#{cmd_obj.group}:\n"
|
77
|
+
last_group = cmd_obj.group
|
78
|
+
end
|
79
|
+
cmd_text << "%-#{longest_line}s " % cmd
|
76
80
|
cmd_text << "# #{cmd_obj.desc}" if cmd_obj.desc
|
77
81
|
cmd_obj.args.each do |arg|
|
78
82
|
if arg.desc
|
@@ -104,4 +108,4 @@ class Optitron
|
|
104
108
|
help_output.join("\n\n")
|
105
109
|
end
|
106
110
|
end
|
107
|
-
end
|
111
|
+
end
|
data/lib/optitron/option.rb
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
class Optitron
|
2
2
|
class Option
|
3
3
|
attr_reader :inclusion_test, :type
|
4
|
-
attr_accessor :required, :name, :default, :parameterize, :desc, :has_default
|
4
|
+
attr_accessor :required, :name, :default, :parameterize, :desc, :has_default, :group
|
5
5
|
alias_method :required?, :required
|
6
6
|
alias_method :has_default?, :has_default
|
7
7
|
alias_method :parameterize?, :parameterize
|
@@ -112,6 +112,7 @@ class Optitron
|
|
112
112
|
self.type = opts && opts[:type] || :boolean
|
113
113
|
self.short_name = opts[:short_name] if opts && opts[:short_name]
|
114
114
|
self.run = opts[:run] if opts && opts[:run]
|
115
|
+
self.group = opts[:group] if opts && opts[:group]
|
115
116
|
self.inclusion_test = opts[:in] if opts && opts[:in]
|
116
117
|
self.required = opts && opts.key?(:required) ? opts[:required] : false
|
117
118
|
self.default = opts && opts.key?(:default) ? opts[:default] : (@type == :boolean ? false : nil)
|
@@ -191,6 +192,7 @@ class Optitron
|
|
191
192
|
end
|
192
193
|
@name, @desc = name, desc
|
193
194
|
@run = opts[:run] if opts && opts[:run]
|
195
|
+
@group = opts[:group] if opts && opts[:group]
|
194
196
|
@options = []
|
195
197
|
@args = []
|
196
198
|
end
|
@@ -205,6 +207,7 @@ class Optitron
|
|
205
207
|
@name, @desc = name, desc
|
206
208
|
self.inclusion_test = opts[:in] if opts && opts[:in]
|
207
209
|
self.default = opts && opts[:default]
|
210
|
+
self.group = opts[:group] if opts && opts[:group]
|
208
211
|
self.type = opts && opts[:type]
|
209
212
|
self.required = opts && opts.key?(:required) ? opts[:required] : (@default.nil? and !greedy?)
|
210
213
|
end
|
data/lib/optitron/parser.rb
CHANGED
@@ -15,8 +15,8 @@ class Optitron
|
|
15
15
|
@help.generate
|
16
16
|
end
|
17
17
|
|
18
|
-
def parse(
|
19
|
-
tokens = Tokenizer.new(self,
|
18
|
+
def parse(argv = ARGV)
|
19
|
+
tokens = Tokenizer.new(self, argv).tokens
|
20
20
|
response = Response.new(self, tokens)
|
21
21
|
options = @options
|
22
22
|
args = @args
|
@@ -27,8 +27,21 @@ class Optitron
|
|
27
27
|
response.command = cmd_tok.lit
|
28
28
|
options += @commands.assoc(cmd_tok.lit).last.options
|
29
29
|
args = @commands.assoc(cmd_tok.lit).last.args
|
30
|
+
elsif !potential_cmd_toks.empty? && @target.respond_to?(:command_missing)
|
31
|
+
command = potential_cmd_toks.first.lit
|
32
|
+
response.command = 'command_missing'
|
33
|
+
@commands << [response.command, Option::Cmd.new(response.command)]
|
34
|
+
@commands.assoc(response.command).last.options.insert(-1, *tokens.select { |t| !t.respond_to?(:lit) }.map { |t|
|
35
|
+
t.is_a?(Tokenizer::Named) ?
|
36
|
+
Option::Opt.new(t.name, nil, :short_name => t.name) :
|
37
|
+
Option::Opt.new(t.name, nil, :type => (t.value ? :string : :boolean))
|
38
|
+
})
|
39
|
+
@commands.assoc(response.command).last.args <<
|
40
|
+
Option::Arg.new('command', 'Command name', :type => :string) <<
|
41
|
+
Option::Arg.new('args', 'Command arguments', :type => :greedy)
|
42
|
+
options += @commands.assoc(response.command).last.options
|
43
|
+
args = @commands.assoc(response.command).last.args
|
30
44
|
else
|
31
|
-
puts @help.generate
|
32
45
|
potential_cmd_toks.first ?
|
33
46
|
response.add_error('an unknown command', potential_cmd_toks.first.lit) :
|
34
47
|
response.add_error('unknown command')
|
@@ -56,4 +69,4 @@ class Optitron
|
|
56
69
|
args.each { |arg| arg.consume(response, tokens) }
|
57
70
|
end
|
58
71
|
end
|
59
|
-
end
|
72
|
+
end
|
data/lib/optitron/version.rb
CHANGED
data/spec/cli_spec.rb
CHANGED
@@ -100,6 +100,11 @@ describe "Optitron::Parser defaults" do
|
|
100
100
|
capture(:stdout) { CLIExample.dispatch(%w(use))}.should == "using this\n"
|
101
101
|
end
|
102
102
|
|
103
|
+
it "should display help when there is no args" do
|
104
|
+
capture(:stdout) { CLIExample.dispatch([])}.should == "Commands\n\nuse # Use this\n -u/--use_opt \nuse_too [one(HASH)] <two=\"three\"> # Use this too\n -a/--another_opt \nuse_greedy [one] <two1 two2 ...> # Use this three\n -A/--another_opt_as_well=[NUMERIC] \nwith_array <ary=[1, 2, 3]> # something with an array\n\nGlobal options\n\n-v/--verbose \n-?/--help # Print help message\n"
|
105
|
+
end
|
106
|
+
|
107
|
+
|
103
108
|
it "should dispatch with the type hinting" do
|
104
109
|
capture(:stdout) { CLIExample.dispatch(%w(use_too one:two three:four))}.should == 'one: [["one", "two"], ["three", "four"]] "three"' + "\n"
|
105
110
|
end
|
@@ -114,7 +119,7 @@ describe "Optitron::Parser defaults" do
|
|
114
119
|
end
|
115
120
|
|
116
121
|
it "should be able to suppress help" do
|
117
|
-
capture(:stdout) { NoHelpExample.dispatch(%w(--help)) }.should == "Commands\n\nuse_too [one] <two=\"three\"> # Use this too\n -a/--another_opt \n\nGlobal options\n\n-v/--verbose \
|
122
|
+
capture(:stdout) { NoHelpExample.dispatch(%w(--help)) }.should == "Commands\n\nuse_too [one] <two=\"three\"> # Use this too\n -a/--another_opt \n\nGlobal options\n\n-v/--verbose \n"
|
118
123
|
end
|
119
124
|
|
120
125
|
it "should strip the type information from the names when its using the _type info" do
|
@@ -135,4 +140,4 @@ describe "Optitron::Parser defaults" do
|
|
135
140
|
Nested::NestedExample.build
|
136
141
|
AModule::CLIInAModule.optitron_parser.help.should == "Commands\n\nmethod [arg1] # a method\n\nGlobal options\n\n-?/--help # Print help message"
|
137
142
|
end
|
138
|
-
end
|
143
|
+
end
|
data/spec/group_spec.rb
ADDED
@@ -0,0 +1,25 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
describe "Optitron::Parser groups" do
|
4
|
+
it "generate help for command parsers" do
|
5
|
+
@parser = Optitron.new {
|
6
|
+
opt 'verbose', "Be very loud", :use_no => true
|
7
|
+
cmd "install", "This installs things", :group => "group1" do
|
8
|
+
arg "file", "The file to install"
|
9
|
+
end
|
10
|
+
cmd "show", "This shows things", :group => "group1" do
|
11
|
+
arg "first", "The first thing to show"
|
12
|
+
arg "second", "The second optional thing to show", :required => false
|
13
|
+
end
|
14
|
+
cmd "kill", "This kills things", :group => "group2" do
|
15
|
+
opt "pids", "A list of pids to kill", :type => :array
|
16
|
+
opt "pid", "A pid to kill", :type => :numeric
|
17
|
+
opt "names", "Some sort of hash", :type => :hash
|
18
|
+
end
|
19
|
+
cmd "join", "This joins things" do
|
20
|
+
arg "thing", "Stuff to join", :type => :greedy, :required => true
|
21
|
+
end
|
22
|
+
}
|
23
|
+
@parser.help.should == "Commands\n\njoin [thing1 thing2 ...] # This joins things\n # thing -- Stuff to join\ngroup1:\nshow [first] <second> # This shows things\n # first -- The first thing to show\n # second -- The second optional thing to show\ninstall [file] # This installs things\n # file -- The file to install\ngroup2:\nkill # This kills things\n -p/--pids=[ARRAY] # A list of pids to kill\n -P/--pid=[NUMERIC] # A pid to kill\n -n/--names=[HASH] # Some sort of hash\n\nGlobal options\n\n-v/--(no-)verbose # Be very loud"
|
24
|
+
end
|
25
|
+
end
|
data/spec/option_spec.rb
CHANGED
@@ -16,6 +16,10 @@ describe "Optitron::Parser options" do
|
|
16
16
|
@parser.parse(%w(--option=test)).params.should == {'option' => 'test'}
|
17
17
|
end
|
18
18
|
|
19
|
+
it "should parse '--option=\"test -testing\"'" do
|
20
|
+
@parser.parse(['--option=test -testing']).params.should == {'option' => 'test -testing'}
|
21
|
+
end
|
22
|
+
|
19
23
|
it "shouldn't parse '--option test'" do
|
20
24
|
@parser.parse(%w(--option test)).valid?.should be_false
|
21
25
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: optitron
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 19
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 2
|
9
|
-
-
|
10
|
-
version: 0.2.
|
9
|
+
- 2
|
10
|
+
version: 0.2.2
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Joshua Hull
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-12-13 00:00:00 -08:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -157,6 +157,7 @@ files:
|
|
157
157
|
- spec/default_spec.rb
|
158
158
|
- spec/dispatch_spec.rb
|
159
159
|
- spec/errors_spec.rb
|
160
|
+
- spec/group_spec.rb
|
160
161
|
- spec/help_spec.rb
|
161
162
|
- spec/option_spec.rb
|
162
163
|
- spec/short_name_spec.rb
|