choosy 0.1.0 → 0.2.0
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/README.markdown +229 -221
- data/Rakefile +21 -3
- data/examples/bar.rb +44 -0
- data/examples/foo.rb +198 -0
- data/examples/superfoo.rb +125 -0
- data/lib/VERSION +1 -1
- data/lib/choosy/argument.rb +51 -0
- data/lib/choosy/base_command.rb +22 -7
- data/lib/choosy/command.rb +12 -4
- data/lib/choosy/dsl/argument_builder.rb +88 -0
- data/lib/choosy/dsl/base_command_builder.rb +71 -56
- data/lib/choosy/dsl/command_builder.rb +14 -2
- data/lib/choosy/dsl/option_builder.rb +43 -83
- data/lib/choosy/dsl/super_command_builder.rb +37 -9
- data/lib/choosy/option.rb +13 -11
- data/lib/choosy/parse_result.rb +8 -27
- data/lib/choosy/parser.rb +20 -16
- data/lib/choosy/printing/color.rb +39 -21
- data/lib/choosy/printing/erb_printer.rb +12 -3
- data/lib/choosy/printing/formatting_element.rb +17 -0
- data/lib/choosy/printing/help_printer.rb +204 -117
- data/lib/choosy/printing/terminal.rb +53 -0
- data/lib/choosy/super_command.rb +6 -6
- data/lib/choosy/super_parser.rb +26 -15
- data/lib/choosy/verifier.rb +61 -6
- data/spec/choosy/base_command_spec.rb +27 -2
- data/spec/choosy/command_spec.rb +31 -9
- data/spec/choosy/dsl/argument_builder_spec.rb +180 -0
- data/spec/choosy/dsl/base_command_builder_spec.rb +87 -44
- data/spec/choosy/dsl/commmand_builder_spec.rb +15 -4
- data/spec/choosy/dsl/option_builder_spec.rb +101 -191
- data/spec/choosy/dsl/super_command_builder_spec.rb +34 -9
- data/spec/choosy/parser_spec.rb +30 -8
- data/spec/choosy/printing/color_spec.rb +19 -5
- data/spec/choosy/printing/help_printer_spec.rb +152 -73
- data/spec/choosy/printing/terminal_spec.rb +27 -0
- data/spec/choosy/super_command_spec.rb +17 -17
- data/spec/choosy/super_parser_spec.rb +20 -10
- data/spec/choosy/verifier_spec.rb +137 -47
- data/spec/integration/command-A_spec.rb +6 -6
- data/spec/integration/command-B_spec.rb +45 -0
- data/spec/integration/supercommand-A_spec.rb +33 -27
- data/spec/integration/supercommand-B_spec.rb +32 -0
- data/spec/spec_helpers.rb +8 -5
- metadata +95 -54
@@ -11,16 +11,16 @@ module Choosy::DSL
|
|
11
11
|
|
12
12
|
describe :command do
|
13
13
|
it "should add the command to the listing" do
|
14
|
-
@builder.command :foo do
|
15
|
-
|
14
|
+
@builder.command :foo do
|
15
|
+
boolean :count, "The count"
|
16
16
|
end
|
17
17
|
|
18
18
|
@command.listing.should have(1).item
|
19
19
|
end
|
20
20
|
|
21
21
|
it "should add the command builder to the command_builders" do
|
22
|
-
o = @builder.command :foo do
|
23
|
-
|
22
|
+
o = @builder.command :foo do
|
23
|
+
integer :size, "The size"
|
24
24
|
end
|
25
25
|
|
26
26
|
@command.command_builders[:foo].should be(o.builder)
|
@@ -32,13 +32,31 @@ module Choosy::DSL
|
|
32
32
|
end
|
33
33
|
|
34
34
|
it "should be able to accept a new command as an argument" do
|
35
|
-
cmd = Choosy::Command.new :cmd do
|
36
|
-
|
35
|
+
cmd = Choosy::Command.new :cmd do
|
36
|
+
float :float, "Float"
|
37
37
|
end
|
38
38
|
@builder.command cmd
|
39
39
|
@command.listing[0].should be(cmd)
|
40
40
|
end
|
41
41
|
end
|
42
|
+
|
43
|
+
describe :parsimonious do
|
44
|
+
it "should not be parsimonous by default" do
|
45
|
+
@command.parsimonious?.should be_false
|
46
|
+
end
|
47
|
+
|
48
|
+
it "should set parsimonious" do
|
49
|
+
@builder.parsimonious
|
50
|
+
@command.parsimonious?.should be_true
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe :metaname do
|
55
|
+
it "should set the super command's metaname for the subcommands" do
|
56
|
+
@builder.metaname 'META'
|
57
|
+
@command.metaname.should eql('META')
|
58
|
+
end
|
59
|
+
end
|
42
60
|
|
43
61
|
describe "standard options" do
|
44
62
|
it "should also be able to set flags" do
|
@@ -47,6 +65,13 @@ module Choosy::DSL
|
|
47
65
|
end
|
48
66
|
end
|
49
67
|
|
68
|
+
describe :finalize! do
|
69
|
+
it "should set the metaname if not already set" do
|
70
|
+
@builder.finalize!
|
71
|
+
@command.metaname.should eql('COMMAND')
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
50
75
|
describe :help do
|
51
76
|
it "should create a help command when asked" do
|
52
77
|
h = @builder.help
|
@@ -67,14 +92,14 @@ module Choosy::DSL
|
|
67
92
|
it "should return the super command name when called without arguments" do
|
68
93
|
h = @builder.help
|
69
94
|
attempting {
|
70
|
-
h.
|
71
|
-
}.should raise_error(Choosy::HelpCalled,
|
95
|
+
h.arguments.validation_step.call([])
|
96
|
+
}.should raise_error(Choosy::HelpCalled, nil)
|
72
97
|
end
|
73
98
|
|
74
99
|
it "should return the name of the first argument when called, as a symbol" do
|
75
100
|
h = @builder.help
|
76
101
|
attempting {
|
77
|
-
h.
|
102
|
+
h.arguments.validation_step.call(['foo'])
|
78
103
|
}.should raise_error(Choosy::HelpCalled, :foo)
|
79
104
|
end
|
80
105
|
end
|
data/spec/choosy/parser_spec.rb
CHANGED
@@ -5,6 +5,8 @@ require 'choosy/dsl/command_builder'
|
|
5
5
|
|
6
6
|
module Choosy
|
7
7
|
class ParserBuilder
|
8
|
+
attr_reader :command, :lazy
|
9
|
+
|
8
10
|
def initialize
|
9
11
|
@terminals = nil
|
10
12
|
@lazy = false
|
@@ -26,17 +28,22 @@ module Choosy
|
|
26
28
|
self
|
27
29
|
end
|
28
30
|
|
29
|
-
def boolean(sym, default=nil)
|
31
|
+
def boolean(sym, default=nil, negated=nil)
|
30
32
|
default ||= false
|
31
|
-
|
32
|
-
|
33
|
+
negated ||= false
|
34
|
+
@command.alter do
|
35
|
+
boolean(sym, sym.to_s, :default => default) do
|
36
|
+
if negated
|
37
|
+
negate
|
38
|
+
end
|
39
|
+
end
|
33
40
|
end
|
34
41
|
self
|
35
42
|
end
|
36
43
|
|
37
44
|
def single(sym)
|
38
|
-
@command.alter do
|
39
|
-
|
45
|
+
@command.alter do
|
46
|
+
single(sym, sym.to_s)
|
40
47
|
end
|
41
48
|
self
|
42
49
|
end
|
@@ -44,9 +51,9 @@ module Choosy
|
|
44
51
|
def multiple(sym, min=nil, max=nil)
|
45
52
|
min ||= 1
|
46
53
|
max ||= 1000
|
47
|
-
@command.alter do
|
48
|
-
|
49
|
-
|
54
|
+
@command.alter do
|
55
|
+
multiple(sym, sym.to_s) do
|
56
|
+
count :at_least => min, :at_most => max
|
50
57
|
end
|
51
58
|
end
|
52
59
|
self
|
@@ -149,6 +156,21 @@ module Choosy
|
|
149
156
|
res.options.should eql({:o => true})
|
150
157
|
end
|
151
158
|
|
159
|
+
it "should handle negated boolean arguments" do
|
160
|
+
@pb.boolean(:o, false, true)
|
161
|
+
@pb.build.flags['--no-o'].should_not be_nil
|
162
|
+
end
|
163
|
+
|
164
|
+
it "should handle a negated boolean argument" do
|
165
|
+
res = @pb.boolean(:o, false, true).parse!('--no-o')
|
166
|
+
res.options.should eql({:o => false})
|
167
|
+
end
|
168
|
+
|
169
|
+
it "should handle a negated boolean argument whose default is true" do
|
170
|
+
res = @pb.boolean(:o, true, true).parse!('--no-o')
|
171
|
+
res.options.should eql({:o => true})
|
172
|
+
end
|
173
|
+
|
152
174
|
it "should handle a boolean flag whose default is true" do
|
153
175
|
res = @pb.boolean(:opt, true).parse!('-o')
|
154
176
|
res.options.should eql({:opt => false})
|
@@ -52,23 +52,37 @@ module Choosy::Printing
|
|
52
52
|
end
|
53
53
|
|
54
54
|
it "should return a formatted string for just the color code when no args are given" do
|
55
|
-
@c.red.should eql("
|
55
|
+
@c.red.should eql("\e[31m")
|
56
56
|
end
|
57
57
|
|
58
58
|
it "should return a formatted string with a reset if a full string is supplied" do
|
59
|
-
@c.red("this").should eql("
|
59
|
+
@c.red("this").should eql("\e[31mthis\e[0m")
|
60
60
|
end
|
61
61
|
|
62
62
|
it "should recognize when the foreground is being set" do
|
63
|
-
@c.red("this", :foreground).should eql("
|
63
|
+
@c.red("this", :foreground).should eql("\e[31mthis\e[0m")
|
64
64
|
end
|
65
65
|
|
66
66
|
it "should recognize when the background is being set" do
|
67
|
-
@c.red("this", :background).should eql("
|
67
|
+
@c.red("this", :background).should eql("\e[41mthis\e[0m")
|
68
68
|
end
|
69
69
|
|
70
70
|
it "should also handle effects" do
|
71
|
-
@c.blink("this").should eql("
|
71
|
+
@c.blink("this").should eql("\e[5mthis\e[0m")
|
72
|
+
end
|
73
|
+
|
74
|
+
it "should fail when effects are handed too many parameters" do
|
75
|
+
attempting {
|
76
|
+
@c.blink("this", :noarg)
|
77
|
+
}.should raise_error(ArgumentError, /max 1/)
|
78
|
+
end
|
79
|
+
|
80
|
+
it "should not add an extra reset to the end if decorated more than once" do
|
81
|
+
@c.red(@c.blink("this")).should eql("\e[31m\e[5mthis\e[0m")
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should be able to format multiple items" do
|
85
|
+
@c.multiple("this", [:red, :blink]).should eql("\e[5m\e[31mthis\e[0m")
|
72
86
|
end
|
73
87
|
end
|
74
88
|
end
|
@@ -1,117 +1,196 @@
|
|
1
1
|
require 'spec_helpers'
|
2
2
|
require 'choosy/command'
|
3
|
+
require 'choosy/super_command'
|
3
4
|
require 'choosy/printing/help_printer'
|
4
5
|
|
5
6
|
module Choosy::Printing
|
6
7
|
describe HelpPrinter do
|
7
8
|
before :each do
|
8
|
-
@
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
This is a description of this command that should span
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
9
|
+
@c = Choosy::Command.new :foo do
|
10
|
+
summary "This is a fairly long summary that should wrap around the whole screen at least once, so that I can test whether it's properly formatted"
|
11
|
+
|
12
|
+
header 'DESCRIPTION'
|
13
|
+
para 'This is a description of this command that should span'
|
14
|
+
para 'Multiple lines and carry itself beyond the average line length when actually called out from the unit tests itself so that we can correctly guage the line wrapping.'
|
15
|
+
|
16
|
+
header 'OPTIONS'
|
17
|
+
boolean :evaluate, "The evaluation of some boolean something or other that really should span at least 3 lines of continuous text for testing the output of the option command."
|
18
|
+
integer :count, "The count of something that should also really span multiple lines, if possible."
|
19
|
+
boolean_ :debug, "Debug output"
|
20
|
+
version "1.2"
|
21
|
+
help
|
22
|
+
|
23
|
+
arguments do
|
24
|
+
metaname 'FOOS'
|
25
|
+
count 0..3
|
26
|
+
end
|
25
27
|
end
|
26
|
-
end
|
27
28
|
|
28
|
-
|
29
|
-
@h.columns.should satisfy {|c| c >= HelpPrinter::DEFAULT_COLUMN_COUNT }
|
30
|
-
end
|
29
|
+
@b = @c.builder
|
31
30
|
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
@s = Choosy::SuperCommand.new :super do
|
32
|
+
printer :standard, :color => true, :header_styles => [:bold, :blue]
|
33
|
+
command @c
|
34
|
+
metaname 'CMDS'
|
35
35
|
|
36
|
-
|
37
|
-
o = capture :stdout do
|
38
|
-
@h.print_usage(@c)
|
36
|
+
boolean :bold, "Bold"
|
39
37
|
end
|
40
38
|
|
41
|
-
|
39
|
+
@h = @s.printer
|
42
40
|
end
|
43
41
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
42
|
+
describe :print_usage do
|
43
|
+
it "should know how to format a regular command" do
|
44
|
+
@h.color.disable!
|
45
|
+
@h.columns = 60
|
46
|
+
@h.print_usage(@c)
|
47
|
+
|
48
|
+
@h.buffer.should eql("Usage: foo [-e|--evaluate] [-c|--count=COUNT] [--debug]
|
49
|
+
[--version] [-h|--help] FOOS\n")
|
48
50
|
end
|
49
51
|
|
50
|
-
|
51
|
-
@h.
|
52
|
+
it "should know how to format a super command" do
|
53
|
+
@h.color.disable!
|
54
|
+
@h.columns = 60
|
55
|
+
@h.print_usage(@s)
|
56
|
+
|
57
|
+
@h.buffer.should eql("Usage: super [-b|--bold] CMDS\n")
|
52
58
|
end
|
59
|
+
end
|
53
60
|
|
54
|
-
|
61
|
+
it "should write a header, properly colored" do
|
62
|
+
@h.print_header("option")
|
63
|
+
@h.buffer.should eql("\e[34m\e[1moption\e[0m")
|
55
64
|
end
|
56
65
|
|
57
|
-
it "should print a
|
58
|
-
|
59
|
-
|
60
|
-
|
66
|
+
it "should print out a formatted header" do
|
67
|
+
@h.print_element(@c.listing[0])
|
68
|
+
@h.buffer.should eql("\n\e[34m\e[1mDESCRIPTION\e[0m\n")
|
69
|
+
end
|
61
70
|
|
62
|
-
|
71
|
+
it "should print out a formatting element correctly" do
|
72
|
+
@h.print_element(@c.listing[1])
|
73
|
+
@h.buffer.should eql("\n This is a description of this command that should span\n")
|
63
74
|
end
|
64
75
|
|
65
|
-
it "should
|
66
|
-
|
67
|
-
|
68
|
-
|
76
|
+
it "should wrap lines in a paragraph correctly" do
|
77
|
+
@h.columns = 70
|
78
|
+
@h.print_element(@c.listing[2])
|
79
|
+
@h.buffer.should eql("\n Multiple lines and carry itself beyond the average line length when
|
80
|
+
actually called out from the unit tests itself so that we can
|
81
|
+
correctly guage the line wrapping.\n")
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should print out an option on multiple lines" do
|
85
|
+
@h.columns = 70
|
86
|
+
@h.print_option(@c.listing[4], '-e, --evaluate', ' ' * 20)
|
87
|
+
@h.buffer.should eql(' -e, --evaluate The evaluation of some boolean something or other
|
88
|
+
that really should span at least 3 lines of
|
89
|
+
continuous text for testing the output of the
|
90
|
+
option command.
|
91
|
+
')
|
92
|
+
end
|
69
93
|
|
70
|
-
|
94
|
+
it "should print out any commands that are present" do
|
95
|
+
@h.columns = 70
|
96
|
+
@h.print_command(@c, 'foo', ' ')
|
97
|
+
@h.buffer.should eql(" foo This is a fairly long summary that should wrap around the
|
98
|
+
whole screen at least once, so that I can test whether it's
|
99
|
+
properly formatted\n")
|
71
100
|
end
|
72
101
|
|
73
|
-
|
74
|
-
|
75
|
-
@
|
102
|
+
describe "for the usage line" do
|
103
|
+
it "should format a full boolean option" do
|
104
|
+
o = @b.boolean :bold, "bold"
|
105
|
+
@h.usage_option(o).should eql("[-b|--bold]")
|
76
106
|
end
|
77
107
|
|
78
|
-
|
79
|
-
|
108
|
+
it "should format a partial boolean option" do
|
109
|
+
o = @b.boolean_ :bold, "bold"
|
110
|
+
@h.usage_option(o).should eql('[--bold]')
|
111
|
+
end
|
80
112
|
|
81
|
-
|
82
|
-
|
83
|
-
|
113
|
+
it "should format a short boolean option" do
|
114
|
+
o = @b.option :bold do
|
115
|
+
short '-b'
|
116
|
+
end
|
117
|
+
@h.usage_option(o).should eql('[-b]')
|
84
118
|
end
|
85
119
|
|
86
|
-
|
87
|
-
|
120
|
+
it "should format a negation of a boolean option" do
|
121
|
+
o = @b.boolean :bold, "Bold!!" do
|
122
|
+
negate 'un'
|
123
|
+
end
|
124
|
+
@h.usage_option(o).should eql('[-b|--bold|--un-bold]')
|
125
|
+
end
|
126
|
+
|
127
|
+
it "should format a full single option" do
|
128
|
+
o = @b.single :color, "color"
|
129
|
+
@h.usage_option(o).should eql('[-c|--color=COLOR]')
|
130
|
+
end
|
88
131
|
|
89
|
-
|
90
|
-
|
91
|
-
@h.
|
132
|
+
it "should format a parial boolean option" do
|
133
|
+
o = @b.single_ :color, "color"
|
134
|
+
@h.usage_option(o).should eql('[--color=COLOR]')
|
135
|
+
end
|
136
|
+
|
137
|
+
it "shoudl format a full multiple option" do
|
138
|
+
o = @b.multiple :colors, "c"
|
139
|
+
@h.usage_option(o).should eql('[-c|--colors COLORS+]')
|
92
140
|
end
|
93
141
|
|
94
|
-
|
142
|
+
it "should format a partial multiple option" do
|
143
|
+
o = @b.multiple_ :colors, "c"
|
144
|
+
@h.usage_option(o).should eql('[--colors COLORS+]')
|
145
|
+
end
|
95
146
|
end
|
96
|
-
|
97
|
-
it "should print out any commands that are present"
|
98
147
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
@h.
|
148
|
+
describe "for the option line" do
|
149
|
+
it "should format a full boolean option" do
|
150
|
+
o = @b.boolean :bold, "b"
|
151
|
+
@h.regular_option(o).should eql('-b, --bold')
|
103
152
|
end
|
104
153
|
|
105
|
-
|
154
|
+
it "should format a partial boolean option" do
|
155
|
+
o = @b.boolean_ :bold, "b"
|
156
|
+
@h.regular_option(o).should eql(' --bold')
|
157
|
+
end
|
106
158
|
|
107
|
-
|
108
|
-
|
159
|
+
it "should format a short boolean option" do
|
160
|
+
o = @b.option :bold do |b|
|
161
|
+
b.short '-b'
|
162
|
+
end
|
109
163
|
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
164
|
+
@h.regular_option(o).should eql('-b')
|
165
|
+
end
|
166
|
+
|
167
|
+
it "should format a negation of an option" do
|
168
|
+
o = @b.boolean :bold, "Bold" do
|
169
|
+
negate 'un'
|
170
|
+
end
|
171
|
+
|
172
|
+
@h.regular_option(o).should eql('-b, --[un-]bold')
|
173
|
+
end
|
174
|
+
|
175
|
+
it "should format a full single option" do
|
176
|
+
o = @b.single :color, "color"
|
177
|
+
@h.regular_option(o).should eql('-c, --color COLOR')
|
178
|
+
end
|
179
|
+
|
180
|
+
it "should format a partial single option" do
|
181
|
+
o = @b.single_ :color, "color"
|
182
|
+
@h.regular_option(o).should eql(' --color COLOR')
|
183
|
+
end
|
184
|
+
|
185
|
+
it "should format a full multiple option" do
|
186
|
+
o = @b.multiple :colors, "colors"
|
187
|
+
@h.regular_option(o).should eql('-c, --colors COLORS+')
|
188
|
+
end
|
189
|
+
|
190
|
+
it "should format a partial multiple option" do
|
191
|
+
o = @b.multiple_ :colors, "colors"
|
192
|
+
@h.regular_option(o).should eql(' --colors COLORS+')
|
193
|
+
end
|
115
194
|
end
|
116
195
|
end
|
117
196
|
end
|