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.
Files changed (62) hide show
  1. data/Gemfile +4 -8
  2. data/Gemfile.lock +0 -28
  3. data/README.rdoc +13 -5
  4. data/Rakefile +9 -1
  5. data/VERSION +1 -1
  6. data/bin/nucleon +55 -0
  7. data/lib/core/codes.rb +107 -0
  8. data/lib/core/config/collection.rb +57 -0
  9. data/lib/core/config/options.rb +70 -0
  10. data/lib/core/config.rb +342 -0
  11. data/lib/core/core.rb +54 -0
  12. data/lib/core/errors.rb +84 -0
  13. data/lib/core/facade.rb +283 -0
  14. data/lib/core/gems.rb +80 -0
  15. data/lib/core/manager.rb +594 -0
  16. data/lib/core/mixin/action/commit.rb +58 -0
  17. data/lib/core/mixin/action/project.rb +53 -0
  18. data/lib/core/mixin/action/push.rb +52 -0
  19. data/lib/core/mixin/config/collection.rb +53 -0
  20. data/lib/core/mixin/config/options.rb +39 -0
  21. data/lib/core/mixin/macro/object_interface.rb +361 -0
  22. data/lib/core/mixin/macro/plugin_interface.rb +380 -0
  23. data/lib/core/mixin/settings.rb +46 -0
  24. data/lib/core/mixin/sub_config.rb +148 -0
  25. data/lib/core/mod/hash.rb +29 -0
  26. data/lib/core/plugin/action.rb +371 -0
  27. data/lib/core/plugin/base.rb +313 -0
  28. data/lib/core/plugin/command.rb +98 -0
  29. data/lib/core/plugin/event.rb +53 -0
  30. data/lib/core/plugin/extension.rb +12 -0
  31. data/lib/core/plugin/project.rb +890 -0
  32. data/lib/core/plugin/template.rb +80 -0
  33. data/lib/core/plugin/translator.rb +38 -0
  34. data/lib/core/util/cli.rb +353 -0
  35. data/lib/core/util/console.rb +237 -0
  36. data/lib/core/util/data.rb +404 -0
  37. data/lib/core/util/disk.rb +114 -0
  38. data/lib/core/util/git.rb +43 -0
  39. data/lib/core/util/liquid.rb +17 -0
  40. data/lib/core/util/logger.rb +147 -0
  41. data/lib/core/util/package.rb +93 -0
  42. data/lib/core/util/shell.rb +239 -0
  43. data/lib/nucleon/action/add.rb +69 -0
  44. data/lib/nucleon/action/create.rb +52 -0
  45. data/lib/nucleon/action/extract.rb +49 -0
  46. data/lib/nucleon/action/remove.rb +51 -0
  47. data/lib/nucleon/action/save.rb +53 -0
  48. data/lib/nucleon/action/update.rb +37 -0
  49. data/lib/nucleon/command/bash.rb +146 -0
  50. data/lib/nucleon/event/regex.rb +52 -0
  51. data/lib/nucleon/project/git.rb +465 -0
  52. data/lib/nucleon/project/github.rb +108 -0
  53. data/lib/nucleon/template/json.rb +16 -0
  54. data/lib/nucleon/template/wrapper.rb +16 -0
  55. data/lib/nucleon/template/yaml.rb +16 -0
  56. data/lib/nucleon/translator/json.rb +27 -0
  57. data/lib/nucleon/translator/yaml.rb +27 -0
  58. data/lib/nucleon.rb +18 -15
  59. data/locales/en.yml +3 -132
  60. data/nucleon.gemspec +66 -27
  61. data/spec/core/util/console_spec.rb +489 -0
  62. metadata +109 -96
@@ -0,0 +1,342 @@
1
+
2
+ module Nucleon
3
+ class Config
4
+
5
+ #-----------------------------------------------------------------------------
6
+ # Global interface
7
+
8
+ extend Mixin::ConfigOptions
9
+ extend Mixin::ConfigCollection
10
+
11
+ #-----------------------------------------------------------------------------
12
+ # Instance generators
13
+
14
+ def self.ensure(config)
15
+ case config
16
+ when Nucleon::Config
17
+ return config
18
+ when Hash
19
+ return new(config)
20
+ end
21
+ return new
22
+ end
23
+
24
+ #---
25
+
26
+ def self.init(options, contexts = [], hierarchy = [], defaults = {})
27
+ contexts = contexts(contexts, hierarchy)
28
+ config = new(get_options(contexts), defaults)
29
+ config.import(options) unless Util::Data.empty?(options)
30
+ return config
31
+ end
32
+
33
+ #---
34
+
35
+ def self.init_flat(options, contexts = [], defaults = {})
36
+ return init(options, contexts, [], defaults)
37
+ end
38
+
39
+ #-----------------------------------------------------------------------------
40
+ # Constructor / Destructor
41
+
42
+ def initialize(data = {}, defaults = {}, force = true)
43
+ @force = force
44
+ @properties = {}
45
+
46
+ if defaults.is_a?(Hash) && ! defaults.empty?
47
+ defaults = symbol_map(defaults)
48
+ end
49
+
50
+ case data
51
+ when Nucleon::Config
52
+ @properties = Util::Data.merge([ defaults, data.export ], force)
53
+ when Hash
54
+ @properties = {}
55
+ if data.is_a?(Hash)
56
+ @properties = Util::Data.merge([ defaults, symbol_map(data) ], force)
57
+ end
58
+ end
59
+ end
60
+
61
+ #-----------------------------------------------------------------------------
62
+ # Checks
63
+
64
+ def empty?
65
+ @properties.empty?
66
+ end
67
+
68
+ #---
69
+
70
+ def has_key?(keys)
71
+ get(keys) ? true : false
72
+ end
73
+
74
+ #-----------------------------------------------------------------------------
75
+ # Property accessors / modifiers
76
+
77
+ def keys
78
+ @properties.keys
79
+ end
80
+
81
+ #---
82
+
83
+ def fetch(data, keys, default = nil, format = false)
84
+ if keys.is_a?(String) || keys.is_a?(Symbol)
85
+ keys = [ keys ]
86
+ end
87
+ key = keys.shift.to_sym
88
+
89
+ if data.has_key?(key)
90
+ value = data[key]
91
+
92
+ if keys.empty?
93
+ return filter(value, format)
94
+ else
95
+ return fetch(data[key], keys, default, format)
96
+ end
97
+ end
98
+ return filter(default, format)
99
+ end
100
+ protected :fetch
101
+
102
+ #---
103
+
104
+ def modify(data, keys, value = nil)
105
+ if keys.is_a?(String) || keys.is_a?(Symbol)
106
+ keys = [ keys ]
107
+ end
108
+
109
+ key = keys.shift.to_sym
110
+ has_key = data.has_key?(key)
111
+ existing = {
112
+ :key => key,
113
+ :value => ( has_key ? data[key] : nil )
114
+ }
115
+
116
+ if keys.empty?
117
+ existing[:value] = data[key] if has_key
118
+
119
+ if value.nil?
120
+ data.delete(key) if has_key
121
+ else
122
+ data[key] = value
123
+ end
124
+ else
125
+ data[key] = {} unless has_key
126
+ existing = modify(data[key], keys, value)
127
+ end
128
+
129
+ return existing
130
+ end
131
+ protected :modify
132
+
133
+ #---
134
+
135
+ def get(keys, default = nil, format = false)
136
+ return fetch(@properties, array(keys).flatten, default, format)
137
+ end
138
+
139
+ #---
140
+
141
+ def [](name, default = nil, format = false)
142
+ get(name, default, format)
143
+ end
144
+
145
+ #---
146
+
147
+ def get_array(keys, default = [])
148
+ return get(keys, default, :array)
149
+ end
150
+
151
+ #---
152
+
153
+ def get_hash(keys, default = {})
154
+ return get(keys, default, :hash)
155
+ end
156
+
157
+ #---
158
+
159
+ def init(keys, default = nil)
160
+ return set(keys, get(keys, default))
161
+ end
162
+
163
+ #---
164
+
165
+ def set(keys, value)
166
+ modify(@properties, array(keys).flatten, value)
167
+ return self
168
+ end
169
+
170
+ #---
171
+
172
+ def []=(name, value)
173
+ set(name, value)
174
+ end
175
+
176
+ #---
177
+
178
+ def delete(keys, default = nil)
179
+ existing = modify(@properties, array(keys).flatten, nil)
180
+ return existing[:value] if existing[:value]
181
+ return default
182
+ end
183
+
184
+ #---
185
+
186
+ def clear
187
+ @properties = {}
188
+ return self
189
+ end
190
+
191
+ #-----------------------------------------------------------------------------
192
+ # Import / Export
193
+
194
+ def import_base(properties, options = {})
195
+ config = Config.new(options, { :force => @force }).set(:context, :hash)
196
+ import_type = config.get(:import_type, :override)
197
+
198
+ properties = properties.export if properties.is_a?(Nucleon::Config)
199
+
200
+ case properties
201
+ when Hash
202
+ data = [ @properties, symbol_map(properties) ]
203
+ data = data.reverse if import_type != :override
204
+
205
+ @properties = Util::Data.merge(data, config)
206
+
207
+ when String, Symbol
208
+ properties = self.class.lookup(properties.to_s, {}, config)
209
+
210
+ data = [ @properties, symbol_map(properties) ]
211
+ data = data.reverse if import_type != :override
212
+
213
+ @properties = Util::Data.merge(data, config)
214
+
215
+ when Array
216
+ properties.each do |item|
217
+ import_base(item, config)
218
+ end
219
+ end
220
+
221
+ return self
222
+ end
223
+ protected :import_base
224
+
225
+ #---
226
+
227
+ def import(properties, options = {})
228
+ return import_base(properties, options)
229
+ end
230
+
231
+ #---
232
+
233
+ def defaults(defaults, options = {})
234
+ config = Config.new(options).set(:import_type, :default)
235
+ return import_base(defaults, config)
236
+ end
237
+
238
+ #---
239
+
240
+ def export
241
+ return @properties
242
+ end
243
+
244
+ #-----------------------------------------------------------------------------
245
+ # Utilities
246
+
247
+ def self.symbol_map(data)
248
+ return Util::Data.symbol_map(data)
249
+ end
250
+
251
+ #---
252
+
253
+ def symbol_map(data)
254
+ return self.class.symbol_map(data)
255
+ end
256
+
257
+ #---
258
+
259
+ def self.string_map(data)
260
+ return Util::Data.string_map(data)
261
+ end
262
+
263
+ #---
264
+
265
+ def string_map(data)
266
+ return self.class.string_map(data)
267
+ end
268
+
269
+ #-----------------------------------------------------------------------------
270
+
271
+ def self.filter(data, method = false)
272
+ return Util::Data.filter(data, method)
273
+ end
274
+
275
+ #---
276
+
277
+ def filter(data, method = false)
278
+ return self.class.filter(data, method)
279
+ end
280
+
281
+ #-----------------------------------------------------------------------------
282
+
283
+ def self.array(data, default = [], split_string = false)
284
+ return Util::Data.array(data, default, split_string)
285
+ end
286
+
287
+ #---
288
+
289
+ def array(data, default = [], split_string = false)
290
+ return self.class.array(data, default, split_string)
291
+ end
292
+
293
+ #---
294
+
295
+ def self.hash(data, default = {})
296
+ data = data.export if data.is_a?(Nucleon::Config)
297
+ return Util::Data.hash(data, default)
298
+ end
299
+
300
+ #---
301
+
302
+ def hash(data, default = {})
303
+ return self.class.hash(data, default)
304
+ end
305
+
306
+ #---
307
+
308
+ def self.string(data, default = '')
309
+ return Util::Data.string(data, default)
310
+ end
311
+
312
+ #---
313
+
314
+ def string(data, default = '')
315
+ return self.class.string(data, default)
316
+ end
317
+
318
+ #---
319
+
320
+ def self.symbol(data, default = :undefined)
321
+ return Util::Data.symbol(data, default)
322
+ end
323
+
324
+ #---
325
+
326
+ def symbol(data, default = :undefined)
327
+ return self.class.symbol(data, default)
328
+ end
329
+
330
+ #---
331
+
332
+ def self.test(data)
333
+ return Util::Data.test(data)
334
+ end
335
+
336
+ #---
337
+
338
+ def test(data)
339
+ return self.class.test(data)
340
+ end
341
+ end
342
+ end
data/lib/core/core.rb ADDED
@@ -0,0 +1,54 @@
1
+
2
+ module Nucleon
3
+ class Core < Config
4
+
5
+ #-----------------------------------------------------------------------------
6
+ # Properties
7
+
8
+ @@logger = Util::Logger.new('core')
9
+ @@ui = Util::Console.new('core')
10
+
11
+ #-----------------------------------------------------------------------------
12
+ # Constructor / Destructor
13
+
14
+ def initialize(data = {}, defaults = {}, force = true)
15
+ super(data, defaults, force)
16
+
17
+ class_label = self.class.to_s.downcase.gsub(/^nucleon::/, '')
18
+
19
+ @logger = Util::Logger.new(delete(:logger, class_label))
20
+ @ui = Util::Console.new(Config.new(export).defaults({ :resource => class_label }))
21
+
22
+ logger.debug('Initialized instance logger and interface')
23
+ end
24
+
25
+ #-----------------------------------------------------------------------------
26
+ # Accessor / Modifiers
27
+
28
+ attr_accessor :logger, :ui
29
+
30
+ #---
31
+
32
+ def self.logger
33
+ return @@logger
34
+ end
35
+
36
+ #---
37
+
38
+ def self.ui
39
+ return @@ui
40
+ end
41
+
42
+ #-----------------------------------------------------------------------------
43
+ # General utilities
44
+
45
+ def ui_group(resource)
46
+ ui_resource = ui.resource
47
+ ui.resource = resource
48
+ yield
49
+
50
+ ensure
51
+ ui.resource = ui_resource
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,84 @@
1
+
2
+ module Nucleon
3
+ module Errors
4
+
5
+ #-----------------------------------------------------------------------------
6
+ # Base error (based on VagrantError)
7
+
8
+ class NucleonError < StandardError
9
+
10
+ #---------------------------------------------------------------------------
11
+ # Error constructor / destructor
12
+
13
+ def initialize(*args)
14
+ key = args.shift if args.first.is_a?(Symbol)
15
+ message = args.shift if args.first.is_a?(Hash)
16
+ message ||= {}
17
+
18
+ @extra_data = message.dup
19
+
20
+ message[:key] ||= error_key
21
+ message[:namespace] ||= error_namespace
22
+ message[:key] = key if key
23
+
24
+ if message[:key]
25
+ message = translate_error(message)
26
+ else
27
+ message = error_message
28
+ end
29
+
30
+ super(message)
31
+ end
32
+
33
+ #---------------------------------------------------------------------------
34
+ # Property accessor / modifiers
35
+
36
+ attr_accessor :extra_data
37
+
38
+ #---
39
+
40
+ def self.error_key(key = nil, namespace = nil)
41
+ define_method(:error_key) { key }
42
+ error_namespace(namespace) if namespace
43
+ end
44
+ def error_key; nil; end # Default
45
+
46
+ #---
47
+
48
+ def self.error_message(message)
49
+ define_method(:error_message) { message }
50
+ end
51
+ def error_message; "No error message"; end # Default
52
+
53
+ #---
54
+
55
+ def self.error_namespace(namespace)
56
+ define_method(:error_namespace) { namespace }
57
+ end
58
+ def error_namespace; "nucleon.errors"; end # Default
59
+
60
+ #---
61
+
62
+ def self.status_code(code)
63
+ define_method(:status_code) { code }
64
+ end
65
+ def status_code; 1; end # Default
66
+
67
+ #---------------------------------------------------------------------------
68
+ # Utilities
69
+
70
+ def translate_error(options)
71
+ return nil unless options[:key]
72
+ I18n.t("#{options[:namespace]}.#{options[:key]}", options)
73
+ end
74
+ protected :translate_error
75
+ end
76
+
77
+ #-----------------------------------------------------------------------------
78
+ # Specialized errors
79
+
80
+ class BatchError < NucleonError
81
+ error_key(:batch_error)
82
+ end
83
+ end
84
+ end