nucleon 0.2.0 → 0.2.1

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 (141) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile +1 -0
  3. data/Gemfile.lock +2 -0
  4. data/VERSION +1 -1
  5. data/lib/core/config.rb +21 -20
  6. data/lib/core/environment.rb +2 -2
  7. data/lib/core/facade.rb +15 -0
  8. data/lib/core/mixin/action/registration.rb +84 -0
  9. data/lib/core/mixin/sub_config.rb +5 -5
  10. data/lib/core/plugin/action.rb +66 -10
  11. data/lib/core/plugin/base.rb +100 -19
  12. data/lib/core/plugin/command.rb +4 -0
  13. data/lib/core/util/cache.rb +13 -1
  14. data/lib/core/util/cli.rb +77 -11
  15. data/lib/core/util/console.rb +55 -72
  16. data/lib/core/util/data.rb +19 -9
  17. data/lib/core/util/logger.rb +16 -6
  18. data/lib/core/util/shell.rb +3 -1
  19. data/lib/core/util/ssh.rb +28 -25
  20. data/lib/nucleon/translator/JSON.rb +2 -2
  21. data/lib/nucleon/translator/YAML.rb +2 -2
  22. data/lib/nucleon_base.rb +22 -8
  23. data/nucleon.gemspec +122 -2
  24. data/rdoc/site/0.2.0/ARCHITECTURE_rdoc.html +638 -0
  25. data/rdoc/site/0.2.0/Hash.html +351 -0
  26. data/rdoc/site/0.2.0/Kernel.html +416 -0
  27. data/rdoc/site/0.2.0/Nucleon.html +607 -0
  28. data/rdoc/site/0.2.0/Nucleon/Action.html +284 -0
  29. data/rdoc/site/0.2.0/Nucleon/Action/Extract.html +455 -0
  30. data/rdoc/site/0.2.0/Nucleon/Action/Project.html +283 -0
  31. data/rdoc/site/0.2.0/Nucleon/Action/Project/Add.html +500 -0
  32. data/rdoc/site/0.2.0/Nucleon/Action/Project/Create.html +457 -0
  33. data/rdoc/site/0.2.0/Nucleon/Action/Project/Remove.html +503 -0
  34. data/rdoc/site/0.2.0/Nucleon/Action/Project/Save.html +476 -0
  35. data/rdoc/site/0.2.0/Nucleon/Action/Project/Update.html +423 -0
  36. data/rdoc/site/0.2.0/Nucleon/Codes.html +567 -0
  37. data/rdoc/site/0.2.0/Nucleon/Command.html +279 -0
  38. data/rdoc/site/0.2.0/Nucleon/Command/Bash.html +548 -0
  39. data/rdoc/site/0.2.0/Nucleon/Config.html +1631 -0
  40. data/rdoc/site/0.2.0/Nucleon/Config/Collection.html +513 -0
  41. data/rdoc/site/0.2.0/Nucleon/Config/Options.html +493 -0
  42. data/rdoc/site/0.2.0/Nucleon/Core.html +639 -0
  43. data/rdoc/site/0.2.0/Nucleon/Environment.html +1208 -0
  44. data/rdoc/site/0.2.0/Nucleon/Errors.html +279 -0
  45. data/rdoc/site/0.2.0/Nucleon/Errors/BatchError.html +285 -0
  46. data/rdoc/site/0.2.0/Nucleon/Errors/NucleonError.html +661 -0
  47. data/rdoc/site/0.2.0/Nucleon/Errors/SSHUnavailable.html +285 -0
  48. data/rdoc/site/0.2.0/Nucleon/Event.html +279 -0
  49. data/rdoc/site/0.2.0/Nucleon/Event/Regex.html +471 -0
  50. data/rdoc/site/0.2.0/Nucleon/Facade.html +2409 -0
  51. data/rdoc/site/0.2.0/Nucleon/Gems.html +639 -0
  52. data/rdoc/site/0.2.0/Nucleon/Manager.html +1860 -0
  53. data/rdoc/site/0.2.0/Nucleon/Mixin.html +288 -0
  54. data/rdoc/site/0.2.0/Nucleon/Mixin/Action.html +281 -0
  55. data/rdoc/site/0.2.0/Nucleon/Mixin/Action/Commit.html +385 -0
  56. data/rdoc/site/0.2.0/Nucleon/Mixin/Action/Project.html +399 -0
  57. data/rdoc/site/0.2.0/Nucleon/Mixin/Action/Push.html +375 -0
  58. data/rdoc/site/0.2.0/Nucleon/Mixin/Colors.html +549 -0
  59. data/rdoc/site/0.2.0/Nucleon/Mixin/ConfigCollection.html +485 -0
  60. data/rdoc/site/0.2.0/Nucleon/Mixin/ConfigOptions.html +453 -0
  61. data/rdoc/site/0.2.0/Nucleon/Mixin/Macro.html +280 -0
  62. data/rdoc/site/0.2.0/Nucleon/Mixin/Macro/ObjectInterface.html +699 -0
  63. data/rdoc/site/0.2.0/Nucleon/Mixin/Macro/PluginInterface.html +686 -0
  64. data/rdoc/site/0.2.0/Nucleon/Mixin/Settings.html +485 -0
  65. data/rdoc/site/0.2.0/Nucleon/Mixin/SubConfig.html +891 -0
  66. data/rdoc/site/0.2.0/Nucleon/Parallel.html +330 -0
  67. data/rdoc/site/0.2.0/Nucleon/Parallel/ClassMethods.html +329 -0
  68. data/rdoc/site/0.2.0/Nucleon/Parallel/InstanceMethods.html +456 -0
  69. data/rdoc/site/0.2.0/Nucleon/Plugin.html +286 -0
  70. data/rdoc/site/0.2.0/Nucleon/Plugin/Action.html +1829 -0
  71. data/rdoc/site/0.2.0/Nucleon/Plugin/Action/Option.html +463 -0
  72. data/rdoc/site/0.2.0/Nucleon/Plugin/Base.html +1803 -0
  73. data/rdoc/site/0.2.0/Nucleon/Plugin/Command.html +725 -0
  74. data/rdoc/site/0.2.0/Nucleon/Plugin/Event.html +446 -0
  75. data/rdoc/site/0.2.0/Nucleon/Plugin/Extension.html +285 -0
  76. data/rdoc/site/0.2.0/Nucleon/Plugin/Project.html +2898 -0
  77. data/rdoc/site/0.2.0/Nucleon/Plugin/Template.html +480 -0
  78. data/rdoc/site/0.2.0/Nucleon/Plugin/Translator.html +375 -0
  79. data/rdoc/site/0.2.0/Nucleon/Project.html +280 -0
  80. data/rdoc/site/0.2.0/Nucleon/Project/Git.html +1805 -0
  81. data/rdoc/site/0.2.0/Nucleon/Project/Github.html +553 -0
  82. data/rdoc/site/0.2.0/Nucleon/Template.html +281 -0
  83. data/rdoc/site/0.2.0/Nucleon/Template/JSON.html +333 -0
  84. data/rdoc/site/0.2.0/Nucleon/Template/Wrapper.html +333 -0
  85. data/rdoc/site/0.2.0/Nucleon/Template/YAML.html +333 -0
  86. data/rdoc/site/0.2.0/Nucleon/Translator.html +280 -0
  87. data/rdoc/site/0.2.0/Nucleon/Translator/JSON.html +370 -0
  88. data/rdoc/site/0.2.0/Nucleon/Translator/YAML.html +370 -0
  89. data/rdoc/site/0.2.0/Nucleon/Util.html +289 -0
  90. data/rdoc/site/0.2.0/Nucleon/Util/CLI.html +392 -0
  91. data/rdoc/site/0.2.0/Nucleon/Util/CLI/Parser.html +1250 -0
  92. data/rdoc/site/0.2.0/Nucleon/Util/Cache.html +784 -0
  93. data/rdoc/site/0.2.0/Nucleon/Util/Console.html +1318 -0
  94. data/rdoc/site/0.2.0/Nucleon/Util/Data.html +1411 -0
  95. data/rdoc/site/0.2.0/Nucleon/Util/Disk.html +526 -0
  96. data/rdoc/site/0.2.0/Nucleon/Util/Git.html +365 -0
  97. data/rdoc/site/0.2.0/Nucleon/Util/Liquid.html +369 -0
  98. data/rdoc/site/0.2.0/Nucleon/Util/Logger.html +810 -0
  99. data/rdoc/site/0.2.0/Nucleon/Util/Package.html +562 -0
  100. data/rdoc/site/0.2.0/Nucleon/Util/SSH.html +1033 -0
  101. data/rdoc/site/0.2.0/Nucleon/Util/SSH/Keypair.html +605 -0
  102. data/rdoc/site/0.2.0/Nucleon/Util/Shell.html +693 -0
  103. data/rdoc/site/0.2.0/Nucleon/Util/Shell/Result.html +501 -0
  104. data/rdoc/site/0.2.0/README_rdoc.html +316 -0
  105. data/rdoc/site/0.2.0/TODO_rdoc.html +265 -0
  106. data/rdoc/site/0.2.0/created.rid +61 -0
  107. data/rdoc/site/0.2.0/images/add.png +0 -0
  108. data/rdoc/site/0.2.0/images/brick.png +0 -0
  109. data/rdoc/site/0.2.0/images/brick_link.png +0 -0
  110. data/rdoc/site/0.2.0/images/bug.png +0 -0
  111. data/rdoc/site/0.2.0/images/bullet_black.png +0 -0
  112. data/rdoc/site/0.2.0/images/bullet_toggle_minus.png +0 -0
  113. data/rdoc/site/0.2.0/images/bullet_toggle_plus.png +0 -0
  114. data/rdoc/site/0.2.0/images/date.png +0 -0
  115. data/rdoc/site/0.2.0/images/delete.png +0 -0
  116. data/rdoc/site/0.2.0/images/find.png +0 -0
  117. data/rdoc/site/0.2.0/images/loadingAnimation.gif +0 -0
  118. data/rdoc/site/0.2.0/images/macFFBgHack.png +0 -0
  119. data/rdoc/site/0.2.0/images/package.png +0 -0
  120. data/rdoc/site/0.2.0/images/page_green.png +0 -0
  121. data/rdoc/site/0.2.0/images/page_white_text.png +0 -0
  122. data/rdoc/site/0.2.0/images/page_white_width.png +0 -0
  123. data/rdoc/site/0.2.0/images/plugin.png +0 -0
  124. data/rdoc/site/0.2.0/images/ruby.png +0 -0
  125. data/rdoc/site/0.2.0/images/tag_blue.png +0 -0
  126. data/rdoc/site/0.2.0/images/tag_green.png +0 -0
  127. data/rdoc/site/0.2.0/images/transparent.png +0 -0
  128. data/rdoc/site/0.2.0/images/wrench.png +0 -0
  129. data/rdoc/site/0.2.0/images/wrench_orange.png +0 -0
  130. data/rdoc/site/0.2.0/images/zoom.png +0 -0
  131. data/rdoc/site/0.2.0/index.html +315 -0
  132. data/rdoc/site/0.2.0/js/darkfish.js +155 -0
  133. data/rdoc/site/0.2.0/js/jquery.js +18 -0
  134. data/rdoc/site/0.2.0/js/navigation.js +142 -0
  135. data/rdoc/site/0.2.0/js/search.js +94 -0
  136. data/rdoc/site/0.2.0/js/search_index.js +1 -0
  137. data/rdoc/site/0.2.0/js/searcher.js +228 -0
  138. data/rdoc/site/0.2.0/rdoc.css +543 -0
  139. data/rdoc/site/0.2.0/table_of_contents.html +1657 -0
  140. data/spec/core/util/console_spec.rb +50 -18
  141. metadata +133 -2
@@ -4,12 +4,14 @@ module Plugin
4
4
  class Base < Core
5
5
 
6
6
  def self.register_ids
7
- :name
7
+ [ :plugin_name, :name ]
8
8
  end
9
9
 
10
10
  # All Plugin classes should directly or indirectly extend Base
11
11
 
12
12
  def initialize(namespace, plugin_type, provider, options)
13
+ @actor = Nucleon.handle(self)
14
+
13
15
  config = Util::Data.clean(Config.ensure(options), false)
14
16
  name = Util::Data.ensure_value(config.delete(:plugin_name), config.delete(:name, provider))
15
17
 
@@ -56,7 +58,7 @@ class Base < Core
56
58
  # Property accessor / modifiers
57
59
 
58
60
  def myself
59
- Nucleon.handle(self)
61
+ @actor
60
62
  end
61
63
  alias_method :me, :myself
62
64
 
@@ -201,6 +203,19 @@ class Base < Core
201
203
  Nucleon.collect(hook_method(hook), Config.ensure(options).import({ :plugin => myself }))
202
204
  end
203
205
 
206
+ #-----------------------------------------------------------------------------
207
+ # Input
208
+
209
+ def ask(message, options = {})
210
+ ui.ask(message, options)
211
+ end
212
+
213
+ #---
214
+
215
+ def password(type, options = {})
216
+ ui.password(type, options)
217
+ end
218
+
204
219
  #-----------------------------------------------------------------------------
205
220
  # Output
206
221
 
@@ -211,38 +226,77 @@ class Base < Core
211
226
 
212
227
  #---
213
228
 
214
- def render(display, options = {})
215
- ui.info(display.strip, options) unless quiet? || display.strip.empty?
229
+ def render_message(message, options = {})
230
+ config = Config.ensure(options)
231
+
232
+ if config.delete(:i18n, true)
233
+ message = I18n.t(message, Util::Data.merge([ Config.ensure(render_options).export, config.export ], true))
234
+ end
235
+ message
216
236
  end
237
+ protected :render_message
217
238
 
218
239
  #---
219
-
220
- def info(name, options = {})
221
- ui.info(I18n.t(name, Util::Data.merge([ Config.ensure(render_options).export, options ], true))) unless quiet?
240
+
241
+ def render(data, options = {})
242
+ config = Config.ensure(options)
243
+
244
+ if ! quiet? || config[:silent]
245
+ translator = nil
246
+ translator = CORL.translator({}, config[:format]) if config[:format]
247
+ data = translator.generate(data) if translator
248
+
249
+ ui.dump(data, options) unless data.strip.empty? || config[:silent]
250
+ end
251
+ data
222
252
  end
223
253
 
224
254
  #---
225
-
226
- def alert(display, options = {})
227
- ui.warn(display.strip, options) unless quiet? || display.strip.empty?
228
- end
229
255
 
256
+ def info(message, options = {})
257
+ config = Config.ensure(options)
258
+
259
+ unless quiet?
260
+ message = render_message(message, config)
261
+ ui.info(message, config.export)
262
+ end
263
+ message
264
+ end
265
+
230
266
  #---
231
267
 
232
- def warn(name, options = {})
233
- ui.warn(I18n.t(name, Util::Data.merge([ Config.ensure(render_options).export, options ], true))) unless quiet?
268
+ def warn(message, options = {})
269
+ config = Config.ensure(options)
270
+
271
+ unless quiet?
272
+ message = render_message(message, config)
273
+ ui.warn(message, config.export)
274
+ end
275
+ message
234
276
  end
235
277
 
236
278
  #---
237
279
 
238
- def error(name, options = {})
239
- ui.error(I18n.t(name, Util::Data.merge([ Config.ensure(render_options).export, options ], true))) unless quiet?
280
+ def error(message, options = {})
281
+ config = Config.ensure(options)
282
+
283
+ unless quiet?
284
+ message = render_message(message, config)
285
+ ui.error(message, config.export)
286
+ end
287
+ message
240
288
  end
241
289
 
242
290
  #---
243
291
 
244
- def success(name, options = {})
245
- ui.success(I18n.t(name, Util::Data.merge([ Config.ensure(render_options).export, options ], true))) unless quiet?
292
+ def success(message, options = {})
293
+ config = Config.ensure(options)
294
+
295
+ unless quiet?
296
+ message = render_message(message, config)
297
+ ui.success(message, config.export)
298
+ end
299
+ message
246
300
  end
247
301
 
248
302
  #-----------------------------------------------------------------------------
@@ -282,6 +336,33 @@ class Base < Core
282
336
 
283
337
  #---
284
338
 
339
+ def self.translate_reference(reference, editable = false)
340
+ # ex: provider:::name
341
+ if reference && reference.match(/^\s*([a-zA-Z0-9_-]+)(?::::)?(.*)?\s*$/)
342
+ provider = $1
343
+ name = $2
344
+
345
+ logger.debug("Translating plugin reference: #{provider} #{name}")
346
+
347
+ info = {
348
+ :provider => provider,
349
+ :name => name
350
+ }
351
+
352
+ logger.debug("Plugin reference info: #{info.inspect}")
353
+ return info
354
+ end
355
+ nil
356
+ end
357
+
358
+ #---
359
+
360
+ def translate_reference(reference, editable = false)
361
+ myself.class.translate_reference(reference, editable)
362
+ end
363
+
364
+ #---
365
+
285
366
  def self.init_plugin_collection(*external_block_methods)
286
367
  logger.debug("Initializing plugin collection interface at #{Time.now}")
287
368
 
@@ -306,7 +387,7 @@ class Base < Core
306
387
  logger.error(error.inspect)
307
388
  logger.error(error.message)
308
389
 
309
- ui.error(error.message, { :prefix => false }) if error.message
390
+ error(error.message, { :prefix => false, :i18n => false }) if error.message
310
391
  end
311
392
  return false
312
393
  end
@@ -317,7 +398,7 @@ class Base < Core
317
398
  if Nucleon.admin?
318
399
  safe_exec(return_result, &block)
319
400
  else
320
- ui.warn("The #{plugin_provider} action must be run as a machine administrator")
401
+ warn("The #{plugin_provider} action must be run as a machine administrator", { :i18n => false })
321
402
  myself.status = code.access_denied
322
403
  end
323
404
  end
@@ -3,6 +3,10 @@ module Nucleon
3
3
  module Plugin
4
4
  class Command < Nucleon.plugin_class(:nucleon, :base)
5
5
 
6
+ def self.register_ids
7
+ [ :command, :args, :flags, :data, :subcommand ]
8
+ end
9
+
6
10
  #-----------------------------------------------------------------------------
7
11
  # Command plugin interface
8
12
 
@@ -24,11 +24,19 @@ class Cache < Core
24
24
  @cache_translator = Nucleon.type_default(:nucleon, :translator)
25
25
  @cache_filename = "#{id}.#{translator}"
26
26
  @cache_path = File.join(@cache_root, @cache_filename)
27
+
28
+ load
27
29
  end
28
30
 
29
31
  #-----------------------------------------------------------------------------
30
32
  # Property accessors / modifiers
31
33
 
34
+ def status
35
+ @status
36
+ end
37
+
38
+ #---
39
+
32
40
  def base_path
33
41
  @cache_root
34
42
  end
@@ -72,7 +80,7 @@ class Cache < Core
72
80
 
73
81
  #---
74
82
 
75
- def set(keys, value)
83
+ def set(keys, value, delete_nil = false)
76
84
  result = super
77
85
  save if initialized?
78
86
  result
@@ -109,6 +117,7 @@ class Cache < Core
109
117
 
110
118
  def load
111
119
  success = false
120
+ @status = 255
112
121
 
113
122
  @@cache_lock.synchronize do
114
123
  logger.info("Loading #{translator} translated cache from #{file}")
@@ -124,6 +133,7 @@ class Cache < Core
124
133
 
125
134
  import(parse_properties, { :no_save => true }) unless parse_properties.empty?
126
135
  success = true
136
+ @status = Nucleon.code.success
127
137
  end
128
138
  end
129
139
  success
@@ -134,6 +144,7 @@ class Cache < Core
134
144
 
135
145
  def save
136
146
  success = false
147
+ @status = 255
137
148
 
138
149
  @@cache_lock.synchronize do
139
150
  if renderer = CORL.translator({}, translator)
@@ -143,6 +154,7 @@ class Cache < Core
143
154
 
144
155
  if Disk.write(file, rendering)
145
156
  success = true
157
+ @status = Nucleon.code.success
146
158
  end
147
159
  end
148
160
  end
@@ -22,17 +22,14 @@ module CLI
22
22
  def self.decode(encoded_string)
23
23
  Util::Data.symbol_map(Util::Data.parse_json(Base64.urlsafe_decode64(encoded_string)))
24
24
  end
25
-
25
+
26
26
  #-------------------------------------------------------------------------
27
27
  # Parser
28
28
 
29
29
  class Parser
30
30
 
31
- attr_accessor :parser
32
- attr_accessor :options
33
- attr_accessor :arguments
34
- attr_accessor :processed
35
-
31
+ attr_accessor :parser, :options, :arguments, :extra, :processed, :strict
32
+
36
33
  #---
37
34
 
38
35
  include Mixin::Colors
@@ -40,12 +37,13 @@ module CLI
40
37
  #---
41
38
 
42
39
  def initialize(args, banner = '', help = '', split_help = false)
43
-
44
40
  @parser = OptionParser.new
45
-
41
+
46
42
  self.options = {}
47
43
  self.arguments = {}
44
+ self.extra = {}
48
45
  self.processed = false
46
+ self.strict = true
49
47
 
50
48
  @arg_settings = []
51
49
 
@@ -53,7 +51,7 @@ module CLI
53
51
  self.help = help
54
52
 
55
53
  yield(self) if block_given?
56
-
54
+
57
55
  parse_command(args, split_help)
58
56
  end
59
57
 
@@ -148,10 +146,16 @@ module CLI
148
146
  options[:help] = true
149
147
  end
150
148
  end
151
- parser.parse!(args)
149
+
150
+ if strict
151
+ parser.parse!(args)
152
+ extra_args = {}
153
+ else
154
+ args, extra_args = parse_known_args(parser, args)
155
+ end
152
156
 
153
157
  # Now we can act on options given
154
- Util::Console.use_colors = options[:color] unless split_help
158
+ options[:color] = Util::Console.use_colors
155
159
 
156
160
  if options[:version]
157
161
  puts version
@@ -163,6 +167,8 @@ module CLI
163
167
  parse_encoded
164
168
 
165
169
  Nucleon.log_level = options[:log_level] if options[:log_level]
170
+
171
+ self.extra = normalize_extra_options(extra_args) unless extra_args.empty?
166
172
 
167
173
  remaining_args = args.dup
168
174
  arg_messages = []
@@ -252,6 +258,66 @@ module CLI
252
258
  options.delete(:encoded_params)
253
259
  end
254
260
 
261
+ #---
262
+
263
+ def parse_known_args(parser, args)
264
+ extra_args = []
265
+
266
+ parse_args = lambda do |arg_list|
267
+ begin
268
+ original_list = arg_list.clone
269
+
270
+ parser.parse! arg_list
271
+ args = arg_list
272
+
273
+ rescue OptionParser::InvalidOption => e
274
+ extra_args += e.args
275
+ while arg_list[0] && arg_list[0][0] != '-'
276
+ extra_args << arg_list.shift
277
+ end
278
+ parse_args.call original_list - extra_args
279
+ end
280
+ end
281
+ parse_args.call args
282
+ [ args, extra_args ]
283
+ end
284
+
285
+ #---
286
+
287
+ def normalize_extra_options(arg_list)
288
+ options = {}
289
+ last_option = nil
290
+
291
+ Util::Data.array(arg_list).each do |arg|
292
+ components = arg.split('=')
293
+ value = nil
294
+
295
+ if components.size > 1
296
+ arg = components[0]
297
+ value = components[1]
298
+ end
299
+
300
+ if arg[0] == '-'
301
+ last_option = arg.sub(/^\-+/, '').to_sym
302
+ options[last_option] = Util::Data.value(value) if value
303
+ else
304
+ if last_option
305
+ if options[last_option]
306
+ options[last_option] = [ options[last_option] ] unless options[last_option].is_a?(Array)
307
+ options[last_option] << Util::Data.value(arg)
308
+ else
309
+ options[last_option] = Util::Data.value(arg)
310
+ end
311
+ else
312
+ parser.warn(CLI.message('nucleon.core.util.cli.parse.error') + "\n\n" + parser.help)
313
+ break
314
+ end
315
+ end
316
+ end
317
+ options
318
+ end
319
+ protected :normalize_extra_options
320
+
255
321
  #---
256
322
 
257
323
  def option(name, default, option_str, allowed_values, message_id, config = {})
@@ -9,7 +9,6 @@ class Console
9
9
 
10
10
  #---
11
11
 
12
- @@console_lock = Nucleon.console_lock
13
12
  @@quiet = false
14
13
  @@use_colors = true
15
14
 
@@ -95,22 +94,20 @@ class Console
95
94
  defaults = { :new_line => true, :prefix => true }
96
95
  options = defaults.merge(options)
97
96
  printer = options[:new_line] ? :puts : :print
98
- channel = type == :error || options[:channel] == :error ? @error : @output
99
97
 
100
- options[:sync] = true unless options.has_key?(:sync)
98
+ puts_options = { :printer => printer }
99
+ puts_options[:channel] = options[:channel] if options.has_key?(:channel)
101
100
 
102
- render = lambda do
103
- safe_puts(format_message(type, message, options),
104
- :channel => channel, :printer => printer)
105
- end
101
+ safe_puts(format_message(type, message, options), puts_options)
102
+ end
103
+
104
+ #---
105
+
106
+ def dump(data, options = {})
107
+ return @delegate.dump(data, options) if check_delegate('dump')
106
108
 
107
- if options[:sync]
108
- #@@console_lock.synchronize do
109
- render.call
110
- #end
111
- else
112
- render.call
113
- end
109
+ options[:channel] = options.has_key?(:channel) ? options[:channel] : @error
110
+ safe_puts(data.to_s, options)
114
111
  end
115
112
 
116
113
  #---
@@ -122,30 +119,18 @@ class Console
122
119
  options[:prefix] = false if ! options.has_key?(:prefix)
123
120
  options[:echo] = true if ! options.has_key?(:echo)
124
121
 
125
- options[:sync] = true unless options.has_key?(:sync)
126
-
127
122
  user_input = nil
128
123
 
129
- collect = lambda do
130
- say(:info, message, Config.ensure(options).import({ :sync => false, :quiet_override => true }).export)
124
+ say(:info, message, Config.ensure(options).import({ :quiet_override => true }).export)
131
125
 
132
- if options[:echo]
133
- user_input = @input.gets.chomp
134
- else
135
- require 'io/console'
136
- user_input = @input.noecho(&:gets).chomp
137
- end
138
- safe_puts("\n")
139
- user_input
140
- end
141
-
142
- if options[:sync]
143
- #@@console_lock.synchronize do
144
- return collect.call
145
- #end
126
+ if options[:echo]
127
+ user_input = @input.gets.chomp
146
128
  else
147
- return collect.call
129
+ require 'io/console'
130
+ user_input = @input.noecho(&:gets).chomp
148
131
  end
132
+ safe_puts("\n")
133
+ user_input
149
134
  end
150
135
 
151
136
  #---
@@ -153,35 +138,23 @@ class Console
153
138
  def password(type, options = {})
154
139
  return @delegate.password(type, options) if check_delegate('password')
155
140
 
156
- options[:sync] = true unless options.has_key?(:sync)
157
-
158
- collect = lambda do
159
- try_again = true
160
- password = nil
141
+ try_again = true
142
+ password = nil
161
143
 
162
- while try_again
163
- # Get and check a password from the keyboard
164
- password = ask("Enter #{type} password: ", { :echo => false, :sync => false })
165
- confirmation_password = ask("Confirm #{type} password: ", { :echo => false, :sync => false })
144
+ while try_again
145
+ # Get and check a password from the keyboard
146
+ password = ask("Enter #{type} password: ", { :echo => false })
147
+ confirmation_password = ask("Confirm #{type} password: ", { :echo => false })
166
148
 
167
- if password != confirmation_password
168
- choice = ask('Passwords do not match! Try again? (Y|N): ', { :sync => false })
169
- try_again = choice.upcase == "Y"
170
- password = nil unless try_again
171
- else
172
- try_again = false
173
- end
149
+ if password != confirmation_password
150
+ choice = ask('Passwords do not match! Try again? (Y|N): ')
151
+ try_again = choice.upcase == "Y"
152
+ password = nil unless try_again
153
+ else
154
+ try_again = false
174
155
  end
175
- password.strip
176
- end
177
-
178
- if options[:sync]
179
- #@@console_lock.synchronize do
180
- return collect.call
181
- #end
182
- else
183
- return collect.call
184
156
  end
157
+ password.strip
185
158
  end
186
159
 
187
160
  #-----------------------------------------------------------------------------
@@ -219,8 +192,13 @@ class Console
219
192
  return @delegate.format_message(type, message, options) if check_delegate('format_message')
220
193
  return '' if message.to_s.strip.empty?
221
194
 
222
- if @resource && ! @resource.empty? && options[:prefix]
223
- prefix = "[#{@resource}]"
195
+ if options[:prefix]
196
+ if prefix_text = options[:prefix_text]
197
+ prefix = "[#{prefix_text}]"
198
+
199
+ elsif @resource && ! @resource.empty?
200
+ prefix = "[#{@resource}]"
201
+ end
224
202
  end
225
203
 
226
204
  lines = []
@@ -228,23 +206,28 @@ class Console
228
206
  escaped_clear = Regexp.escape(@@colors[:clear])
229
207
 
230
208
  message.split("\n").each do |line|
231
- line = prev_color + line if prev_color
232
-
233
- lines << "#{prefix} #{line}".sub(/^ +/, '')
209
+ line = prev_color + line if self.class.use_colors && @color && prev_color
234
210
 
235
- # Set next previous color
236
- if line =~ /#{escaped_clear}$/
237
- prev_color = nil
238
- else
239
- line_section = line.split(/#{escaped_clear}/).pop
240
- prev_colors = line_section.scan(/\e\[[0-9][0-9]?m/)
241
- prev_color = prev_colors.pop unless prev_colors.empty?
242
- end
211
+ lines << "#{prefix} #{line}".sub(/^ /, '')
212
+
213
+ if self.class.use_colors && @color
214
+ # Set next previous color
215
+ if line =~ /#{escaped_clear}$/
216
+ prev_color = nil
217
+ else
218
+ line_section = line.split(/#{escaped_clear}/).pop
219
+
220
+ if line_section
221
+ prev_colors = line_section.scan(/\e\[[0-9][0-9]?m/)
222
+ prev_color = prev_colors.pop unless prev_colors.empty?
223
+ end
224
+ end
225
+ end
243
226
  end
244
227
 
245
228
  message = lines.join("\n")
246
229
 
247
- if @@use_colors && @color
230
+ if self.class.use_colors && @color
248
231
  if options.has_key?(:color)
249
232
  message = self.class.colorize(message, options[:color])
250
233
  else