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/Gemfile
CHANGED
@@ -2,18 +2,14 @@ source "http://rubygems.org"
|
|
2
2
|
|
3
3
|
gem "log4r", "~> 1.1"
|
4
4
|
gem "i18n", "~> 0.6"
|
5
|
+
gem "rgen", "~> 0.6"
|
6
|
+
gem "netrc", "~> 0.7"
|
5
7
|
gem "deep_merge", "~> 1.0"
|
6
|
-
|
7
|
-
gem "sshkey", "~> 1.6"
|
8
|
-
gem "hiera", "~> 1.3"
|
8
|
+
|
9
9
|
gem "multi_json", "~> 1.7"
|
10
10
|
gem "grit", "~> 2.5"
|
11
11
|
gem "octokit", "~> 2.7"
|
12
|
-
gem "
|
13
|
-
gem "fog", "~> 1.20"
|
14
|
-
gem "rgen", "~> 0.6"
|
15
|
-
gem "facter", "~> 1.7"
|
16
|
-
gem "puppet", "~> 3.2"
|
12
|
+
gem "celluloid", "~> 0.15"
|
17
13
|
|
18
14
|
group :development do
|
19
15
|
gem "bundler", "~> 1.2"
|
data/Gemfile.lock
CHANGED
@@ -8,20 +8,8 @@ GEM
|
|
8
8
|
deep_merge (1.0.1)
|
9
9
|
descendants_tracker (0.0.3)
|
10
10
|
diff-lcs (1.2.5)
|
11
|
-
excon (0.31.0)
|
12
|
-
facter (1.7.5)
|
13
11
|
faraday (0.9.0)
|
14
12
|
multipart-post (>= 1.2, < 3)
|
15
|
-
fog (1.20.0)
|
16
|
-
builder
|
17
|
-
excon (~> 0.31.0)
|
18
|
-
formatador (~> 0.2.0)
|
19
|
-
mime-types
|
20
|
-
multi_json (~> 1.0)
|
21
|
-
net-scp (~> 1.1)
|
22
|
-
net-ssh (>= 2.1.3)
|
23
|
-
nokogiri (>= 1.5.11)
|
24
|
-
formatador (0.2.4)
|
25
13
|
git (1.2.6)
|
26
14
|
github_api (0.11.2)
|
27
15
|
addressable (~> 2.3)
|
@@ -36,8 +24,6 @@ GEM
|
|
36
24
|
mime-types (~> 1.15)
|
37
25
|
posix-spawn (~> 0.3.6)
|
38
26
|
hashie (2.0.5)
|
39
|
-
hiera (1.3.1)
|
40
|
-
json_pure
|
41
27
|
highline (1.6.20)
|
42
28
|
i18n (0.6.9)
|
43
29
|
jeweler (2.0.1)
|
@@ -50,7 +36,6 @@ GEM
|
|
50
36
|
rake
|
51
37
|
rdoc
|
52
38
|
json (1.8.1)
|
53
|
-
json_pure (1.8.1)
|
54
39
|
jwt (0.1.11)
|
55
40
|
multi_json (>= 1.5)
|
56
41
|
log4r (1.1.10)
|
@@ -59,9 +44,6 @@ GEM
|
|
59
44
|
multi_json (1.8.4)
|
60
45
|
multi_xml (0.5.5)
|
61
46
|
multipart-post (2.0.0)
|
62
|
-
net-scp (1.1.2)
|
63
|
-
net-ssh (>= 2.6.5)
|
64
|
-
net-ssh (2.8.0)
|
65
47
|
netrc (0.7.7)
|
66
48
|
nokogiri (1.6.1)
|
67
49
|
mini_portile (~> 0.5.0)
|
@@ -74,10 +56,6 @@ GEM
|
|
74
56
|
octokit (2.7.1)
|
75
57
|
sawyer (~> 0.5.2)
|
76
58
|
posix-spawn (0.3.8)
|
77
|
-
puppet (3.4.3)
|
78
|
-
facter (~> 1.6)
|
79
|
-
hiera (~> 1.0)
|
80
|
-
rgen (~> 0.6.5)
|
81
59
|
rack (1.5.2)
|
82
60
|
rake (10.1.1)
|
83
61
|
rdoc (3.12.2)
|
@@ -94,7 +72,6 @@ GEM
|
|
94
72
|
sawyer (0.5.3)
|
95
73
|
addressable (~> 2.3.5)
|
96
74
|
faraday (~> 0.8, < 0.10)
|
97
|
-
sshkey (1.6.1)
|
98
75
|
timers (1.1.0)
|
99
76
|
yard (0.8.7.3)
|
100
77
|
|
@@ -105,19 +82,14 @@ DEPENDENCIES
|
|
105
82
|
bundler (~> 1.2)
|
106
83
|
celluloid (~> 0.15)
|
107
84
|
deep_merge (~> 1.0)
|
108
|
-
facter (~> 1.7)
|
109
|
-
fog (~> 1.20)
|
110
85
|
grit (~> 2.5)
|
111
|
-
hiera (~> 1.3)
|
112
86
|
i18n (~> 0.6)
|
113
87
|
jeweler (~> 2.0)
|
114
88
|
log4r (~> 1.1)
|
115
89
|
multi_json (~> 1.7)
|
116
90
|
netrc (~> 0.7)
|
117
91
|
octokit (~> 2.7)
|
118
|
-
puppet (~> 3.2)
|
119
92
|
rdoc (~> 3.12)
|
120
93
|
rgen (~> 0.6)
|
121
94
|
rspec (~> 2.10)
|
122
|
-
sshkey (~> 1.6)
|
123
95
|
yard (~> 0.8)
|
data/README.rdoc
CHANGED
@@ -1,9 +1,17 @@
|
|
1
|
-
=
|
1
|
+
= Nucleon
|
2
2
|
|
3
|
-
|
4
|
-
scaffolding but it is functional.
|
3
|
+
A framework that provides a simple foundation for building apps that are:
|
5
4
|
|
6
|
-
|
5
|
+
1. Distributively configured
|
6
|
+
2. Extremely pluggable and extendable
|
7
|
+
3. Easily parallel
|
8
|
+
|
9
|
+
More coming soon!
|
10
|
+
|
11
|
+
Note: This library is still very early in development!
|
12
|
+
|
13
|
+
|
14
|
+
== Contributing to Nucleon
|
7
15
|
|
8
16
|
* Check out the latest {major}.{minor} branch to make sure the feature hasn't
|
9
17
|
been implemented or the bug hasn't been fixed yet.
|
@@ -22,5 +30,5 @@ scaffolding but it is functional.
|
|
22
30
|
|
23
31
|
Licensed under GPLv3. See LICENSE.txt for further details.
|
24
32
|
|
25
|
-
Copyright (c)
|
33
|
+
Copyright (c) 2014 Adrian Webb <adrian.webb@coralnexus.com>
|
26
34
|
Coral Technology Group LLC
|
data/Rakefile
CHANGED
@@ -33,7 +33,15 @@ Jeweler::Tasks.new do |gem|
|
|
33
33
|
gem.email = "adrian.webb@coralnexus.com"
|
34
34
|
gem.authors = ["Adrian Webb"]
|
35
35
|
gem.summary = %Q{Framework that provides a simple foundation for building distributively configured, extremely pluggable and extendable, and easily parallel Ruby applications}
|
36
|
-
gem.description = %Q{
|
36
|
+
gem.description = %Q{
|
37
|
+
A framework that provides a simple foundation for building Ruby applications that are:
|
38
|
+
|
39
|
+
* Highly configurable (with both distributed and persistent configurations)
|
40
|
+
* Extremely pluggable and extendable
|
41
|
+
* Easily parallel
|
42
|
+
|
43
|
+
Note: This framework is still very early in development!
|
44
|
+
}
|
37
45
|
gem.required_ruby_version = '>= 1.8.1'
|
38
46
|
gem.has_rdoc = true
|
39
47
|
gem.rdoc_options << '--title' << 'Nucleon' <<
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.1.
|
1
|
+
0.1.1
|
data/bin/nucleon
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
Signal.trap("INT") { exit 1 }
|
4
|
+
|
5
|
+
#---
|
6
|
+
|
7
|
+
require 'nucleon'
|
8
|
+
|
9
|
+
logger = Nucleon.logger
|
10
|
+
logger.info("`nucleon` invoked: #{ARGV.inspect}")
|
11
|
+
|
12
|
+
#---
|
13
|
+
|
14
|
+
$stdout.sync = true
|
15
|
+
$stderr.sync = true
|
16
|
+
|
17
|
+
#---
|
18
|
+
|
19
|
+
begin
|
20
|
+
logger.debug("Beginning execution run")
|
21
|
+
|
22
|
+
arg_components = Nucleon::Util::CLI::Parser.split(ARGV, 'nucleon <action> [ <arg> ... ]')
|
23
|
+
main_command = arg_components.shift
|
24
|
+
sub_command = arg_components.shift
|
25
|
+
sub_args = arg_components
|
26
|
+
|
27
|
+
if main_command.processed && sub_command
|
28
|
+
exit_status = Nucleon.action_cli(sub_command, sub_args)
|
29
|
+
else
|
30
|
+
puts I18n.t('nucleon.core.exec.help.usage') + ': ' + main_command.help + "\n"
|
31
|
+
puts I18n.t('nucleon.core.exec.help.header') + ":\n\n"
|
32
|
+
|
33
|
+
Nucleon.loaded_plugins(:action).each do |provider, action|
|
34
|
+
puts sprintf(" %-10s : %s\n",
|
35
|
+
"<#{provider}>",
|
36
|
+
Nucleon.action(provider, { :settings => {}, :quiet => true }).help
|
37
|
+
)
|
38
|
+
end
|
39
|
+
|
40
|
+
puts "\n" + I18n.t('nucleon.core.exec.help.footer') + "\n\n"
|
41
|
+
exit_status = Nucleon.code.help_wanted
|
42
|
+
end
|
43
|
+
|
44
|
+
rescue Exception => error
|
45
|
+
logger.error("Nucleon executable experienced an error:")
|
46
|
+
logger.error(error.inspect)
|
47
|
+
logger.error(error.message)
|
48
|
+
logger.error(Nucleon::Util::Data.to_yaml(error.backtrace))
|
49
|
+
|
50
|
+
Nucleon.ui.error(error.message, { :prefix => false }) if error.message
|
51
|
+
|
52
|
+
exit_status = error.status_code if error.respond_to?(:status_code)
|
53
|
+
end
|
54
|
+
|
55
|
+
exit(exit_status)
|
data/lib/core/codes.rb
ADDED
@@ -0,0 +1,107 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
class Codes
|
4
|
+
|
5
|
+
#-----------------------------------------------------------------------------
|
6
|
+
# Code index
|
7
|
+
|
8
|
+
@@registry = {}
|
9
|
+
@@status_index = {}
|
10
|
+
@@next_code = 0
|
11
|
+
|
12
|
+
#---
|
13
|
+
|
14
|
+
def self.registry
|
15
|
+
@@registry
|
16
|
+
end
|
17
|
+
|
18
|
+
#---
|
19
|
+
|
20
|
+
def self.index(status_code = nil)
|
21
|
+
if status_code.nil? || ! status_code.integer?
|
22
|
+
@@status_index
|
23
|
+
else
|
24
|
+
status_code = status_code.to_i
|
25
|
+
|
26
|
+
if @@status_index.has_key?(status_code)
|
27
|
+
@@status_index[status_code]
|
28
|
+
else
|
29
|
+
@@status_index[registry[:unknown_status]]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
#---
|
35
|
+
|
36
|
+
def self.render_index(status_code = nil)
|
37
|
+
output = "Status index:\n"
|
38
|
+
@@status_index.each do |code, name|
|
39
|
+
name = name.gsub(/_/, ' ').capitalize
|
40
|
+
|
41
|
+
if ! status_code.nil? && status_code == code
|
42
|
+
output << sprintf(" [ %3i ] - %s\n", code, name)
|
43
|
+
else
|
44
|
+
output << sprintf(" %3i - %s\n", code, name)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
output << "\n"
|
48
|
+
output
|
49
|
+
end
|
50
|
+
|
51
|
+
#-----------------------------------------------------------------------------
|
52
|
+
# Code construction
|
53
|
+
|
54
|
+
def self.code(name)
|
55
|
+
name = name.to_sym
|
56
|
+
|
57
|
+
unless registry.has_key?(name)
|
58
|
+
status_code = @@next_code
|
59
|
+
@@next_code = @@next_code + 1
|
60
|
+
|
61
|
+
# TODO: Add more information to the index (like a help message)
|
62
|
+
@@registry[name] = status_code
|
63
|
+
@@status_index[status_code] = name.to_s
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
#---
|
68
|
+
|
69
|
+
def self.codes(*codes)
|
70
|
+
codes.each do |name|
|
71
|
+
code(name)
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
#-----------------------------------------------------------------------------
|
76
|
+
# Return status codes on demand
|
77
|
+
|
78
|
+
def [](name)
|
79
|
+
name = name.to_sym
|
80
|
+
|
81
|
+
if @@registry.has_key?(name)
|
82
|
+
@@registry[name]
|
83
|
+
else
|
84
|
+
@@registry[:unknown_status]
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
#---
|
89
|
+
|
90
|
+
def method_missing(method, *args, &block)
|
91
|
+
self[method]
|
92
|
+
end
|
93
|
+
|
94
|
+
#-----------------------------------------------------------------------------
|
95
|
+
# Core status codes
|
96
|
+
|
97
|
+
code(:success) # This must be added first (needs to be 0)
|
98
|
+
code(:help_wanted)
|
99
|
+
code(:unknown_status)
|
100
|
+
|
101
|
+
code(:action_unprocessed)
|
102
|
+
code(:batch_error)
|
103
|
+
|
104
|
+
code(:validation_failed)
|
105
|
+
code(:access_denied)
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
class Config
|
4
|
+
class Collection
|
5
|
+
|
6
|
+
#-----------------------------------------------------------------------------
|
7
|
+
# Property accessor / modifiers
|
8
|
+
|
9
|
+
@@properties = {}
|
10
|
+
|
11
|
+
#---
|
12
|
+
|
13
|
+
def self.all
|
14
|
+
return @@properties
|
15
|
+
end
|
16
|
+
|
17
|
+
#---
|
18
|
+
|
19
|
+
def self.get(name)
|
20
|
+
return @@properties[name.to_sym]
|
21
|
+
end
|
22
|
+
|
23
|
+
#---
|
24
|
+
|
25
|
+
def self.set(name, value)
|
26
|
+
@@properties[name.to_sym] = value
|
27
|
+
end
|
28
|
+
|
29
|
+
#---
|
30
|
+
|
31
|
+
def self.delete(name)
|
32
|
+
@@properties.delete(name.to_sym)
|
33
|
+
end
|
34
|
+
|
35
|
+
#---
|
36
|
+
|
37
|
+
def self.clear
|
38
|
+
@@properties = {}
|
39
|
+
end
|
40
|
+
|
41
|
+
#---
|
42
|
+
|
43
|
+
def self.save
|
44
|
+
log_options = Options.get(:nucleon_log)
|
45
|
+
|
46
|
+
unless Util::Data.empty?(log_options[:config_log])
|
47
|
+
config_log = log_options[:config_log]
|
48
|
+
|
49
|
+
if log_options[:config_store]
|
50
|
+
Util::Disk.write(config_log, MultiJson.dump(@@properties, :pretty => true))
|
51
|
+
Util::Disk.close(config_log)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
@@ -0,0 +1,70 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
class Config
|
4
|
+
class Options
|
5
|
+
|
6
|
+
#-----------------------------------------------------------------------------
|
7
|
+
# Property accessors / modifiers
|
8
|
+
|
9
|
+
@@options = {}
|
10
|
+
|
11
|
+
#---
|
12
|
+
|
13
|
+
def self.contexts(contexts = [], hierarchy = [])
|
14
|
+
contexts = [ 'all', contexts ].flatten
|
15
|
+
|
16
|
+
unless hierarchy.is_a?(Array)
|
17
|
+
hierarchy = ( ! Util::Data.empty?(hierarchy) ? [ hierarchy ].flatten : [] )
|
18
|
+
end
|
19
|
+
|
20
|
+
hierarchy.each do |group|
|
21
|
+
group_contexts = Util::Data.prefix(group, contexts)
|
22
|
+
contexts = [ contexts, group_contexts ].flatten
|
23
|
+
end
|
24
|
+
|
25
|
+
return contexts
|
26
|
+
end
|
27
|
+
|
28
|
+
#---
|
29
|
+
|
30
|
+
def self.get(contexts, force = true)
|
31
|
+
options = {}
|
32
|
+
|
33
|
+
unless contexts.is_a?(Array)
|
34
|
+
contexts = ( ! Util::Data.empty?(contexts) ? [ contexts ].flatten : [] )
|
35
|
+
end
|
36
|
+
contexts.each do |name|
|
37
|
+
name = name.to_sym
|
38
|
+
if @@options.has_key?(name)
|
39
|
+
options = Util::Data.merge([ options, @@options[name] ], force)
|
40
|
+
end
|
41
|
+
end
|
42
|
+
return options
|
43
|
+
end
|
44
|
+
|
45
|
+
#---
|
46
|
+
|
47
|
+
def self.set(contexts, options, force = true)
|
48
|
+
unless contexts.is_a?(Array)
|
49
|
+
contexts = ( ! Util::Data.empty?(contexts) ? [ contexts ].flatten : [] )
|
50
|
+
end
|
51
|
+
contexts.each do |name|
|
52
|
+
name = name.to_sym
|
53
|
+
current_options = ( @@options.has_key?(name) ? @@options[name] : {} )
|
54
|
+
@@options[name] = Util::Data.merge([ current_options, Config.symbol_map(options) ], force)
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
#---
|
59
|
+
|
60
|
+
def self.clear(contexts)
|
61
|
+
unless contexts.is_a?(Array)
|
62
|
+
contexts = [ contexts ]
|
63
|
+
end
|
64
|
+
contexts.each do |name|
|
65
|
+
@@options.delete(name.to_sym)
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
70
|
+
end
|