clamp 0.5.0 → 0.5.1
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 +15 -0
- data/.rspec +1 -0
- data/Gemfile +2 -2
- data/lib/clamp/parameter.rb +13 -19
- data/lib/clamp/version.rb +1 -1
- data/spec/clamp/command_group_spec.rb +27 -26
- data/spec/clamp/command_spec.rb +166 -166
- data/spec/clamp/option_module_spec.rb +10 -10
- data/spec/clamp/option_spec.rb +37 -36
- data/spec/clamp/parameter_spec.rb +77 -44
- data/spec/spec_helper.rb +2 -2
- metadata +6 -13
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
NDFlNTQ5ZTA5ODJmZjI4NjU3OTE0YzEwYzJjMzcwNTAzNzlhMGJjMA==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
MjhlMDdmNGYzY2E2ZDVmYTQxMzA2OTcwYmY1NDBmZjM1ZGJlMTczNA==
|
7
|
+
!binary "U0hBNTEy":
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
YjNlMjQ0OTdiMzZlYzYzOGJiNGI3YmI0NGIwODA4NmRhYTVlMWMxMTE0NzVl
|
10
|
+
NDRiYjIxN2JhNjMzMDliZDdjODgxMmJmOTU0MWY5NTUwYTg2YjY3MzBkZTU0
|
11
|
+
MGExZmI3NzRkMWM1NWEyY2ZlODIxOTFkZDYyMGMxYjFhYTJkN2E=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
ZDc0NzQ1YTYyNzIzZTY2ODZlYzk4ZjVmYmE1OGU5OGYxODI2MzMzMDk5YzEx
|
14
|
+
ZTBkMzM3ZjNhZGNkYTNlODhjZWFhMjI1ZTA4NmRlMGJhNmVkNmFjNGIxZDc4
|
15
|
+
ZmY4ZGJhYWZhMWJlNzlkZWM1YzBjMGUzZGI2YWUxNzk3MmQyMzk=
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--color
|
data/Gemfile
CHANGED
data/lib/clamp/parameter.rb
CHANGED
@@ -7,7 +7,8 @@ module Clamp
|
|
7
7
|
def initialize(name, description, options = {})
|
8
8
|
@name = name
|
9
9
|
@description = description
|
10
|
-
|
10
|
+
@multivalued = (@name =~ ELLIPSIS_SUFFIX)
|
11
|
+
@required = (@name !~ OPTIONAL)
|
11
12
|
if options.has_key?(:attribute_name)
|
12
13
|
@attribute_name = options[:attribute_name].to_s
|
13
14
|
end
|
@@ -17,6 +18,7 @@ module Clamp
|
|
17
18
|
if options.has_key?(:environment_variable)
|
18
19
|
@environment_variable = options[:environment_variable]
|
19
20
|
end
|
21
|
+
@attribute_name ||= infer_attribute_name
|
20
22
|
end
|
21
23
|
|
22
24
|
attr_reader :name, :attribute_name
|
@@ -48,26 +50,18 @@ module Clamp
|
|
48
50
|
|
49
51
|
private
|
50
52
|
|
51
|
-
|
53
|
+
ELLIPSIS_SUFFIX = / \.\.\.$/
|
54
|
+
OPTIONAL = /^\[(.*)\]/
|
52
55
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
@multivalued = true
|
60
|
-
when /^#{NAME_PATTERN} ...$/
|
61
|
-
@attribute_name = "#{$1}_list"
|
62
|
-
@multivalued = true
|
63
|
-
@required = true
|
64
|
-
when /^#{NAME_PATTERN}$/
|
65
|
-
@attribute_name = @name
|
66
|
-
@required = true
|
67
|
-
else
|
68
|
-
raise "invalid parameter name: '#{name}'"
|
56
|
+
VALID_ATTRIBUTE_NAME = /^[a-z0-9_]+$/
|
57
|
+
|
58
|
+
def infer_attribute_name
|
59
|
+
inferred_name = name.downcase.tr('-', '_').sub(ELLIPSIS_SUFFIX, '').sub(OPTIONAL) { $1 }
|
60
|
+
unless inferred_name =~ VALID_ATTRIBUTE_NAME
|
61
|
+
raise "cannot infer attribute_name from #{name.inspect}"
|
69
62
|
end
|
70
|
-
|
63
|
+
inferred_name += "_list" if multivalued?
|
64
|
+
inferred_name
|
71
65
|
end
|
72
66
|
|
73
67
|
def multivalued?
|
data/lib/clamp/version.rb
CHANGED
@@ -29,10 +29,10 @@ describe Clamp::Command do
|
|
29
29
|
|
30
30
|
it "delegates to sub-commands" do
|
31
31
|
|
32
|
-
|
32
|
+
command.run(["flip"])
|
33
33
|
stdout.should =~ /FLIPPED/
|
34
34
|
|
35
|
-
|
35
|
+
command.run(["flop"])
|
36
36
|
stdout.should =~ /FLOPPED/
|
37
37
|
|
38
38
|
end
|
@@ -41,7 +41,7 @@ describe Clamp::Command do
|
|
41
41
|
|
42
42
|
it "triggers help" do
|
43
43
|
lambda do
|
44
|
-
|
44
|
+
command.run([])
|
45
45
|
end.should raise_error(Clamp::HelpWanted)
|
46
46
|
end
|
47
47
|
|
@@ -50,18 +50,18 @@ describe Clamp::Command do
|
|
50
50
|
describe "#help" do
|
51
51
|
|
52
52
|
it "shows subcommand parameters in usage" do
|
53
|
-
|
53
|
+
command.help.should include("flipflop [OPTIONS] SUBCOMMAND [ARGS] ...")
|
54
54
|
end
|
55
55
|
|
56
56
|
it "lists subcommands" do
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
57
|
+
help = command.help
|
58
|
+
help.should =~ /Subcommands:/
|
59
|
+
help.should =~ /flip +flip it/
|
60
|
+
help.should =~ /flop +flop it/
|
61
61
|
end
|
62
62
|
|
63
63
|
it "handles new lines in subcommand descriptions" do
|
64
|
-
|
64
|
+
command.help.should =~ /flop +flop it\n +for extra flop/
|
65
65
|
end
|
66
66
|
|
67
67
|
end
|
@@ -86,10 +86,10 @@ describe Clamp::Command do
|
|
86
86
|
|
87
87
|
it "responds to both aliases" do
|
88
88
|
|
89
|
-
|
89
|
+
command.run(["say", "boo"])
|
90
90
|
stdout.should =~ /boo/
|
91
91
|
|
92
|
-
|
92
|
+
command.run(["talk", "jive"])
|
93
93
|
stdout.should =~ /jive/
|
94
94
|
|
95
95
|
end
|
@@ -97,8 +97,8 @@ describe Clamp::Command do
|
|
97
97
|
describe "#help" do
|
98
98
|
|
99
99
|
it "lists all aliases" do
|
100
|
-
|
101
|
-
|
100
|
+
help = command.help
|
101
|
+
help.should =~ /say, talk .* Say something/
|
102
102
|
end
|
103
103
|
|
104
104
|
end
|
@@ -122,7 +122,7 @@ describe Clamp::Command do
|
|
122
122
|
end
|
123
123
|
|
124
124
|
it "delegates multiple levels" do
|
125
|
-
|
125
|
+
command.run(["foo", "bar"])
|
126
126
|
stdout.should =~ /FUBAR/
|
127
127
|
end
|
128
128
|
|
@@ -147,7 +147,7 @@ describe Clamp::Command do
|
|
147
147
|
context "executed with no subcommand" do
|
148
148
|
|
149
149
|
it "invokes the default subcommand" do
|
150
|
-
|
150
|
+
command.run([])
|
151
151
|
stdout.should =~ /All good/
|
152
152
|
end
|
153
153
|
|
@@ -172,7 +172,7 @@ describe Clamp::Command do
|
|
172
172
|
context "executed with no subcommand" do
|
173
173
|
|
174
174
|
it "invokes the default subcommand" do
|
175
|
-
|
175
|
+
command.run([])
|
176
176
|
stdout.should =~ /All good/
|
177
177
|
end
|
178
178
|
|
@@ -182,14 +182,14 @@ describe Clamp::Command do
|
|
182
182
|
|
183
183
|
describe "each subcommand" do
|
184
184
|
|
185
|
-
|
185
|
+
let(:command_class) do
|
186
186
|
|
187
187
|
speed_options = Module.new do
|
188
188
|
extend Clamp::Option::Declaration
|
189
189
|
option "--speed", "SPEED", "how fast", :default => "slowly"
|
190
190
|
end
|
191
191
|
|
192
|
-
|
192
|
+
Class.new(Clamp::Command) do
|
193
193
|
|
194
194
|
option "--direction", "DIR", "which way", :default => "home"
|
195
195
|
|
@@ -205,29 +205,30 @@ describe Clamp::Command do
|
|
205
205
|
end
|
206
206
|
|
207
207
|
end
|
208
|
+
end
|
208
209
|
|
209
|
-
|
210
|
-
|
210
|
+
let(:command) do
|
211
|
+
command_class.new("go")
|
211
212
|
end
|
212
213
|
|
213
214
|
it "accepts options defined in superclass (specified after the subcommand)" do
|
214
|
-
|
215
|
+
command.run(["move", "--direction", "north"])
|
215
216
|
stdout.should =~ /walking north/
|
216
217
|
end
|
217
218
|
|
218
219
|
it "accepts options defined in superclass (specified before the subcommand)" do
|
219
|
-
|
220
|
+
command.run(["--direction", "north", "move"])
|
220
221
|
stdout.should =~ /walking north/
|
221
222
|
end
|
222
223
|
|
223
224
|
it "accepts options defined in included modules" do
|
224
|
-
|
225
|
+
command.run(["move", "--speed", "very quickly"])
|
225
226
|
stdout.should =~ /walking home very quickly/
|
226
227
|
end
|
227
228
|
|
228
229
|
it "has access to command context" do
|
229
|
-
|
230
|
-
|
230
|
+
command = command_class.new("go", :motion => "wandering")
|
231
|
+
command.run(["move"])
|
231
232
|
stdout.should =~ /wandering home/
|
232
233
|
end
|
233
234
|
|
@@ -248,7 +249,7 @@ describe Clamp::Command do
|
|
248
249
|
end
|
249
250
|
|
250
251
|
it "only parses options once" do
|
251
|
-
|
252
|
+
command.run(['--json', '{"a":"b"}', 'woohoohoo'])
|
252
253
|
stdout.should == 'parsing!'
|
253
254
|
end
|
254
255
|
|
data/spec/clamp/command_spec.rb
CHANGED
@@ -17,7 +17,7 @@ describe Clamp::Command do
|
|
17
17
|
describe "#help" do
|
18
18
|
|
19
19
|
it "describes usage" do
|
20
|
-
|
20
|
+
command.help.should =~ /^Usage:\n cmd.*\n/
|
21
21
|
end
|
22
22
|
|
23
23
|
end
|
@@ -25,7 +25,7 @@ describe Clamp::Command do
|
|
25
25
|
describe "#run" do
|
26
26
|
|
27
27
|
before do
|
28
|
-
|
28
|
+
command.run([])
|
29
29
|
end
|
30
30
|
|
31
31
|
it "executes the #execute method" do
|
@@ -37,21 +37,21 @@ describe Clamp::Command do
|
|
37
37
|
describe ".option" do
|
38
38
|
|
39
39
|
it "declares option argument accessors" do
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
40
|
+
command.class.option "--flavour", "FLAVOUR", "Flavour of the month"
|
41
|
+
command.flavour.should == nil
|
42
|
+
command.flavour = "chocolate"
|
43
|
+
command.flavour.should == "chocolate"
|
44
44
|
end
|
45
45
|
|
46
46
|
describe "with type :flag" do
|
47
47
|
|
48
48
|
before do
|
49
|
-
|
49
|
+
command.class.option "--verbose", :flag, "Be heartier"
|
50
50
|
end
|
51
51
|
|
52
52
|
it "declares a predicate-style reader" do
|
53
|
-
|
54
|
-
|
53
|
+
command.should respond_to(:verbose?)
|
54
|
+
command.should_not respond_to(:verbose)
|
55
55
|
end
|
56
56
|
|
57
57
|
end
|
@@ -59,17 +59,17 @@ describe Clamp::Command do
|
|
59
59
|
describe "with explicit :attribute_name" do
|
60
60
|
|
61
61
|
before do
|
62
|
-
|
62
|
+
command.class.option "--foo", "FOO", "A foo", :attribute_name => :bar
|
63
63
|
end
|
64
64
|
|
65
65
|
it "uses the specified attribute_name name to name accessors" do
|
66
|
-
|
67
|
-
|
66
|
+
command.bar = "chocolate"
|
67
|
+
command.bar.should == "chocolate"
|
68
68
|
end
|
69
69
|
|
70
70
|
it "does not attempt to create the default accessors" do
|
71
|
-
|
72
|
-
|
71
|
+
command.should_not respond_to(:foo)
|
72
|
+
command.should_not respond_to(:foo=)
|
73
73
|
end
|
74
74
|
|
75
75
|
end
|
@@ -77,8 +77,8 @@ describe Clamp::Command do
|
|
77
77
|
describe "with default method" do
|
78
78
|
|
79
79
|
before do
|
80
|
-
|
81
|
-
|
80
|
+
command.class.option "--port", "PORT", "port"
|
81
|
+
command.class.class_eval do
|
82
82
|
def default_port
|
83
83
|
4321
|
84
84
|
end
|
@@ -86,7 +86,7 @@ describe Clamp::Command do
|
|
86
86
|
end
|
87
87
|
|
88
88
|
it "sets the specified default value" do
|
89
|
-
|
89
|
+
command.port.should == 4321
|
90
90
|
end
|
91
91
|
|
92
92
|
end
|
@@ -94,17 +94,17 @@ describe Clamp::Command do
|
|
94
94
|
describe "with :default value" do
|
95
95
|
|
96
96
|
before do
|
97
|
-
|
97
|
+
command.class.option "--port", "PORT", "port to listen on", :default => 4321
|
98
98
|
end
|
99
99
|
|
100
100
|
it "declares default method" do
|
101
|
-
|
101
|
+
command.default_port.should == 4321
|
102
102
|
end
|
103
103
|
|
104
104
|
describe "#help" do
|
105
105
|
|
106
106
|
it "describes the default value" do
|
107
|
-
|
107
|
+
command.help.should include("port to listen on (default: 4321)")
|
108
108
|
end
|
109
109
|
|
110
110
|
end
|
@@ -114,33 +114,33 @@ describe Clamp::Command do
|
|
114
114
|
describe "with :environment_variable value" do
|
115
115
|
|
116
116
|
before do
|
117
|
-
|
117
|
+
command.class.option "--port", "PORT", "port to listen on", :default => 4321, :environment_variable => "PORT" do |value|
|
118
118
|
value.to_i
|
119
119
|
end
|
120
120
|
end
|
121
121
|
|
122
122
|
it "should use the default if neither flag nor env var are present" do
|
123
123
|
ENV.delete("PORT")
|
124
|
-
|
125
|
-
|
124
|
+
command.parse([])
|
125
|
+
command.port.should == 4321
|
126
126
|
end
|
127
127
|
|
128
128
|
it "should use the env value if present (instead of default)" do
|
129
129
|
ENV["PORT"] = rand(10000).to_s
|
130
|
-
|
131
|
-
|
130
|
+
command.parse([])
|
131
|
+
command.port.should == ENV["PORT"].to_i
|
132
132
|
end
|
133
133
|
|
134
134
|
it "should use the the flag value if present (instead of env)" do
|
135
135
|
ENV["PORT"] = "12345"
|
136
|
-
|
137
|
-
|
136
|
+
command.parse(%w(--port 1500))
|
137
|
+
command.port.should == 1500
|
138
138
|
end
|
139
139
|
|
140
140
|
describe "#help" do
|
141
141
|
|
142
142
|
it "describes the default value and env usage" do
|
143
|
-
|
143
|
+
command.help.should include("port to listen on (default: $PORT, or 4321)")
|
144
144
|
end
|
145
145
|
|
146
146
|
end
|
@@ -150,19 +150,19 @@ describe Clamp::Command do
|
|
150
150
|
describe "with :environment_variable value on a :flag option" do
|
151
151
|
|
152
152
|
before do
|
153
|
-
|
153
|
+
command.class.option "--[no-]enable", :flag, "enable?", :default => false, :environment_variable => "ENABLE"
|
154
154
|
end
|
155
155
|
|
156
156
|
it "should use the default if neither flag nor env var are present" do
|
157
|
-
|
158
|
-
|
157
|
+
command.parse([])
|
158
|
+
command.enable?.should == false
|
159
159
|
end
|
160
160
|
|
161
161
|
Clamp::Option::Parsing::TRUTHY_ENVIRONMENT_VALUES.each do |value|
|
162
162
|
it "should use environment value '#{value}' to mean true" do
|
163
163
|
ENV["ENABLE"] = value
|
164
|
-
|
165
|
-
|
164
|
+
command.parse([])
|
165
|
+
command.enable?.should == true
|
166
166
|
end
|
167
167
|
end
|
168
168
|
|
@@ -176,15 +176,15 @@ describe Clamp::Command do
|
|
176
176
|
it "should use an env value other than truthy ones to mean false" do
|
177
177
|
[nil, "0", "no", "whatever"].each do |val|
|
178
178
|
ENV["ENABLE"] = val
|
179
|
-
|
180
|
-
|
179
|
+
command.parse([])
|
180
|
+
command.enable?.should == false
|
181
181
|
end
|
182
182
|
end
|
183
183
|
|
184
184
|
it "should use the the flag value if present (instead of env)" do
|
185
185
|
ENV["ENABLE"] = "1"
|
186
|
-
|
187
|
-
|
186
|
+
command.parse(%w(--no-enable))
|
187
|
+
command.enable?.should == false
|
188
188
|
end
|
189
189
|
|
190
190
|
end
|
@@ -192,15 +192,15 @@ describe Clamp::Command do
|
|
192
192
|
describe "with :required value" do
|
193
193
|
|
194
194
|
before do
|
195
|
-
|
195
|
+
command.class.option "--port", "PORT", "port to listen on", :required => true
|
196
196
|
end
|
197
197
|
|
198
198
|
it "should fail if a required option is not provided" do
|
199
|
-
expect {
|
199
|
+
expect { command.parse([]) }.to raise_error(Clamp::UsageError)
|
200
200
|
end
|
201
201
|
|
202
202
|
it "should succeed if a required option is provided" do
|
203
|
-
|
203
|
+
command.parse(["--port", "12345"])
|
204
204
|
end
|
205
205
|
|
206
206
|
end
|
@@ -208,22 +208,22 @@ describe Clamp::Command do
|
|
208
208
|
describe "with :required value with :env" do
|
209
209
|
|
210
210
|
before do
|
211
|
-
|
211
|
+
command.class.option "--port", "PORT", "port to listen on", :required => true, :environment_variable => "PORT"
|
212
212
|
end
|
213
213
|
|
214
214
|
it "should fail if a required option is not provided" do
|
215
215
|
ENV.delete("PORT")
|
216
|
-
expect {
|
216
|
+
expect { command.parse([]) }.to raise_error(Clamp::UsageError)
|
217
217
|
end
|
218
218
|
|
219
219
|
it "should succeed if a required option is provided via arguments" do
|
220
220
|
ENV.delete("PORT")
|
221
|
-
|
221
|
+
command.parse(["--port", "12345"])
|
222
222
|
end
|
223
223
|
|
224
224
|
it "should succeed if a required option is provided via env" do
|
225
225
|
ENV["PORT"] = "12345"
|
226
|
-
|
226
|
+
command.parse([])
|
227
227
|
end
|
228
228
|
|
229
229
|
end
|
@@ -232,17 +232,17 @@ describe Clamp::Command do
|
|
232
232
|
describe "with a block" do
|
233
233
|
|
234
234
|
before do
|
235
|
-
|
235
|
+
command.class.option "--port", "PORT", "Port to listen on" do |port|
|
236
236
|
Integer(port)
|
237
237
|
end
|
238
238
|
end
|
239
239
|
|
240
240
|
it "uses the block to validate and convert the option argument" do
|
241
241
|
lambda do
|
242
|
-
|
242
|
+
command.port = "blah"
|
243
243
|
end.should raise_error(ArgumentError)
|
244
|
-
|
245
|
-
|
244
|
+
command.port = "1234"
|
245
|
+
command.port.should == 1234
|
246
246
|
end
|
247
247
|
|
248
248
|
end
|
@@ -252,10 +252,10 @@ describe Clamp::Command do
|
|
252
252
|
describe "with options declared" do
|
253
253
|
|
254
254
|
before do
|
255
|
-
|
256
|
-
|
257
|
-
|
258
|
-
|
255
|
+
command.class.option ["-f", "--flavour"], "FLAVOUR", "Flavour of the month"
|
256
|
+
command.class.option ["-c", "--color"], "COLOR", "Preferred hue"
|
257
|
+
command.class.option ["-n", "--[no-]nuts"], :flag, "Nuts (or not)\nMay include nuts"
|
258
|
+
command.class.parameter "[ARG] ...", "extra arguments", :attribute_name => :arguments
|
259
259
|
end
|
260
260
|
|
261
261
|
describe "#parse" do
|
@@ -264,7 +264,7 @@ describe Clamp::Command do
|
|
264
264
|
|
265
265
|
it "raises a UsageError" do
|
266
266
|
lambda do
|
267
|
-
|
267
|
+
command.parse(%w(--foo bar))
|
268
268
|
end.should raise_error(Clamp::UsageError)
|
269
269
|
end
|
270
270
|
|
@@ -273,13 +273,13 @@ describe Clamp::Command do
|
|
273
273
|
describe "with options" do
|
274
274
|
|
275
275
|
before do
|
276
|
-
|
276
|
+
command.parse(%w(--flavour strawberry --nuts --color blue))
|
277
277
|
end
|
278
278
|
|
279
279
|
it "maps the option values onto the command object" do
|
280
|
-
|
281
|
-
|
282
|
-
|
280
|
+
command.flavour.should == "strawberry"
|
281
|
+
command.color.should == "blue"
|
282
|
+
command.nuts?.should == true
|
283
283
|
end
|
284
284
|
|
285
285
|
end
|
@@ -287,12 +287,12 @@ describe Clamp::Command do
|
|
287
287
|
describe "with short options" do
|
288
288
|
|
289
289
|
before do
|
290
|
-
|
290
|
+
command.parse(%w(-f strawberry -c blue))
|
291
291
|
end
|
292
292
|
|
293
293
|
it "recognises short options as aliases" do
|
294
|
-
|
295
|
-
|
294
|
+
command.flavour.should == "strawberry"
|
295
|
+
command.color.should == "blue"
|
296
296
|
end
|
297
297
|
|
298
298
|
end
|
@@ -300,11 +300,11 @@ describe Clamp::Command do
|
|
300
300
|
describe "with a value appended to a short option" do
|
301
301
|
|
302
302
|
before do
|
303
|
-
|
303
|
+
command.parse(%w(-fstrawberry))
|
304
304
|
end
|
305
305
|
|
306
306
|
it "works as though the value were separated" do
|
307
|
-
|
307
|
+
command.flavour.should == "strawberry"
|
308
308
|
end
|
309
309
|
|
310
310
|
end
|
@@ -312,12 +312,12 @@ describe Clamp::Command do
|
|
312
312
|
describe "with combined short options" do
|
313
313
|
|
314
314
|
before do
|
315
|
-
|
315
|
+
command.parse(%w(-nf strawberry))
|
316
316
|
end
|
317
317
|
|
318
318
|
it "works as though the options were separate" do
|
319
|
-
|
320
|
-
|
319
|
+
command.flavour.should == "strawberry"
|
320
|
+
command.nuts?.should == true
|
321
321
|
end
|
322
322
|
|
323
323
|
end
|
@@ -325,12 +325,12 @@ describe Clamp::Command do
|
|
325
325
|
describe "with option arguments attached using equals sign" do
|
326
326
|
|
327
327
|
before do
|
328
|
-
|
328
|
+
command.parse(%w(--flavour=strawberry --color=blue))
|
329
329
|
end
|
330
330
|
|
331
331
|
it "works as though the option arguments were separate" do
|
332
|
-
|
333
|
-
|
332
|
+
command.flavour.should == "strawberry"
|
333
|
+
command.color.should == "blue"
|
334
334
|
end
|
335
335
|
|
336
336
|
end
|
@@ -338,8 +338,8 @@ describe Clamp::Command do
|
|
338
338
|
describe "with option-like things beyond the arguments" do
|
339
339
|
|
340
340
|
it "treats them as positional arguments" do
|
341
|
-
|
342
|
-
|
341
|
+
command.parse(%w(a b c --flavour strawberry))
|
342
|
+
command.arguments.should == %w(a b c --flavour strawberry)
|
343
343
|
end
|
344
344
|
|
345
345
|
end
|
@@ -347,13 +347,13 @@ describe Clamp::Command do
|
|
347
347
|
describe "with multi-line arguments that look like options" do
|
348
348
|
|
349
349
|
before do
|
350
|
-
|
350
|
+
command.parse(["foo\n--flavour=strawberry", "bar\n-cblue"])
|
351
351
|
end
|
352
352
|
|
353
353
|
it "treats them as positional arguments" do
|
354
|
-
|
355
|
-
|
356
|
-
|
354
|
+
command.arguments.should == ["foo\n--flavour=strawberry", "bar\n-cblue"]
|
355
|
+
command.flavour.should be_nil
|
356
|
+
command.color.should be_nil
|
357
357
|
end
|
358
358
|
|
359
359
|
end
|
@@ -361,8 +361,8 @@ describe Clamp::Command do
|
|
361
361
|
describe "with an option terminator" do
|
362
362
|
|
363
363
|
it "considers everything after the terminator to be an argument" do
|
364
|
-
|
365
|
-
|
364
|
+
command.parse(%w(--color blue -- --flavour strawberry))
|
365
|
+
command.arguments.should == %w(--flavour strawberry)
|
366
366
|
end
|
367
367
|
|
368
368
|
end
|
@@ -370,11 +370,11 @@ describe Clamp::Command do
|
|
370
370
|
describe "with --flag" do
|
371
371
|
|
372
372
|
before do
|
373
|
-
|
373
|
+
command.parse(%w(--nuts))
|
374
374
|
end
|
375
375
|
|
376
376
|
it "sets the flag" do
|
377
|
-
|
377
|
+
command.nuts?.should be_true
|
378
378
|
end
|
379
379
|
|
380
380
|
end
|
@@ -382,12 +382,12 @@ describe Clamp::Command do
|
|
382
382
|
describe "with --no-flag" do
|
383
383
|
|
384
384
|
before do
|
385
|
-
|
386
|
-
|
385
|
+
command.nuts = true
|
386
|
+
command.parse(%w(--no-nuts))
|
387
387
|
end
|
388
388
|
|
389
389
|
it "clears the flag" do
|
390
|
-
|
390
|
+
command.nuts?.should be_false
|
391
391
|
end
|
392
392
|
|
393
393
|
end
|
@@ -396,7 +396,7 @@ describe Clamp::Command do
|
|
396
396
|
|
397
397
|
it "requests help" do
|
398
398
|
lambda do
|
399
|
-
|
399
|
+
command.parse(%w(--help))
|
400
400
|
end.should raise_error(Clamp::HelpWanted)
|
401
401
|
end
|
402
402
|
|
@@ -406,7 +406,7 @@ describe Clamp::Command do
|
|
406
406
|
|
407
407
|
it "requests help" do
|
408
408
|
lambda do
|
409
|
-
|
409
|
+
command.parse(%w(-h))
|
410
410
|
end.should raise_error(Clamp::HelpWanted)
|
411
411
|
end
|
412
412
|
|
@@ -415,7 +415,7 @@ describe Clamp::Command do
|
|
415
415
|
describe "when option-writer raises an ArgumentError" do
|
416
416
|
|
417
417
|
before do
|
418
|
-
|
418
|
+
command.class.class_eval do
|
419
419
|
|
420
420
|
def color=(c)
|
421
421
|
unless c == "black"
|
@@ -428,7 +428,7 @@ describe Clamp::Command do
|
|
428
428
|
|
429
429
|
it "re-raises it as a UsageError" do
|
430
430
|
lambda do
|
431
|
-
|
431
|
+
command.parse(%w(--color red))
|
432
432
|
end.should raise_error(Clamp::UsageError, /^option '--color': sorry, we're out of red/)
|
433
433
|
end
|
434
434
|
|
@@ -439,16 +439,16 @@ describe Clamp::Command do
|
|
439
439
|
describe "#help" do
|
440
440
|
|
441
441
|
it "indicates that there are options" do
|
442
|
-
|
442
|
+
command.help.should include("cmd [OPTIONS]")
|
443
443
|
end
|
444
444
|
|
445
445
|
it "includes option details" do
|
446
|
-
|
447
|
-
|
446
|
+
command.help.should =~ %r(--flavour FLAVOUR +Flavour of the month)
|
447
|
+
command.help.should =~ %r(--color COLOR +Preferred hue)
|
448
448
|
end
|
449
449
|
|
450
450
|
it "handles new lines in option descriptions" do
|
451
|
-
|
451
|
+
command.help.should =~ %r(--\[no-\]nuts +Nuts \(or not\)\n +May include nuts)
|
452
452
|
end
|
453
453
|
|
454
454
|
end
|
@@ -458,19 +458,19 @@ describe Clamp::Command do
|
|
458
458
|
describe "with an explicit --help option declared" do
|
459
459
|
|
460
460
|
before do
|
461
|
-
|
461
|
+
command.class.option ["--help"], :flag, "help wanted"
|
462
462
|
end
|
463
463
|
|
464
464
|
it "does not generate implicit help option" do
|
465
465
|
lambda do
|
466
|
-
|
466
|
+
command.parse(%w(--help))
|
467
467
|
end.should_not raise_error
|
468
|
-
|
468
|
+
command.help.should be_true
|
469
469
|
end
|
470
470
|
|
471
471
|
it "does not recognise -h" do
|
472
472
|
lambda do
|
473
|
-
|
473
|
+
command.parse(%w(-h))
|
474
474
|
end.should raise_error(Clamp::UsageError)
|
475
475
|
end
|
476
476
|
|
@@ -479,18 +479,18 @@ describe Clamp::Command do
|
|
479
479
|
describe "with an explicit -h option declared" do
|
480
480
|
|
481
481
|
before do
|
482
|
-
|
482
|
+
command.class.option ["-h", "--humidity"], "PERCENT", "relative humidity" do |n|
|
483
483
|
Integer(n)
|
484
484
|
end
|
485
485
|
end
|
486
486
|
|
487
487
|
it "does not map -h to help" do
|
488
|
-
|
488
|
+
command.help.should_not =~ %r( -h[, ].*help)
|
489
489
|
end
|
490
490
|
|
491
491
|
it "still recognises --help" do
|
492
492
|
lambda do
|
493
|
-
|
493
|
+
command.parse(%w(--help))
|
494
494
|
end.should raise_error(Clamp::HelpWanted)
|
495
495
|
end
|
496
496
|
|
@@ -499,21 +499,21 @@ describe Clamp::Command do
|
|
499
499
|
describe ".parameter" do
|
500
500
|
|
501
501
|
it "declares option argument accessors" do
|
502
|
-
|
503
|
-
|
504
|
-
|
505
|
-
|
502
|
+
command.class.parameter "FLAVOUR", "flavour of the month"
|
503
|
+
command.flavour.should == nil
|
504
|
+
command.flavour = "chocolate"
|
505
|
+
command.flavour.should == "chocolate"
|
506
506
|
end
|
507
507
|
|
508
508
|
describe "with explicit :attribute_name" do
|
509
509
|
|
510
510
|
before do
|
511
|
-
|
511
|
+
command.class.parameter "FOO", "a foo", :attribute_name => :bar
|
512
512
|
end
|
513
513
|
|
514
514
|
it "uses the specified attribute_name name to name accessors" do
|
515
|
-
|
516
|
-
|
515
|
+
command.bar = "chocolate"
|
516
|
+
command.bar.should == "chocolate"
|
517
517
|
end
|
518
518
|
|
519
519
|
end
|
@@ -521,17 +521,17 @@ describe Clamp::Command do
|
|
521
521
|
describe "with :default value" do
|
522
522
|
|
523
523
|
before do
|
524
|
-
|
524
|
+
command.class.parameter "[ORIENTATION]", "direction", :default => "west"
|
525
525
|
end
|
526
526
|
|
527
527
|
it "sets the specified default value" do
|
528
|
-
|
528
|
+
command.orientation.should == "west"
|
529
529
|
end
|
530
530
|
|
531
531
|
describe "#help" do
|
532
532
|
|
533
533
|
it "describes the default value" do
|
534
|
-
|
534
|
+
command.help.should include("direction (default: \"west\")")
|
535
535
|
end
|
536
536
|
|
537
537
|
end
|
@@ -541,17 +541,17 @@ describe Clamp::Command do
|
|
541
541
|
describe "with a block" do
|
542
542
|
|
543
543
|
before do
|
544
|
-
|
544
|
+
command.class.parameter "PORT", "port to listen on" do |port|
|
545
545
|
Integer(port)
|
546
546
|
end
|
547
547
|
end
|
548
548
|
|
549
549
|
it "uses the block to validate and convert the argument" do
|
550
550
|
lambda do
|
551
|
-
|
551
|
+
command.port = "blah"
|
552
552
|
end.should raise_error(ArgumentError)
|
553
|
-
|
554
|
-
|
553
|
+
command.port = "1234"
|
554
|
+
command.port.should == 1234
|
555
555
|
end
|
556
556
|
|
557
557
|
end
|
@@ -559,12 +559,12 @@ describe Clamp::Command do
|
|
559
559
|
describe "with ellipsis" do
|
560
560
|
|
561
561
|
before do
|
562
|
-
|
562
|
+
command.class.parameter "FILE ...", "files"
|
563
563
|
end
|
564
564
|
|
565
565
|
it "accepts multiple arguments" do
|
566
|
-
|
567
|
-
|
566
|
+
command.parse(%w(X Y Z))
|
567
|
+
command.file_list.should == %w(X Y Z)
|
568
568
|
end
|
569
569
|
|
570
570
|
end
|
@@ -572,13 +572,13 @@ describe Clamp::Command do
|
|
572
572
|
describe "optional, with ellipsis" do
|
573
573
|
|
574
574
|
before do
|
575
|
-
|
575
|
+
command.class.parameter "[FILE] ...", "files"
|
576
576
|
end
|
577
577
|
|
578
578
|
it "default to an empty list" do
|
579
|
-
|
580
|
-
|
581
|
-
|
579
|
+
command.parse([])
|
580
|
+
command.default_file_list.should == []
|
581
|
+
command.file_list.should == []
|
582
582
|
end
|
583
583
|
|
584
584
|
end
|
@@ -586,31 +586,31 @@ describe Clamp::Command do
|
|
586
586
|
describe "with :environment_variable value" do
|
587
587
|
|
588
588
|
before do
|
589
|
-
|
589
|
+
command.class.parameter "[FILE]", "a file", :environment_variable => "FILE",
|
590
590
|
:default => "/dev/null"
|
591
591
|
end
|
592
592
|
|
593
593
|
it "should use the default if neither flag nor env var are present" do
|
594
|
-
|
595
|
-
|
594
|
+
command.parse([])
|
595
|
+
command.file.should == "/dev/null"
|
596
596
|
end
|
597
597
|
|
598
598
|
it "should use the env value if present (instead of default)" do
|
599
599
|
ENV["FILE"] = "/etc/motd"
|
600
|
-
|
601
|
-
|
600
|
+
command.parse([])
|
601
|
+
command.file.should == ENV["FILE"]
|
602
602
|
end
|
603
603
|
|
604
604
|
it "should use the the flag value if present (instead of env)" do
|
605
605
|
ENV["FILE"] = "/etc/motd"
|
606
|
-
|
607
|
-
|
606
|
+
command.parse(%w(/bin/sh))
|
607
|
+
command.file.should == "/bin/sh"
|
608
608
|
end
|
609
609
|
|
610
610
|
describe "#help" do
|
611
611
|
|
612
612
|
it "describes the default value and env usage" do
|
613
|
-
|
613
|
+
command.help.should include(%{ (default: $FILE, or "/dev/null")})
|
614
614
|
end
|
615
615
|
|
616
616
|
end
|
@@ -627,7 +627,7 @@ describe Clamp::Command do
|
|
627
627
|
|
628
628
|
it "raises a UsageError" do
|
629
629
|
lambda do
|
630
|
-
|
630
|
+
command.parse(["crash"])
|
631
631
|
end.should raise_error(Clamp::UsageError, "too many arguments")
|
632
632
|
end
|
633
633
|
|
@@ -640,9 +640,9 @@ describe Clamp::Command do
|
|
640
640
|
describe "with parameters declared" do
|
641
641
|
|
642
642
|
before do
|
643
|
-
|
644
|
-
|
645
|
-
|
643
|
+
command.class.parameter "X", "x\nxx"
|
644
|
+
command.class.parameter "Y", "y"
|
645
|
+
command.class.parameter "[Z]", "z", :default => "ZZZ"
|
646
646
|
end
|
647
647
|
|
648
648
|
describe "#parse" do
|
@@ -650,13 +650,13 @@ describe Clamp::Command do
|
|
650
650
|
describe "with arguments for all parameters" do
|
651
651
|
|
652
652
|
before do
|
653
|
-
|
653
|
+
command.parse(["crash", "bang", "wallop"])
|
654
654
|
end
|
655
655
|
|
656
656
|
it "maps arguments onto the command object" do
|
657
|
-
|
658
|
-
|
659
|
-
|
657
|
+
command.x.should == "crash"
|
658
|
+
command.y.should == "bang"
|
659
|
+
command.z.should == "wallop"
|
660
660
|
end
|
661
661
|
|
662
662
|
end
|
@@ -665,7 +665,7 @@ describe Clamp::Command do
|
|
665
665
|
|
666
666
|
it "raises a UsageError" do
|
667
667
|
lambda do
|
668
|
-
|
668
|
+
command.parse(["crash"])
|
669
669
|
end.should raise_error(Clamp::UsageError, "parameter 'Y': no value provided")
|
670
670
|
end
|
671
671
|
|
@@ -674,10 +674,10 @@ describe Clamp::Command do
|
|
674
674
|
describe "with optional argument omitted" do
|
675
675
|
|
676
676
|
it "defaults the optional argument" do
|
677
|
-
|
678
|
-
|
679
|
-
|
680
|
-
|
677
|
+
command.parse(["crash", "bang"])
|
678
|
+
command.x.should == "crash"
|
679
|
+
command.y.should == "bang"
|
680
|
+
command.z.should == "ZZZ"
|
681
681
|
end
|
682
682
|
|
683
683
|
end
|
@@ -685,10 +685,10 @@ describe Clamp::Command do
|
|
685
685
|
describe "with multi-line arguments" do
|
686
686
|
|
687
687
|
it "parses them correctly" do
|
688
|
-
|
689
|
-
|
690
|
-
|
691
|
-
|
688
|
+
command.parse(["foo\nhi", "bar", "baz"])
|
689
|
+
command.x.should == "foo\nhi"
|
690
|
+
command.y.should == "bar"
|
691
|
+
command.z.should == "baz"
|
692
692
|
end
|
693
693
|
|
694
694
|
end
|
@@ -697,7 +697,7 @@ describe Clamp::Command do
|
|
697
697
|
|
698
698
|
it "raises a UsageError" do
|
699
699
|
lambda do
|
700
|
-
|
700
|
+
command.parse(["crash", "bang", "wallop", "kapow"])
|
701
701
|
end.should raise_error(Clamp::UsageError, "too many arguments")
|
702
702
|
end
|
703
703
|
|
@@ -708,17 +708,17 @@ describe Clamp::Command do
|
|
708
708
|
describe "#help" do
|
709
709
|
|
710
710
|
it "indicates that there are parameters" do
|
711
|
-
|
711
|
+
command.help.should include("cmd [OPTIONS] X Y [Z]")
|
712
712
|
end
|
713
713
|
|
714
714
|
it "includes parameter details" do
|
715
|
-
|
716
|
-
|
717
|
-
|
715
|
+
command.help.should =~ %r(X +x)
|
716
|
+
command.help.should =~ %r(Y +y)
|
717
|
+
command.help.should =~ %r(\[Z\] +z \(default: "ZZZ"\))
|
718
718
|
end
|
719
719
|
|
720
720
|
it "handles new lines in option descriptions" do
|
721
|
-
|
721
|
+
command.help.should =~ %r(X +x\n +xx)
|
722
722
|
end
|
723
723
|
|
724
724
|
end
|
@@ -737,7 +737,7 @@ describe Clamp::Command do
|
|
737
737
|
describe "#help" do
|
738
738
|
|
739
739
|
it "includes the explicit usage" do
|
740
|
-
|
740
|
+
command.help.should include("blah FOO BAR ...\n")
|
741
741
|
end
|
742
742
|
|
743
743
|
end
|
@@ -756,8 +756,8 @@ describe Clamp::Command do
|
|
756
756
|
describe "#help" do
|
757
757
|
|
758
758
|
it "includes both potential usages" do
|
759
|
-
|
760
|
-
|
759
|
+
command.help.should include("put THIS HERE\n")
|
760
|
+
command.help.should include("put THAT THERE\n")
|
761
761
|
end
|
762
762
|
|
763
763
|
end
|
@@ -780,8 +780,8 @@ describe Clamp::Command do
|
|
780
780
|
describe "#help" do
|
781
781
|
|
782
782
|
it "includes the description" do
|
783
|
-
|
784
|
-
|
783
|
+
command.help.should =~ /^ Punt is an example command/
|
784
|
+
command.help.should =~ /^ The prefix/
|
785
785
|
end
|
786
786
|
|
787
787
|
end
|
@@ -791,26 +791,26 @@ describe Clamp::Command do
|
|
791
791
|
describe ".run" do
|
792
792
|
|
793
793
|
it "creates a new Command instance and runs it" do
|
794
|
-
|
794
|
+
command.class.class_eval do
|
795
795
|
parameter "WORD ...", "words"
|
796
796
|
def execute
|
797
797
|
print word_list.inspect
|
798
798
|
end
|
799
799
|
end
|
800
800
|
@xyz = %w(x y z)
|
801
|
-
|
801
|
+
command.class.run("cmd", @xyz)
|
802
802
|
stdout.should == @xyz.inspect
|
803
803
|
end
|
804
804
|
|
805
805
|
describe "invoked with a context hash" do
|
806
806
|
|
807
807
|
it "makes the context available within the command" do
|
808
|
-
|
808
|
+
command.class.class_eval do
|
809
809
|
def execute
|
810
810
|
print context[:foo]
|
811
811
|
end
|
812
812
|
end
|
813
|
-
|
813
|
+
command.class.run("xyz", [], :foo => "bar")
|
814
814
|
stdout.should == "bar"
|
815
815
|
end
|
816
816
|
|
@@ -820,14 +820,14 @@ describe Clamp::Command do
|
|
820
820
|
|
821
821
|
before do
|
822
822
|
|
823
|
-
|
823
|
+
command.class.class_eval do
|
824
824
|
def execute
|
825
825
|
signal_usage_error "bad dog!"
|
826
826
|
end
|
827
827
|
end
|
828
828
|
|
829
829
|
begin
|
830
|
-
|
830
|
+
command.class.run("cmd", [])
|
831
831
|
rescue SystemExit => e
|
832
832
|
@system_exit = e
|
833
833
|
end
|
@@ -852,7 +852,7 @@ describe Clamp::Command do
|
|
852
852
|
describe "when help is requested" do
|
853
853
|
|
854
854
|
it "outputs help" do
|
855
|
-
|
855
|
+
command.class.run("cmd", ["--help"])
|
856
856
|
stdout.should include "Usage:"
|
857
857
|
end
|
858
858
|
|
@@ -862,19 +862,19 @@ describe Clamp::Command do
|
|
862
862
|
|
863
863
|
describe "subclass" do
|
864
864
|
|
865
|
-
|
866
|
-
|
865
|
+
let(:command) do
|
866
|
+
parent_command_class = Class.new(Clamp::Command) do
|
867
867
|
option "--verbose", :flag, "be louder"
|
868
868
|
end
|
869
|
-
|
869
|
+
derived_command_class = Class.new(parent_command_class) do
|
870
870
|
option "--iterations", "N", "number of times to go around"
|
871
871
|
end
|
872
|
-
|
872
|
+
derived_command_class.new("cmd")
|
873
873
|
end
|
874
874
|
|
875
875
|
it "inherits options from it's superclass" do
|
876
|
-
|
877
|
-
|
876
|
+
command.parse(["--verbose"])
|
877
|
+
command.should be_verbose
|
878
878
|
end
|
879
879
|
|
880
880
|
end
|