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,93 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Util
|
4
|
+
class Package
|
5
|
+
|
6
|
+
#-----------------------------------------------------------------------------
|
7
|
+
# Constructor / Destructor
|
8
|
+
|
9
|
+
def initialize(options = {})
|
10
|
+
if options.is_a?(String)
|
11
|
+
@data = Config.new
|
12
|
+
decode(options)
|
13
|
+
else
|
14
|
+
@data = Config.ensure(options)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
#-----------------------------------------------------------------------------
|
19
|
+
# Property accessors / modifiers
|
20
|
+
|
21
|
+
attr_reader :data
|
22
|
+
|
23
|
+
#-----------------------------------------------------------------------------
|
24
|
+
# Operations
|
25
|
+
|
26
|
+
def encode
|
27
|
+
Base64.encode64(Data.to_json(data.export, false))
|
28
|
+
end
|
29
|
+
|
30
|
+
def decode(encoded_string)
|
31
|
+
data.import(Data.symbol_map(Data.parse_json(Base64.decode64(encoded_string))))
|
32
|
+
end
|
33
|
+
|
34
|
+
#---
|
35
|
+
|
36
|
+
def add_file(file, target_path = nil, perm = 0600)
|
37
|
+
target_path = file if target_path.nil?
|
38
|
+
file = File.expand_path(file)
|
39
|
+
|
40
|
+
if File.exists?(file)
|
41
|
+
content = Disk.read(file)
|
42
|
+
data.set([ :files, target_path ], { :perm => perm, :content => content }) if content
|
43
|
+
end
|
44
|
+
self
|
45
|
+
end
|
46
|
+
|
47
|
+
#---
|
48
|
+
|
49
|
+
def add_files(base_path, file_glob, target_path = nil, perm = 0600)
|
50
|
+
target_path = base_path if target_path.nil?
|
51
|
+
curr_dir = Dir.pwd
|
52
|
+
|
53
|
+
Dir.chdir(File.expand_path(base_path))
|
54
|
+
Dir.glob(file_glob.gsub(/^[\/\\]+/, '')) do |file|
|
55
|
+
content = Disk.read(file)
|
56
|
+
|
57
|
+
if content
|
58
|
+
data.set([ :dir, target_path, file ], { :perm => perm, :content => content })
|
59
|
+
end
|
60
|
+
end
|
61
|
+
Dir.chdir(curr_dir)
|
62
|
+
self
|
63
|
+
end
|
64
|
+
|
65
|
+
#---
|
66
|
+
|
67
|
+
def extract(base_path)
|
68
|
+
success = true
|
69
|
+
|
70
|
+
data.get_hash(:files).each do |target_path, info|
|
71
|
+
file = File.join(base_path.to_s, target_path.to_s)
|
72
|
+
perm = info[:perm]
|
73
|
+
content = info[:content]
|
74
|
+
|
75
|
+
FileUtils.mkdir_p(File.dirname(file))
|
76
|
+
success = false unless Disk.write(file, content) && File.chmod(perm, file)
|
77
|
+
end
|
78
|
+
|
79
|
+
data.get_hash(:dir).each do |target_path, files|
|
80
|
+
files.each do |file, info|
|
81
|
+
file = File.join(base_path.to_s, target_path.to_s, file.to_s)
|
82
|
+
perm = info[:perm]
|
83
|
+
content = info[:content]
|
84
|
+
|
85
|
+
FileUtils.mkdir_p(File.dirname(file))
|
86
|
+
success = false unless Disk.write(file, content) && File.chmod(perm, file)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
success
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Util
|
4
|
+
class Shell < Core
|
5
|
+
|
6
|
+
include Celluloid
|
7
|
+
|
8
|
+
#-----------------------------------------------------------------------------
|
9
|
+
|
10
|
+
@@supervisors = {}
|
11
|
+
|
12
|
+
#-----------------------------------------------------------------------------
|
13
|
+
# Execution result interface
|
14
|
+
|
15
|
+
class Result
|
16
|
+
attr_accessor :status
|
17
|
+
attr_reader :command
|
18
|
+
|
19
|
+
def initialize(command)
|
20
|
+
@command = command
|
21
|
+
@output = ''
|
22
|
+
@errors = ''
|
23
|
+
@status = Nucleon.code.success
|
24
|
+
end
|
25
|
+
|
26
|
+
#---
|
27
|
+
|
28
|
+
def output
|
29
|
+
@output.strip
|
30
|
+
end
|
31
|
+
|
32
|
+
def errors
|
33
|
+
@errors.strip
|
34
|
+
end
|
35
|
+
|
36
|
+
#---
|
37
|
+
|
38
|
+
def append_output(output_str)
|
39
|
+
@output << output_str
|
40
|
+
end
|
41
|
+
|
42
|
+
def append_errors(error_str)
|
43
|
+
@errors << error_str
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
#-----------------------------------------------------------------------------
|
48
|
+
# Shell interface
|
49
|
+
|
50
|
+
def self.connection(name = :core)
|
51
|
+
name = name.to_sym
|
52
|
+
init_shell(name) unless @@supervisors.has_key?(name)
|
53
|
+
@@supervisors[name]
|
54
|
+
end
|
55
|
+
|
56
|
+
def self.init_shell(name)
|
57
|
+
name = name.to_sym
|
58
|
+
|
59
|
+
Shell.supervise_as name
|
60
|
+
@@supervisors[name] = Celluloid::Actor[name]
|
61
|
+
end
|
62
|
+
|
63
|
+
#---
|
64
|
+
|
65
|
+
execute_block_on_receiver :exec
|
66
|
+
|
67
|
+
def exec(command, options = {}, &code)
|
68
|
+
config = Config.ensure(options)
|
69
|
+
|
70
|
+
min = config.get(:min, 1).to_i
|
71
|
+
tries = config.get(:tries, min).to_i
|
72
|
+
tries = ( min > tries ? min : tries )
|
73
|
+
|
74
|
+
info_prefix = config.get(:info_prefix, '')
|
75
|
+
info_suffix = config.get(:info_suffix, '')
|
76
|
+
error_prefix = config.get(:error_prefix, '')
|
77
|
+
error_suffix = config.get(:error_suffix, '')
|
78
|
+
|
79
|
+
ui = config.get(:ui, Nucleon.ui)
|
80
|
+
|
81
|
+
conditions = Nucleon.events(config.get(:exit, {}), true)
|
82
|
+
|
83
|
+
$stdout.sync = true
|
84
|
+
$stderr.sync = true
|
85
|
+
|
86
|
+
system_result = Result.new(command)
|
87
|
+
|
88
|
+
for i in tries.downto(1)
|
89
|
+
logger.info(">> running: #{command}")
|
90
|
+
|
91
|
+
begin
|
92
|
+
t1, output_new, output_orig, output_reader = pipe_exec_stream($stdout, conditions, {
|
93
|
+
:prefix => info_prefix,
|
94
|
+
:suffix => info_suffix,
|
95
|
+
}, 'output') do |data|
|
96
|
+
system_result.append_output(data)
|
97
|
+
block_given? ? code.call(:output, command, data) : true
|
98
|
+
end
|
99
|
+
|
100
|
+
t2, error_new, error_orig, error_reader = pipe_exec_stream($stderr, conditions, {
|
101
|
+
:prefix => error_prefix,
|
102
|
+
:suffix => error_suffix,
|
103
|
+
}, 'error') do |data|
|
104
|
+
system_result.append_errors(data)
|
105
|
+
block_given? ? code.call(:error, command, data) : true
|
106
|
+
end
|
107
|
+
|
108
|
+
system_success = system(command)
|
109
|
+
system_result.status = $?.exitstatus
|
110
|
+
|
111
|
+
ensure
|
112
|
+
output_success = close_exec_pipe(t1, $stdout, output_orig, output_new, 'output')
|
113
|
+
error_success = close_exec_pipe(t2, $stderr, error_orig, error_new, 'error')
|
114
|
+
end
|
115
|
+
|
116
|
+
success = ( system_success && output_success && error_success )
|
117
|
+
|
118
|
+
min -= 1
|
119
|
+
break if success && min <= 0 && conditions.empty?
|
120
|
+
end
|
121
|
+
system_result
|
122
|
+
end
|
123
|
+
|
124
|
+
#---
|
125
|
+
|
126
|
+
def pipe_exec_stream(output, conditions, options, label, &code)
|
127
|
+
original = output.dup
|
128
|
+
read, write = IO.pipe
|
129
|
+
|
130
|
+
match_prefix = ( options[:match_prefix] ? options[:match_prefix] : 'EXIT' )
|
131
|
+
|
132
|
+
thread = process_stream(read, original, options, label) do |data|
|
133
|
+
check_conditions(data, conditions, match_prefix) do
|
134
|
+
block_given? ? code.call(data) : true
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
thread.abort_on_exception = false
|
139
|
+
|
140
|
+
output.reopen(write)
|
141
|
+
return thread, write, original, read
|
142
|
+
end
|
143
|
+
protected :pipe_exec_stream
|
144
|
+
|
145
|
+
#---
|
146
|
+
|
147
|
+
def close_exec_pipe(thread, output, original, write, label)
|
148
|
+
output.reopen(original)
|
149
|
+
|
150
|
+
write.close
|
151
|
+
success = thread.value
|
152
|
+
|
153
|
+
original.close
|
154
|
+
return success
|
155
|
+
end
|
156
|
+
protected :close_exec_pipe
|
157
|
+
|
158
|
+
#---
|
159
|
+
|
160
|
+
def check_conditions(data, conditions, match_prefix = '', &code)
|
161
|
+
prefix = ''
|
162
|
+
|
163
|
+
unless ! conditions || conditions.empty?
|
164
|
+
conditions.each do |key, event|
|
165
|
+
if event.check(data)
|
166
|
+
prefix = match_prefix
|
167
|
+
conditions.delete(key)
|
168
|
+
end
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
result = true
|
173
|
+
if block_given?
|
174
|
+
result = code.call
|
175
|
+
|
176
|
+
unless prefix.empty?
|
177
|
+
case result
|
178
|
+
when Hash
|
179
|
+
result[:prefix] = prefix
|
180
|
+
else
|
181
|
+
result = { :success => result, :prefix => prefix }
|
182
|
+
end
|
183
|
+
end
|
184
|
+
end
|
185
|
+
return result
|
186
|
+
end
|
187
|
+
protected :check_conditions
|
188
|
+
|
189
|
+
#---
|
190
|
+
|
191
|
+
def process_stream(input, output, options, label, &code)
|
192
|
+
return Thread.new do
|
193
|
+
success = true
|
194
|
+
default_prefix = ( options[:prefix] ? options[:prefix] : '' )
|
195
|
+
default_suffix = ( options[:suffix] ? options[:suffix] : '' )
|
196
|
+
|
197
|
+
begin
|
198
|
+
while ( data = input.readpartial(1024) )
|
199
|
+
message = data.strip
|
200
|
+
newline = ( data[-1,1].match(/\n/) ? true : false )
|
201
|
+
|
202
|
+
unless message.empty?
|
203
|
+
lines = message.split(/\n/)
|
204
|
+
lines.each_with_index do |line, index|
|
205
|
+
prefix = default_prefix
|
206
|
+
suffix = default_suffix
|
207
|
+
|
208
|
+
unless line.empty?
|
209
|
+
if block_given?
|
210
|
+
result = code.call(line)
|
211
|
+
|
212
|
+
if result && result.is_a?(Hash)
|
213
|
+
prefix = result[:prefix]
|
214
|
+
suffix = result[:suffix]
|
215
|
+
result = result[:success]
|
216
|
+
end
|
217
|
+
success = result if success
|
218
|
+
end
|
219
|
+
|
220
|
+
prefix = ( prefix && ! prefix.empty? ? "#{prefix}: " : '' )
|
221
|
+
suffix = ( suffix && ! suffix.empty? ? suffix : '' )
|
222
|
+
eol = ( index < lines.length - 1 || newline ? "\n" : ' ' )
|
223
|
+
|
224
|
+
output.write(prefix.lstrip + line + suffix.rstrip + eol)
|
225
|
+
end
|
226
|
+
end
|
227
|
+
end
|
228
|
+
end
|
229
|
+
rescue EOFError
|
230
|
+
end
|
231
|
+
|
232
|
+
input.close()
|
233
|
+
success
|
234
|
+
end
|
235
|
+
end
|
236
|
+
protected :process_stream
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Action
|
4
|
+
class Add < Plugin::Action
|
5
|
+
|
6
|
+
include Mixin::Action::Project
|
7
|
+
include Mixin::Action::Push
|
8
|
+
|
9
|
+
#-----------------------------------------------------------------------------
|
10
|
+
# Add action interface
|
11
|
+
|
12
|
+
def normalize
|
13
|
+
super('nucleon add <subproject/path> <subproject:::reference>')
|
14
|
+
|
15
|
+
codes :project_failure => 20,
|
16
|
+
:add_failure => 21,
|
17
|
+
:push_failure => 22
|
18
|
+
end
|
19
|
+
|
20
|
+
#-----------------------------------------------------------------------------
|
21
|
+
# Action operations
|
22
|
+
|
23
|
+
def parse(parser)
|
24
|
+
parser.arg_str(:sub_path, nil,
|
25
|
+
'nucleon.core.actions.add.options.sub_path'
|
26
|
+
)
|
27
|
+
parser.arg_str(:sub_reference, nil,
|
28
|
+
'nucleon.core.actions.add.options.sub_reference'
|
29
|
+
)
|
30
|
+
parser.option_bool(:editable, false,
|
31
|
+
'--editable',
|
32
|
+
'nucleon.core.actions.add.options.editable'
|
33
|
+
)
|
34
|
+
project_options(parser, true, true)
|
35
|
+
push_options(parser, true)
|
36
|
+
end
|
37
|
+
|
38
|
+
#---
|
39
|
+
|
40
|
+
def execute
|
41
|
+
super do |node, network, status|
|
42
|
+
info('nucleon.core.actions.add.start')
|
43
|
+
|
44
|
+
if project = project_load(Dir.pwd, false)
|
45
|
+
sub_info = project.translate_reference(settings[:sub_reference], settings[:editable])
|
46
|
+
sub_path = settings[:sub_path]
|
47
|
+
|
48
|
+
if sub_info
|
49
|
+
sub_url = sub_info[:url]
|
50
|
+
sub_revision = sub_info[:revision]
|
51
|
+
else
|
52
|
+
sub_url = settings[:sub_reference]
|
53
|
+
sub_revision = nil
|
54
|
+
end
|
55
|
+
|
56
|
+
if project.add_subproject(sub_path, sub_url, sub_revision)
|
57
|
+
status = code.push_failure unless push(project)
|
58
|
+
else
|
59
|
+
status = code.add_failure
|
60
|
+
end
|
61
|
+
else
|
62
|
+
status = code.project_failure
|
63
|
+
end
|
64
|
+
status
|
65
|
+
end
|
66
|
+
end
|
67
|
+
end
|
68
|
+
end
|
69
|
+
end
|
@@ -0,0 +1,52 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Action
|
4
|
+
class Create < Plugin::Action
|
5
|
+
|
6
|
+
#-----------------------------------------------------------------------------
|
7
|
+
# Create action interface
|
8
|
+
|
9
|
+
def normalize
|
10
|
+
super('nucleon create [ <project:::reference> ]')
|
11
|
+
|
12
|
+
codes :project_failure => 20
|
13
|
+
end
|
14
|
+
|
15
|
+
#-----------------------------------------------------------------------------
|
16
|
+
# Action operations
|
17
|
+
|
18
|
+
def parse(parser)
|
19
|
+
parser.option_str(:path, Dir.pwd,
|
20
|
+
'--path PROJECT_DIR',
|
21
|
+
'nucleon.core.actions.create.options.path'
|
22
|
+
)
|
23
|
+
parser.option_str(:revision, :master,
|
24
|
+
'--revision REVISION/BRANCH',
|
25
|
+
'nucleon.core.actions.create.options.revision'
|
26
|
+
)
|
27
|
+
parser.arg_str(:reference,
|
28
|
+
'github:::coralnexus/puppet-cloud-template',
|
29
|
+
'nucleon.core.actions.create.options.reference'
|
30
|
+
)
|
31
|
+
end
|
32
|
+
|
33
|
+
#---
|
34
|
+
|
35
|
+
def execute
|
36
|
+
super do |node, network, status|
|
37
|
+
info('nucleon.core.actions.create.start')
|
38
|
+
|
39
|
+
project = Nucleon.project(extended_config(:project, {
|
40
|
+
:create => true,
|
41
|
+
:directory => settings[:path],
|
42
|
+
:url => settings[:reference],
|
43
|
+
:revision => settings[:revision],
|
44
|
+
:pull => true
|
45
|
+
}))
|
46
|
+
|
47
|
+
project ? status : code.project_failure
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Action
|
4
|
+
class Extract < Plugin::Action
|
5
|
+
|
6
|
+
#-----------------------------------------------------------------------------
|
7
|
+
# Action settings
|
8
|
+
|
9
|
+
def configure
|
10
|
+
super do
|
11
|
+
codes :extract_failure
|
12
|
+
|
13
|
+
register :path, :str, nil do |value|
|
14
|
+
unless File.directory?(value)
|
15
|
+
warn('nucleon.actions.extract.errors.path', { :value => value })
|
16
|
+
next false
|
17
|
+
end
|
18
|
+
true
|
19
|
+
end
|
20
|
+
register :encoded, :str, nil do |value|
|
21
|
+
@package = Util::Package.new(value)
|
22
|
+
if @package.data.export.empty?
|
23
|
+
warn('nucleon.actions.extract.errors.encoded', { :value => value })
|
24
|
+
next false
|
25
|
+
end
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
#---
|
32
|
+
|
33
|
+
def arguments
|
34
|
+
[ :path, :encoded ]
|
35
|
+
end
|
36
|
+
|
37
|
+
#-----------------------------------------------------------------------------
|
38
|
+
# Action operations
|
39
|
+
|
40
|
+
def execute
|
41
|
+
super do |node, network|
|
42
|
+
unless @package.extract(settings[:path])
|
43
|
+
myself.status = code.extract_failure
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Action
|
4
|
+
class Remove < Plugin::Action
|
5
|
+
|
6
|
+
include Mixin::Action::Project
|
7
|
+
include Mixin::Action::Push
|
8
|
+
|
9
|
+
#-----------------------------------------------------------------------------
|
10
|
+
# Remove action interface
|
11
|
+
|
12
|
+
def normalize
|
13
|
+
super('nucleon remove <subproject/path>')
|
14
|
+
|
15
|
+
codes :project_failure => 20,
|
16
|
+
:delete_failure => 21,
|
17
|
+
:push_failure => 22
|
18
|
+
end
|
19
|
+
|
20
|
+
#-----------------------------------------------------------------------------
|
21
|
+
# Action operations
|
22
|
+
|
23
|
+
def parse(parser)
|
24
|
+
parser.arg_str(:sub_path, nil,
|
25
|
+
'nucleon.core.actions.remove.options.sub_path'
|
26
|
+
)
|
27
|
+
project_options(parser, true, true)
|
28
|
+
push_options(parser, true)
|
29
|
+
end
|
30
|
+
|
31
|
+
#---
|
32
|
+
|
33
|
+
def execute
|
34
|
+
super do |node, network, status|
|
35
|
+
info('nucleon.core.actions.remove.start')
|
36
|
+
|
37
|
+
if project = project_load(Dir.pwd, false)
|
38
|
+
if project.delete_subproject(settings[:sub_path])
|
39
|
+
status = code.push_failure unless push(project)
|
40
|
+
else
|
41
|
+
status = code.delete_failure
|
42
|
+
end
|
43
|
+
else
|
44
|
+
status = code.project_failure
|
45
|
+
end
|
46
|
+
status
|
47
|
+
end
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Action
|
4
|
+
class Save < Plugin::Action
|
5
|
+
|
6
|
+
include Mixin::Action::Project
|
7
|
+
include Mixin::Action::Commit
|
8
|
+
include Mixin::Action::Push
|
9
|
+
|
10
|
+
#-----------------------------------------------------------------------------
|
11
|
+
# Save action interface
|
12
|
+
|
13
|
+
def normalize
|
14
|
+
super('nucleon save [ <file> ... ]')
|
15
|
+
|
16
|
+
codes :project_failure => 20,
|
17
|
+
:commit_failure => 21,
|
18
|
+
:push_failure => 22
|
19
|
+
end
|
20
|
+
|
21
|
+
#-----------------------------------------------------------------------------
|
22
|
+
# Action operations
|
23
|
+
|
24
|
+
def parse(parser)
|
25
|
+
parser.arg_array(:files, '.',
|
26
|
+
'nucleon.core.actions.save.options.files'
|
27
|
+
)
|
28
|
+
project_options(parser, true, false)
|
29
|
+
commit_options(parser, false)
|
30
|
+
push_options(parser, true)
|
31
|
+
end
|
32
|
+
|
33
|
+
#---
|
34
|
+
|
35
|
+
def execute
|
36
|
+
super do |node, network, status|
|
37
|
+
info('nucleon.core.actions.save.start')
|
38
|
+
|
39
|
+
if project = project_load(Dir.pwd, false)
|
40
|
+
if commit(project, settings[:files])
|
41
|
+
status = code.push_failure unless push(project)
|
42
|
+
else
|
43
|
+
status = code.commit_failure
|
44
|
+
end
|
45
|
+
else
|
46
|
+
status = code.project_failure
|
47
|
+
end
|
48
|
+
status
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
@@ -0,0 +1,37 @@
|
|
1
|
+
|
2
|
+
module Nucleon
|
3
|
+
module Action
|
4
|
+
class Update < Plugin::Action
|
5
|
+
|
6
|
+
include Mixin::Action::Project
|
7
|
+
|
8
|
+
#-----------------------------------------------------------------------------
|
9
|
+
# Update action interface
|
10
|
+
|
11
|
+
def normalize
|
12
|
+
super('nucleon update')
|
13
|
+
|
14
|
+
codes :project_failure => 20
|
15
|
+
end
|
16
|
+
|
17
|
+
#-----------------------------------------------------------------------------
|
18
|
+
# Action operations
|
19
|
+
|
20
|
+
def parse(parser)
|
21
|
+
project_options(parser, true, true)
|
22
|
+
end
|
23
|
+
|
24
|
+
#---
|
25
|
+
|
26
|
+
def execute
|
27
|
+
super do |node, network, status|
|
28
|
+
info('nucleon.core.actions.update.start')
|
29
|
+
|
30
|
+
project = project_load(Dir.pwd, true)
|
31
|
+
status = code.project_failure unless project
|
32
|
+
status
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|