boson 0.4.0 → 1.0.0

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