optitron 0.2.1 → 0.2.2
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.
- 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
|