clamp 0.3.0 → 0.3.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +1 -0
- data/.travis.yml +5 -0
- data/Gemfile +2 -2
- data/README.markdown +22 -0
- data/lib/clamp/attribute.rb +7 -7
- data/lib/clamp/attribute_declaration.rb +1 -1
- data/lib/clamp/option/declaration.rb +1 -1
- data/lib/clamp/parameter.rb +18 -8
- data/lib/clamp/subcommand/declaration.rb +1 -1
- data/lib/clamp/subcommand/parsing.rb +3 -4
- data/lib/clamp/version.rb +1 -1
- data/spec/clamp/command_group_spec.rb +21 -0
- data/spec/clamp/command_spec.rb +30 -3
- data/spec/clamp/parameter_spec.rb +75 -0
- data/spec/spec_helper.rb +5 -5
- metadata +6 -5
data/.gitignore
CHANGED
data/.travis.yml
ADDED
data/Gemfile
CHANGED
data/README.markdown
CHANGED
@@ -246,6 +246,28 @@ All Clamp commands support a "`--help`" option, which outputs brief usage docume
|
|
246
246
|
-n, --iterations N say it N times (default: 1)
|
247
247
|
-h, --help print help
|
248
248
|
|
249
|
+
License
|
250
|
+
-------
|
251
|
+
|
252
|
+
Copyright (C) 2011 [Mike Williams](mailto:mdub@dogbiscuit.org)
|
253
|
+
|
254
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
255
|
+
of this software and associated documentation files (the "Software"), to
|
256
|
+
deal in the Software without restriction, including without limitation the
|
257
|
+
rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
258
|
+
sell copies of the Software, and to permit persons to whom the Software is
|
259
|
+
furnished to do so, subject to the following conditions:
|
260
|
+
|
261
|
+
The above copyright notice and this permission notice shall be included in
|
262
|
+
all copies or substantial portions of the Software.
|
263
|
+
|
264
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
265
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
266
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
267
|
+
THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
|
268
|
+
IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
269
|
+
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
270
|
+
|
249
271
|
Contributing to Clamp
|
250
272
|
---------------------
|
251
273
|
|
data/lib/clamp/attribute.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
module Clamp
|
2
|
-
|
2
|
+
|
3
3
|
class Attribute
|
4
4
|
|
5
5
|
attr_reader :description, :attribute_name, :default_value
|
@@ -11,27 +11,27 @@ module Clamp
|
|
11
11
|
end
|
12
12
|
rhs
|
13
13
|
end
|
14
|
-
|
14
|
+
|
15
15
|
def help
|
16
16
|
[help_lhs, help_rhs]
|
17
17
|
end
|
18
|
-
|
18
|
+
|
19
19
|
def ivar_name
|
20
20
|
"@#{attribute_name}"
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
def read_method
|
24
24
|
attribute_name
|
25
25
|
end
|
26
|
-
|
26
|
+
|
27
27
|
def default_method
|
28
28
|
"default_#{read_method}"
|
29
29
|
end
|
30
|
-
|
30
|
+
|
31
31
|
def write_method
|
32
32
|
"#{attribute_name}="
|
33
33
|
end
|
34
34
|
|
35
35
|
end
|
36
|
-
|
36
|
+
|
37
37
|
end
|
@@ -30,7 +30,7 @@ module Clamp
|
|
30
30
|
private
|
31
31
|
|
32
32
|
def declare_implicit_options
|
33
|
-
return nil if @implicit_options_declared
|
33
|
+
return nil if defined?(@implicit_options_declared)
|
34
34
|
unless effective_options.find { |o| o.handles?("--help") }
|
35
35
|
help_switches = ["--help"]
|
36
36
|
help_switches.unshift("-h") unless effective_options.find { |o| o.handles?("-h") }
|
data/lib/clamp/parameter.rb
CHANGED
@@ -9,7 +9,7 @@ module Clamp
|
|
9
9
|
@description = description
|
10
10
|
infer_attribute_name_and_multiplicity
|
11
11
|
if options.has_key?(:attribute_name)
|
12
|
-
@attribute_name = options[:attribute_name].to_s
|
12
|
+
@attribute_name = options[:attribute_name].to_s
|
13
13
|
end
|
14
14
|
if options.has_key?(:default)
|
15
15
|
@default_value = options[:default]
|
@@ -17,7 +17,7 @@ module Clamp
|
|
17
17
|
end
|
18
18
|
|
19
19
|
attr_reader :name, :attribute_name
|
20
|
-
|
20
|
+
|
21
21
|
def help_lhs
|
22
22
|
name
|
23
23
|
end
|
@@ -27,16 +27,26 @@ module Clamp
|
|
27
27
|
raise ArgumentError, "no value provided"
|
28
28
|
end
|
29
29
|
if multivalued?
|
30
|
-
arguments.
|
30
|
+
if arguments.length > 0
|
31
|
+
arguments.shift(arguments.length)
|
32
|
+
end
|
31
33
|
else
|
32
34
|
arguments.shift
|
33
35
|
end
|
34
36
|
end
|
35
|
-
|
37
|
+
|
38
|
+
def default_value
|
39
|
+
if defined?(@default_value)
|
40
|
+
@default_value
|
41
|
+
elsif multivalued?
|
42
|
+
[]
|
43
|
+
end
|
44
|
+
end
|
45
|
+
|
36
46
|
private
|
37
47
|
|
38
48
|
NAME_PATTERN = "([A-Za-z0-9_-]+)"
|
39
|
-
|
49
|
+
|
40
50
|
def infer_attribute_name_and_multiplicity
|
41
51
|
case @name
|
42
52
|
when /^\[#{NAME_PATTERN}\]$/
|
@@ -56,7 +66,7 @@ module Clamp
|
|
56
66
|
end
|
57
67
|
@attribute_name = @attribute_name.downcase.tr('-', '_')
|
58
68
|
end
|
59
|
-
|
69
|
+
|
60
70
|
def multivalued?
|
61
71
|
@multivalued
|
62
72
|
end
|
@@ -64,7 +74,7 @@ module Clamp
|
|
64
74
|
def required?
|
65
75
|
@required
|
66
76
|
end
|
67
|
-
|
77
|
+
|
68
78
|
end
|
69
79
|
|
70
|
-
end
|
80
|
+
end
|
@@ -29,7 +29,7 @@ module Clamp
|
|
29
29
|
|
30
30
|
def default_subcommand(*args, &block)
|
31
31
|
if args.empty?
|
32
|
-
@default_subcommand
|
32
|
+
@default_subcommand ||= nil
|
33
33
|
else
|
34
34
|
$stderr.puts "WARNING: Clamp default_subcommand syntax has changed; check the README."
|
35
35
|
$stderr.puts " (from #{caller.first})"
|
@@ -28,9 +28,8 @@ module Clamp
|
|
28
28
|
subcommand_class = find_subcommand(name).subcommand_class
|
29
29
|
subcommand = subcommand_class.new("#{invocation_path} #{name}", context)
|
30
30
|
self.class.recognised_options.each do |option|
|
31
|
-
|
32
|
-
|
33
|
-
subcommand.send(option.write_method, self.send(option.read_method))
|
31
|
+
if instance_variable_defined?(option.ivar_name)
|
32
|
+
subcommand.instance_variable_set(option.ivar_name, instance_variable_get(option.ivar_name))
|
34
33
|
end
|
35
34
|
end
|
36
35
|
subcommand
|
@@ -39,4 +38,4 @@ module Clamp
|
|
39
38
|
end
|
40
39
|
|
41
40
|
end
|
42
|
-
end
|
41
|
+
end
|
data/lib/clamp/version.rb
CHANGED
@@ -243,4 +243,25 @@ describe Clamp::Command do
|
|
243
243
|
|
244
244
|
end
|
245
245
|
|
246
|
+
describe "with a subcommand, with options" do
|
247
|
+
|
248
|
+
given_command 'weeheehee' do
|
249
|
+
option '--json', 'JSON', 'a json blob' do |option|
|
250
|
+
print "parsing!"
|
251
|
+
option
|
252
|
+
end
|
253
|
+
|
254
|
+
subcommand 'woohoohoo', 'like weeheehee but with more o' do
|
255
|
+
def execute
|
256
|
+
end
|
257
|
+
end
|
258
|
+
end
|
259
|
+
|
260
|
+
it "only parses options once" do
|
261
|
+
@command.run(['--json', '{"a":"b"}', 'woohoohoo'])
|
262
|
+
stdout.should == 'parsing!'
|
263
|
+
end
|
264
|
+
|
265
|
+
end
|
266
|
+
|
246
267
|
end
|
data/spec/clamp/command_spec.rb
CHANGED
@@ -301,7 +301,7 @@ describe Clamp::Command do
|
|
301
301
|
@command.help.should =~ %r(--flavour FLAVOUR +Flavour of the month)
|
302
302
|
@command.help.should =~ %r(--color COLOR +Preferred hue)
|
303
303
|
end
|
304
|
-
|
304
|
+
|
305
305
|
it "handles new lines in option descriptions" do
|
306
306
|
@command.help.should =~ %r(--\[no-\]nuts +Nuts \(or not\)\n +May include nuts)
|
307
307
|
end
|
@@ -411,6 +411,33 @@ describe Clamp::Command do
|
|
411
411
|
|
412
412
|
end
|
413
413
|
|
414
|
+
describe "with ellipsis" do
|
415
|
+
|
416
|
+
before do
|
417
|
+
@command.class.parameter "FILE ...", "files"
|
418
|
+
end
|
419
|
+
|
420
|
+
it "accepts multiple arguments" do
|
421
|
+
@command.parse(%w(X Y Z))
|
422
|
+
@command.file_list.should == %w(X Y Z)
|
423
|
+
end
|
424
|
+
|
425
|
+
end
|
426
|
+
|
427
|
+
describe "optional, with ellipsis" do
|
428
|
+
|
429
|
+
before do
|
430
|
+
@command.class.parameter "[FILE] ...", "files"
|
431
|
+
end
|
432
|
+
|
433
|
+
it "default to an empty list" do
|
434
|
+
@command.parse([])
|
435
|
+
@command.default_file_list.should == []
|
436
|
+
@command.file_list.should == []
|
437
|
+
end
|
438
|
+
|
439
|
+
end
|
440
|
+
|
414
441
|
end
|
415
442
|
|
416
443
|
describe "with no parameters declared" do
|
@@ -497,9 +524,9 @@ describe Clamp::Command do
|
|
497
524
|
it "includes parameter details" do
|
498
525
|
@command.help.should =~ %r(X +x)
|
499
526
|
@command.help.should =~ %r(Y +y)
|
500
|
-
@command.help.should =~ %r(\[Z\] +z \(default: "ZZZ"\))
|
527
|
+
@command.help.should =~ %r(\[Z\] +z \(default: "ZZZ"\))
|
501
528
|
end
|
502
|
-
|
529
|
+
|
503
530
|
it "handles new lines in option descriptions" do
|
504
531
|
@command.help.should =~ %r(X +x\n +xx)
|
505
532
|
end
|
@@ -123,4 +123,79 @@ describe Clamp::Parameter do
|
|
123
123
|
end
|
124
124
|
end
|
125
125
|
|
126
|
+
describe "optional list" do
|
127
|
+
|
128
|
+
before do
|
129
|
+
@parameter = Clamp::Parameter.new("[FILES] ...", "files to process")
|
130
|
+
end
|
131
|
+
|
132
|
+
describe "#attribute_name" do
|
133
|
+
|
134
|
+
it "indicates multiplicity" do
|
135
|
+
@parameter.attribute_name.should == "files_list"
|
136
|
+
end
|
137
|
+
|
138
|
+
end
|
139
|
+
|
140
|
+
describe "#default_value" do
|
141
|
+
|
142
|
+
it "is an empty list" do
|
143
|
+
@parameter.default_value.should == []
|
144
|
+
end
|
145
|
+
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "#help" do
|
149
|
+
|
150
|
+
it "does not include default" do
|
151
|
+
@parameter.help_rhs.should_not include("default:")
|
152
|
+
end
|
153
|
+
|
154
|
+
end
|
155
|
+
|
156
|
+
describe "with specified default value" do
|
157
|
+
|
158
|
+
before do
|
159
|
+
@parameter = Clamp::Parameter.new("[FILES] ...", "files to process", :default => %w(a b c))
|
160
|
+
end
|
161
|
+
|
162
|
+
describe "#default_value" do
|
163
|
+
|
164
|
+
it "is that specified" do
|
165
|
+
@parameter.default_value.should == %w(a b c)
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
describe "#help" do
|
171
|
+
|
172
|
+
it "includes the default value" do
|
173
|
+
@parameter.help_rhs.should include("default:")
|
174
|
+
end
|
175
|
+
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "#consume" do
|
179
|
+
|
180
|
+
it "consumes all the remaining arguments" do
|
181
|
+
@arguments = %w(a b c)
|
182
|
+
@parameter.consume(@arguments).should == %w(a b c)
|
183
|
+
@arguments.should == []
|
184
|
+
end
|
185
|
+
|
186
|
+
describe "with no arguments" do
|
187
|
+
|
188
|
+
it "don't override defaults" do
|
189
|
+
@arguments = []
|
190
|
+
@parameter.consume(@arguments).should == nil
|
191
|
+
end
|
192
|
+
|
193
|
+
end
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
end
|
198
|
+
|
199
|
+
end
|
200
|
+
|
126
201
|
end
|
data/spec/spec_helper.rb
CHANGED
@@ -2,14 +2,14 @@ require "rspec"
|
|
2
2
|
require "clamp"
|
3
3
|
require 'stringio'
|
4
4
|
|
5
|
-
|
6
|
-
|
5
|
+
RSpec.configure do |config|
|
6
|
+
|
7
7
|
config.mock_with :rr
|
8
8
|
|
9
9
|
end
|
10
10
|
|
11
11
|
module OutputCapture
|
12
|
-
|
12
|
+
|
13
13
|
def self.included(target)
|
14
14
|
|
15
15
|
target.before do
|
@@ -21,7 +21,7 @@ module OutputCapture
|
|
21
21
|
$stdout = STDOUT
|
22
22
|
$stderr = STDERR
|
23
23
|
end
|
24
|
-
|
24
|
+
|
25
25
|
end
|
26
26
|
|
27
27
|
def stdout
|
@@ -35,7 +35,7 @@ module OutputCapture
|
|
35
35
|
end
|
36
36
|
|
37
37
|
module CommandFactory
|
38
|
-
|
38
|
+
|
39
39
|
def given_command(name, &block)
|
40
40
|
before do
|
41
41
|
@command = Class.new(Clamp::Command, &block).new(name)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: clamp
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.3.
|
4
|
+
version: 0.3.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
12
|
+
date: 2012-04-03 00:00:00.000000000 Z
|
13
13
|
dependencies: []
|
14
14
|
description: ! "Clamp provides an object-model for command-line utilities. \nIt handles
|
15
15
|
parsing of command-line options, and generation of usage help.\n"
|
@@ -19,6 +19,7 @@ extensions: []
|
|
19
19
|
extra_rdoc_files: []
|
20
20
|
files:
|
21
21
|
- .gitignore
|
22
|
+
- .travis.yml
|
22
23
|
- Gemfile
|
23
24
|
- README.markdown
|
24
25
|
- Rakefile
|
@@ -63,7 +64,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
63
64
|
version: '0'
|
64
65
|
segments:
|
65
66
|
- 0
|
66
|
-
hash:
|
67
|
+
hash: -1856448867096069066
|
67
68
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
68
69
|
none: false
|
69
70
|
requirements:
|
@@ -72,10 +73,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
72
73
|
version: '0'
|
73
74
|
segments:
|
74
75
|
- 0
|
75
|
-
hash:
|
76
|
+
hash: -1856448867096069066
|
76
77
|
requirements: []
|
77
78
|
rubyforge_project:
|
78
|
-
rubygems_version: 1.8.
|
79
|
+
rubygems_version: 1.8.21
|
79
80
|
signing_key:
|
80
81
|
specification_version: 3
|
81
82
|
summary: a minimal framework for command-line utilities
|