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
data/lib/core/manager.rb
ADDED
@@ -0,0 +1,594 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
class Manager
|
4
|
+
|
5
|
+
include Celluloid
|
6
|
+
|
7
|
+
#-----------------------------------------------------------------------------
|
8
|
+
|
9
|
+
@@supervisors = {}
|
10
|
+
|
11
|
+
#-----------------------------------------------------------------------------
|
12
|
+
# Plugin manager interface
|
13
|
+
|
14
|
+
def self.init_manager(name)
|
15
|
+
name = name.to_sym
|
16
|
+
|
17
|
+
Manager.supervise_as name
|
18
|
+
@@supervisors[name] = Celluloid::Actor[name]
|
19
|
+
end
|
20
|
+
|
21
|
+
#---
|
22
|
+
|
23
|
+
def self.connection(name = :core)
|
24
|
+
name = name.to_sym
|
25
|
+
|
26
|
+
init_manager(name) unless @@supervisors.has_key?(name)
|
27
|
+
|
28
|
+
begin
|
29
|
+
@@supervisors[name].test_connection
|
30
|
+
rescue Celluloid::DeadActorError
|
31
|
+
retry
|
32
|
+
end
|
33
|
+
@@supervisors[name]
|
34
|
+
end
|
35
|
+
|
36
|
+
#---
|
37
|
+
|
38
|
+
def initialize
|
39
|
+
@logger = Nucleon.logger
|
40
|
+
|
41
|
+
@namespaces = {}
|
42
|
+
@types = {}
|
43
|
+
@load_info = {}
|
44
|
+
@plugins = {}
|
45
|
+
end
|
46
|
+
|
47
|
+
#-----------------------------------------------------------------------------
|
48
|
+
# Property accessor / modifiers
|
49
|
+
|
50
|
+
attr_reader :logger
|
51
|
+
|
52
|
+
#---
|
53
|
+
|
54
|
+
def namespaces
|
55
|
+
@namespaces.keys
|
56
|
+
end
|
57
|
+
|
58
|
+
def define_namespace(*namespaces)
|
59
|
+
namespaces.each do |namespace|
|
60
|
+
@namespaces[namespace.to_sym] = true
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
#---
|
65
|
+
|
66
|
+
def types
|
67
|
+
@types.keys
|
68
|
+
end
|
69
|
+
|
70
|
+
#---
|
71
|
+
|
72
|
+
def type_default(type)
|
73
|
+
@types[type.to_sym]
|
74
|
+
end
|
75
|
+
|
76
|
+
#---
|
77
|
+
|
78
|
+
def loaded_plugins(type = nil, provider = nil)
|
79
|
+
results = {}
|
80
|
+
type = type.to_sym if type
|
81
|
+
provider = provider.to_sym if provider
|
82
|
+
|
83
|
+
if type && @load_info.has_key?(type)
|
84
|
+
if provider && @load_info.has_key?(provider)
|
85
|
+
results = @load_info[type][provider]
|
86
|
+
else
|
87
|
+
results = @load_info[type]
|
88
|
+
end
|
89
|
+
elsif ! type
|
90
|
+
results = @load_info
|
91
|
+
end
|
92
|
+
results
|
93
|
+
end
|
94
|
+
|
95
|
+
#---
|
96
|
+
|
97
|
+
def plugins(type = nil, provider = nil)
|
98
|
+
results = {}
|
99
|
+
type = type.to_sym if type
|
100
|
+
provider = provider.to_sym if provider
|
101
|
+
|
102
|
+
if type && @plugins.has_key?(type)
|
103
|
+
if provider && ! @plugins[type].keys.empty?
|
104
|
+
@plugins[type].each do |instance_name, plugin|
|
105
|
+
plugin = @plugins[type][instance_name]
|
106
|
+
results[instance_name] = plugin if plugin.plugin_provider == provider
|
107
|
+
end
|
108
|
+
else
|
109
|
+
results = @plugins[type]
|
110
|
+
end
|
111
|
+
elsif ! type
|
112
|
+
results = @plugins
|
113
|
+
end
|
114
|
+
results
|
115
|
+
end
|
116
|
+
|
117
|
+
#-----------------------------------------------------------------------------
|
118
|
+
# Operations
|
119
|
+
|
120
|
+
def test_connection
|
121
|
+
true
|
122
|
+
end
|
123
|
+
|
124
|
+
#---
|
125
|
+
|
126
|
+
def reload
|
127
|
+
current_time = Time.now
|
128
|
+
Celluloid.logger = logger
|
129
|
+
|
130
|
+
logger.info("Initializing the Nucleon plugin system at #{current_time}")
|
131
|
+
|
132
|
+
define_namespace :nucleon
|
133
|
+
|
134
|
+
define_type :extension => nil, # Core
|
135
|
+
:action => :update, # Core
|
136
|
+
:project => :git, # Core
|
137
|
+
:command => :bash, # Core
|
138
|
+
:event => :regex, # Utility
|
139
|
+
:template => :json, # Utility
|
140
|
+
:translator => :json # Utility
|
141
|
+
|
142
|
+
load_plugins(true)
|
143
|
+
logger.info("Finished initializing Nucleon plugin system at #{Time.now}")
|
144
|
+
end
|
145
|
+
|
146
|
+
#---
|
147
|
+
|
148
|
+
def define_type(type_info)
|
149
|
+
if type_info.is_a?(Hash)
|
150
|
+
logger.info("Defining plugin types at #{Time.now}")
|
151
|
+
|
152
|
+
type_info.each do |type, default_provider|
|
153
|
+
logger.debug("Mapping plugin type #{type} to default provider #{default_provider}")
|
154
|
+
@types[type.to_sym] = default_provider
|
155
|
+
end
|
156
|
+
else
|
157
|
+
logger.warn("Defined types must be specified as a hash to be registered properly")
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
#---
|
162
|
+
|
163
|
+
def load_plugins(reset_gems = false)
|
164
|
+
# Register core plugins
|
165
|
+
logger.info("Initializing core plugins at #{Time.now}")
|
166
|
+
register(File.join(File.dirname(__FILE__), '..'))
|
167
|
+
|
168
|
+
# Register external Gem defined plugins
|
169
|
+
Gems.register(reset_gems)
|
170
|
+
|
171
|
+
# Register any other extension plugins
|
172
|
+
exec(:register_plugins)
|
173
|
+
|
174
|
+
# Autoload all registered plugins
|
175
|
+
autoload
|
176
|
+
end
|
177
|
+
|
178
|
+
#---
|
179
|
+
|
180
|
+
def register(base_path, &code)
|
181
|
+
namespaces.each do |namespace|
|
182
|
+
namespace_path = File.join(base_path, namespace.to_s)
|
183
|
+
|
184
|
+
if File.directory?(namespace_path)
|
185
|
+
register_namespace(namespace, namespace_path, &code)
|
186
|
+
end
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
#---
|
191
|
+
|
192
|
+
def register_namespace(namespace, base_path, &code)
|
193
|
+
if File.directory?(base_path)
|
194
|
+
logger.info("Loading files from #{base_path} at #{Time.now}")
|
195
|
+
|
196
|
+
Dir.glob(File.join(base_path, '*.rb')).each do |file|
|
197
|
+
logger.debug("Loading file: #{file}")
|
198
|
+
require file
|
199
|
+
end
|
200
|
+
|
201
|
+
logger.info("Loading directories from #{base_path} at #{Time.now}")
|
202
|
+
Dir.entries(base_path).each do |path|
|
203
|
+
unless path.match(/^\.\.?$/)
|
204
|
+
register_type(namespace, base_path, path, &code) if types.include?(path.to_sym)
|
205
|
+
end
|
206
|
+
end
|
207
|
+
end
|
208
|
+
end
|
209
|
+
protected :register_namespace
|
210
|
+
|
211
|
+
#---
|
212
|
+
|
213
|
+
def register_type(namespace, base_path, plugin_type, &code)
|
214
|
+
base_directory = File.join(base_path, plugin_type.to_s)
|
215
|
+
|
216
|
+
if File.directory?(base_directory)
|
217
|
+
logger.info("Registering #{base_directory} at #{Time.now}")
|
218
|
+
|
219
|
+
Dir.glob(File.join(base_directory, '*.rb')).each do |file|
|
220
|
+
add_build_info(namespace, plugin_type, file)
|
221
|
+
end
|
222
|
+
end
|
223
|
+
end
|
224
|
+
protected :register_type
|
225
|
+
|
226
|
+
#---
|
227
|
+
|
228
|
+
def add_build_info(namespace, type, file, &code)
|
229
|
+
type = type.to_sym
|
230
|
+
|
231
|
+
@load_info[type] = {} unless @load_info.has_key?(type)
|
232
|
+
|
233
|
+
components = file.split(File::SEPARATOR)
|
234
|
+
provider = components.pop.sub(/\.rb/, '').to_sym
|
235
|
+
directory = components.join(File::SEPARATOR)
|
236
|
+
|
237
|
+
logger.info("Loading nucleon #{type} plugin #{provider} at #{Time.now}")
|
238
|
+
|
239
|
+
unless @load_info[type].has_key?(provider)
|
240
|
+
data = {
|
241
|
+
:namespace => namespace,
|
242
|
+
:type => type,
|
243
|
+
:provider => provider,
|
244
|
+
:directory => directory,
|
245
|
+
:file => file
|
246
|
+
}
|
247
|
+
code.call(data) if code
|
248
|
+
|
249
|
+
logger.debug("Plugin #{type} loaded: #{data.inspect}")
|
250
|
+
@load_info[type][provider] = data
|
251
|
+
end
|
252
|
+
end
|
253
|
+
protected :add_build_info
|
254
|
+
|
255
|
+
#---
|
256
|
+
|
257
|
+
def autoload
|
258
|
+
logger.info("Autoloading registered plugins at #{Time.now}")
|
259
|
+
|
260
|
+
@load_info.keys.each do |type|
|
261
|
+
logger.debug("Autoloading type: #{type}")
|
262
|
+
|
263
|
+
@load_info[type].each do |provider, plugin|
|
264
|
+
logger.debug("Autoloading provider #{provider} at #{plugin[:directory]}")
|
265
|
+
|
266
|
+
nucleon_require(plugin[:directory], provider)
|
267
|
+
|
268
|
+
@load_info[type][provider][:class] = provider_class(plugin[:namespace], type, provider)
|
269
|
+
logger.debug("Updated #{type} #{provider} load info: #{@load_info[type][provider].inspect}")
|
270
|
+
|
271
|
+
# Make sure extensions are listening from the time they are loaded
|
272
|
+
load(:extension, provider, { :name => provider }) if type == :extension # Create a persistent instance
|
273
|
+
end
|
274
|
+
end
|
275
|
+
end
|
276
|
+
|
277
|
+
#---
|
278
|
+
|
279
|
+
def load(type, provider = nil, options = {})
|
280
|
+
config = Config.ensure(options)
|
281
|
+
name = config.get(:name, nil)
|
282
|
+
|
283
|
+
logger.info("Fetching plugin #{type} provider #{provider} at #{Time.now}")
|
284
|
+
logger.debug("Plugin options: #{config.export.inspect}")
|
285
|
+
|
286
|
+
default_provider = type_default(type)
|
287
|
+
|
288
|
+
if options.is_a?(Hash) || options.is_a?(Nucleon::Config)
|
289
|
+
config = Config.ensure(translate_type(type, options))
|
290
|
+
provider = config.get(:provider, provider)
|
291
|
+
options = config.export
|
292
|
+
end
|
293
|
+
provider = default_provider unless provider
|
294
|
+
|
295
|
+
if name
|
296
|
+
logger.debug("Looking up existing instance of #{name}")
|
297
|
+
|
298
|
+
existing_instance = get(type, name)
|
299
|
+
logger.info("Using existing instance of #{type}, #{name}") if existing_instance
|
300
|
+
end
|
301
|
+
|
302
|
+
return existing_instance if existing_instance
|
303
|
+
create(type, provider, config.export)
|
304
|
+
end
|
305
|
+
|
306
|
+
#---
|
307
|
+
|
308
|
+
def load_multiple(type, data, build_hash = false, keep_array = false)
|
309
|
+
logger.info("Fetching multiple plugins of #{type} at #{Time.now}")
|
310
|
+
|
311
|
+
group = ( build_hash ? {} : [] )
|
312
|
+
klass = base_plugin_class(type)
|
313
|
+
data = klass.build_info(type, data) if klass.respond_to?(:build_info)
|
314
|
+
|
315
|
+
logger.debug("Translated plugin data: #{data.inspect}")
|
316
|
+
|
317
|
+
data.each do |options|
|
318
|
+
if plugin = load(type, options[:provider], options)
|
319
|
+
if build_hash
|
320
|
+
group[plugin.plugin_name] = plugin
|
321
|
+
else
|
322
|
+
group << plugin
|
323
|
+
end
|
324
|
+
end
|
325
|
+
end
|
326
|
+
return group.shift if ! build_hash && group.length == 1 && ! keep_array
|
327
|
+
group
|
328
|
+
end
|
329
|
+
|
330
|
+
#---
|
331
|
+
|
332
|
+
def create(type, provider, options = {})
|
333
|
+
type = type.to_sym
|
334
|
+
provider = provider.to_sym
|
335
|
+
|
336
|
+
unless @types.has_key?(type)
|
337
|
+
logger.warn("Plugin type #{type} creation requested but it has not been registered yet")
|
338
|
+
return nil
|
339
|
+
end
|
340
|
+
|
341
|
+
info = @load_info[type][provider] if Util::Data.exists?(@load_info, [ type, provider ])
|
342
|
+
|
343
|
+
if info
|
344
|
+
logger.debug("Plugin information for #{provider} #{type} found. Data: #{info.inspect}")
|
345
|
+
|
346
|
+
instance_name = "#{provider}_" + Nucleon.sha1(options)
|
347
|
+
options = translate(info[:namespace], type, provider, options)
|
348
|
+
|
349
|
+
@plugins[type] = {} unless @plugins.has_key?(type)
|
350
|
+
|
351
|
+
unless instance_name && @plugins[type].has_key?(instance_name)
|
352
|
+
info[:instance_name] = instance_name
|
353
|
+
options[:meta] = Config.new(info).import(Util::Data.hash(options[:meta]))
|
354
|
+
|
355
|
+
logger.info("Creating new plugin #{provider} #{type} with #{options.inspect}")
|
356
|
+
|
357
|
+
plugin = info[:class].new(type, provider, options)
|
358
|
+
|
359
|
+
@plugins[type][instance_name] = plugin
|
360
|
+
end
|
361
|
+
return @plugins[type][instance_name]
|
362
|
+
end
|
363
|
+
|
364
|
+
logger.warn("Plugin information cannot be found for plugin #{type} #{provider}")
|
365
|
+
nil
|
366
|
+
end
|
367
|
+
|
368
|
+
#---
|
369
|
+
|
370
|
+
def get(type, name)
|
371
|
+
logger.info("Fetching plugin #{type} #{name}")
|
372
|
+
|
373
|
+
if @plugins.has_key?(type)
|
374
|
+
@plugins[type].each do |instance_name, plugin|
|
375
|
+
if plugin.plugin_name.to_s == name.to_s
|
376
|
+
logger.debug("Plugin #{type} #{name} found")
|
377
|
+
return plugin
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
381
|
+
logger.debug("Plugin #{type} #{name} not found")
|
382
|
+
nil
|
383
|
+
end
|
384
|
+
|
385
|
+
#---
|
386
|
+
|
387
|
+
def remove(plugin)
|
388
|
+
if plugin && plugin.respond_to?(:plugin_type) && @plugins.has_key?(plugin.plugin_type)
|
389
|
+
logger.debug("Removing #{plugin.plugin_type} #{plugin.plugin_name}")
|
390
|
+
@plugins[plugin.plugin_type].delete(plugin.plugin_instance_name)
|
391
|
+
plugin.terminate if plugin.respond_to?(:terminate)
|
392
|
+
else
|
393
|
+
logger.warn("Cannot remove plugin: #{plugin.inspect}")
|
394
|
+
end
|
395
|
+
end
|
396
|
+
|
397
|
+
#-----------------------------------------------------------------------------
|
398
|
+
# Extension hook execution
|
399
|
+
|
400
|
+
def exec(method, options = {})
|
401
|
+
results = nil
|
402
|
+
|
403
|
+
if Nucleon.log_level == :hook # To save processing on rendering
|
404
|
+
logger.hook("Executing extension hook { #{method} } at #{Time.now} with:\n#{PP.pp(options, '')}\n")
|
405
|
+
end
|
406
|
+
|
407
|
+
extensions = plugins(:extension)
|
408
|
+
|
409
|
+
extensions.each do |name, plugin|
|
410
|
+
provider = plugin.plugin_provider
|
411
|
+
result = nil
|
412
|
+
|
413
|
+
logger.debug("Checking extension #{provider}")
|
414
|
+
|
415
|
+
if plugin.respond_to?(method)
|
416
|
+
results = {} if results.nil?
|
417
|
+
|
418
|
+
result = plugin.send(method, options)
|
419
|
+
logger.info("Completed hook #{method} at #{Time.now} with: #{result.inspect}")
|
420
|
+
|
421
|
+
if block_given?
|
422
|
+
results[provider] = yield(:process, result)
|
423
|
+
logger.debug("Processed extension result into: #{results[provider].inspect}")
|
424
|
+
end
|
425
|
+
|
426
|
+
if results[provider].nil?
|
427
|
+
logger.debug("Setting extension result to: #{result.inspect}")
|
428
|
+
results[provider] = result
|
429
|
+
end
|
430
|
+
end
|
431
|
+
end
|
432
|
+
|
433
|
+
if ! results.nil? && block_given?
|
434
|
+
results = yield(:reduce, results)
|
435
|
+
logger.debug("Reducing extension results to: #{results.inspect}")
|
436
|
+
else
|
437
|
+
logger.debug("Final extension results: #{results.inspect}")
|
438
|
+
end
|
439
|
+
results
|
440
|
+
end
|
441
|
+
|
442
|
+
#---
|
443
|
+
|
444
|
+
def config(type, options = {})
|
445
|
+
config = Config.ensure(options)
|
446
|
+
|
447
|
+
logger.debug("Generating #{type} extended configuration from: #{config.export.inspect}")
|
448
|
+
|
449
|
+
exec("#{type}_config", Config.new(config.export)) do |op, data|
|
450
|
+
if op == :reduce
|
451
|
+
data.each do |provider, result|
|
452
|
+
config.defaults(result)
|
453
|
+
end
|
454
|
+
nil
|
455
|
+
else
|
456
|
+
hash(data)
|
457
|
+
end
|
458
|
+
end
|
459
|
+
config.delete(:extension_type)
|
460
|
+
|
461
|
+
logger.debug("Final extended configuration: #{config.export.inspect}")
|
462
|
+
config
|
463
|
+
end
|
464
|
+
|
465
|
+
#---
|
466
|
+
|
467
|
+
def check(method, options = {})
|
468
|
+
config = Config.ensure(options)
|
469
|
+
|
470
|
+
logger.debug("Checking extension #{method} given: #{config.export.inspect}")
|
471
|
+
|
472
|
+
success = exec(method, config.import({ :extension_type => :check })) do |op, data|
|
473
|
+
if op == :reduce
|
474
|
+
! data.values.include?(false)
|
475
|
+
else
|
476
|
+
data ? true : false
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
success = success.nil? || success ? true : false
|
481
|
+
|
482
|
+
logger.debug("Extension #{method} check result: #{success.inspect}")
|
483
|
+
success
|
484
|
+
end
|
485
|
+
|
486
|
+
#---
|
487
|
+
|
488
|
+
def value(method, value, options = {})
|
489
|
+
config = Config.ensure(options)
|
490
|
+
|
491
|
+
logger.debug("Setting extension #{method} value given: #{value.inspect}")
|
492
|
+
|
493
|
+
exec(method, config.import({ :value => value, :extension_type => :value })) do |op, data|
|
494
|
+
if op == :process
|
495
|
+
value = data unless data.nil?
|
496
|
+
end
|
497
|
+
end
|
498
|
+
|
499
|
+
logger.debug("Extension #{method} retrieved value: #{value.inspect}")
|
500
|
+
value
|
501
|
+
end
|
502
|
+
|
503
|
+
#---
|
504
|
+
|
505
|
+
def collect(method, options = {})
|
506
|
+
config = Config.ensure(options)
|
507
|
+
values = []
|
508
|
+
|
509
|
+
logger.debug("Collecting extension #{method} values")
|
510
|
+
|
511
|
+
exec(method, config.import({ :extension_type => :collect })) do |op, data|
|
512
|
+
if op == :process
|
513
|
+
values << data unless data.nil?
|
514
|
+
end
|
515
|
+
end
|
516
|
+
|
517
|
+
logger.debug("Extension #{method} collected values: #{values.inspect}")
|
518
|
+
values
|
519
|
+
end
|
520
|
+
|
521
|
+
#-----------------------------------------------------------------------------
|
522
|
+
# Utilities
|
523
|
+
|
524
|
+
def translate_type(type, options)
|
525
|
+
klass = base_plugin_class(type)
|
526
|
+
logger.debug("Executing option translation for: #{klass.inspect}")
|
527
|
+
|
528
|
+
options = klass.send(:translate, options) if klass.respond_to?(method)
|
529
|
+
options
|
530
|
+
end
|
531
|
+
|
532
|
+
#---
|
533
|
+
|
534
|
+
def translate(namespace, type, provider, options)
|
535
|
+
klass = provider_class(namespace, type, provider)
|
536
|
+
logger.debug("Executing option translation for: #{klass.inspect}")
|
537
|
+
|
538
|
+
options = klass.send(:translate, options) if klass.respond_to?(method)
|
539
|
+
options
|
540
|
+
end
|
541
|
+
|
542
|
+
#---
|
543
|
+
|
544
|
+
def class_name(name, separator = '::', want_array = FALSE)
|
545
|
+
components = []
|
546
|
+
|
547
|
+
case name
|
548
|
+
when String, Symbol
|
549
|
+
components = name.to_s.split(separator)
|
550
|
+
when Array
|
551
|
+
components = name
|
552
|
+
end
|
553
|
+
|
554
|
+
components.collect! do |value|
|
555
|
+
value = value.to_s.strip
|
556
|
+
value[0] = value.capitalize[0] if value =~ /^[a-z]/
|
557
|
+
value
|
558
|
+
end
|
559
|
+
|
560
|
+
if want_array
|
561
|
+
return components
|
562
|
+
end
|
563
|
+
components.join(separator)
|
564
|
+
end
|
565
|
+
|
566
|
+
#---
|
567
|
+
|
568
|
+
def class_const(name, separator = '::')
|
569
|
+
components = class_name(name, separator, TRUE)
|
570
|
+
constant = Object
|
571
|
+
|
572
|
+
components.each do |component|
|
573
|
+
constant = constant.const_defined?(component) ?
|
574
|
+
constant.const_get(component) :
|
575
|
+
constant.const_missing(component)
|
576
|
+
end
|
577
|
+
constant
|
578
|
+
end
|
579
|
+
|
580
|
+
#---
|
581
|
+
|
582
|
+
def base_plugin_class(type)
|
583
|
+
class_const([ :nucleon, :plugin, type ])
|
584
|
+
end
|
585
|
+
protected :base_plugin_class
|
586
|
+
|
587
|
+
#---
|
588
|
+
|
589
|
+
def provider_class(namespace, type, provider)
|
590
|
+
class_const([ namespace, type, provider ])
|
591
|
+
end
|
592
|
+
protected :provider_class
|
593
|
+
end
|
594
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Mixin
|
4
|
+
module Action
|
5
|
+
module Commit
|
6
|
+
|
7
|
+
#-----------------------------------------------------------------------------
|
8
|
+
# Options
|
9
|
+
|
10
|
+
def commit_options(parser, optional = true)
|
11
|
+
if optional
|
12
|
+
parser.option_bool(:commit, false,
|
13
|
+
'--commit',
|
14
|
+
'nucleon.core.mixins.commit.options.commit'
|
15
|
+
)
|
16
|
+
else
|
17
|
+
parser.options[:commit] = true
|
18
|
+
end
|
19
|
+
|
20
|
+
parser.option_bool(:allow_empty, false,
|
21
|
+
'--empty',
|
22
|
+
'nucleon.core.mixins.commit.options.empty'
|
23
|
+
)
|
24
|
+
parser.option_bool(:propogate, false,
|
25
|
+
'--propogate',
|
26
|
+
'nucleon.core.mixins.commit.options.propogate'
|
27
|
+
)
|
28
|
+
parser.option_str(:message, '',
|
29
|
+
'--message COMMIT_MESSAGE',
|
30
|
+
'nucleon.core.mixins.commit.options.message'
|
31
|
+
)
|
32
|
+
parser.option_str(:author, nil,
|
33
|
+
'--author COMMIT_AUTHOR',
|
34
|
+
'nucleon.core.mixins.commit.options.author'
|
35
|
+
)
|
36
|
+
end
|
37
|
+
|
38
|
+
#-----------------------------------------------------------------------------
|
39
|
+
# Operations
|
40
|
+
|
41
|
+
def commit(project, files = '.')
|
42
|
+
success = true
|
43
|
+
|
44
|
+
if project && settings[:commit]
|
45
|
+
success = project.commit(files, extended_config(:commit, {
|
46
|
+
:allow_empty => settings[:allow_empty],
|
47
|
+
:message => settings[:message],
|
48
|
+
:author => settings[:author],
|
49
|
+
:propogate => settings[:propogate]
|
50
|
+
}))
|
51
|
+
end
|
52
|
+
success
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Mixin
|
4
|
+
module Action
|
5
|
+
module Project
|
6
|
+
|
7
|
+
#-----------------------------------------------------------------------------
|
8
|
+
# Options
|
9
|
+
|
10
|
+
def project_options(parser, ref_override = false, rev_override = false)
|
11
|
+
parser.option_str(:project_provider, 'git',
|
12
|
+
'--proj-provider PROVIDER',
|
13
|
+
'nucleon.core.mixins.project.options.provider'
|
14
|
+
)
|
15
|
+
if ref_override
|
16
|
+
parser.option_str(:reference, nil,
|
17
|
+
'--reference PROJECT_REF',
|
18
|
+
'nucleon.core.mixins.project.options.reference'
|
19
|
+
)
|
20
|
+
end
|
21
|
+
if rev_override
|
22
|
+
parser.option_str(:revision, nil,
|
23
|
+
'--revision PROJECT_REV',
|
24
|
+
'nucleon.core.mixins.project.options.revision'
|
25
|
+
)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
#-----------------------------------------------------------------------------
|
30
|
+
# Operations
|
31
|
+
|
32
|
+
def project_load(root_dir, update = false)
|
33
|
+
|
34
|
+
# 1. Set a default project provider (reference can override)
|
35
|
+
# 2. Get project from root directory
|
36
|
+
# 3. Initialize project if not yet initialized
|
37
|
+
# 4. Set remote if needed
|
38
|
+
# 5. Checkout revision if needed
|
39
|
+
# 6. Pull down updates if requested
|
40
|
+
|
41
|
+
return Nucleon.project(extended_config(:project, {
|
42
|
+
:provider => settings[:project_provider],
|
43
|
+
:directory => root_dir,
|
44
|
+
:url => settings[:reference],
|
45
|
+
:revision => settings[:revision],
|
46
|
+
:pull => update
|
47
|
+
}))
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|