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 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