clamp 0.1.0 → 0.1.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.
- data/README.markdown +1 -1
- data/lib/clamp/command.rb +4 -4
- data/lib/clamp/help.rb +2 -1
- data/lib/clamp/option/parsing.rb +3 -3
- data/lib/clamp/parameter/parsing.rb +2 -4
- data/lib/clamp/subcommand/declaration.rb +8 -0
- data/lib/clamp/subcommand/execution.rb +2 -3
- data/lib/clamp/version.rb +1 -1
- data/spec/clamp/command_spec.rb +18 -19
- metadata +3 -3
data/README.markdown
CHANGED
@@ -121,7 +121,7 @@ Parsing and validation of options and parameters
|
|
121
121
|
|
122
122
|
When you `#run` a command, it will first attempt to `#parse` command-line arguments, and map them onto the declared options and parameters, before invoking your `#execute` method.
|
123
123
|
|
124
|
-
|
124
|
+
Clamp will verify that all required (ie. non-optional) parameters are present, and signal a error if they aren't.
|
125
125
|
|
126
126
|
### Validation block
|
127
127
|
|
data/lib/clamp/command.rb
CHANGED
@@ -35,8 +35,8 @@ module Clamp
|
|
35
35
|
|
36
36
|
# @return [Array<String>] unconsumed command-line arguments
|
37
37
|
#
|
38
|
-
def
|
39
|
-
@
|
38
|
+
def remaining_arguments
|
39
|
+
@remaining_arguments
|
40
40
|
end
|
41
41
|
|
42
42
|
# Parse command-line arguments.
|
@@ -45,10 +45,10 @@ module Clamp
|
|
45
45
|
# @return [Array<String>] unconsumed arguments
|
46
46
|
#
|
47
47
|
def parse(arguments)
|
48
|
-
@
|
48
|
+
@remaining_arguments = arguments.dup
|
49
49
|
parse_options
|
50
50
|
parse_parameters
|
51
|
-
@
|
51
|
+
@remaining_arguments
|
52
52
|
end
|
53
53
|
|
54
54
|
# Run the command, with the specified arguments.
|
data/lib/clamp/help.rb
CHANGED
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'stringio'
|
2
|
+
|
1
3
|
module Clamp
|
2
4
|
|
3
5
|
module Help
|
@@ -11,7 +13,6 @@ module Clamp
|
|
11
13
|
|
12
14
|
def derived_usage_description
|
13
15
|
parts = parameters.map { |a| a.name }
|
14
|
-
parts.unshift("SUBCOMMAND") if has_subcommands?
|
15
16
|
parts.unshift("[OPTIONS]") if has_options?
|
16
17
|
parts.join(" ")
|
17
18
|
end
|
data/lib/clamp/option/parsing.rb
CHANGED
@@ -6,13 +6,13 @@ module Clamp
|
|
6
6
|
protected
|
7
7
|
|
8
8
|
def parse_options
|
9
|
-
while
|
9
|
+
while remaining_arguments.first =~ /^-/
|
10
10
|
|
11
|
-
switch =
|
11
|
+
switch = remaining_arguments.shift
|
12
12
|
break if switch == "--"
|
13
13
|
|
14
14
|
option = find_option(switch)
|
15
|
-
value = option.extract_value(switch,
|
15
|
+
value = option.extract_value(switch, remaining_arguments)
|
16
16
|
|
17
17
|
begin
|
18
18
|
send("#{option.attribute_name}=", value)
|
@@ -7,18 +7,16 @@ module Clamp
|
|
7
7
|
|
8
8
|
def parse_parameters
|
9
9
|
|
10
|
-
return false if self.class.parameters.empty?
|
11
|
-
|
12
10
|
self.class.parameters.each do |parameter|
|
13
11
|
begin
|
14
|
-
value = parameter.consume(
|
12
|
+
value = parameter.consume(remaining_arguments)
|
15
13
|
send("#{parameter.attribute_name}=", value)
|
16
14
|
rescue ArgumentError => e
|
17
15
|
signal_usage_error "parameter '#{parameter.name}': #{e.message}"
|
18
16
|
end
|
19
17
|
end
|
20
18
|
|
21
|
-
unless
|
19
|
+
unless remaining_arguments.empty?
|
22
20
|
signal_usage_error "too many arguments"
|
23
21
|
end
|
24
22
|
|
@@ -13,6 +13,7 @@ module Clamp
|
|
13
13
|
end
|
14
14
|
|
15
15
|
def subcommand(name, description, subcommand_class = self, &block)
|
16
|
+
has_subcommands!
|
16
17
|
if block
|
17
18
|
# generate a anonymous sub-class
|
18
19
|
subcommand_class = Class.new(subcommand_class, &block)
|
@@ -27,6 +28,13 @@ module Clamp
|
|
27
28
|
def find_subcommand(name)
|
28
29
|
recognised_subcommands.find { |sc| sc.name == name }
|
29
30
|
end
|
31
|
+
|
32
|
+
def has_subcommands!
|
33
|
+
unless method_defined?(:subcommand_name)
|
34
|
+
parameter "SUBCOMMAND", "subcommand name", :attribute_name => :subcommand_name
|
35
|
+
parameter "[ARGS] ...", "subcommand arguments", :attribute_name => :subcommand_arguments
|
36
|
+
end
|
37
|
+
end
|
30
38
|
|
31
39
|
end
|
32
40
|
|
@@ -6,12 +6,11 @@ module Clamp
|
|
6
6
|
protected
|
7
7
|
|
8
8
|
def execute_subcommand
|
9
|
-
signal_usage_error "no subcommand specified"
|
10
|
-
subcommand_name = arguments.shift
|
9
|
+
signal_usage_error "no subcommand specified" unless subcommand_name
|
11
10
|
subcommand_class = find_subcommand_class(subcommand_name)
|
12
11
|
subcommand = subcommand_class.new("#{invocation_path} #{subcommand_name}", context)
|
13
12
|
subcommand.parent_command = self
|
14
|
-
subcommand.run(
|
13
|
+
subcommand.run(subcommand_arguments)
|
15
14
|
end
|
16
15
|
|
17
16
|
private
|
data/lib/clamp/version.rb
CHANGED
data/spec/clamp/command_spec.rb
CHANGED
@@ -14,7 +14,7 @@ describe Clamp::Command do
|
|
14
14
|
given_command("cmd") do
|
15
15
|
|
16
16
|
def execute
|
17
|
-
|
17
|
+
puts "Hello, world"
|
18
18
|
end
|
19
19
|
|
20
20
|
end
|
@@ -30,18 +30,13 @@ describe Clamp::Command do
|
|
30
30
|
describe "#run" do
|
31
31
|
|
32
32
|
before do
|
33
|
-
@
|
34
|
-
@command.run(@abc)
|
33
|
+
@command.run([])
|
35
34
|
end
|
36
35
|
|
37
36
|
it "executes the #execute method" do
|
38
37
|
stdout.should_not be_empty
|
39
38
|
end
|
40
39
|
|
41
|
-
it "provides access to the argument list" do
|
42
|
-
stdout.should == @abc.inspect
|
43
|
-
end
|
44
|
-
|
45
40
|
end
|
46
41
|
|
47
42
|
describe ".option" do
|
@@ -122,6 +117,7 @@ describe Clamp::Command do
|
|
122
117
|
@command.class.option "--flavour", "FLAVOUR", "Flavour of the month"
|
123
118
|
@command.class.option "--color", "COLOR", "Preferred hue"
|
124
119
|
@command.class.option "--[no-]nuts", :flag, "Nuts (or not)"
|
120
|
+
@command.class.parameter "[ARG] ...", "extra arguments", :attribute_name => :arguments
|
125
121
|
end
|
126
122
|
|
127
123
|
describe "#parse" do
|
@@ -139,7 +135,7 @@ describe Clamp::Command do
|
|
139
135
|
describe "with options" do
|
140
136
|
|
141
137
|
before do
|
142
|
-
@command.parse(%w(--flavour strawberry --nuts --color blue
|
138
|
+
@command.parse(%w(--flavour strawberry --nuts --color blue))
|
143
139
|
end
|
144
140
|
|
145
141
|
it "maps the option values onto the command object" do
|
@@ -148,10 +144,6 @@ describe Clamp::Command do
|
|
148
144
|
@command.nuts?.should == true
|
149
145
|
end
|
150
146
|
|
151
|
-
it "retains unconsumed arguments" do
|
152
|
-
@command.arguments.should == %w(a b c)
|
153
|
-
end
|
154
|
-
|
155
147
|
end
|
156
148
|
|
157
149
|
describe "with option-like things beyond the arguments" do
|
@@ -282,9 +274,14 @@ describe Clamp::Command do
|
|
282
274
|
|
283
275
|
describe "#parse" do
|
284
276
|
|
285
|
-
|
286
|
-
|
287
|
-
|
277
|
+
describe "with arguments" do
|
278
|
+
|
279
|
+
it "raises a UsageError" do
|
280
|
+
lambda do
|
281
|
+
@command.parse(["crash"])
|
282
|
+
end.should raise_error(Clamp::UsageError, "too many arguments")
|
283
|
+
end
|
284
|
+
|
288
285
|
end
|
289
286
|
|
290
287
|
end
|
@@ -313,10 +310,6 @@ describe Clamp::Command do
|
|
313
310
|
@command.z.should == "wallop"
|
314
311
|
end
|
315
312
|
|
316
|
-
it "consumes all the arguments" do
|
317
|
-
@command.arguments.should == []
|
318
|
-
end
|
319
|
-
|
320
313
|
end
|
321
314
|
|
322
315
|
describe "with insufficient arguments" do
|
@@ -395,6 +388,12 @@ describe Clamp::Command do
|
|
395
388
|
describe ".run" do
|
396
389
|
|
397
390
|
it "creates a new Command instance and runs it" do
|
391
|
+
@command.class.class_eval do
|
392
|
+
parameter "WORD ...", "words"
|
393
|
+
def execute
|
394
|
+
print word_list.inspect
|
395
|
+
end
|
396
|
+
end
|
398
397
|
@xyz = %w(x y z)
|
399
398
|
@command.class.run("cmd", @xyz)
|
400
399
|
stdout.should == @xyz.inspect
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clamp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 25
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 1
|
10
|
+
version: 0.1.1
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Mike Williams
|