clamp 0.1.8 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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