nucleon 0.1.0 → 0.1.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.
- data/Gemfile +4 -8
- data/Gemfile.lock +0 -28
- data/README.rdoc +13 -5
- data/Rakefile +9 -1
- data/VERSION +1 -1
- data/bin/nucleon +55 -0
- data/lib/core/codes.rb +107 -0
- data/lib/core/config/collection.rb +57 -0
- data/lib/core/config/options.rb +70 -0
- data/lib/core/config.rb +342 -0
- data/lib/core/core.rb +54 -0
- data/lib/core/errors.rb +84 -0
- data/lib/core/facade.rb +283 -0
- data/lib/core/gems.rb +80 -0
- data/lib/core/manager.rb +594 -0
- data/lib/core/mixin/action/commit.rb +58 -0
- data/lib/core/mixin/action/project.rb +53 -0
- data/lib/core/mixin/action/push.rb +52 -0
- data/lib/core/mixin/config/collection.rb +53 -0
- data/lib/core/mixin/config/options.rb +39 -0
- data/lib/core/mixin/macro/object_interface.rb +361 -0
- data/lib/core/mixin/macro/plugin_interface.rb +380 -0
- data/lib/core/mixin/settings.rb +46 -0
- data/lib/core/mixin/sub_config.rb +148 -0
- data/lib/core/mod/hash.rb +29 -0
- data/lib/core/plugin/action.rb +371 -0
- data/lib/core/plugin/base.rb +313 -0
- data/lib/core/plugin/command.rb +98 -0
- data/lib/core/plugin/event.rb +53 -0
- data/lib/core/plugin/extension.rb +12 -0
- data/lib/core/plugin/project.rb +890 -0
- data/lib/core/plugin/template.rb +80 -0
- data/lib/core/plugin/translator.rb +38 -0
- data/lib/core/util/cli.rb +353 -0
- data/lib/core/util/console.rb +237 -0
- data/lib/core/util/data.rb +404 -0
- data/lib/core/util/disk.rb +114 -0
- data/lib/core/util/git.rb +43 -0
- data/lib/core/util/liquid.rb +17 -0
- data/lib/core/util/logger.rb +147 -0
- data/lib/core/util/package.rb +93 -0
- data/lib/core/util/shell.rb +239 -0
- data/lib/nucleon/action/add.rb +69 -0
- data/lib/nucleon/action/create.rb +52 -0
- data/lib/nucleon/action/extract.rb +49 -0
- data/lib/nucleon/action/remove.rb +51 -0
- data/lib/nucleon/action/save.rb +53 -0
- data/lib/nucleon/action/update.rb +37 -0
- data/lib/nucleon/command/bash.rb +146 -0
- data/lib/nucleon/event/regex.rb +52 -0
- data/lib/nucleon/project/git.rb +465 -0
- data/lib/nucleon/project/github.rb +108 -0
- data/lib/nucleon/template/json.rb +16 -0
- data/lib/nucleon/template/wrapper.rb +16 -0
- data/lib/nucleon/template/yaml.rb +16 -0
- data/lib/nucleon/translator/json.rb +27 -0
- data/lib/nucleon/translator/yaml.rb +27 -0
- data/lib/nucleon.rb +18 -15
- data/locales/en.yml +3 -132
- data/nucleon.gemspec +66 -27
- data/spec/core/util/console_spec.rb +489 -0
- metadata +109 -96
@@ -0,0 +1,371 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Plugin
|
4
|
+
class Action < Base
|
5
|
+
|
6
|
+
#-----------------------------------------------------------------------------
|
7
|
+
# Default option interface
|
8
|
+
|
9
|
+
class Option
|
10
|
+
def initialize(provider, name, type, default, locale = nil, &validator)
|
11
|
+
@provider = provider
|
12
|
+
@name = name
|
13
|
+
@type = type
|
14
|
+
@default = default
|
15
|
+
@locale = locale.nil? ? "nucleon.actions.#{provider}.options.#{name}" : locale
|
16
|
+
@validator = validator if validator
|
17
|
+
end
|
18
|
+
|
19
|
+
#---
|
20
|
+
|
21
|
+
attr_reader :provider, :name, :type
|
22
|
+
attr_accessor :default, :locale, :validator
|
23
|
+
|
24
|
+
#---
|
25
|
+
|
26
|
+
def validate(value, *args)
|
27
|
+
success = true
|
28
|
+
if @validator
|
29
|
+
success = @validator.call(value, *args)
|
30
|
+
end
|
31
|
+
success
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
#-----------------------------------------------------------------------------
|
36
|
+
# Action plugin interface
|
37
|
+
|
38
|
+
def self.exec_safe(provider, options)
|
39
|
+
action_result = nil
|
40
|
+
|
41
|
+
begin
|
42
|
+
logger = Nucleon.logger
|
43
|
+
|
44
|
+
logger.debug("Running nucleon action #{provider} with #{options.inspect}")
|
45
|
+
action = Nucleon.action(provider, options)
|
46
|
+
exit_status = action.execute
|
47
|
+
action_result = action.result
|
48
|
+
|
49
|
+
rescue Exception => error
|
50
|
+
logger.error("Nucleon action #{provider} experienced an error:")
|
51
|
+
logger.error(error.inspect)
|
52
|
+
logger.error(error.message)
|
53
|
+
logger.error(Nucleon::Util::Data.to_yaml(error.backtrace))
|
54
|
+
|
55
|
+
Nucleon.ui.error(error.message, { :prefix => false }) if error.message
|
56
|
+
|
57
|
+
exit_status = error.status_code if error.respond_to?(:status_code)
|
58
|
+
end
|
59
|
+
|
60
|
+
Nucleon.remove_plugin(action) if action
|
61
|
+
|
62
|
+
exit_status = Nucleon.code.unknown_status unless exit_status.is_a?(Integer)
|
63
|
+
{ :status => exit_status, :result => action_result }
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.exec(provider, options, quiet = true)
|
67
|
+
exec_safe(provider, { :settings => Config.ensure(options), :quiet => quiet })
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.exec_cli(provider, args, quiet = false)
|
71
|
+
results = exec_safe(provider, { :args => args, :quiet => quiet })
|
72
|
+
results[:status]
|
73
|
+
end
|
74
|
+
|
75
|
+
#---
|
76
|
+
|
77
|
+
def normalize
|
78
|
+
args = array(delete(:args, []))
|
79
|
+
|
80
|
+
@action_interface = Util::Liquid.new do |method, method_args|
|
81
|
+
options = {}
|
82
|
+
options = method_args[0] if method_args.length > 0
|
83
|
+
|
84
|
+
quiet = true
|
85
|
+
quiet = method_args[1] if method_args.length > 1
|
86
|
+
|
87
|
+
myself.class.exec(method, options, quiet)
|
88
|
+
end
|
89
|
+
|
90
|
+
set(:config, Config.new)
|
91
|
+
|
92
|
+
if get(:settings, nil)
|
93
|
+
# Internal processing
|
94
|
+
configure
|
95
|
+
set(:processed, true)
|
96
|
+
set(:settings, Config.ensure(get(:settings)))
|
97
|
+
|
98
|
+
Nucleon.log_level = settings[:log_level] if settings.has_key?(:log_level)
|
99
|
+
else
|
100
|
+
# External processing
|
101
|
+
set(:settings, Config.new)
|
102
|
+
configure
|
103
|
+
parse_base(args)
|
104
|
+
end
|
105
|
+
end
|
106
|
+
|
107
|
+
#-----------------------------------------------------------------------------
|
108
|
+
# Checks
|
109
|
+
|
110
|
+
def processed?
|
111
|
+
get(:processed, false)
|
112
|
+
end
|
113
|
+
|
114
|
+
#-----------------------------------------------------------------------------
|
115
|
+
# Property accessor / modifiers
|
116
|
+
|
117
|
+
def config
|
118
|
+
get(:config)
|
119
|
+
end
|
120
|
+
|
121
|
+
#---
|
122
|
+
|
123
|
+
def config_subset(names)
|
124
|
+
Util::Data.subset(config, names)
|
125
|
+
end
|
126
|
+
|
127
|
+
#---
|
128
|
+
|
129
|
+
def settings
|
130
|
+
get(:settings)
|
131
|
+
end
|
132
|
+
|
133
|
+
#---
|
134
|
+
|
135
|
+
def register(name, type, default, locale = nil)
|
136
|
+
name = name.to_sym
|
137
|
+
|
138
|
+
if block_given?
|
139
|
+
option = Option.new(plugin_provider, name, type, default, locale) do |value, success|
|
140
|
+
yield(value, success)
|
141
|
+
end
|
142
|
+
else
|
143
|
+
option = Option.new(plugin_provider, name, type, default, locale)
|
144
|
+
end
|
145
|
+
|
146
|
+
config[name] = option
|
147
|
+
settings[name] = option.default if settings[name].nil?
|
148
|
+
end
|
149
|
+
|
150
|
+
#---
|
151
|
+
|
152
|
+
def remove(names)
|
153
|
+
Util::Data.rm_keys(config, names)
|
154
|
+
Util::Data.rm_keys(settings, names)
|
155
|
+
end
|
156
|
+
|
157
|
+
#---
|
158
|
+
|
159
|
+
def ignore
|
160
|
+
[]
|
161
|
+
end
|
162
|
+
|
163
|
+
def options
|
164
|
+
config.keys - arguments - ignore
|
165
|
+
end
|
166
|
+
|
167
|
+
def arguments
|
168
|
+
[]
|
169
|
+
end
|
170
|
+
|
171
|
+
#---
|
172
|
+
|
173
|
+
def configure(executable_name = 'nucleon')
|
174
|
+
yield if block_given?
|
175
|
+
|
176
|
+
usage = "#{executable_name} #{plugin_provider} "
|
177
|
+
arguments.each do |arg|
|
178
|
+
arg_config = config[arg.to_sym]
|
179
|
+
|
180
|
+
if arg_config.type == :array
|
181
|
+
usage << "<#{arg}> ..."
|
182
|
+
else
|
183
|
+
usage << "<#{arg}> "
|
184
|
+
end
|
185
|
+
end
|
186
|
+
myself.usage = usage
|
187
|
+
myself
|
188
|
+
end
|
189
|
+
|
190
|
+
#---
|
191
|
+
|
192
|
+
def usage=usage
|
193
|
+
set(:usage, usage)
|
194
|
+
end
|
195
|
+
|
196
|
+
def usage
|
197
|
+
get(:usage, '')
|
198
|
+
end
|
199
|
+
|
200
|
+
#---
|
201
|
+
|
202
|
+
def help
|
203
|
+
return @parser.help if @parser
|
204
|
+
usage
|
205
|
+
end
|
206
|
+
|
207
|
+
#---
|
208
|
+
|
209
|
+
def result=result
|
210
|
+
set(:result, result)
|
211
|
+
end
|
212
|
+
|
213
|
+
def result
|
214
|
+
get(:result, nil)
|
215
|
+
end
|
216
|
+
|
217
|
+
#-----------------------------------------------------------------------------
|
218
|
+
# Operations
|
219
|
+
|
220
|
+
def parse_base(args)
|
221
|
+
logger.info("Parsing action #{plugin_provider} with: #{args.inspect}")
|
222
|
+
|
223
|
+
@parser = Util::CLI::Parser.new(args, usage) do |parser|
|
224
|
+
parse(parser)
|
225
|
+
extension(:parse, { :parser => parser, :config => config })
|
226
|
+
end
|
227
|
+
|
228
|
+
if @parser
|
229
|
+
if @parser.processed
|
230
|
+
set(:processed, true)
|
231
|
+
settings.import(Util::Data.merge([ @parser.options, @parser.arguments ], true))
|
232
|
+
logger.debug("Parse successful: #{export.inspect}")
|
233
|
+
|
234
|
+
elsif @parser.options[:help] && ! quiet?
|
235
|
+
puts I18n.t('nucleon.core.exec.help.usage') + ': ' + help + "\n"
|
236
|
+
|
237
|
+
else
|
238
|
+
if @parser.options[:help]
|
239
|
+
logger.debug("Help wanted but running in silent mode")
|
240
|
+
else
|
241
|
+
logger.warn("Parse failed for unknown reasons")
|
242
|
+
end
|
243
|
+
end
|
244
|
+
end
|
245
|
+
end
|
246
|
+
|
247
|
+
#---
|
248
|
+
|
249
|
+
def parse(parser)
|
250
|
+
|
251
|
+
generate = lambda do |format, name|
|
252
|
+
formats = [ :option, :arg ]
|
253
|
+
types = [ :bool, :int, :float, :str, :array ]
|
254
|
+
name = name.to_sym
|
255
|
+
|
256
|
+
if config.export.has_key?(name) && formats.include?(format.to_sym)
|
257
|
+
option_config = config[name]
|
258
|
+
type = option_config.type
|
259
|
+
default = option_config.default
|
260
|
+
locale = option_config.locale
|
261
|
+
|
262
|
+
if types.include?(type.to_sym)
|
263
|
+
value_label = "#{type.to_s.upcase}"
|
264
|
+
|
265
|
+
if type == :bool
|
266
|
+
parser.send("option_#{type}", name, default, "--[no-]#{name}", locale)
|
267
|
+
elsif format == :arg
|
268
|
+
parser.send("#{format}_#{type}", name, default, locale)
|
269
|
+
else
|
270
|
+
if type == :array
|
271
|
+
parser.send("option_#{type}", name, default, "--#{name} #{value_label},...", locale)
|
272
|
+
else
|
273
|
+
parser.send("option_#{type}", name, default, "--#{name} #{value_label}", locale)
|
274
|
+
end
|
275
|
+
end
|
276
|
+
end
|
277
|
+
end
|
278
|
+
end
|
279
|
+
|
280
|
+
#---
|
281
|
+
|
282
|
+
options.each do |name|
|
283
|
+
generate.call(:option, name)
|
284
|
+
end
|
285
|
+
|
286
|
+
arguments.each do |name|
|
287
|
+
generate.call(:arg, name)
|
288
|
+
end
|
289
|
+
end
|
290
|
+
|
291
|
+
#---
|
292
|
+
|
293
|
+
def validate
|
294
|
+
# TODO: Add extension hooks and logging
|
295
|
+
|
296
|
+
# Validate all of the configurations
|
297
|
+
success = true
|
298
|
+
config.export.each do |name, option|
|
299
|
+
success = false unless option.validate(settings[name])
|
300
|
+
end
|
301
|
+
if success
|
302
|
+
# Check for missing arguments (in case of internal execution mode)
|
303
|
+
arguments.each do |name|
|
304
|
+
if settings[name.to_sym].nil?
|
305
|
+
warn('nucleon.core.exec.errors.missing_argument', { :name => name })
|
306
|
+
success = false
|
307
|
+
end
|
308
|
+
end
|
309
|
+
end
|
310
|
+
success
|
311
|
+
end
|
312
|
+
|
313
|
+
#---
|
314
|
+
|
315
|
+
def execute
|
316
|
+
logger.info("Executing action #{plugin_provider}")
|
317
|
+
|
318
|
+
myself.status = code.success
|
319
|
+
myself.result = nil
|
320
|
+
|
321
|
+
if processed?
|
322
|
+
begin
|
323
|
+
yield if block_given? && extension_check(:exec_init)
|
324
|
+
myself.status = extension_set(:exec_exit)
|
325
|
+
ensure
|
326
|
+
cleanup
|
327
|
+
end
|
328
|
+
else
|
329
|
+
if @parser.options[:help]
|
330
|
+
myself.status = code.help_wanted
|
331
|
+
else
|
332
|
+
myself.status = code.action_unprocessed
|
333
|
+
end
|
334
|
+
end
|
335
|
+
|
336
|
+
myself.status = code.unknown_status unless status.is_a?(Integer)
|
337
|
+
|
338
|
+
if processed? && status != code.success
|
339
|
+
logger.warn("Execution failed for #{plugin_provider} with status #{status}: #{export.inspect}")
|
340
|
+
alert(Codes.render_index(status))
|
341
|
+
end
|
342
|
+
|
343
|
+
status
|
344
|
+
end
|
345
|
+
|
346
|
+
#---
|
347
|
+
|
348
|
+
def run
|
349
|
+
@action_interface
|
350
|
+
end
|
351
|
+
|
352
|
+
#---
|
353
|
+
|
354
|
+
def cleanup
|
355
|
+
logger.info("Running cleanup for action #{plugin_provider}")
|
356
|
+
|
357
|
+
yield if block_given?
|
358
|
+
|
359
|
+
# Nothing to do right now
|
360
|
+
extension(:cleanup)
|
361
|
+
end
|
362
|
+
|
363
|
+
#-----------------------------------------------------------------------------
|
364
|
+
# Output
|
365
|
+
|
366
|
+
def render_options
|
367
|
+
settings
|
368
|
+
end
|
369
|
+
end
|
370
|
+
end
|
371
|
+
end
|
@@ -0,0 +1,313 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Plugin
|
4
|
+
class Base < Core
|
5
|
+
|
6
|
+
# All Plugin classes should directly or indirectly extend Base
|
7
|
+
|
8
|
+
def initialize(type, provider, options)
|
9
|
+
config = Util::Data.clean(Config.ensure(options))
|
10
|
+
name = Util::Data.ensure_value(config.delete(:plugin_name), config.delete(:name, provider))
|
11
|
+
|
12
|
+
@quiet = config.delete(:quiet, false)
|
13
|
+
|
14
|
+
set_meta(config.delete(:meta, Config.new))
|
15
|
+
|
16
|
+
# No logging statements aove this line!!
|
17
|
+
super(config.import({ :logger => "#{plugin_type}->#{plugin_provider}" }))
|
18
|
+
myself.plugin_name = name
|
19
|
+
|
20
|
+
logger.debug("Normalizing #{plugin_type} plugin #{plugin_name} with meta data: #{meta.inspect}")
|
21
|
+
normalize
|
22
|
+
end
|
23
|
+
|
24
|
+
#---
|
25
|
+
|
26
|
+
def method_missing(method, *args, &block)
|
27
|
+
return nil
|
28
|
+
end
|
29
|
+
|
30
|
+
#-----------------------------------------------------------------------------
|
31
|
+
# Checks
|
32
|
+
|
33
|
+
def initialized?(options = {})
|
34
|
+
return true
|
35
|
+
end
|
36
|
+
|
37
|
+
#---
|
38
|
+
|
39
|
+
def quiet?
|
40
|
+
@quiet
|
41
|
+
end
|
42
|
+
|
43
|
+
#-----------------------------------------------------------------------------
|
44
|
+
# Property accessor / modifiers
|
45
|
+
|
46
|
+
def myself
|
47
|
+
return current_actor if respond_to?(:current_actor) # Celluloid enhanced plugin
|
48
|
+
self
|
49
|
+
end
|
50
|
+
alias_method :me, :myself
|
51
|
+
|
52
|
+
#---
|
53
|
+
|
54
|
+
def quiet=quiet
|
55
|
+
@quiet = quiet
|
56
|
+
end
|
57
|
+
|
58
|
+
#---
|
59
|
+
|
60
|
+
def meta
|
61
|
+
return @meta
|
62
|
+
end
|
63
|
+
|
64
|
+
#---
|
65
|
+
|
66
|
+
def set_meta(meta)
|
67
|
+
@meta = Config.ensure(meta)
|
68
|
+
end
|
69
|
+
|
70
|
+
#---
|
71
|
+
|
72
|
+
def plugin_namespace
|
73
|
+
return meta.get(:namespace)
|
74
|
+
end
|
75
|
+
|
76
|
+
#---
|
77
|
+
|
78
|
+
def plugin_type
|
79
|
+
return meta.get(:type)
|
80
|
+
end
|
81
|
+
|
82
|
+
#---
|
83
|
+
|
84
|
+
def plugin_provider
|
85
|
+
return meta.get(:provider)
|
86
|
+
end
|
87
|
+
|
88
|
+
#---
|
89
|
+
|
90
|
+
def plugin_name
|
91
|
+
return meta.get(:name)
|
92
|
+
end
|
93
|
+
|
94
|
+
def plugin_name=plugin_name
|
95
|
+
meta.set(:name, string(plugin_name))
|
96
|
+
end
|
97
|
+
|
98
|
+
#---
|
99
|
+
|
100
|
+
def plugin_directory
|
101
|
+
return meta.get(:directory)
|
102
|
+
end
|
103
|
+
|
104
|
+
#---
|
105
|
+
|
106
|
+
def plugin_file
|
107
|
+
return meta.get(:file)
|
108
|
+
end
|
109
|
+
|
110
|
+
#---
|
111
|
+
|
112
|
+
def plugin_instance_name
|
113
|
+
return meta.get(:instance_name)
|
114
|
+
end
|
115
|
+
|
116
|
+
#---
|
117
|
+
|
118
|
+
def plugin_parent=parent
|
119
|
+
meta.set(:parent, parent) if parent.is_a?(Nucleon::Plugin::Base)
|
120
|
+
end
|
121
|
+
|
122
|
+
def plugin_parent
|
123
|
+
return meta.get(:parent)
|
124
|
+
end
|
125
|
+
|
126
|
+
#-----------------------------------------------------------------------------
|
127
|
+
# Status codes
|
128
|
+
|
129
|
+
def code
|
130
|
+
Nucleon.code
|
131
|
+
end
|
132
|
+
|
133
|
+
def codes(*codes)
|
134
|
+
Nucleon.codes(*codes)
|
135
|
+
end
|
136
|
+
|
137
|
+
#---
|
138
|
+
|
139
|
+
def status=status
|
140
|
+
meta.set(:status, status)
|
141
|
+
end
|
142
|
+
|
143
|
+
def status
|
144
|
+
meta.get(:status, code.unknown_status)
|
145
|
+
end
|
146
|
+
|
147
|
+
#-----------------------------------------------------------------------------
|
148
|
+
# Plugin operations
|
149
|
+
|
150
|
+
def normalize
|
151
|
+
# Implement in sub classes
|
152
|
+
end
|
153
|
+
|
154
|
+
#-----------------------------------------------------------------------------
|
155
|
+
# Extensions
|
156
|
+
|
157
|
+
def hook_method(hook)
|
158
|
+
"#{plugin_type}_#{plugin_provider}_#{hook}"
|
159
|
+
end
|
160
|
+
|
161
|
+
#---
|
162
|
+
|
163
|
+
def extension(hook, options = {}, &code)
|
164
|
+
Nucleon.exec(hook_method(hook), Config.ensure(options).import({ :plugin => myself }), &code)
|
165
|
+
end
|
166
|
+
|
167
|
+
#---
|
168
|
+
|
169
|
+
def extended_config(type, options = {})
|
170
|
+
Nucleon.config(type, Config.ensure(options).import({ :plugin => myself }))
|
171
|
+
end
|
172
|
+
|
173
|
+
#---
|
174
|
+
|
175
|
+
def extension_check(hook, options = {})
|
176
|
+
Nucleon.check(hook_method(hook), Config.ensure(options).import({ :plugin => myself }))
|
177
|
+
end
|
178
|
+
|
179
|
+
#---
|
180
|
+
|
181
|
+
def extension_set(hook, value, options = {})
|
182
|
+
Nucleon.set(hook_method(hook), value, Config.ensure(options).import({ :plugin => myself }))
|
183
|
+
end
|
184
|
+
|
185
|
+
#---
|
186
|
+
|
187
|
+
def extension_collect(hook, options = {})
|
188
|
+
Nucleon.collect(hook_method(hook), Config.ensure(options).import({ :plugin => myself }))
|
189
|
+
end
|
190
|
+
|
191
|
+
#-----------------------------------------------------------------------------
|
192
|
+
# Output
|
193
|
+
|
194
|
+
def render_options
|
195
|
+
export
|
196
|
+
end
|
197
|
+
protected :render_options
|
198
|
+
|
199
|
+
#---
|
200
|
+
|
201
|
+
def render(display, options = {})
|
202
|
+
ui.info(display.strip, options) unless quiet? || display.strip.empty?
|
203
|
+
end
|
204
|
+
|
205
|
+
#---
|
206
|
+
|
207
|
+
def info(name, options = {})
|
208
|
+
ui.info(I18n.t(name, Util::Data.merge([ Config.ensure(render_options).export, options ], true))) unless quiet?
|
209
|
+
end
|
210
|
+
|
211
|
+
#---
|
212
|
+
|
213
|
+
def alert(display, options = {})
|
214
|
+
ui.warn(display.strip, options) unless quiet? || display.strip.empty?
|
215
|
+
end
|
216
|
+
|
217
|
+
#---
|
218
|
+
|
219
|
+
def warn(name, options = {})
|
220
|
+
ui.warn(I18n.t(name, Util::Data.merge([ Config.ensure(render_options).export, options ], true))) unless quiet?
|
221
|
+
end
|
222
|
+
|
223
|
+
#---
|
224
|
+
|
225
|
+
def error(name, options = {})
|
226
|
+
ui.error(I18n.t(name, Util::Data.merge([ Config.ensure(render_options).export, options ], true))) unless quiet?
|
227
|
+
end
|
228
|
+
|
229
|
+
#---
|
230
|
+
|
231
|
+
def success(name, options = {})
|
232
|
+
ui.success(I18n.t(name, Util::Data.merge([ Config.ensure(render_options).export, options ], true))) unless quiet?
|
233
|
+
end
|
234
|
+
|
235
|
+
#-----------------------------------------------------------------------------
|
236
|
+
# Utilities
|
237
|
+
|
238
|
+
def self.build_info(type, data)
|
239
|
+
plugins = []
|
240
|
+
|
241
|
+
if data.is_a?(Hash)
|
242
|
+
data = [ data ]
|
243
|
+
end
|
244
|
+
|
245
|
+
logger.debug("Building plugin list of #{type} from data: #{data.inspect}")
|
246
|
+
|
247
|
+
if data.is_a?(Array)
|
248
|
+
data.each do |info|
|
249
|
+
unless Util::Data.empty?(info)
|
250
|
+
info = translate(info)
|
251
|
+
|
252
|
+
if Util::Data.empty?(info[:provider])
|
253
|
+
info[:provider] = Nucleon.type_default(type)
|
254
|
+
end
|
255
|
+
|
256
|
+
logger.debug("Translated plugin info: #{info.inspect}")
|
257
|
+
|
258
|
+
plugins << info
|
259
|
+
end
|
260
|
+
end
|
261
|
+
end
|
262
|
+
return plugins
|
263
|
+
end
|
264
|
+
|
265
|
+
#---
|
266
|
+
|
267
|
+
def self.translate(data)
|
268
|
+
logger.debug("Translating data to internal plugin structure: #{data.inspect}")
|
269
|
+
return ( data.is_a?(Hash) ? symbol_map(data) : {} )
|
270
|
+
end
|
271
|
+
|
272
|
+
#---
|
273
|
+
|
274
|
+
def self.init_plugin_collection
|
275
|
+
logger.debug("Initializing plugin collection interface at #{Time.now}")
|
276
|
+
|
277
|
+
include Celluloid
|
278
|
+
include Mixin::Settings
|
279
|
+
include Mixin::SubConfig
|
280
|
+
|
281
|
+
extend Mixin::Macro::PluginInterface
|
282
|
+
end
|
283
|
+
|
284
|
+
#---
|
285
|
+
|
286
|
+
def safe_exec(return_result = true, &code)
|
287
|
+
begin
|
288
|
+
result = code.call
|
289
|
+
return result if return_result
|
290
|
+
return true
|
291
|
+
|
292
|
+
rescue Exception => error
|
293
|
+
logger.error(error.inspect)
|
294
|
+
logger.error(error.message)
|
295
|
+
|
296
|
+
ui.error(error.message, { :prefix => false }) if error.message
|
297
|
+
end
|
298
|
+
return false
|
299
|
+
end
|
300
|
+
|
301
|
+
#---
|
302
|
+
|
303
|
+
def admin_exec(return_result = true, &code)
|
304
|
+
if Nucleon.admin?
|
305
|
+
safe_exec(return_result, &code) if block_given?
|
306
|
+
else
|
307
|
+
ui.warn("The #{plugin_provider} action must be run as a machine administrator")
|
308
|
+
myself.status = code.access_denied
|
309
|
+
end
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|