cp 0.0.1 → 0.0.2

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