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 CHANGED
@@ -1,5 +1,6 @@
1
1
  *.gem
2
2
  .bundle
3
+ .rvmrc
3
4
  .yardoc
4
5
  doc
5
6
  pkg/*
@@ -0,0 +1,5 @@
1
+ language: ruby
2
+ rvm:
3
+ - 1.8.7
4
+ - 1.9.2
5
+ - 1.9.3
data/Gemfile CHANGED
@@ -4,6 +4,6 @@ gemspec
4
4
 
5
5
  group :test do
6
6
  gem "rake"
7
- gem "rspec", "~> 2.0.1"
8
- gem "rr", "~> 1.0.0"
7
+ gem "rspec", "~> 2.6.0"
8
+ gem "rr", "~> 1.0.4"
9
9
  end
@@ -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
 
@@ -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
@@ -14,7 +14,7 @@ module Clamp
14
14
  define_method(attribute.read_method) do
15
15
  if instance_variable_defined?(attribute.ivar_name)
16
16
  instance_variable_get(attribute.ivar_name)
17
- elsif respond_to?(attribute.default_method)
17
+ else
18
18
  send(attribute.default_method)
19
19
  end
20
20
  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") }
@@ -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.shift(arguments.length)
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
- option_set = instance_variable_defined?(option.ivar_name)
32
- if option_set && subcommand.respond_to?(option.write_method)
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
@@ -1,3 +1,3 @@
1
1
  module Clamp
2
- VERSION = "0.3.0".freeze
2
+ VERSION = "0.3.1".freeze
3
3
  end
@@ -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
@@ -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
@@ -2,14 +2,14 @@ require "rspec"
2
2
  require "clamp"
3
3
  require 'stringio'
4
4
 
5
- Rspec.configure do |config|
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.0
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: 2011-10-30 00:00:00.000000000Z
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: 2140542804318955849
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: 2140542804318955849
76
+ hash: -1856448867096069066
76
77
  requirements: []
77
78
  rubyforge_project:
78
- rubygems_version: 1.8.10
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