clamp 0.1.8 → 0.2.0

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.
@@ -203,6 +203,22 @@ Clamp generates an anonymous subclass of the current class, to represent the sub
203
203
 
204
204
  end
205
205
 
206
+ ### Default subcommand
207
+
208
+ You can mark a subcommand as "default" by using `default_subcommand` to declare it, rather than `subcommand`. Usually the SUBCOMMAND paramater is mandatory, but if a default subcommand is declared, it becomes optional.
209
+
210
+ class MainCommand < Clamp::Command
211
+
212
+ default_subcommand "status", "Display current status" do
213
+
214
+ def execute
215
+ # ...
216
+ end
217
+
218
+ end
219
+
220
+ end
221
+
206
222
  ### Subcommand options and parameters
207
223
 
208
224
  Options are inheritable, so any options declared for a parent command are supported for it's subcommands. Parameters, on the other hand, are not inherited - each subcommand must declare it's own parameter list.
@@ -3,10 +3,16 @@
3
3
  # An example of subcommands
4
4
 
5
5
  require "clamp"
6
+ require "clamp/version"
6
7
 
7
8
  class FlipFlop < Clamp::Command
8
9
 
9
- subcommand "flip", "flip it" do
10
+ option ["--version", "-v"], :flag, "Show version" do
11
+ puts "Powered by Clamp-#{Clamp::VERSION}"
12
+ exit(0)
13
+ end
14
+
15
+ default_subcommand "flip", "flip it" do
10
16
  def execute
11
17
  puts "FLIPPED"
12
18
  end
@@ -10,12 +10,12 @@ module Clamp
10
10
 
11
11
  def option(switches, type, description, opts = {}, &block)
12
12
  option = Clamp::Option.new(switches, type, description, opts)
13
- my_declared_options << option
13
+ declared_options << option
14
14
  define_accessors_for(option, &block)
15
15
  end
16
16
 
17
17
  def has_options?
18
- !declared_options.empty?
18
+ !documented_options.empty?
19
19
  end
20
20
 
21
21
  def find_option(switch)
@@ -23,24 +23,26 @@ module Clamp
23
23
  end
24
24
 
25
25
  def declared_options
26
- my_declared_options + inherited_declared_options
26
+ @declared_options ||= []
27
27
  end
28
28
 
29
- private
29
+ def documented_options
30
+ declared_options + inherited_declared_options
31
+ end
30
32
 
31
33
  def recognised_options
32
- declared_options + standard_options
34
+ documented_options + standard_options
33
35
  end
34
36
 
35
- def my_declared_options
36
- @my_declared_options ||= []
37
- end
37
+ private
38
38
 
39
39
  def inherited_declared_options
40
- if superclass.respond_to?(:declared_options)
41
- superclass.declared_options
42
- else
43
- []
40
+ ancestors.inject([]) do |options, ancestor|
41
+ if ancestor.kind_of?(Clamp::Option::Declaration)
42
+ options + ancestor.declared_options
43
+ else
44
+ options
45
+ end
44
46
  end
45
47
  end
46
48
 
@@ -11,28 +11,47 @@ module Clamp
11
11
 
12
12
  def subcommand(name, description, subcommand_class = self, &block)
13
13
  has_subcommands!
14
- if block
15
- # generate a anonymous sub-class
16
- subcommand_class = Class.new(subcommand_class, &block)
17
- end
18
- recognised_subcommands << Subcommand.new(name, description, subcommand_class)
14
+ declare_subcommand(name, description, subcommand_class, &block)
15
+ end
16
+
17
+ def default_subcommand(name, description, subcommand_class = self, &block)
18
+ has_subcommands!(name)
19
+ declare_subcommand(name, description, subcommand_class, &block)
19
20
  end
20
21
 
21
22
  def has_subcommands?
22
- !recognised_subcommands.empty?
23
+ @has_subcommands
23
24
  end
24
25
 
25
26
  def find_subcommand(name)
26
27
  recognised_subcommands.find { |sc| sc.is_called?(name) }
27
28
  end
28
29
 
29
- def has_subcommands!
30
- unless @has_subcommands
31
- parameter "SUBCOMMAND", "subcommand name", :attribute_name => :subcommand_name
30
+ def has_subcommands!(default = nil)
31
+ if @has_subcommands
32
+ if default
33
+ raise "You must declare the default_subcommand before any other subcommands"
34
+ end
35
+ else
36
+ if default
37
+ parameter "[SUBCOMMAND]", "subcommand name", :attribute_name => :subcommand_name, :default => default
38
+ else
39
+ parameter "SUBCOMMAND", "subcommand name", :attribute_name => :subcommand_name
40
+ end
32
41
  parameter "[ARGS] ...", "subcommand arguments", :attribute_name => :subcommand_arguments
33
42
  @has_subcommands = true
34
43
  end
35
44
  end
45
+
46
+ private
47
+
48
+ def declare_subcommand(name, description, subcommand_class = self, &block)
49
+ if block
50
+ # generate a anonymous sub-class
51
+ subcommand_class = Class.new(subcommand_class, &block)
52
+ end
53
+ recognised_subcommands << Subcommand.new(name, description, subcommand_class)
54
+ end
36
55
 
37
56
  end
38
57
 
@@ -9,7 +9,7 @@ module Clamp
9
9
  signal_usage_error "no subcommand specified" unless subcommand_name
10
10
  subcommand_class = find_subcommand_class(subcommand_name)
11
11
  subcommand = subcommand_class.new("#{invocation_path} #{subcommand_name}", context)
12
- self.class.declared_options.each do |option|
12
+ self.class.recognised_options.each do |option|
13
13
  option_set = instance_variable_defined?(option.ivar_name)
14
14
  if option_set && subcommand.respond_to?(option.write_method)
15
15
  subcommand.send(option.write_method, self.send(option.read_method))
@@ -1,3 +1,3 @@
1
1
  module Clamp
2
- VERSION = "0.1.8".freeze
2
+ VERSION = "0.2.0".freeze
3
3
  end
@@ -1,16 +1,10 @@
1
1
  require 'spec_helper'
2
- require 'stringio'
3
2
 
4
3
  describe Clamp::Command do
5
4
 
5
+ extend CommandFactory
6
6
  include OutputCapture
7
7
 
8
- def self.given_command(name, &block)
9
- before do
10
- @command = Class.new(Clamp::Command, &block).new(name)
11
- end
12
- end
13
-
14
8
  describe "with subcommands" do
15
9
 
16
10
  given_command "flipflop" do
@@ -112,6 +106,27 @@ describe Clamp::Command do
112
106
 
113
107
  end
114
108
 
109
+ describe "with a default subcommand" do
110
+
111
+ given_command "admin" do
112
+
113
+ default_subcommand "status", "Show status" do
114
+
115
+ def execute
116
+ puts "All good!"
117
+ end
118
+
119
+ end
120
+
121
+ end
122
+
123
+ it "delegates multiple levels" do
124
+ @command.run([])
125
+ stdout.should =~ /All good/
126
+ end
127
+
128
+ end
129
+
115
130
  describe "each subcommand" do
116
131
 
117
132
  before do
@@ -1,16 +1,10 @@
1
1
  require 'spec_helper'
2
- require 'stringio'
3
2
 
4
3
  describe Clamp::Command do
5
4
 
5
+ extend CommandFactory
6
6
  include OutputCapture
7
7
 
8
- def self.given_command(name, &block)
9
- before do
10
- @command = Class.new(Clamp::Command, &block).new(name)
11
- end
12
- end
13
-
14
8
  given_command("cmd") do
15
9
 
16
10
  def execute
@@ -0,0 +1,37 @@
1
+ require 'spec_helper'
2
+
3
+ describe Clamp::Command do
4
+
5
+ include OutputCapture
6
+
7
+ describe "with included module" do
8
+
9
+ before do
10
+
11
+ shared_options = Module.new do
12
+ extend Clamp::Option::Declaration
13
+ option "--size", "SIZE", :default => 4
14
+ end
15
+
16
+ @command_class = Class.new(Clamp::Command) do
17
+
18
+ include shared_options
19
+
20
+ def execute
21
+ puts "size = #{size}"
22
+ end
23
+
24
+ end
25
+
26
+ @command = @command_class.new("foo")
27
+
28
+ end
29
+
30
+ it "accepts options from included module" do
31
+ @command.run(["--size", "42"])
32
+ stdout.should == "size = 42\n"
33
+ end
34
+
35
+ end
36
+
37
+ end
@@ -1,5 +1,6 @@
1
1
  require "rspec"
2
2
  require "clamp"
3
+ require 'stringio'
3
4
 
4
5
  Rspec.configure do |config|
5
6
 
@@ -32,3 +33,13 @@ module OutputCapture
32
33
  end
33
34
 
34
35
  end
36
+
37
+ module CommandFactory
38
+
39
+ def given_command(name, &block)
40
+ before do
41
+ @command = Class.new(Clamp::Command, &block).new(name)
42
+ end
43
+ end
44
+
45
+ end
metadata CHANGED
@@ -1,13 +1,8 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: clamp
3
3
  version: !ruby/object:Gem::Version
4
- hash: 11
5
4
  prerelease:
6
- segments:
7
- - 0
8
- - 1
9
- - 8
10
- version: 0.1.8
5
+ version: 0.2.0
11
6
  platform: ruby
12
7
  authors:
13
8
  - Mike Williams
@@ -15,8 +10,7 @@ autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
12
 
18
- date: 2011-01-31 00:00:00 +11:00
19
- default_executable:
13
+ date: 2011-05-24 00:00:00 Z
20
14
  dependencies: []
21
15
 
22
16
  description: |
@@ -57,10 +51,10 @@ files:
57
51
  - lib/clamp/version.rb
58
52
  - spec/clamp/command_group_spec.rb
59
53
  - spec/clamp/command_spec.rb
54
+ - spec/clamp/option_module_spec.rb
60
55
  - spec/clamp/option_spec.rb
61
56
  - spec/clamp/parameter_spec.rb
62
57
  - spec/spec_helper.rb
63
- has_rdoc: true
64
58
  homepage: http://github.com/mdub/clamp
65
59
  licenses: []
66
60
 
@@ -74,7 +68,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
74
68
  requirements:
75
69
  - - ">="
76
70
  - !ruby/object:Gem::Version
77
- hash: 3
71
+ hash: 1396886237993251491
78
72
  segments:
79
73
  - 0
80
74
  version: "0"
@@ -83,20 +77,21 @@ required_rubygems_version: !ruby/object:Gem::Requirement
83
77
  requirements:
84
78
  - - ">="
85
79
  - !ruby/object:Gem::Version
86
- hash: 3
80
+ hash: 1396886237993251491
87
81
  segments:
88
82
  - 0
89
83
  version: "0"
90
84
  requirements: []
91
85
 
92
86
  rubyforge_project:
93
- rubygems_version: 1.4.2
87
+ rubygems_version: 1.7.2
94
88
  signing_key:
95
89
  specification_version: 3
96
90
  summary: a minimal framework for command-line utilities
97
91
  test_files:
98
92
  - spec/clamp/command_group_spec.rb
99
93
  - spec/clamp/command_spec.rb
94
+ - spec/clamp/option_module_spec.rb
100
95
  - spec/clamp/option_spec.rb
101
96
  - spec/clamp/parameter_spec.rb
102
97
  - spec/spec_helper.rb