boson 0.2.2 → 0.2.3

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/lib/boson/options.rb CHANGED
@@ -4,7 +4,7 @@ module Boson
4
4
  # === Creating Your Own Option Type
5
5
  # Defining your own option type simply requires one method (create_@type) to parse the option value and create
6
6
  # the desired object. To create an option type :date, you could create the following create_date method:
7
- # # Drop this in your ~/.irbrc after require 'boson'
7
+ # # Drop this in ~/.boson/commands/date_option.rb
8
8
  # module Boson::Options::Date
9
9
  # def create_date(value)
10
10
  # # value should be mm/dd
@@ -13,6 +13,10 @@ module Boson
13
13
  # end
14
14
  # Boson::OptionParser.send :include, Boson::Options::Date
15
15
  #
16
+ # Modify your config to load this new library by default:
17
+ # :defaults:
18
+ # - date_option
19
+ #
16
20
  # In a FileLibrary, we could then use this new option:
17
21
  # module Calendar
18
22
  # #@options :day=>:date
@@ -76,15 +80,8 @@ module Boson
76
80
  end
77
81
 
78
82
  def create_hash(value)
79
- splitter = current_attributes[:split] || ','
80
83
  (keys = current_attributes[:keys]) && keys = keys.sort_by {|e| e.to_s }
81
- if !value.include?(':') && current_attributes[:default_keys]
82
- value = current_attributes[:default_keys].to_s + ":#{value}"
83
- end
84
- # Creates array pairs, grouping array of keys with a value
85
- aoa = Hash[*value.split(/(?::)([^#{Regexp.quote(splitter)}]+)#{Regexp.quote(splitter)}?/)].to_a
86
- aoa.each_with_index {|(k,v),i| aoa[i][0] = keys.join(splitter) if k == '*' } if keys
87
- hash = aoa.inject({}) {|t,(k,v)| k.split(splitter).each {|e| t[e] = v }; t }
84
+ hash = parse_hash(value, keys)
88
85
  if keys
89
86
  hash = hash.inject({}) {|h,(k,v)|
90
87
  h[auto_alias_value(keys, k)] = v; h
@@ -94,6 +91,18 @@ module Boson
94
91
  hash
95
92
  end
96
93
 
94
+ def parse_hash(value, keys)
95
+ splitter = current_attributes[:split] || ','
96
+ if !value.include?(':') && current_attributes[:default_keys]
97
+ value = current_attributes[:default_keys].to_s + ":#{value}"
98
+ end
99
+
100
+ # 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
103
+ aoa.inject({}) {|t,(k,v)| k.split(splitter).each {|e| t[e] = v }; t }
104
+ end
105
+
97
106
  # Validation methods
98
107
  def validate_string(value)
99
108
  raise OptionParser::Error, "cannot pass '#{value}' as an argument to option '#{@current_option}'" if valid?(value)
data/lib/boson/pipe.rb CHANGED
@@ -1,8 +1,10 @@
1
1
  module Boson
2
- # This module passes a command's return value through methods/commands specified as pipe options. Pipe options
2
+ # This module passes an original command's return value through methods/commands specified as pipe options. Pipe options
3
3
  # are processed in this order:
4
- # * A :query option searches an array of objects or hashes using Pipe.search_object.
5
- # * A :sort option sorts an array of objects or hashes using Pipe.sort_object.
4
+ # * A :query option searches an array of objects or hashes using Pipes.query_pipe.
5
+ # * A :sort option sorts an array of objects or hashes using Pipes.sort_pipe.
6
+ # * A :reverse_sort pipe option reverses an array.
7
+ # * A :pipes option takes an array of commands that modify the return value using Pipes.pipes_pipe.
6
8
  # * All user-defined pipe options (:pipe_options key in Repo.config) are processed in random order.
7
9
  #
8
10
  # Some points:
@@ -10,35 +12,27 @@ module Boson
10
12
  # command loaded when used. The easiest way to do this is by adding the pipe command's library to :defaults in main config.
11
13
  # * By default, pipe commands do not modify the value their given. This means you can activate multiple pipes using
12
14
  # a method's original return value.
13
- # * If you want a pipe command to modify the value its given, set its pipe option's :filter attribute to true.
14
15
  # * A pipe command expects a command's return value as its first argument. If the pipe option takes an argument, it's passed
15
16
  # on as a second argument.
16
17
  # * When piping occurs in relation to rendering depends on the Hirb view. With the default Hirb view, piping occurs
17
18
  # occurs in the middle of the rendering, after Hirb has converted the return value into an array of hashes.
18
19
  # If using a custom Hirb view, piping occurs before rendering.
20
+ # * What the pipe command should expect as a return value depends on the type of command. If it's a command rendered with hirb's
21
+ # tables, the return value is a an array of hashes. For everything else, it's the method's original return value.
19
22
  #
20
- # === Default Pipes: Search and Sort
21
- # The default pipe options, :query, :sort and :reverse_sort, are quite useful for searching and sorting arrays:
22
- # Some examples using default commands:
23
- # # Searches commands in the full_name field for 'lib' and sorts results by that field.
24
- # bash> boson commands -q=f:lib -s=f # or commands --query=full_name:lib --sort=full_name
23
+ # === User Pipes
24
+ # User pipes have the following attributes which alter their behavior:
25
+ # [*:pipe*] Pipe command the pipe executes when called. Default is the pipe's name.
26
+ # [*:env*] Boolean which enables passing an additional hash to the pipe command. This hash contains information from the first
27
+ # command's input with the following keys: :args (command's arguments), :options (command's options),
28
+ # :global_options (command's global options) and :config (a command's configuration hash). Default is false.
29
+ # [*:filter*] Boolean which has the pipe command modify the original command's output with the value it returns. Default is false.
30
+ # [*:no_render*] Boolean to turn off auto-rendering of the original command's final output. Only applicable to :filter enabled
31
+ # pipes. Default is false.
32
+ # [*:solo*] Boolean to indicate this pipe can't run with other user pipes or pipes from :pipes option.
33
+ # If a user calls multiple solo pipes, only the first one detected is called.
25
34
  #
26
- # # Multiple fields can be searched if separated by a ','. This searches the full_name and desc fields.
27
- # bash> boson commands -q=f,d:web # or commands --query=full_name,desc:web
28
- #
29
- # # All fields can be queried using a '*'.
30
- # # Searches all library fields and then reverse sorts on name field
31
- # bash> boson libraries -q=*:core -s=n -R # or libraries --query=*:core --sort=name --reverse_sort
32
- #
33
- # # Multiple searches can be joined together by ','
34
- # # Searches for libraries that have the name matching core or a library_type matching gem
35
- # bash> boson libraries -q=n:core,l:gem # or libraries --query=name:core,library_type:gem
36
- #
37
- # In these examples, we queried commands and examples with an explicit --query. However, -q or --query isn't necessary
38
- # for these commands because they already default to it when not present. This behavior comes from the default_option
39
- # attribute a command can have.
40
- #
41
- # === User-defined Pipes
35
+ # === User Pipes Example
42
36
  # Let's say you want to have two commands, browser and copy, you want to make available as pipe options:
43
37
  # # Opens url in browser. This command already ships with Boson.
44
38
  # def browser(url)
@@ -63,93 +57,89 @@ module Boson
63
57
  #
64
58
  # Some examples of these options using commands from {my libraries}[http://github.com/cldwalker/irbfiles]:
65
59
  # # Creates a gist and then opens url in browser and copies it.
66
- # bash> cat some_file | boson gist -bC # or cat some_file | boson gist --browser --copy
60
+ # $ cat some_file | boson gist -bC # or cat some_file | boson gist --browser --copy
67
61
  #
68
62
  # # Generates rdoc in current directory and then opens it in browser
69
63
  # irb>> rdoc '-b' # or rdoc '--browser'
70
64
  module Pipe
71
65
  extend self
72
66
 
73
- # Main method which processes all pipe commands, both default and user-defined ones.
74
- def process(object, options)
75
- if object.is_a?(Array)
76
- object = search_object(object, options[:query]) if options[:query]
77
- object = sort_object(object, options[:sort], options[:reverse_sort]) if options[:sort]
78
- end
79
- process_user_pipes(object, options)
67
+ # Process pipes for Scientist
68
+ def scientist_process(object, global_opt, env={})
69
+ @env = env
70
+ [:query, :sort, :reverse_sort].each {|e| global_opt.delete(e) } unless object.is_a?(Array)
71
+ process_pipes(object, global_opt)
80
72
  end
81
73
 
82
- # Searches an array of objects or hashes using the :query option.
83
- # This option is a hash of fields mapped to their search terms. Searches are OR-ed.
84
- def search_object(object, query_hash)
85
- if object[0].is_a?(Hash)
86
- TableCallbacks.search_callback(object, :query=>query_hash)
87
- else
88
- query_hash.map {|field,query| object.select {|e| e.send(field).to_s =~ /#{query}/i } }.flatten.uniq
89
- end
90
- rescue NoMethodError
91
- $stderr.puts "Query failed with nonexistant method '#{$!.message[/`(.*)'/,1]}'"
74
+ # Main method which processes all pipe commands, both default and user-defined ones.
75
+ def process_pipes(obj, options)
76
+ internal_pipes(options).each {|pipe|
77
+ obj = Pipes.send("#{pipe}_pipe", obj, options[pipe]) if options[pipe]
78
+ }
79
+ process_user_pipes(obj, options)
92
80
  end
93
81
 
94
- # Sorts an array of objects or hashes using a sort field. Sort is reversed with reverse_sort set to true.
95
- def sort_object(object, sort, reverse_sort=false)
96
- if object[0].is_a?(Hash)
97
- TableCallbacks.sort_callback(object, :sort=>sort, :reverse_sort=>reverse_sort)
98
- else
99
- sort_lambda = object.all? {|e| e.send(sort).respond_to?(:<=>) } ? lambda {|e| e.send(sort) || ''} :
100
- lambda {|e| e.send(sort).to_s }
101
- object = object.sort_by &sort_lambda
102
- object = object.reverse if reverse_sort
103
- object
104
- end
105
- rescue NoMethodError, ArgumentError
106
- $stderr.puts "Sort failed with nonexistant method '#{sort}'"
82
+ # A hash that defines user pipes in the same way as the :pipe_options key in Repo.config.
83
+ # This method should be called when a pipe's library is loading.
84
+ def add_pipes(hash)
85
+ pipe_options.merge! setup_pipes(hash)
107
86
  end
108
87
 
109
88
  #:stopdoc:
89
+ def internal_pipes(global_opt)
90
+ internals = [:query, :sort, :reverse_sort, :pipes]
91
+ internals.delete(:pipes) if pipes_to_process(global_opt).any? {|e| pipe(e)[:solo] }
92
+ internals
93
+ end
94
+
110
95
  def pipe_options
111
- @pipe_options ||= Boson.repo.config[:pipe_options] || {}
96
+ @pipe_options ||= setup_pipes(Boson.repo.config[:pipe_options] || {})
97
+ end
98
+
99
+ def setup_pipes(hash)
100
+ hash.each {|k,v| v[:pipe] ||= k }
112
101
  end
113
102
 
114
- def process_user_pipes(result, options)
115
- (options.keys & pipe_options.keys).each {|e|
116
- command = pipe_options[e][:pipe] ||= e
117
- pipe_result = pipe_options[e][:type] == :boolean ? Boson.invoke(command, result) :
118
- Boson.invoke(command, result, options[e])
119
- result = pipe_result if pipe_options[e][:filter]
103
+ def pipe(key)
104
+ pipe_options[key] || {}
105
+ end
106
+
107
+ # global_opt can come from Hirb callback or Scientist
108
+ def process_user_pipes(result, global_opt)
109
+ pipes_to_process(global_opt).each {|e|
110
+ args = [pipe(e)[:pipe], result]
111
+ args << global_opt[e] unless pipe(e)[:type] == :boolean
112
+ args << get_env(e, global_opt) if pipe(e)[:env]
113
+ pipe_result = Boson.invoke(*args)
114
+ result = pipe_result if pipe(e)[:filter]
120
115
  }
121
116
  result
122
117
  end
118
+
119
+ def get_env(key, global_opt)
120
+ { :global_options=>global_opt.merge(:delete_callbacks=>[:z_boson_pipes]),
121
+ :config=>(@env[:config].dup[key] || {}),
122
+ :args=>@env[:args],
123
+ :options=>@env[:options] || {}
124
+ }
125
+ end
126
+
127
+ def any_no_render_pipes?(global_opt)
128
+ !(pipes = pipes_to_process(global_opt)).empty? &&
129
+ pipes.any? {|e| pipe(e)[:no_render] }
130
+ end
131
+
132
+ def pipes_to_process(global_opt)
133
+ pipes = (global_opt.keys & pipe_options.keys)
134
+ (solo_pipe = pipes.find {|e| pipe(e)[:solo] }) ? [solo_pipe] : pipes
135
+ end
123
136
  #:startdoc:
124
137
 
125
138
  # Callbacks used by Hirb::Helpers::Table to search,sort and run custom pipe commands on arrays of hashes.
126
139
  module TableCallbacks
127
- extend self
128
- # Case-insensitive searches an array of hashes using the option :query. Numerical string keys
129
- # in :query are converted to actual numbers to interface with Hirb. See Pipe.search_object for more
130
- # about :query.
131
- def search_callback(obj, options)
132
- !options[:query] ? obj : begin
133
- options[:query].map {|field,query|
134
- field = field.to_i if field.to_s[/^\d+$/]
135
- obj.select {|e| e[field].to_s =~ /#{query}/i }
136
- }.flatten.uniq
137
- end
138
- end
139
-
140
- # Sorts an array of hashes using :sort option and reverses the sort with :reverse_sort option.
141
- def sort_callback(obj, options)
142
- return obj unless options[:sort]
143
- sort = options[:sort].to_s[/^\d+$/] ? options[:sort].to_i : options[:sort]
144
- sort_lambda = (obj.all? {|e| e[sort].respond_to?(:<=>) } ? lambda {|e| e[sort] } : lambda {|e| e[sort].to_s })
145
- obj = obj.sort_by &sort_lambda
146
- obj = obj.reverse if options[:reverse_sort]
147
- obj
148
- end
149
-
150
- # Processes user-defined pipes in random order.
151
- def z_user_pipes_callback(obj, options)
152
- Pipe.process_user_pipes(obj, options)
140
+ # Processes boson's pipes
141
+ def z_boson_pipes_callback(obj, options)
142
+ Pipe.process_pipes(obj, options)
153
143
  end
154
144
  end
155
145
  end
@@ -0,0 +1,67 @@
1
+ module Boson
2
+ # === Default Pipes: Search and Sort
3
+ # The default pipe options, :query, :sort and :reverse_sort, are quite useful for searching and sorting arrays:
4
+ # Some examples using default commands:
5
+ # # Searches commands in the full_name field for 'lib' and sorts results by that field.
6
+ # $ boson commands -q=f:lib -s=f # or commands --query=full_name:lib --sort=full_name
7
+ #
8
+ # # Multiple fields can be searched if separated by a ','. This searches the full_name and desc fields.
9
+ # $ boson commands -q=f,d:web # or commands --query=full_name,desc:web
10
+ #
11
+ # # All fields can be queried using a '*'.
12
+ # # Searches all library fields and then reverse sorts on name field
13
+ # $ boson libraries -q=*:core -s=n -R # or libraries --query=*:core --sort=name --reverse_sort
14
+ #
15
+ # # Multiple searches can be joined together by ','
16
+ # # Searches for libraries that have the name matching core or a library_type matching gem
17
+ # $ boson libraries -q=n:core,l:gem # or libraries --query=name:core,library_type:gem
18
+ #
19
+ # In these examples, we queried commands and examples with an explicit --query. However, -q or --query isn't necessary
20
+ # for these commands because they already default to it when not present. This behavior comes from the default_option
21
+ # attribute a command can have.
22
+ module Pipes
23
+ extend self
24
+
25
+ # Case-insensitive search an array of objects or hashes for the :query option.
26
+ # This option is a hash of fields mapped to their search terms. Searches are OR-ed.
27
+ # When searching hashes, numerical string keys in query_hash are converted to actual numbers to
28
+ # interface with Hirb.
29
+ def query_pipe(object, query_hash)
30
+ if object[0].is_a?(Hash)
31
+ query_hash.map {|field,query|
32
+ field = field.to_i if field.to_s[/^\d+$/]
33
+ object.select {|e| e[field].to_s =~ /#{query}/i }
34
+ }.flatten.uniq
35
+ else
36
+ query_hash.map {|field,query| object.select {|e| e.send(field).to_s =~ /#{query}/i } }.flatten.uniq
37
+ end
38
+ rescue NoMethodError
39
+ $stderr.puts "Query failed with nonexistant method '#{$!.message[/`(.*)'/,1]}'"
40
+ end
41
+
42
+ # Sorts an array of objects or hashes using a sort field. Sort is reversed with reverse_sort set to true.
43
+ def sort_pipe(object, sort)
44
+ sort_lambda = lambda {}
45
+ if object[0].is_a?(Hash)
46
+ sort = sort.to_i if sort.to_s[/^\d+$/]
47
+ sort_lambda = (object.all? {|e| e[sort].respond_to?(:<=>) } ? lambda {|e| e[sort] } : lambda {|e| e[sort].to_s })
48
+ else
49
+ sort_lambda = object.all? {|e| e.send(sort).respond_to?(:<=>) } ? lambda {|e| e.send(sort) || ''} :
50
+ lambda {|e| e.send(sort).to_s }
51
+ end
52
+ object.sort_by &sort_lambda
53
+ rescue NoMethodError, ArgumentError
54
+ $stderr.puts "Sort failed with nonexistant method '#{sort}'"
55
+ end
56
+
57
+ # Reverse an object
58
+ def reverse_sort_pipe(object, extra=nil)
59
+ object.reverse
60
+ end
61
+
62
+ # Pipes output of multiple commands recursively, given initial object
63
+ def pipes_pipe(obj, arr)
64
+ arr.inject(obj) {|acc,e| Boson.full_invoke(e, [acc]) }
65
+ end
66
+ end
67
+ end
data/lib/boson/repo.rb CHANGED
@@ -70,10 +70,12 @@ module Boson
70
70
  # depend on commands from other libraries. Default is false.
71
71
  # [:ignore_directories] Array of directories to ignore when detecting local repositories for Boson.local_repo.
72
72
  # [:no_auto_render] When set, turns off commandline auto-rendering of a command's output. Default is false.
73
+ # [:option_underscore_search] When set, OptionParser option values (with :values or :keys) are auto aliased with underscore searching.
74
+ # Default is true. See Util.underscore_search.
73
75
  def config(reload=false)
74
76
  if reload || @config.nil?
75
77
  begin
76
- @config = {:libraries=>{}, :command_aliases=>{}, :console_defaults=>[]}
78
+ @config = {:libraries=>{}, :command_aliases=>{}, :console_defaults=>[], :option_underscore_search=>true}
77
79
  @config.merge!(YAML::load_file(config_file(true))) if File.exists?(config_file)
78
80
  rescue ArgumentError
79
81
  message = $!.message !~ /syntax error on line (\d+)/ ? "Error"+$!.message :
@@ -84,6 +86,16 @@ module Boson
84
86
  @config
85
87
  end
86
88
 
89
+ # Updates main config file by passing config into a block to be modified and then saved
90
+ def update_config
91
+ yield(config)
92
+ write_config_file
93
+ end
94
+
95
+ def write_config_file #:nodoc:
96
+ File.open(config_file, 'w') {|f| f.write config.to_yaml }
97
+ end
98
+
87
99
  def detected_libraries #:nodoc:
88
100
  Dir[File.join(commands_dir, '**/*.rb')].map {|e| e.gsub(/^#{commands_dir}\/|\.rb$/, '') }
89
101
  end
@@ -65,10 +65,10 @@ module Boson
65
65
  else
66
66
  execute_command
67
67
  end
68
- rescue Exception
68
+ rescue
69
69
  is_invalid_command = lambda {|command| !Boson.can_invoke?(command[/\w+/]) ||
70
70
  (Boson.can_invoke?(command[/\w+/]) && command.include?('.') && $!.is_a?(NoMethodError)) }
71
- print_error_message @command && is_invalid_command.call(@command) ?
71
+ print_error_message @command.to_s[/\w+/] && is_invalid_command.call(@command) ?
72
72
  "Error: Command '#{@command}' not found" : "Error: #{$!.message}"
73
73
  end
74
74
 
@@ -115,10 +115,11 @@ module Boson
115
115
  begin
116
116
  output = Boson.full_invoke(@command, @args)
117
117
  rescue ArgumentError
118
- # for the rare case it's raised outside of boson
119
- raise unless $!.backtrace.first.include?('boson/')
118
+ raise unless $!.message[/wrong number of arguments/] &&
119
+ # Throw out errors that aren't external or from option_command
120
+ ($!.backtrace.first[/boson/].nil? || $!.backtrace.first[/boson\/option_command.rb/])
120
121
  print_error_message "'#{@command}' was called incorrectly."
121
- Boson.invoke(:usage, @command)
122
+ Boson.invoke(:usage, @command, :one_line=>true)
122
123
  return
123
124
  end
124
125
  render_output output
@@ -88,12 +88,12 @@ module Boson
88
88
 
89
89
  def translate_and_render(obj, command, args, &block)
90
90
  @global_options, @command, original_args = {}, command, args.dup
91
- args = translate_args(obj, args)
91
+ @args = translate_args(obj, args)
92
92
  return run_help_option if @global_options[:help]
93
- run_pretend_option(args)
94
- render_or_raw call_original_command(args, &block) unless @global_options[:pretend]
93
+ run_pretend_option(@args)
94
+ render_or_raw call_original_command(@args, &block) unless @global_options[:pretend]
95
95
  rescue OptionCommand::CommandArgumentError
96
- run_pretend_option(args ||= [])
96
+ run_pretend_option(@args ||= [])
97
97
  return if !@global_options[:pretend] && run_verbose_help(option_command, original_args)
98
98
  raise unless @global_options[:pretend]
99
99
  rescue OptionParser::Error, Error
@@ -104,17 +104,17 @@ module Boson
104
104
 
105
105
  def translate_args(obj, args)
106
106
  option_command.modify_args(args)
107
- @global_options, parsed_options, args = option_command.parse(args)
107
+ @global_options, @current_options, args = option_command.parse(args)
108
108
  return if @global_options[:help]
109
109
 
110
110
  (@global_options[:delete_options] || []).map {|e|
111
111
  @global_options.keys.map {|k| k.to_s }.grep(/^#{e}/)
112
112
  }.flatten.each {|e| @global_options.delete(e.to_sym) }
113
113
 
114
- if parsed_options
114
+ if @current_options
115
115
  option_command.add_default_args(args, obj)
116
116
  return args if @no_option_commands.include?(@command)
117
- args << parsed_options
117
+ args << @current_options
118
118
  option_command.check_argument_size(args)
119
119
  end
120
120
  args
@@ -131,7 +131,9 @@ module Boson
131
131
  end
132
132
 
133
133
  def run_help_option
134
- Boson.invoke(:usage, @command.name, :verbose=>@global_options[:verbose])
134
+ opts = @global_options[:verbose] ? ['--verbose'] : []
135
+ opts << "--render_options=#{@global_options[:usage_options]}" if @global_options[:usage_options]
136
+ Boson.invoke :usage, @command.name + " " + opts.join(' ')
135
137
  end
136
138
 
137
139
  def run_pretend_option(args)
@@ -143,18 +145,19 @@ module Boson
143
145
 
144
146
  def render_or_raw(result)
145
147
  if (@rendered = render?)
146
- result = Pipe.process(result, @global_options) if @global_options.key?(:class) ||
147
- @global_options.key?(:method)
148
+ if @global_options.key?(:class) || @global_options.key?(:method)
149
+ result = Pipe.scientist_process(result, @global_options, :config=>@command.config, :args=>@args, :options=>@current_options)
150
+ end
148
151
  View.render(result, OptionCommand.delete_non_render_options(@global_options.dup), false)
149
152
  else
150
- Pipe.process(result, @global_options)
153
+ Pipe.scientist_process(result, @global_options, :config=>@command.config, :args=>@args, :options=>@current_options)
151
154
  end
152
155
  rescue StandardError
153
156
  raise Error, $!.message, $!.backtrace
154
157
  end
155
158
 
156
159
  def render?
157
- !!@command.render_options ^ @global_options[:render]
160
+ (!!@command.render_options ^ @global_options[:render]) && !Pipe.any_no_render_pipes?(@global_options)
158
161
  end
159
162
  #:startdoc:
160
163
  end