commandable 0.2.0.beta01 → 0.2.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,2 @@
1
+ term-ansicolor-hi conflicts with term-ansicolor.
2
+
@@ -16,7 +16,16 @@ You can now "use your words" to let people interact with your apps in a natural
16
16
 
17
17
  ## Status
18
18
 
19
- 2011-03-17 - Final testing and building the example app. You could use it now, it's in feature freeze except for adding the example app (Widget).
19
+ 2011-03-18 - Final testing and building the example app. I'd wait to use it till I finish the example app. I'm finding new use cases as I do this and correcting some omissions of logic.
20
+
21
+ ## Principle of Least Surprise
22
+
23
+ I've tried to honestly follow the theory of the principle of least surprise so it should just work like you would expect it to.
24
+
25
+ ## Requirements ##
26
+
27
+ * Ruby 1.9.2
28
+ * *Nix OS (Probably works on Windows but not tested yet)
20
29
 
21
30
  ## Installation
22
31
  From the command line:
@@ -226,7 +235,7 @@ Then you can do something like this:
226
235
 
227
236
  require 'term/ansicolor'
228
237
 
229
- c = Term::ANSIColor
238
+ c = Term::ANSIColorHI
230
239
 
231
240
  Commandable.color_app_info = c.intense_white + c.bold
232
241
  Commandable.color_app_name = c.intense_green + c.bold
@@ -4,7 +4,7 @@ require 'commandable'
4
4
  Commandable.color_output = true
5
5
  Commandable.verbose_parameters = false
6
6
  Commandable.app_name = "commandable"
7
- Commandable.app_info =
7
+ Commandable.app_info =
8
8
  """
9
9
  \e[92mCommandable\e[0m - The easiest way to add command line control to your app.
10
10
  Copyrighted free software - Copyright (c) 2011 Mike Bethany.
@@ -11,11 +11,12 @@ Gem::Specification.new do |s|
11
11
  s.email = ["mikbe.tk@gmail.com"]
12
12
  s.homepage = "http://mikbe.tk"
13
13
  s.summary = %q{The easiest way to add command line control to your app.}
14
- s.description = %q{Adding command line control to your app is as easy as putting 'command "this command does xyz"' above a method. Parameter lists and a help command are automatically built for you.}
14
+ s.description = %q{The easiest way to add command line control to your app.\nAdding command line control to your app is as easy as putting 'command "this command does xyz"' above a method.\nParameter lists and a help command are automatically built for you.}
15
15
 
16
- s.add_dependency("term-ansicolor-hi", "~>1.0.6")
16
+ s.add_dependency("term-ansicolor-hi", "~>1.0.7")
17
17
 
18
18
  s.add_development_dependency("rspec", "~>2.5")
19
+ s.add_development_dependency("cucumber")
19
20
 
20
21
  s.files = `git ls-files`.split("\n")
21
22
  s.test_files = `git ls-files -- {spec,autotest}/*`.split("\n")
@@ -0,0 +1,11 @@
1
+ Feature: Ansicolor
2
+ In order to not have horrible looking colors
3
+ As a programmer
4
+ I want to make sure I'm using ANSIColorHI
5
+ And it doesn't conflict with the original ANSIColor
6
+
7
+
8
+ Scenario: Run a feature
9
+ When I run cucumber
10
+ Then it doesn't give an error
11
+
@@ -0,0 +1,3 @@
1
+ $LOAD_PATH.unshift(File.dirname(__FILE__) + '/../../lib')
2
+ require 'rspec/expectations'
3
+ require 'commandable'
@@ -0,0 +1,7 @@
1
+ When /^I run cucumber$/ do
2
+ true.should be_true
3
+ end
4
+
5
+ Then /^it doesn't give an error$/ do
6
+ true.should be_true
7
+ end
@@ -12,13 +12,13 @@ module Commandable
12
12
  `open #{File.expand_path((File.dirname(__FILE__) + '/../../readme.markdown'))}`
13
13
  end
14
14
 
15
- command "Copies a fully working app demonstrating how\n to use Commandable with RSpec and Cucumber"
15
+ command "Copies a fully working app demonstrating how\nto use Commandable with RSpec and Cucumber"
16
16
  # Creates a simple example app demonstrating a fully working app
17
17
  def widget(path="./widget")
18
18
  puts "This feature hasn't been added yet. I'm working on it now and it will be in the release version."
19
19
  end
20
20
 
21
- command "Copies the test classes to a folder so\n you can see a bunch of small examples"
21
+ command "Copies the test classes to a folder so\nyou can see a bunch of small examples"
22
22
  # Copies the test classes to a folder so you can see a bunch of small examples
23
23
  def examples(path="./example_classes")
24
24
  FileUtils.copy_dir(File.expand_path(File.dirname(__FILE__) + '/../../spec/source_code_examples'),path)
@@ -1,4 +1,4 @@
1
- require 'term/ansicolor'
1
+ require 'term/ansicolorhi'
2
2
  require 'set'
3
3
 
4
4
  # This library allows you to incredibly easily make
@@ -19,13 +19,13 @@ module Commandable
19
19
 
20
20
  # Describes your application, printed at the top of help/usage messages
21
21
  attr_accessor :app_info
22
-
22
+
23
23
  # Used when building the usage line, e.g. Usage: app_name [command] [parameters]
24
24
  attr_accessor :app_name
25
-
25
+
26
26
  # If optional parameters show default values, true by default
27
27
  attr_accessor :verbose_parameters
28
-
28
+
29
29
  # Boolean: If help/usage messages will print in color
30
30
  attr_accessor :color_output
31
31
  # What color the app_info text will be in the help message
@@ -40,7 +40,7 @@ module Commandable
40
40
  attr_accessor :color_parameter
41
41
  # What color the word "Usage:" will be in the help message
42
42
  attr_accessor :color_usage
43
-
43
+
44
44
  # What color the word "Error:" text will be in error messages
45
45
  attr_accessor :color_error_word
46
46
  # What color the friendly name of the error will be in error messages
@@ -145,18 +145,16 @@ module Commandable
145
145
  puts com[:proc].call
146
146
  end
147
147
  rescue Exception => exception
148
- if exception.respond_to?(:friendly_name)
149
- set_colors
150
- puts help(" #{@c_error_word}Error:#{@c_reset} #{@c_error_name}#{exception.friendly_name}#{@c_reset}\n #{@c_error_description}#{exception.message}#{@c_reset}\n\n")
151
- else
152
- #rescue Exception => exception
153
-
154
- puts "\n Bleep, bloop, bleep! Danger Will Robinson! Danger!"
155
- puts "\n Error: #{exception.inspect}"
156
- puts "\n Backtrace:"
157
- puts exception.backtrace.collect{|line| " #{line}"}
158
- puts
159
- end
148
+ if exception.respond_to?(:friendly_name)
149
+ set_colors
150
+ puts help("\n #{@c_error_word}Error:#{@c_reset} #{@c_error_name}#{exception.friendly_name}#{@c_reset}\n #{@c_error_description}#{exception.message}#{@c_reset}\n\n")
151
+ else
152
+ puts "\n Bleep, bloop, bleep! Danger Will Robinson! Danger!"
153
+ puts "\n Error: #{exception.inspect}"
154
+ puts "\n Backtrace:"
155
+ puts exception.backtrace.collect{|line| " #{line}"}
156
+ puts
157
+ end
160
158
  end
161
159
  end
162
160
 
@@ -202,6 +200,13 @@ module Commandable
202
200
  method_hash.each do |meth, params|
203
201
  command = @@commands[meth]
204
202
 
203
+ # Test for missing parameters
204
+ required = command[:parameters].select{|param| param[0]==:req} if command[:parameters]
205
+ if required
206
+ required.shift(params.count)
207
+ raise MissingRequiredParameterError, {:method=>meth, :parameters=>required.collect!{|meth| meth[1]}.to_s[1...-1].gsub(":","")} unless required.empty?
208
+ end
209
+
205
210
  # Test for duplicate XORs
206
211
  proc_array.select{|x| x[:xor] and x[:xor]==command[:xor] }.each {|bad| raise ExclusiveMethodClashError, "#{meth}, #{bad[:method]}"}
207
212
 
@@ -211,6 +216,7 @@ module Commandable
211
216
  proc_array << {:method=>meth, :xor=>command[:xor], :parameters=>params, :priority=>command[:priority], :proc=>lambda{klass.send(meth, *params)}}
212
217
  end
213
218
  proc_array.sort{|a,b| a[:priority] <=> b[:priority]}.reverse
219
+
214
220
  end
215
221
 
216
222
  # Set colors to their default values
@@ -218,8 +224,8 @@ module Commandable
218
224
  # Colors - off by default
219
225
  @color_output ||= false
220
226
  # Build the default colors
221
- Term::ANSIColor.coloring = true
222
- c = Term::ANSIColor
227
+ Term::ANSIColorHI.coloring = true
228
+ c = Term::ANSIColorHI
223
229
  @color_app_info = c.intense_white + c.bold
224
230
  @color_app_name = c.intense_green + c.bold
225
231
  @color_command = c.intense_yellow
@@ -34,6 +34,20 @@ module Commandable
34
34
  end
35
35
  end
36
36
 
37
+
38
+ # An error raised if a user does not provide a required command
39
+ class MissingRequiredParameterError < ScriptError
40
+ # Returns a more print friendly error name
41
+ def friendly_name
42
+ "Missing Required Parmeter"
43
+ end
44
+ # Create a new instance of the MissingRequiredParameterError class
45
+ def initialize(msg)
46
+ super("The command \"#{msg[:method]}\" is missing the required parameter \"#{msg[:parameters]}\".")
47
+ end
48
+ end
49
+
50
+
37
51
  # This error is raised if a user gives two or more commands from the same exclusive group
38
52
  class ExclusiveMethodClashError < ScriptError
39
53
  # Returns a more print friendly error name
@@ -1,4 +1,4 @@
1
1
  module Commandable
2
2
  # The application's version number
3
- VERSION = "0.2.0.beta01"
3
+ VERSION = "0.2.0.beta2"
4
4
  end
@@ -1,7 +1,7 @@
1
1
  require 'fileutils'
2
2
 
3
3
  module FileUtils
4
- # Monkeypatch FileUtils really annoying directory copying
4
+ # Monkeypatch FileUtils really annoying lack of proper directory copying
5
5
  def copy_dir(source, dest)
6
6
  files = Dir.glob("#{source}/**")
7
7
  mkdir_p dest
@@ -6,10 +6,10 @@ describe Commandable do
6
6
  Commandable.reset_all
7
7
  Commandable.app_name = "mycoolapp"
8
8
  Commandable.app_info =
9
- """
10
- My Cool App - It does stuff and things!
11
- Copyright (c) 2011 Acme Inc.
12
- """
9
+ """
10
+ My Cool App - It does stuff and things!
11
+ Copyright (c) 2011 Acme Inc.
12
+ """
13
13
 
14
14
  load 'parameter_class.rb'
15
15
  }
@@ -17,13 +17,29 @@ describe Commandable do
17
17
  context "when parsing arguments" do
18
18
 
19
19
  context "and there is an error in the command line" do
20
-
20
+
21
+ context "because a required parameter is not given" do
22
+
23
+ context "with a class that doesn't have a default method" do
24
+ specify{lambda{execute_queue(["zaz"]).should raise_error(MissingRequiredParameterError)}}
25
+ specify{lambda{execute_output_s(["zaz"]).should include(/Missing Required/)}}
26
+ specify{lambda{execute_queue(["zaz", "potato"]).should raise_error(MissingRequiredParameterError)}}
27
+ specify{lambda{execute_output_s(["zaz", "potato"]).should include(/Missing Required/)}}
28
+ specify{lambda{execute_queue(["zaz", "potato", "gump"]).should_not raise_error}}
29
+ specify{lambda{execute_output_s(["zaz", "potato", "gump"]).should_not include(/Missing Required/)}}
30
+ end
31
+
32
+ # When a default method has a required parameter and nothing is given on the command
33
+ # line Commandable will run help so you won't get a MissingRequiredParameterError
34
+
35
+ end
36
+
21
37
  context "and the default method does not accept parameters" do
22
38
 
23
39
  before(:each) {load 'default_method_no_params.rb'}
24
40
 
25
41
  context "but something that isn't a method is the first thing on the command line" do
26
- specify {lambda{Commandable.execution_queue(["potato"])}.should raise_error(Commandable::UnknownCommandError)}
42
+ specify {lambda{execute_queue(["potato"])}.should raise_error(Commandable::UnknownCommandError)}
27
43
  specify { execute_output_s(["potato"]).should match(/Unknown Command/)}
28
44
  end
29
45
 
@@ -31,7 +47,7 @@ describe Commandable do
31
47
 
32
48
  context "and running procs from the execution queue" do
33
49
  it "raises an error if there is an invalid command given" do
34
- lambda{Commandable.execution_queue(["fly", "navy"])}.should raise_error(Commandable::UnknownCommandError)
50
+ lambda{execute_queue(["fly", "navy"])}.should raise_error(Commandable::UnknownCommandError)
35
51
  end
36
52
  end
37
53
 
@@ -146,9 +162,16 @@ describe Commandable do
146
162
 
147
163
  end
148
164
 
165
+ context "when a default method name isn't specified but the required switch is properly given" do
166
+ before(:each){load "default_method.rb"}
167
+ specify{lambda{execute_queue(["phish"])}.should_not raise_error}
168
+ specify{lambda{execute_output_s(["phish"]).should include(/default method called with: phish/)}}
169
+ specify{execute_queue(["not_a_default_method", "potato"]).should include("not a default method, called with: Cleveland, potato") }
170
+ specify{execute_output_s(["not_a_default_method", "phish"]).should include("not a default method, called with: Cleveland, phish")}
171
+ end
172
+
149
173
  end
150
174
 
151
-
152
175
  end
153
176
 
154
177
  end
@@ -188,14 +188,13 @@ describe Commandable do
188
188
  end
189
189
 
190
190
  it "executes the default command if no command is given" do
191
- execute_output_ary(["Klaatu"]).should == ["default method called with: Klaatu"]
191
+ execute_output_ary(["Klaatu"]).should include("default method called with: Klaatu")
192
192
  end
193
193
 
194
194
  it "executes a default method and a second command" do
195
- execute_output_ary(["Klaatu", "not_a_default_method", "28"]).sort.should == [
195
+ execute_output_ary(["Klaatu", "not_a_default_method", "28"]).should include(
196
196
  "default method called with: Klaatu",
197
- "not a default method, called with: Cleveland",
198
- "28"].sort
197
+ "not a default method, called with: Cleveland, 28")
199
198
  end
200
199
 
201
200
  end
@@ -113,7 +113,7 @@ describe Commandable do
113
113
  Copyright (c) 2011 Acme Inc."""
114
114
  end
115
115
 
116
- let(:c) {Term::ANSIColor}
116
+ let(:c) {Term::ANSIColorHI}
117
117
 
118
118
  it "changes the output if color is enabled" do
119
119
  Commandable.color_output = false
@@ -18,7 +18,7 @@ describe Commandable do
18
18
  from(%{ My Cool App - It does stuff and things!\n Copyright (c) 2011 Acme Inc.}).
19
19
  to(nil)
20
20
  }
21
- specify {lambda{Commandable.reset_all}.should change{Commandable.commands.length}.from(5).to(1)}
21
+ specify {lambda{Commandable.reset_all}.should change{Commandable.commands.length}.from(6).to(1)}
22
22
 
23
23
 
24
24
 
@@ -11,7 +11,7 @@ class DefaultMethods
11
11
 
12
12
  command 'does other stuff'
13
13
  def not_a_default_method(name="Cleveland", age)
14
- ["not a default method, called with: #{name}", age]
14
+ "not a default method, called with: #{name}, #{age}"
15
15
  end
16
16
 
17
17
  end
@@ -0,0 +1,17 @@
1
+ @@command_options
2
+ require "commandable"
3
+
4
+ class DefaultMethodsMultiParameters
5
+ extend Commandable
6
+
7
+ command 'the default method', :default
8
+ def default_method_multi(name, optional="optional")
9
+ "multi default method called with: #{name}, #{optional}"
10
+ end
11
+
12
+ command 'does other stuff'
13
+ def not_a_default_method_multi(name="Cleveland", age)
14
+ ["multi not a default method, called with: #{name}", age]
15
+ end
16
+
17
+ end
@@ -24,4 +24,9 @@ class ParameterClass
24
24
  [number_arg1, string_arg2, array_arg3]
25
25
  end
26
26
 
27
+ command "a method with a required parameter"
28
+ def zaz(required_param, another_required)
29
+ [required_param, another_required]
30
+ end
31
+
27
32
  end
@@ -8,6 +8,3 @@ class TestClass
8
8
  "test_method"
9
9
  end
10
10
  end
11
-
12
-
13
- puts Commandable.execution_queue([])
@@ -3,6 +3,7 @@ $:.unshift File.expand_path((File.dirname(__FILE__) + '/source_code_examples'))
3
3
  $:.unshift File.expand_path((File.dirname(__FILE__) + '/source_code_for_errors'))
4
4
  $:.unshift File.expand_path(File.dirname(__FILE__))
5
5
 
6
+ require 'pp'
6
7
  require 'term/ansicolor'
7
8
  require 'rspec'
8
9
  require 'commandable'
@@ -53,3 +54,8 @@ def execute_output_s(argv)
53
54
  output = capture_output{Commandable.execute(argv)}
54
55
  output[:stdout] + output[:stderr]
55
56
  end
57
+
58
+ def execute_queue(argv)
59
+ queue = Commandable.execution_queue(argv)
60
+ queue.collect{|meth| meth[:proc].call}
61
+ end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: commandable
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0.beta01
4
+ version: 0.2.0.beta2
5
5
  prerelease: 6
6
6
  platform: ruby
7
7
  authors:
@@ -9,23 +9,23 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2011-03-17 00:00:00.000000000 -04:00
12
+ date: 2011-03-21 00:00:00.000000000 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: term-ansicolor-hi
17
- requirement: &2154595880 !ruby/object:Gem::Requirement
17
+ requirement: &2154879100 !ruby/object:Gem::Requirement
18
18
  none: false
19
19
  requirements:
20
20
  - - ~>
21
21
  - !ruby/object:Gem::Version
22
- version: 1.0.6
22
+ version: 1.0.7
23
23
  type: :runtime
24
24
  prerelease: false
25
- version_requirements: *2154595880
25
+ version_requirements: *2154879100
26
26
  - !ruby/object:Gem::Dependency
27
27
  name: rspec
28
- requirement: &2154595380 !ruby/object:Gem::Requirement
28
+ requirement: &2154878600 !ruby/object:Gem::Requirement
29
29
  none: false
30
30
  requirements:
31
31
  - - ~>
@@ -33,10 +33,22 @@ dependencies:
33
33
  version: '2.5'
34
34
  type: :development
35
35
  prerelease: false
36
- version_requirements: *2154595380
37
- description: Adding command line control to your app is as easy as putting 'command
38
- "this command does xyz"' above a method. Parameter lists and a help command are
39
- automatically built for you.
36
+ version_requirements: *2154878600
37
+ - !ruby/object:Gem::Dependency
38
+ name: cucumber
39
+ requirement: &2154878200 !ruby/object:Gem::Requirement
40
+ none: false
41
+ requirements:
42
+ - - ! '>='
43
+ - !ruby/object:Gem::Version
44
+ version: '0'
45
+ type: :development
46
+ prerelease: false
47
+ version_requirements: *2154878200
48
+ description: The easiest way to add command line control to your app.\nAdding command
49
+ line control to your app is as easy as putting 'command "this command does xyz"'
50
+ above a method.\nParameter lists and a help command are automatically built for
51
+ you.
40
52
  email:
41
53
  - mikbe.tk@gmail.com
42
54
  executables:
@@ -45,6 +57,7 @@ extensions: []
45
57
  extra_rdoc_files: []
46
58
  files:
47
59
  - .gitignore
60
+ - BUGS.txt
48
61
  - Gemfile
49
62
  - LICENCE
50
63
  - README.markdown
@@ -53,6 +66,9 @@ files:
53
66
  - autotest/discover.rb
54
67
  - bin/commandable
55
68
  - commandable.gemspec
69
+ - features/ansicolor.feature
70
+ - features/setup/env.rb
71
+ - features/step-definitions/step-definitions.rb
56
72
  - lib/commandable.rb
57
73
  - lib/commandable/app_controller.rb
58
74
  - lib/commandable/commandable.rb
@@ -71,6 +87,7 @@ files:
71
87
  - spec/source_code_examples/command_no_command.rb
72
88
  - spec/source_code_examples/deep_class.rb
73
89
  - spec/source_code_examples/default_method.rb
90
+ - spec/source_code_examples/default_method_multiparameters.rb
74
91
  - spec/source_code_examples/default_method_no_params.rb
75
92
  - spec/source_code_examples/multi_line_description.rb
76
93
  - spec/source_code_examples/multi_line_description_no_params.rb
@@ -124,6 +141,7 @@ test_files:
124
141
  - spec/source_code_examples/command_no_command.rb
125
142
  - spec/source_code_examples/deep_class.rb
126
143
  - spec/source_code_examples/default_method.rb
144
+ - spec/source_code_examples/default_method_multiparameters.rb
127
145
  - spec/source_code_examples/default_method_no_params.rb
128
146
  - spec/source_code_examples/multi_line_description.rb
129
147
  - spec/source_code_examples/multi_line_description_no_params.rb