cp 0.0.1 → 0.0.2

Sign up to get free protection for your applications and to get access to all the features.
data/cp.gemspec CHANGED
@@ -1,4 +1,3 @@
1
- # -*- encoding: utf-8 -*-
2
1
  $:.push File.expand_path("../lib", __FILE__)
3
2
  require "cp/version"
4
3
 
@@ -10,12 +9,14 @@ Gem::Specification.new do |s|
10
9
  s.email = ["fletch@pobox.com"]
11
10
  s.homepage = "https://github.com/baseballdb/cp"
12
11
  s.summary = %q{An alternative API for CmdParse}
13
- s.description = %q{CP provides a less verbose API for the CmdParse gem.}
12
+ s.description = s.summary
14
13
 
15
14
  s.files = `git ls-files`.split("\n")
16
15
  s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
17
16
  s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
18
17
  s.require_paths = ["lib"]
19
18
 
20
- s.add_runtime_dependency(%q<cmdparse>, [">= 2.0.2"])
19
+ s.add_runtime_dependency "cmdparse", "~> 2.0.2"
20
+ s.add_runtime_dependency "highline", "~> 1.6.2"
21
+ s.add_runtime_dependency "json_pure", "~> 1.5.1"
21
22
  end
data/examples/net.rb CHANGED
@@ -32,8 +32,8 @@ command :ipaddr do |c|
32
32
  c.command( :add ) do |s|
33
33
  s.summary = "Add an IP address"
34
34
 
35
- s.execute do |opts, args|
36
- puts "Adding IP addresses: #{args.join(', ')}" if $verbose
35
+ s.action do |opts, args|
36
+ say "Adding IP addresses: #{args.join(', ')}" if $verbose
37
37
  $ipaddrs += args
38
38
  end
39
39
  end
@@ -44,11 +44,11 @@ command :ipaddr do |c|
44
44
 
45
45
  s.option( "-a", "--all", "Delete all IP addresses" ){ $deleteAll = true }
46
46
 
47
- s.execute do |opts, args|
47
+ s.action do |opts, args|
48
48
  if $deleteAll
49
49
  $ipaddrs = []
50
50
  else
51
- puts "Deleting IP addresses: #{args.join(', ')}" if $verbose
51
+ say "Deleting IP addresses: #{args.join(', ')}" if $verbose
52
52
  args.each { |ip| $ipaddrs.delete( ip ) }
53
53
  end
54
54
  end
@@ -59,9 +59,9 @@ command :ipaddr do |c|
59
59
  s.default = true
60
60
  s.summary = "List all IP addresses"
61
61
 
62
- s.execute do |*args|
63
- puts "Listing IP addresses:" if $verbose
64
- puts $ipaddrs.to_yaml
62
+ s.action do |*args|
63
+ say "Listing IP addresses:" if $verbose
64
+ say $ipaddrs.to_yaml
65
65
  end
66
66
  end
67
67
 
@@ -70,15 +70,16 @@ command :ipaddr do |c|
70
70
  s.summary = "Show network statistics"
71
71
  s.description = "This command shows very useful network statistics - eye catching!!!"
72
72
 
73
- s.execute do |opts, args|
74
- puts "Showing network statistics" if $verbose
75
- puts
76
- puts "Yeah, I will do something now..."
77
- puts
73
+ s.action do |opts, args|
74
+ if $verbose
75
+ say "Showing network statistics"
76
+ say
77
+ end
78
+ say "Yeah, I will do something now..."
79
+ say
78
80
  1.upto(10) do |row|
79
- puts " "*(20-row) + "#"*(row*2 - 1)
81
+ say " "*(20-row) + "#"*(row*2 - 1)
80
82
  end
81
- puts
82
83
  end
83
84
  end
84
85
  end
data/lib/cp.rb CHANGED
@@ -1,9 +1,17 @@
1
1
  require "rubygems"
2
+
2
3
  require "cmdparse"
4
+ require "highline"
5
+ require "json"
3
6
  require "optparse"
7
+ require "terminal-table"
8
+ require "yaml"
9
+
10
+ require "ext/core"
4
11
 
5
12
  require "cp/has/commands"
6
13
  require "cp/has/options"
14
+ require "cp/highline"
7
15
 
8
16
  require "cp/app"
9
17
  require "cp/command"
@@ -28,7 +36,7 @@ module CP
28
36
  at_exit { CP::App.run } if is_main
29
37
  end
30
38
 
31
- [:app, :command, :option].each do |method|
39
+ CP::App.exported_methods.each do |method|
32
40
  define_method( method ) { |*args, &block|
33
41
  CP::App.instance.send( method, *args, &block )
34
42
  }
data/lib/cp/app.rb CHANGED
@@ -12,6 +12,8 @@ module CP
12
12
  def initialize
13
13
  self.name = File.basename( $0 )
14
14
  self.runner = CP::Runners::CmdParse
15
+
16
+ define_builtin_options
15
17
  end
16
18
 
17
19
  def app( attr, value )
@@ -22,6 +24,15 @@ module CP
22
24
  end
23
25
  end
24
26
 
27
+ def define_builtin_options
28
+ option( "-f", "--format FORMAT", "Output format" ) do |o|
29
+ o.allowed = [:json, :table, :yaml]
30
+ o.action = lambda { |value|
31
+ CP::HighLine.instance.format = value
32
+ }
33
+ end
34
+ end
35
+
25
36
  def fatal( msg )
26
37
  self.error( msg )
27
38
  exit 1
@@ -31,6 +42,10 @@ module CP
31
42
  $stderr.puts "#{self.name}: #{msg}. See `#{self.name} --help`."
32
43
  end
33
44
 
45
+ def self.exported_methods
46
+ [:app, :command, :option]
47
+ end
48
+
34
49
  def run( *args )
35
50
  CP::App.instance.runner.new( CP::App.instance ).run( *args )
36
51
  end
data/lib/cp/command.rb CHANGED
@@ -3,7 +3,7 @@ module CP
3
3
  include CP::Has::Commands
4
4
  include CP::Has::Options
5
5
 
6
- attr_reader :block, :name, :parent
6
+ attr_reader :name, :parent
7
7
  attr_accessor :default, :description, :summary
8
8
 
9
9
  def initialize( name, parent=nil )
@@ -17,38 +17,54 @@ module CP
17
17
  yield self if block_given?
18
18
  end
19
19
 
20
- def execute( &block )
21
- @block = lambda { |args|
22
- begin
23
- opts = gather_options
24
- rescue CP::MissingOptionError => e
25
- CP::App.instance.fatal( "'#{e}' is required" )
26
- end
20
+ def action( &block )
21
+ if !block_given?
22
+ @action
23
+ else
24
+ @action = lambda { |args|
25
+ begin
26
+ opts = gather_options
27
+ rescue CP::MissingOptionError => e
28
+ CP::App.instance.fatal( "'#{e}' is required" )
29
+ end
27
30
 
28
- block.call( args, opts )
29
- }
31
+ block.call( args, opts )
32
+ CP::HighLine.instance.say_buffer
33
+ }
34
+ end
30
35
  end
31
36
 
32
- private
37
+ def action=( block )
38
+ action( &block )
39
+ end
33
40
 
34
- def gather_options
35
- options = []
41
+ private
36
42
 
37
- current = self
38
- begin
39
- options += current.options
40
- current = current.respond_to?( :parent ) ? current.parent : nil
41
- end while current && current.respond_to?( :options )
43
+ # get ancestor commands [child, parent, grandparent]
44
+ def ancestors
45
+ commands = [self]
46
+ while commands.last.respond_to?( :parent ) && commands.last.parent
47
+ commands << commands.last.parent
48
+ end
49
+ commands
50
+ end
42
51
 
43
- option_names = options.map { |o|
44
- raise CP::MissingOptionError.new( o.switches.last ) if o.required? && o.value.nil?
45
- o.name
46
- }.sort.uniq
52
+ def gather_options
53
+ options = ancestors.reverse.inject( {} ) do |o, command|
54
+ o.merge( command.options )
55
+ end
47
56
 
48
- struct = CP::OptionsStruct.new( *option_names )
57
+ validate_options( options )
49
58
 
50
- options.reverse.each { |o| struct[o.name] = o.value }
59
+ struct = CP::OptionsStruct.new( *options.keys )
60
+ options.each { |k, v| struct[k] = v.value }
51
61
  struct
52
62
  end
63
+
64
+ def validate_options( opts )
65
+ opts.each do |k, v|
66
+ raise CP::MissingOptionError.new( v.switches.last ) if v.required? && v.value.nil?
67
+ end
68
+ end
53
69
  end
54
70
  end
@@ -2,17 +2,17 @@ module CP
2
2
  module Has
3
3
  module Commands
4
4
  def commands
5
- @commands ||= []
5
+ @commands ||= {}
6
6
  @commands
7
7
  end
8
8
 
9
9
  def command( name )
10
10
  cmd = name.to_s.split( " " ).inject( self ) do |parent, name|
11
- subcommand = parent.commands.find { |c| c.name === name.to_sym }
11
+ subcommand = parent.commands[name.to_sym]
12
12
 
13
13
  if subcommand.nil?
14
14
  subcommand = CP::Command.new( name, parent )
15
- parent.commands << subcommand
15
+ parent.commands[subcommand.name] = subcommand
16
16
  end
17
17
 
18
18
  subcommand
@@ -21,7 +21,7 @@ module CP
21
21
  yield cmd if block_given?
22
22
 
23
23
  if cmd.default
24
- default_cmd = commands.find{ |c| c.default }
24
+ default_cmd = commands.values.find{ |c| c.default && c != cmd }
25
25
  if default_cmd
26
26
  raise CP::CommandError.new( "only one default command is allowed: #{default_cmd.name}, #{cmd.name}" )
27
27
  end
@@ -2,14 +2,23 @@ module CP
2
2
  module Has
3
3
  module Options
4
4
  def options
5
- @options ||= []
5
+ @options ||= {}
6
6
  @options
7
7
  end
8
8
 
9
9
  def option( *args )
10
10
  opt = CP::Option.new( *args )
11
11
  yield opt if block_given?
12
- options << opt
12
+
13
+ if( respond_to?( :ancestors, true ) )
14
+ parent_opt = ancestors[1..-1].reverse.inject( {} ) { |opts, c|
15
+ opts.merge( c.options )
16
+ }[opt.name]
17
+
18
+ opt = parent_opt.merge( opt ) if parent_opt
19
+ end
20
+
21
+ options[opt.name] = opt
13
22
  opt
14
23
  end
15
24
  end
@@ -0,0 +1,41 @@
1
+ require "forwardable"
2
+ require "singleton"
3
+
4
+ module CP
5
+ class HighLine < HighLine
6
+ include ::Singleton
7
+
8
+ attr_reader :format
9
+
10
+ def format=( format )
11
+ @format = format
12
+ @buffer = @format.nil? ? nil : []
13
+ end
14
+
15
+ def say( statement="" )
16
+ @output = $stdout # because we override $stdout for testing
17
+
18
+ if !@buffer.nil?
19
+ @buffer << statement
20
+ else
21
+ formatter = "to_#{format}".to_sym
22
+ statement = statement.respond_to?( formatter ) ? statement.send( formatter ) : statement.to_s
23
+ super( statement )
24
+ end
25
+ end
26
+
27
+ def say_buffer
28
+ if !@buffer.nil? && @buffer.size > 0
29
+ statement = @buffer
30
+ @buffer = nil
31
+ say( statement.size === 1 ? statement.first : statement )
32
+ @buffer = []
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ module Kernel
39
+ extend Forwardable
40
+ def_delegators :"CP::HighLine.instance", :agree, :ask, :choose, :say
41
+ end
data/lib/cp/option.rb CHANGED
@@ -3,7 +3,7 @@ require "optparse"
3
3
  module CP
4
4
  class Option
5
5
  attr_accessor :allowed, :default, :description, :type
6
- attr_reader :arg, :block, :short, :long
6
+ attr_reader :arg, :short, :long
7
7
 
8
8
  # see: OptionsParser#make_switch
9
9
  def initialize( *args )
@@ -20,11 +20,21 @@ module CP
20
20
  end
21
21
  end
22
22
 
23
- def block=( block=nil )
24
- @block = lambda { |value|
25
- @value = value
26
- block.call( *( block.arity === 0 ? [] : [value] ) ) if block
27
- }
23
+ def action( &block )
24
+ save_value = lambda { |value| @value = value }
25
+
26
+ if !block_given?
27
+ @action || save_value
28
+ else
29
+ @action = lambda { |value|
30
+ save_value.call( value )
31
+ block.call( *( block.arity === 0 ? [] : [value] ) ) if block
32
+ }
33
+ end
34
+ end
35
+
36
+ def action=( block )
37
+ action( &block )
28
38
  end
29
39
 
30
40
  def long=( val )
@@ -40,6 +50,17 @@ module CP
40
50
  name.gsub( "-", "_" ).to_sym
41
51
  end
42
52
 
53
+ def merge( opt )
54
+ new_opt = self.dup
55
+ new_opt.action = @action
56
+ [:allowed, :default, :description, :type, :short, :long].each { |attr|
57
+ val = opt.send( :"#{attr}" )
58
+ new_opt.send( :"#{attr}=", val.dup ) unless val.nil?
59
+ }
60
+
61
+ new_opt
62
+ end
63
+
43
64
  def required=( val )
44
65
  @required = !!val
45
66
  end
@@ -63,7 +84,7 @@ module CP
63
84
  end
64
85
 
65
86
  def to_option_parser_args
66
- args = self.switches + [self.type, self.allowed, self.description, self.block]
87
+ args = self.switches + [self.type, self.allowed, self.description, self.action]
67
88
  args.find_all { |a| !a.nil? }
68
89
  end
69
90
 
@@ -81,7 +102,7 @@ module CP
81
102
  self.allowed = args.find { |a| a.is_a?( Hash ) || a.is_a?( Array ) }
82
103
  self.type = args.find { |a| a.is_a?( Class ) }
83
104
  self.description = switch.desc.first rescue nil
84
- self.block = switch.block
105
+ self.action = switch.block
85
106
  self.long = switch
86
107
  self.short = switch
87
108
  end
@@ -100,7 +121,8 @@ module CP
100
121
  end
101
122
 
102
123
  @arg = switch.arg
103
- instance_variable_set( :"@#{which}", switch.send( which ).first )
124
+ switch = switch.send( which )
125
+ instance_variable_set( :"@#{which}", switch.first ) unless switch.nil?
104
126
  end
105
127
  end
106
128
  end
@@ -17,12 +17,12 @@ module CP
17
17
 
18
18
  rescue ::CmdParse::InvalidCommandError => e
19
19
  command_name << e.message.gsub( /^.*: /, '' )
20
- CP::App.instance.fatal( "'#{command_name}' is not a #{CP::App.instance.name} command." )
20
+ CP::App.instance.fatal( "'#{command_name}' is not a #{CP::App.instance.name} command" )
21
21
 
22
22
  rescue ::CmdParse::InvalidOptionError,
23
23
  ::OptionParser::InvalidOption => e
24
24
  switch = e.message.gsub( /^.*: /, '' )
25
- CP::App.instance.fatal( "'#{switch}' is not a valid option." )
25
+ CP::App.instance.fatal( "'#{switch}' is not a valid option" )
26
26
  end
27
27
  end
28
28
 
@@ -34,8 +34,8 @@ module CP
34
34
  add_options( runner, @app.options )
35
35
  add_commands( runner, @app.commands )
36
36
 
37
- unless @app.commands.find { |c| c.name === :help }
38
- has_default_command = @app.commands.find { |c| c.default }
37
+ unless @app.commands[:help]
38
+ has_default_command = @app.commands.values.find { |c| c.default }
39
39
  runner.add_command( ::CmdParse::HelpCommand.new, !has_default_command )
40
40
  end
41
41
 
@@ -48,20 +48,20 @@ module CP
48
48
  unless options.empty?
49
49
  target.options = ::CmdParse::OptionParserWrapper.new do |o|
50
50
  o.separator "Global Options:"
51
- options.each { |opt| o.on( *opt.to_option_parser_args ) }
51
+ options.values.each { |opt| o.on( *opt.to_option_parser_args ) }
52
52
  end
53
53
  end
54
54
  end
55
55
 
56
56
  def add_commands( target, commands )
57
57
  unless commands.empty?
58
- commands.each do |c|
58
+ commands.values.each do |c|
59
59
  cmd = ::CmdParse::Command.new( c.name.to_s, !c.commands.empty? )
60
60
  cmd.description = c.description
61
61
  cmd.short_desc = c.summary
62
62
 
63
63
  cmd.set_execution_block do |args|
64
- c.block.call( args )
64
+ c.action.call( args )
65
65
  end
66
66
 
67
67
  add_options( cmd, c.options )
data/lib/cp/version.rb CHANGED
@@ -1,3 +1,3 @@
1
1
  module CP
2
- VERSION = "0.0.1"
2
+ VERSION = "0.0.2"
3
3
  end
data/lib/ext/core.rb ADDED
@@ -0,0 +1,25 @@
1
+ class Array
2
+ def to_table
3
+ if self.first.is_a?( Hash )
4
+ headings = self.first.keys
5
+ Terminal::Table.new(
6
+ :headings => headings,
7
+ :rows => self.map { |r| headings.map { |h| r[h] } }
8
+ ).to_s
9
+ else
10
+ Terminal::Table.new( :rows => self.map { |r| r.is_a?( Array ) ? r : [r] } ).to_s
11
+ end
12
+ end
13
+ end
14
+
15
+ class Hash
16
+ def to_table
17
+ Terminal::Table.new( :headings => self.keys, :rows => [self.values] ).to_s
18
+ end
19
+ end
20
+
21
+ class Object
22
+ def to_table
23
+ Terminal::Table.new( :rows => [[self]] ).to_s
24
+ end
25
+ end
data/spec/app_spec.rb CHANGED
@@ -3,6 +3,7 @@ require File.join( File.dirname( __FILE__ ), "support", "spec_helper" )
3
3
  describe CP::App do
4
4
  before( :each ) do
5
5
  @target = CP::App.instance
6
+ @result = { :foo => "bar" }
6
7
  end
7
8
 
8
9
  it_should_behave_like "it accepts commands"
@@ -38,6 +39,71 @@ describe CP::App do
38
39
  end
39
40
  end
40
41
 
42
+ describe "built-in options" do
43
+ describe "--format" do
44
+ it "should exist" do
45
+ @target.options[:format].should_not be_nil
46
+ end
47
+
48
+ it "should default to unformatted" do
49
+ run( "test" ).output.should === "#{@result}\n"
50
+ end
51
+
52
+ it "should accept 'json'" do
53
+ run( "--format", "json", "test" ).output.should === "#{@result.to_json}\n"
54
+ end
55
+
56
+ it "should accept 'table'" do
57
+ run( "--format", "table", "test" ).output.should === @result.to_table
58
+ end
59
+
60
+ it "should accept 'yaml'" do
61
+ run( "--format", "yaml", "test" ).output.should === @result.to_yaml
62
+ end
63
+
64
+ it "should buffer output for non-default formats" do
65
+ @result = [1,2,3]
66
+ run( "--format", "yaml", "test" ) do |app|
67
+ app.command( :test ) { @result.each { |line| say line } }
68
+ end.output.should === @result.to_yaml
69
+ end
70
+ end
71
+ end
72
+
73
+ describe "per-command options" do
74
+ before( :each ) do
75
+ @target.option( "--opt" ) do |o|
76
+ o.description = "does something optional"
77
+ o.default = "foo"
78
+ end
79
+ @target.command( :test ) do |c|
80
+ c.option( "--opt" ) { |o| o.default = "subfoo" }
81
+ c.command( :subtest ) do |s|
82
+ s.option( "--opt" )
83
+ end
84
+ end
85
+ @parent_opt = @target.options[:opt]
86
+ @child_opt = @target.commands[:test].options[:opt]
87
+ end
88
+
89
+ it "should be a copy of the parent Option" do
90
+ @child_opt.should_not === @parent_opt
91
+ end
92
+
93
+ it "should extend the parent option of the same name" do
94
+ @child_opt.description.should === @parent_opt.description
95
+ end
96
+
97
+ it "should cascade down to any level of commands" do
98
+ @child_opt = @target.commands[:test].commands[:subtest].options[:opt]
99
+ @child_opt.description.should === @parent_opt.description
100
+ end
101
+
102
+ it "should not alter the parent option" do
103
+ @parent_opt.default.should_not === @child_opt.default
104
+ end
105
+ end
106
+
41
107
  describe "properties" do
42
108
  [:name, :version].each do |prop|
43
109
  it "should accept a #{prop} property" do
data/spec/command_spec.rb CHANGED
@@ -7,6 +7,19 @@ describe CP::Command do
7
7
 
8
8
  it_should_behave_like "it accepts commands"
9
9
  it_should_behave_like "it accepts options"
10
+ it_should_behave_like "it has an action"
11
+
12
+ it "has HighLine integration" do
13
+ create_test_app do |app|
14
+ app.command( :test ) do |c|
15
+ c.action do
16
+ [:agree, :ask, :choose, :say].inject( true ) { |b, method|
17
+ b && respond_to?( method )
18
+ }.should be_true
19
+ end
20
+ end
21
+ end.run "test"
22
+ end
10
23
 
11
24
  describe "attributes" do
12
25
  [
@@ -38,8 +51,8 @@ describe CP::Command do
38
51
 
39
52
  it "saves the block as #block" do
40
53
  block_ran = false
41
- @target.execute { block_ran = true }
42
- @target.block.call( nil )
54
+ @target.action { block_ran = true }
55
+ @target.action.call( nil )
43
56
  block_ran.should be_true
44
57
  end
45
58
 
data/spec/option_spec.rb CHANGED
@@ -5,6 +5,7 @@ describe CP::Option do
5
5
  @target = CP::Option.new( "-x" )
6
6
  end
7
7
 
8
+ it_should_behave_like "it has an action"
8
9
 
9
10
  describe "attributes" do
10
11
  [
@@ -37,19 +38,11 @@ describe CP::Option do
37
38
  end
38
39
  end
39
40
 
40
- describe "#block" do
41
+ describe "#action" do
41
42
  it "should save the value" do
42
- block = lambda {}
43
- @target.block.call( "foo" )
43
+ @target.action.call( "foo" )
44
44
  @target.value.should === "foo"
45
45
  end
46
-
47
- it "should call the use's block" do
48
- called = false
49
- @target.block = lambda { |val| called = true }
50
- @target.block.call( "value" )
51
- called.should be_true
52
- end
53
46
  end
54
47
 
55
48
  describe "#default" do
@@ -128,7 +121,7 @@ describe CP::Option do
128
121
  end
129
122
  it "sets the block from arguments" do
130
123
  ran = false
131
- CP::Option.new( "-s", lambda{ ran = true } ).block.call( nil )
124
+ CP::Option.new( "-s", lambda{ ran = true } ).action.call( nil )
132
125
  ran.should be_true
133
126
  end
134
127
 
@@ -1,7 +1,8 @@
1
1
  class TestAppRunner
2
2
  attr_reader :errors, :exit_status, :output
3
3
 
4
- def run( *args )
4
+ def run( *args, result )
5
+ @result = result
5
6
  @errors, @output = trap_output do
6
7
  app = create_test_app
7
8
  yield app if block_given?
@@ -0,0 +1,19 @@
1
+ shared_examples_for "it has an action" do
2
+ describe "#action" do
3
+ it "accepts a block as #action" do
4
+ called = false
5
+ @target.action { |*args| called = true }
6
+ args = [nil] * @target.action.arity
7
+ @target.action.call( *args )
8
+ called.should be_true
9
+ end
10
+
11
+ it "accepts a Proc as #action=" do
12
+ called = false
13
+ @target.action = lambda { |*args| called = true }
14
+ args = [nil] * @target.action.arity
15
+ @target.action.call( *args )
16
+ called.should be_true
17
+ end
18
+ end
19
+ end
@@ -28,8 +28,8 @@ shared_examples_for "it accepts commands" do
28
28
  end
29
29
 
30
30
  describe "#commands" do
31
- it "should return an array" do
32
- @target.commands.should be_an_instance_of( Array )
31
+ it "should return a hash" do
32
+ @target.commands.should be_an_instance_of( Hash )
33
33
  end
34
34
 
35
35
  it "should increase with each defined command" do
@@ -39,12 +39,13 @@ shared_examples_for "it accepts commands" do
39
39
  end
40
40
 
41
41
  it "should include each defined command" do
42
- @target.commands.include?( @target.command( :test ) ).should be_true
42
+ cmd = @target.command( :test )
43
+ @target.commands.values.include?( cmd ).should be_true
43
44
  end
44
45
 
45
46
  it "should only allow one default command" do
47
+ @target.command( :test ) { |c| c.default = true }
46
48
  lambda {
47
- @target.command( :test ) { |c| c.default = true }
48
49
  @target.command( :test2 ) { |c| c.default = true }
49
50
  }.should raise_error( CP::CommandError, /only one/ )
50
51
  end
@@ -6,18 +6,19 @@ shared_examples_for "it accepts options" do
6
6
  end
7
7
 
8
8
  describe "#options" do
9
- it "should return an array" do
10
- @target.options.should be_an_instance_of( Array )
9
+ it "should return a hash" do
10
+ @target.options.should be_an_instance_of( Hash )
11
11
  end
12
12
 
13
13
  it "should increase with each defined option" do
14
14
  lambda {
15
15
  @target.option( "-s" )
16
- }.should change(){ @target.options.length}.by( 1 )
16
+ }.should change(){ @target.options.length }.by( 1 )
17
17
  end
18
18
 
19
19
  it "should include each defined option" do
20
- @target.options.include?( @target.option( "-s" ) ).should be_true
20
+ opt = @target.option( "-s" )
21
+ @target.options.values.include?( opt ).should be_true
21
22
  end
22
23
  end
23
24
  end
@@ -11,7 +11,7 @@ shared_examples_for "it is a runner" do
11
11
 
12
12
  run( "test", "foo", "bar" ) do |app|
13
13
  app.command( :test ) { |c|
14
- c.execute { |args, opts| passed_args = args }
14
+ c.action { |args, opts| passed_args = args }
15
15
  }
16
16
  end
17
17
 
@@ -40,7 +40,7 @@ shared_examples_for "it is a runner" do
40
40
 
41
41
  run( "help" ) do |app|
42
42
  app.command( :help ) do |c|
43
- c.execute { custom_help_ran = true }
43
+ c.action { custom_help_ran = true }
44
44
  end
45
45
  end
46
46
 
@@ -58,7 +58,7 @@ shared_examples_for "it is a runner" do
58
58
  run( "test" ) do |app|
59
59
  app.command( :test ) { |c|
60
60
  c.option( "--[no-]option" ) { |o| o.default = true }
61
- c.execute { |args, opts| passed_value = opts.option }
61
+ c.action { |args, opts| passed_value = opts.option }
62
62
  }
63
63
  end
64
64
 
@@ -71,7 +71,7 @@ shared_examples_for "it is a runner" do
71
71
  run( "test", "--no-option" ) do |app|
72
72
  app.command( :test ) { |c|
73
73
  c.option( "--[no-]option" ) { |o| o.default = true }
74
- c.execute { |args, opts| passed_value = opts.option }
74
+ c.action { |args, opts| passed_value = opts.option }
75
75
  }
76
76
  end
77
77
 
@@ -87,7 +87,7 @@ shared_examples_for "it is a runner" do
87
87
  run( "test" ) do |app|
88
88
  app.command( :test ) { |c|
89
89
  c.option( "--option VAL" ) { |o| o.default = "foo" }
90
- c.execute { |args, opts| passed_value = opts.option }
90
+ c.action { |args, opts| passed_value = opts.option }
91
91
  }
92
92
  end
93
93
 
@@ -111,7 +111,7 @@ shared_examples_for "it is a runner" do
111
111
  @result = run( "test" ) do |app|
112
112
  app.command( :test ) { |c|
113
113
  c.option( "--option" ) { |o| o.required = true }
114
- c.execute { |args, opts| }
114
+ c.action { |args, opts| }
115
115
  }
116
116
  end
117
117
  end
@@ -132,7 +132,7 @@ shared_examples_for "it is a runner" do
132
132
 
133
133
  run( "test", "foo", "bar" ) do |app|
134
134
  app.command( :test ) { |c|
135
- c.execute { |args, opts| opts_struct = opts }
135
+ c.action { |args, opts| opts_struct = opts }
136
136
  }
137
137
  end
138
138
 
@@ -145,7 +145,7 @@ shared_examples_for "it is a runner" do
145
145
  run( "test", "--option", "foo" ) do |app|
146
146
  app.command( :test ) { |c|
147
147
  c.option( "--option FOO" )
148
- c.execute { |args, opts| passed_value = opts.option }
148
+ c.action { |args, opts| passed_value = opts.option }
149
149
  }
150
150
  end
151
151
 
@@ -160,7 +160,7 @@ shared_examples_for "it is a runner" do
160
160
  cmd.command( :sub1 ) { |sub1|
161
161
  sub1.option( "--option FOO" )
162
162
  sub1.command( :sub2 ) { |sub2|
163
- sub2.execute { |args, opts| passed_value = opts.option }
163
+ sub2.action { |args, opts| passed_value = opts.option }
164
164
  }
165
165
  }
166
166
  }
@@ -30,8 +30,8 @@ def create_test_app
30
30
  a.command( :test ) do |c|
31
31
  c.summary = "test summary"
32
32
  c.option "-v", "--verbose", "verbose description"
33
- c.execute do |args|
34
- "test #{args.join( ", " )}"
33
+ c.action do |args|
34
+ say( @result || "test #{args.join( ", " )}" )
35
35
  end
36
36
  end
37
37
 
@@ -42,7 +42,7 @@ end
42
42
 
43
43
  def run *args, &block
44
44
  runner = TestAppRunner.new
45
- runner.run( *args, &block )
45
+ runner.run( *args, @result, &block )
46
46
  runner
47
47
  end
48
48
 
metadata CHANGED
@@ -2,7 +2,7 @@
2
2
  name: cp
3
3
  version: !ruby/object:Gem::Version
4
4
  prerelease:
5
- version: 0.0.1
5
+ version: 0.0.2
6
6
  platform: ruby
7
7
  authors:
8
8
  - Rick Fletcher
@@ -10,7 +10,7 @@ autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
12
 
13
- date: 2011-07-09 00:00:00 Z
13
+ date: 2011-07-17 00:00:00 Z
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
16
16
  name: cmdparse
@@ -18,12 +18,34 @@ dependencies:
18
18
  requirement: &id001 !ruby/object:Gem::Requirement
19
19
  none: false
20
20
  requirements:
21
- - - ">="
21
+ - - ~>
22
22
  - !ruby/object:Gem::Version
23
23
  version: 2.0.2
24
24
  type: :runtime
25
25
  version_requirements: *id001
26
- description: CP provides a less verbose API for the CmdParse gem.
26
+ - !ruby/object:Gem::Dependency
27
+ name: highline
28
+ prerelease: false
29
+ requirement: &id002 !ruby/object:Gem::Requirement
30
+ none: false
31
+ requirements:
32
+ - - ~>
33
+ - !ruby/object:Gem::Version
34
+ version: 1.6.2
35
+ type: :runtime
36
+ version_requirements: *id002
37
+ - !ruby/object:Gem::Dependency
38
+ name: json_pure
39
+ prerelease: false
40
+ requirement: &id003 !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 1.5.1
46
+ type: :runtime
47
+ version_requirements: *id003
48
+ description: An alternative API for CmdParse
27
49
  email:
28
50
  - fletch@pobox.com
29
51
  executables: []
@@ -45,10 +67,12 @@ files:
45
67
  - lib/cp/errors.rb
46
68
  - lib/cp/has/commands.rb
47
69
  - lib/cp/has/options.rb
70
+ - lib/cp/highline.rb
48
71
  - lib/cp/option.rb
49
72
  - lib/cp/options_struct.rb
50
73
  - lib/cp/runners/cmd_parse.rb
51
74
  - lib/cp/version.rb
75
+ - lib/ext/core.rb
52
76
  - spec/app_spec.rb
53
77
  - spec/command_spec.rb
54
78
  - spec/cp_spec.rb
@@ -58,6 +82,7 @@ files:
58
82
  - spec/options_struct_spec.rb
59
83
  - spec/runners/cmd_parse_spec.rb
60
84
  - spec/support/lib/test_app_runner.rb
85
+ - spec/support/shared_examples/action_examples.rb
61
86
  - spec/support/shared_examples/commands_examples.rb
62
87
  - spec/support/shared_examples/options_examples.rb
63
88
  - spec/support/shared_examples/runner_examples.rb
@@ -100,6 +125,7 @@ test_files:
100
125
  - spec/options_struct_spec.rb
101
126
  - spec/runners/cmd_parse_spec.rb
102
127
  - spec/support/lib/test_app_runner.rb
128
+ - spec/support/shared_examples/action_examples.rb
103
129
  - spec/support/shared_examples/commands_examples.rb
104
130
  - spec/support/shared_examples/options_examples.rb
105
131
  - spec/support/shared_examples/runner_examples.rb