boson 0.4.0 → 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (64) hide show
  1. data/.gemspec +6 -7
  2. data/.rspec +2 -0
  3. data/.travis.yml +7 -0
  4. data/CHANGELOG.rdoc +1 -1
  5. data/README.md +144 -0
  6. data/README.rdoc +2 -2
  7. data/Upgrading.md +23 -0
  8. data/bin/boson +2 -2
  9. data/lib/boson.rb +44 -52
  10. data/lib/boson/bare_runner.rb +83 -0
  11. data/lib/boson/bin_runner.rb +114 -0
  12. data/lib/boson/command.rb +92 -132
  13. data/lib/boson/inspector.rb +49 -48
  14. data/lib/boson/library.rb +71 -120
  15. data/lib/boson/loader.rb +73 -84
  16. data/lib/boson/manager.rb +131 -135
  17. data/lib/boson/method_inspector.rb +112 -0
  18. data/lib/boson/option_command.rb +71 -154
  19. data/lib/boson/option_parser.rb +178 -173
  20. data/lib/boson/options.rb +46 -32
  21. data/lib/boson/runner.rb +58 -66
  22. data/lib/boson/runner_library.rb +31 -0
  23. data/lib/boson/scientist.rb +48 -81
  24. data/lib/boson/util.rb +46 -61
  25. data/lib/boson/version.rb +1 -1
  26. data/test/bin_runner_test.rb +53 -191
  27. data/test/command_test.rb +5 -9
  28. data/test/deps.rip +2 -2
  29. data/test/loader_test.rb +18 -216
  30. data/test/manager_test.rb +69 -79
  31. data/test/method_inspector_test.rb +12 -36
  32. data/test/option_parser_test.rb +45 -32
  33. data/test/runner_library_test.rb +10 -0
  34. data/test/runner_test.rb +158 -28
  35. data/test/scientist_test.rb +9 -147
  36. data/test/test_helper.rb +87 -52
  37. metadata +30 -72
  38. data/deps.rip +0 -2
  39. data/lib/boson/commands.rb +0 -7
  40. data/lib/boson/commands/core.rb +0 -77
  41. data/lib/boson/commands/web_core.rb +0 -153
  42. data/lib/boson/index.rb +0 -48
  43. data/lib/boson/inspectors/argument_inspector.rb +0 -97
  44. data/lib/boson/inspectors/comment_inspector.rb +0 -100
  45. data/lib/boson/inspectors/method_inspector.rb +0 -98
  46. data/lib/boson/libraries/file_library.rb +0 -144
  47. data/lib/boson/libraries/gem_library.rb +0 -30
  48. data/lib/boson/libraries/local_file_library.rb +0 -30
  49. data/lib/boson/libraries/module_library.rb +0 -37
  50. data/lib/boson/libraries/require_library.rb +0 -23
  51. data/lib/boson/namespace.rb +0 -31
  52. data/lib/boson/pipe.rb +0 -147
  53. data/lib/boson/pipes.rb +0 -75
  54. data/lib/boson/repo.rb +0 -107
  55. data/lib/boson/runners/bin_runner.rb +0 -208
  56. data/lib/boson/runners/console_runner.rb +0 -58
  57. data/lib/boson/view.rb +0 -95
  58. data/test/argument_inspector_test.rb +0 -62
  59. data/test/commands_test.rb +0 -22
  60. data/test/comment_inspector_test.rb +0 -126
  61. data/test/file_library_test.rb +0 -42
  62. data/test/pipes_test.rb +0 -65
  63. data/test/repo_index_test.rb +0 -122
  64. data/test/repo_test.rb +0 -23
data/lib/boson/options.rb CHANGED
@@ -2,9 +2,10 @@ module Boson
2
2
  # This module contains the methods used to define the default option types.
3
3
  #
4
4
  # === Creating Your Own Option Type
5
- # Defining your own option type simply requires one method (create_@type) to parse the option value and create
6
- # the desired object. To create an option type :date, you could create the following create_date method:
7
- # # Drop this in ~/.boson/commands/date_option.rb
5
+ # Defining your own option type simply requires one method (create_@type) to
6
+ # parse the option value and create the desired object. To create an option
7
+ # type :date, you could create the following create_date method:
8
+ # # Drop this in ~/.bosonrc
8
9
  # module Boson::Options::Date
9
10
  # def create_date(value)
10
11
  # # value should be mm/dd
@@ -13,46 +14,49 @@ module Boson
13
14
  # end
14
15
  # Boson::OptionParser.send :include, Boson::Options::Date
15
16
  #
16
- # Modify your config to load this new library by default:
17
- # :defaults:
18
- # - date_option
19
- #
20
- # In a FileLibrary, we could then use this new option:
21
- # module Calendar
22
- # #@options :day=>:date
17
+ # In a Library, we could then use this new option:
18
+ # class Calendar < Boson::Runner
19
+ # options :day=>:date
23
20
  # def appointments(options={})
24
21
  # # ...
25
22
  # end
26
23
  # end
27
24
  # # >> appointments '-d 10/10' -> {:day=>#<Date: 4910229/2,0,2299161> }
28
- # As you can see, a date object is created from the :date option's value and passed into appointments().
25
+ # As you can see, a date object is created from the :date option's value and
26
+ # passed into appointments().
29
27
  #
30
28
  # Some additional tips on the create_* method:
31
29
  # * The argument passed to the method is the option value from the user.
32
30
  # * To access the current option name use @current_option.
33
- # * To access the hash of attributes the current option has use OptionParser.current_attributes. See
34
- # OptionParser.new for more about option attributes.
31
+ # * To access the hash of attributes the current option has use
32
+ # OptionParser.current_attributes. See OptionParser.new for more about
33
+ # option attributes.
35
34
  #
36
- # There are two optional methods per option type: validate_@type and usage_for_@type i.e. validate_date and usage_for_date.
37
- # Like create_@type, validate_@type takes the option's value. If the value validation fails, raise an
38
- # OptionParser::Error with a proper message. All user-defined option types automatically validate for an option value's existence.
39
- # The usage_for_* method takes an option's name (i.e. --day) and returns a usage string to be wrapped in '[ ]'. If no usage is defined
40
- # the default would look like '[--day=:date]'. Consider using the OptionParser.default_usage helper method for your usage.
35
+ # There are two optional methods per option type: validate_@type and
36
+ # usage_for_@type i.e. validate_date and usage_for_date. Like create_@type,
37
+ # validate_@type takes the option's value. If the value validation fails,
38
+ # raise an OptionParser::Error with a proper message. All user-defined option
39
+ # types automatically validate for an option value's existence. The
40
+ # usage_for_* method takes an option's name (i.e. --day) and returns a usage
41
+ # string to be wrapped in '[ ]'. If no usage is defined the default would look
42
+ # like '[--day=:date]'. Consider using the OptionParser#default_usage helper
43
+ # method for your usage.
41
44
  module Options
42
- #:stopdoc:
43
45
  # Parse/create methods
44
46
  def create_string(value)
45
- if (values = current_attributes[:values]) && (values = values.sort_by {|e| e.to_s})
46
- value = auto_alias_value(values, value)
47
- validate_enum_values(values, value)
47
+ if (values = current_attributes[:values]) &&
48
+ (values = values.sort_by {|e| e.to_s})
49
+ value = auto_alias_value(values, value)
50
+ validate_enum_values(values, value)
48
51
  end
49
52
  value
50
53
  end
51
54
 
52
55
  def create_boolean(value)
53
- if (!@opt_types.key?(dasherize(@current_option)) && @current_option =~ /^no-(\w+)$/)
54
- opt = (opt = original_no_opt($1)) ? undasherize(opt) : $1
55
- (@current_option.replace(opt) && false)
56
+ if (!@opt_types.key?(dasherize(@current_option)) &&
57
+ @current_option =~ /^no-(\w+)$/)
58
+ opt = (opt = original_no_opt($1)) ? undasherize(opt) : $1
59
+ (@current_option.replace(opt) && false)
56
60
  else
57
61
  true
58
62
  end
@@ -65,7 +69,8 @@ module Boson
65
69
  def create_array(value)
66
70
  splitter = current_attributes[:split] || ','
67
71
  array = value.split(splitter)
68
- if (values = current_attributes[:values]) && (values = values.sort_by {|e| e.to_s })
72
+ if (values = current_attributes[:values]) &&
73
+ (values = values.sort_by {|e| e.to_s })
69
74
  if current_attributes[:regexp]
70
75
  array = array.map {|e|
71
76
  (new_values = values.grep(/#{e}/)).empty? ? e : new_values
@@ -98,25 +103,35 @@ module Boson
98
103
  end
99
104
 
100
105
  # Creates array pairs, grouping array of keys with a value
101
- aoa = Hash[*value.split(/(?::)([^#{Regexp.quote(splitter)}]+)#{Regexp.quote(splitter)}?/)].to_a
102
- aoa.each_with_index {|(k,v),i| aoa[i][0] = keys.join(splitter) if k == '*' } if keys
106
+ aoa = Hash[*value.split(
107
+ /(?::)([^#{Regexp.quote(splitter)}]+)#{Regexp.quote(splitter)}?/
108
+ )].to_a
109
+ if keys
110
+ aoa.each_with_index {|(k,v),i| aoa[i][0] = keys.join(splitter) if k == '*' }
111
+ end
103
112
  aoa.inject({}) {|t,(k,v)| k.split(splitter).each {|e| t[e] = v }; t }
104
113
  end
105
114
 
106
115
  # Validation methods
107
116
  def validate_string(value)
108
- raise OptionParser::Error, "cannot pass '#{value}' as an argument to option '#{@current_option}'" if valid?(value)
117
+ if valid?(value)
118
+ raise OptionParser::Error,
119
+ "cannot pass '#{value}' as an argument to option '#{@current_option}'"
120
+ end
109
121
  end
110
122
 
111
123
  def validate_numeric(value)
112
124
  unless value =~ OptionParser::NUMERIC and $& == value
113
- raise OptionParser::Error, "expected numeric value for option '#{@current_option}'; got #{value.inspect}"
125
+ raise OptionParser::Error,
126
+ "expected numeric value for option '#{@current_option}'; got " +
127
+ value.inspect
114
128
  end
115
129
  end
116
130
 
117
131
  def validate_hash(value)
118
132
  if !value.include?(':') && !current_attributes[:default_keys]
119
- raise(OptionParser::Error, "invalid key:value pair for option '#{@current_option}'")
133
+ raise OptionParser::Error,
134
+ "invalid key:value pair for option '#{@current_option}'"
120
135
  end
121
136
  end
122
137
 
@@ -140,7 +155,6 @@ module Boson
140
155
  def usage_for_hash(opt)
141
156
  default_usage opt, "A:B,C:D"
142
157
  end
143
- #:startdoc:
144
158
  end
145
159
  end
146
160
  Boson::OptionParser.send :include, Boson::Options
data/lib/boson/runner.rb CHANGED
@@ -1,81 +1,73 @@
1
- module Boson
2
- # Base class for runners.
3
- class Runner
4
- class<<self
5
- attr_accessor :debug
6
-
7
- # Enables view, adds local load path and loads default_libraries
8
- def init
9
- View.enable
10
- add_load_path
11
- Manager.load default_libraries, load_options
12
- end
1
+ require 'boson'
13
2
 
14
- # Libraries that come with Boson
15
- def default_libraries
16
- Boson.repos.map {|e| e.config[:defaults] || [] }.flatten + [Boson::Commands::Core, Boson::Commands::WebCore]
17
- end
18
-
19
- # Libraries detected in repositories
20
- def detected_libraries
21
- Boson.repos.map {|e| e.detected_libraries }.flatten.uniq
22
- end
3
+ module Boson
4
+ # Defines a RunnerLibrary for use by executables as a simple way to map
5
+ # methods to subcommands
6
+ class Runner < BareRunner
7
+ def self.inherited(mod)
8
+ @help_added ||= add_command_help
9
+ Inspector.enable all_classes: true, module: mod.singleton_class
10
+ end
23
11
 
24
- # Libraries specified in config files and detected_libraries
25
- def all_libraries
26
- Boson.repos.map {|e| e.all_libraries }.flatten.uniq
27
- end
12
+ def self.default_libraries
13
+ [self]
14
+ end
28
15
 
29
- # Returns true if commands are being executed from a non-ruby shell i.e. bash. Returns false if
30
- # in a ruby shell i.e. irb.
31
- def in_shell?
32
- !!@in_shell
33
- end
16
+ def self.start(args=ARGV)
17
+ ENV['BOSONRC'] ||= ''
18
+ super
19
+ init
20
+ command, options, args = parse_args(args)
34
21
 
35
- # Returns true if in commandline with verbose flag or if set explicitly. Useful in plugins.
36
- def verbose?
37
- @verbose.nil? ? Boson.const_defined?(:BinRunner) && BinRunner.options[:verbose] : @verbose
22
+ if options[:help] || command.nil?
23
+ display_default_usage
24
+ else
25
+ execute_command(command, args)
38
26
  end
27
+ end
39
28
 
40
- #:stopdoc:
41
- def verbose=(val)
42
- @verbose = val
43
- end
29
+ def self.execute_command(cmd, args)
30
+ Command.find(cmd) ? super : no_command_error(cmd)
31
+ end
44
32
 
45
- def in_shell=(val)
46
- @in_shell = val
33
+ def self.display_help(cmd)
34
+ puts "Usage: #{app_name} #{cmd.name} #{cmd.basic_usage}".rstrip, ""
35
+ if cmd.options
36
+ puts "Options:"
37
+ cmd.option_parser.print_usage_table(no_headers: true)
38
+ puts ""
47
39
  end
40
+ puts "Description:\n #{cmd.desc || 'TODO'}"
41
+ end
48
42
 
49
- def add_load_path
50
- Boson.repos.each {|repo|
51
- if repo.config[:add_load_path] || File.exists?(File.join(repo.dir, 'lib'))
52
- $: << File.join(repo.dir, 'lib') unless $:.include? File.expand_path(File.join(repo.dir, 'lib'))
53
- end
54
- }
55
- end
43
+ def self.display_default_usage
44
+ commands = Boson.commands.sort_by(&:name).map {|c| [c.name, c.desc.to_s] }
45
+ puts "Usage: #{app_name} COMMAND [ARGS]", "", "Available commands:",
46
+ Util.format_table(commands), "",
47
+ "For help on a command: #{app_name} COMMAND -h"
48
+ end
56
49
 
57
- def load_options
58
- {:verbose=>@options[:verbose]}
59
- end
50
+ def self.app_name
51
+ File.basename($0).split(' ').first
52
+ end
60
53
 
61
- def autoload_command(cmd, opts={:verbose=>verbose?})
62
- Index.read
63
- (lib = Index.find_library(cmd)) && Manager.load(lib, opts)
64
- lib
65
- end
54
+ private
55
+ def self.add_command_help
56
+ # Overrides Scientist' default help
57
+ Scientist.extend(Module.new do
58
+ def run_help_option(cmd)
59
+ Boson::Runner.display_help(cmd)
60
+ end
61
+ end)
66
62
 
67
- def define_autoloader
68
- class << ::Boson.main_object
69
- def method_missing(method, *args, &block)
70
- if Runner.autoload_command(method.to_s)
71
- send(method, *args, &block) if respond_to?(method)
72
- else
73
- super
74
- end
75
- end
63
+ # Ensure all commands have -h
64
+ Command.extend(Module.new do
65
+ def new_attributes(name, library)
66
+ super.update(option_command: true)
76
67
  end
77
- end
78
- #:startdoc:
68
+ end)
69
+ # Ensure this is only called once
70
+ true
79
71
  end
80
72
  end
81
- end
73
+ end
@@ -0,0 +1,31 @@
1
+ module Boson
2
+ # Library created by Runner
3
+ class RunnerLibrary < Library
4
+ handles {|source|
5
+ source.is_a?(Module) && defined?(Runner) && source.ancestors.include?(Runner)
6
+ }
7
+
8
+ def self.delegate_runner_methods(runner, mod)
9
+ mod.module_eval do
10
+ runner.public_instance_methods(false).each do |meth|
11
+ define_method(meth) do |*args, &block|
12
+ runner.new.send(meth, *args, &block)
13
+ end
14
+ end
15
+ end
16
+ end
17
+
18
+ def set_name(runner)
19
+ @runner = runner #reference needed elsewhere
20
+ @runner.to_s[/[^:]+$/].downcase
21
+ end
22
+
23
+ # Since Boson expects libraries to be modules, creates a temporary module
24
+ # and delegates its methods to it
25
+ def load_source_and_set_module
26
+ @module = Util.create_module Boson::Commands, @name
27
+ MethodInspector.instance.rename_store_key @runner, @module
28
+ self.class.delegate_runner_methods @runner, @module
29
+ end
30
+ end
31
+ end
@@ -1,15 +1,15 @@
1
1
  module Boson
2
- # Scientist wraps around and redefines an object's method to give it the following features:
3
- # * Methods can take shell command input with options or receive its normal arguments. See the Commandification
4
- # section.
5
- # * Methods have a slew of global options available. See OptionCommand for an explanation of basic global options.
6
- # * Before a method returns its value, it pipes its return value through pipe commands if pipe options are specified. See Pipe.
7
- # * Methods can have any number of optional views associated with them via global render options (see View). Views can be toggled
8
- # on/off with the global option --render (see OptionCommand).
2
+ # Scientist wraps around and redefines an object's method to give it the
3
+ # following features:
4
+ # * Methods can take shell command input with options or receive its normal
5
+ # arguments. See the Commandification section.
6
+ # * Methods have a slew of global options available. See OptionCommand for an
7
+ # explanation of basic global options.
9
8
  #
10
- # The main methods Scientist provides are redefine_command() for redefining an object's method with a Command object
11
- # and commandify() for redefining with a hash of method attributes. Note that for an object's method to be redefined correctly,
12
- # its last argument _must_ expect a hash.
9
+ # The main methods Scientist provides are redefine_command() for redefining an
10
+ # object's method with a Command object and commandify() for redefining with a
11
+ # hash of method attributes. Note that for an object's method to be redefined
12
+ # correctly, its last argument _must_ expect a hash.
13
13
  #
14
14
  # === Commandification
15
15
  # Take for example this basic method/command with an options definition:
@@ -18,7 +18,8 @@ module Boson
18
18
  # args
19
19
  # end
20
20
  #
21
- # When Scientist wraps around foo(), it can take arguments normally or as a shell command:
21
+ # When Scientist wraps around foo(), it can take arguments normally or as a
22
+ # shell command:
22
23
  # foo 'one', 'two', :verbose=>true # normal call
23
24
  # foo 'one two -v' # commandline call
24
25
  #
@@ -34,7 +35,7 @@ module Boson
34
35
  # Handles all Scientist errors.
35
36
  class Error < StandardError; end
36
37
 
37
- attr_accessor :global_options, :rendered, :render
38
+ attr_accessor :global_options
38
39
  @no_option_commands ||= []
39
40
  @option_commands ||= {}
40
41
  @object_methods = {}
@@ -44,16 +45,17 @@ module Boson
44
45
  cmd_block = redefine_command_block(obj, command)
45
46
  @no_option_commands << command if command.options.nil?
46
47
  [command.name, command.alias].compact.each {|e|
47
- obj.instance_eval("class<<self;self;end").send(:define_method, e, cmd_block)
48
+ obj.singleton_class.send(:define_method, e, cmd_block)
48
49
  }
49
50
  rescue Error
50
- $stderr.puts "Error: #{$!.message}"
51
+ warn "Error: #{$!.message}"
51
52
  end
52
53
 
53
- # A wrapper around redefine_command that doesn't depend on a Command object. Rather you
54
- # simply pass a hash of command attributes (see Command.new) or command methods and let OpenStruct mock a command.
55
- # The only required attribute is :name, though to get any real use you should define :options and
56
- # :arg_size (default is '*'). Example:
54
+ # A wrapper around redefine_command that doesn't depend on a Command object.
55
+ # Rather you simply pass a hash of command attributes (see Command.new) or
56
+ # command methods and let OpenStruct mock a command. The only required
57
+ # attribute is :name, though to get any real use you should define :options
58
+ # and :arg_size (default is '*'). Example:
57
59
  # >> def checkit(*args); args; end
58
60
  # => nil
59
61
  # >> Boson::Scientist.commandify(self, :name=>'checkit', :options=>{:verbose=>:boolean, :num=>:numeric})
@@ -81,49 +83,51 @@ module Boson
81
83
  raise Error, "No method exists to redefine command '#{command.name}'."
82
84
  end
83
85
  lambda {|*args|
84
- Scientist.translate_and_render(obj, command, args) {|args|
86
+ Scientist.analyze(obj, command, args) {|args|
85
87
  Scientist.object_methods(obj)[command.name].call(*args)
86
88
  }
87
89
  }
88
90
  end
89
91
 
90
- #:stopdoc:
92
+ # Returns hash of methods for an object
91
93
  def object_methods(obj)
92
94
  @object_methods[obj] ||= {}
93
95
  end
94
96
 
97
+ # option command for given command
95
98
  def option_command(cmd=@command)
96
99
  @option_commands[cmd] ||= OptionCommand.new(cmd)
97
100
  end
98
101
 
99
- def call_original_command(args, &block)
100
- block.call(args)
101
- end
102
-
103
- def translate_and_render(obj, command, args, &block)
104
- @global_options, @command, original_args = {}, command, args.dup
102
+ # Runs a command given its object and arguments
103
+ def analyze(obj, command, args, &block)
104
+ @global_options, @command, @original_args = {}, command, args.dup
105
105
  @args = translate_args(obj, args)
106
- return run_help_option if @global_options[:help]
107
- run_pretend_option(@args)
108
- render_or_raw call_original_command(@args, &block) unless @global_options[:pretend]
109
- rescue OptionCommand::CommandArgumentError
110
- run_pretend_option(@args ||= [])
111
- return if !@global_options[:pretend] && run_verbose_help(option_command, original_args)
112
- raise unless @global_options[:pretend]
106
+ return run_help_option(@command) if @global_options[:help]
107
+ during_analyze(&block)
113
108
  rescue OptionParser::Error, Error
114
- raise if Runner.in_shell?
115
- message = @global_options[:verbose] ? "#{$!}\n#{$!.backtrace.inspect}" : $!.message
116
- $stderr.puts "Error: " + message
109
+ raise if Boson.in_shell
110
+ warn "Error: #{$!}"
111
+ end
112
+
113
+ # Overridable method called during analyze
114
+ def during_analyze(&block)
115
+ process_result call_original_command(@args, &block)
116
+ end
117
+
118
+ # Hook method available after parse in translate_args
119
+ def after_parse; end
120
+
121
+ private
122
+ def call_original_command(args, &block)
123
+ block.call(args)
117
124
  end
118
125
 
119
126
  def translate_args(obj, args)
120
127
  option_command.modify_args(args)
121
128
  @global_options, @current_options, args = option_command.parse(args)
122
129
  return if @global_options[:help]
123
-
124
- (@global_options[:delete_options] || []).map {|e|
125
- @global_options.keys.map {|k| k.to_s }.grep(/^#{e}/)
126
- }.flatten.each {|e| @global_options.delete(e.to_sym) }
130
+ after_parse
127
131
 
128
132
  if @current_options
129
133
  option_command.add_default_args(args, obj)
@@ -134,49 +138,12 @@ module Boson
134
138
  args
135
139
  end
136
140
 
137
- def run_verbose_help(option_command, original_args)
138
- global_opts = option_command.parse_global_options(original_args)
139
- if global_opts[:help] && global_opts[:verbose]
140
- @global_options = global_opts
141
- run_help_option
142
- return true
143
- end
144
- false
145
- end
146
-
147
- def run_help_option
148
- opts = @global_options[:verbose] ? ['--verbose'] : []
149
- opts << "--render_options=#{@global_options[:usage_options]}" if @global_options[:usage_options]
150
- Boson.invoke :usage, @command.full_name + " " + opts.join(' ')
151
- end
152
-
153
- def run_pretend_option(args)
154
- if @global_options[:verbose] || @global_options[:pretend]
155
- puts "Arguments: #{args.inspect}", "Global options: #{@global_options.inspect}"
156
- end
157
- @rendered = true if @global_options[:pretend]
158
- end
159
-
160
- def render_or_raw(result)
161
- if (@rendered = can_render?)
162
- if @global_options.key?(:class) || @global_options.key?(:method)
163
- result = Pipe.scientist_process(result, @global_options, :config=>@command.config, :args=>@args, :options=>@current_options)
164
- end
165
- View.render(result, OptionCommand.delete_non_render_options(@global_options.dup), false)
166
- else
167
- Pipe.scientist_process(result, @global_options, :config=>@command.config, :args=>@args, :options=>@current_options)
168
- end
169
- rescue StandardError
170
- raise Error, $!.message, $!.backtrace
171
- end
172
-
173
- def can_render?
174
- render.nil? ? command_renders? : render
141
+ def run_help_option(cmd)
142
+ puts "#{cmd.full_name} #{cmd.usage}".rstrip
175
143
  end
176
144
 
177
- def command_renders?
178
- (!!@command.render_options ^ @global_options[:render]) && !Pipe.any_no_render_pipes?(@global_options)
145
+ def process_result(result)
146
+ result
179
147
  end
180
- #:startdoc:
181
148
  end
182
149
  end