clamp 0.3.0 → 0.3.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/.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
|