nucleon 0.1.0 → 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
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