luban 0.6.2 → 0.6.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 226a7a454e9e2362810972688ba0c29d44a0efd5
4
- data.tar.gz: 773a1081ce6c7ccdc380114d51a3c1f01dae99ac
3
+ metadata.gz: 3f5385cce19de66d6ae2ca1b7f4651f33881931b
4
+ data.tar.gz: 5c9b6a5c98b86c9bdd7ac2819d14efd5efcb0679
5
5
  SHA512:
6
- metadata.gz: 53f78a7483a74750790f11e02440332bafcdb6dadb688deff9ce044ac8fc8d4d344d2d0ef26a48e212f60cf5c9cfaffae0ddfccd9491345ee453b3c0f2b3e881
7
- data.tar.gz: 973ba8cce91e3df4d9248c8f6e50c9defeaadd58f1efc38923cbb7296a03fff5c48526b3669cb30389480c985d042cc653f116b1b70af37c02832a1fe83dcaf1
6
+ metadata.gz: 252e997fc1e0e70acd918045ac5b941c8c21a60a14deb9656da1ed0b91be752d1d7f5b6b0fdb3fc83932e7db4badffedf689f93facf18d04b030fbab11efb715
7
+ data.tar.gz: 8484026d33e2de99c9de5c61cbdabf9d48e2fb0e2b13750a38f53f396dec4d5ae7e134764d3ec9e687efc2e29f5147d92d5e30d458b519cc379d516759c94e9f
data/CHANGELOG.md CHANGED
@@ -1,5 +1,25 @@
1
1
  # Change log
2
2
 
3
+ ## Version 0.6.5 (Jul 27, 2016)
4
+
5
+ New features:
6
+ * Remade application release handling to manage multiple releases
7
+ * Supported deployment for multiple releases
8
+ * Supported release deprecation
9
+ * supported release summary
10
+ * Simplified release cleanup
11
+
12
+ Minor enhancements:
13
+ * Changed release_tag format for git commit in Git scm strategy
14
+ * Used attribute :version to unify :branch, :tag and :ref in Git scm strategy
15
+ * Deprecated parameter #keep_releases
16
+ * Releases retension is changed to control by manual configurations
17
+ * Added option #force for command #deploy
18
+ * Minor code refactor and cleanup
19
+
20
+ Bug fixes:
21
+ * Fixed display issue for pgrep under CentOS
22
+
3
23
  ## Version 0.6.2 (Jul 14, 2016)
4
24
 
5
25
  New features:
@@ -9,7 +9,25 @@ module Luban
9
9
 
10
10
  attr_reader :packages
11
11
  attr_reader :services
12
+ attr_reader :current_app
13
+ attr_reader :release_opts
14
+ attr_reader :current_profile
15
+ attr_reader :profile_opts
12
16
 
17
+ def self.action_on_packages(action, as: action)
18
+ define_method(action) do |args:, opts:|
19
+ packages.each_value { |p| p.send(as, args: args, opts: opts) }
20
+ end
21
+ protected action
22
+ end
23
+
24
+ def self.action_on_services(action, as: action)
25
+ define_method(action) do |args:, opts:|
26
+ services.each_value { |s| s.send(as, args: args, opts: opts) }
27
+ end
28
+ protected action
29
+ end
30
+
13
31
  def find_project; parent; end
14
32
  def find_application(name = nil)
15
33
  name.nil? ? self : find_project.apps[name.to_sym]
@@ -20,9 +38,9 @@ module Luban
20
38
  def has_packages?; !packages.empty?; end
21
39
  def has_services?; !services.empty?; end
22
40
 
23
- def installable?; has_source? or has_packages?; end
24
- def deployable?; has_source? or has_profile? or has_services?; end
25
- def controllable?; has_source? or has_profile? or has_services?; end
41
+ def installable?; has_packages?; end
42
+ def deployable?; has_source? or has_profile? end
43
+ def controllable?; has_source? or has_services?; end
26
44
 
27
45
  def use_package?(package_name, package_version, servers: [])
28
46
  package_name = package_name.to_sym
@@ -32,8 +50,8 @@ module Luban
32
50
  end
33
51
 
34
52
  def other_package_users_for(package_name, package_version, servers: [])
35
- parent.package_users_for(package_name, package_version,
36
- exclude: [name], servers: servers)
53
+ find_project.package_users_for(package_name, package_version,
54
+ exclude: [name], servers: servers)
37
55
  end
38
56
 
39
57
  def package(name, version:, **opts)
@@ -50,24 +68,33 @@ module Luban
50
68
  end
51
69
  alias_method :require_package, :package
52
70
 
71
+ def profile(from = nil, **opts)
72
+ from.nil? ? @profile : (@profile = opts.merge(type: 'profile', from: from))
73
+ end
74
+
75
+ def profile_release(version, **opts)
76
+ @current_profile = version if opts[:current]
77
+ profile_opts[version] = opts.merge(version: version)
78
+ end
79
+
53
80
  def source(from = nil, **opts)
54
- return @source if from.nil?
55
- @source = opts.merge(type: 'app', from: from)
56
- if source_version.nil?
57
- abort "Aborted! Please specify the source version with :tag, :branch or :ref."
58
- end
59
- @source
81
+ from.nil? ? @source : (@source = opts.merge(type: 'app', from: from))
60
82
  end
61
83
 
62
- def source_version
63
- @source[:tag] || @source[:branch] || @source[:ref]
84
+ def release(version, **opts)
85
+ @current_app = version if opts[:current]
86
+ release_opts[version] = opts.merge(version: version)
64
87
  end
65
88
 
66
- def profile(from = nil, **opts)
67
- from.nil? ? @profile : (@profile = opts.merge(type: 'profile', from: from))
89
+ def has_version?(version)
90
+ release_opts.has_key?(version)
68
91
  end
69
92
 
70
- def password_for(user); parent.password_for(user); end
93
+ def versions; release_opts.keys; end
94
+ def deprecated_versions; release_opts.select {|r, o| o[:deprecated] }.keys; end
95
+ def deployable_versions; release_opts.select {|r, o| !o[:deprecated] }.keys; end
96
+
97
+ def password_for(user); find_project.password_for(user); end
71
98
 
72
99
  def promptless_authen(args:, opts:)
73
100
  opts = opts.merge(app: self, public_keys: Array(public_key!(args: args, opts: opts)))
@@ -101,63 +128,64 @@ module Luban
101
128
  end
102
129
  dispatch_task :destroy!, to: :constructor, as: :destroy
103
130
 
104
- %i(install_all uninstall_all).each do |action|
105
- define_method("#{action}!") do |args:, opts:|
106
- packages.each_value { |p| p.send(action, args: args, opts: opts) }
131
+ %i(install_all uninstall_all binstubs which whence).each do |action|
132
+ define_method(action) do |args:, opts:|
133
+ show_app_environment
134
+ send("#{action}!", args: args, opts: opts)
107
135
  end
108
- protected "#{action}!"
136
+ action_on_packages("#{action}!", as: action)
137
+ end
138
+
139
+ def cleanup(args:, opts:)
140
+ show_app_environment
141
+ cleanup_packages!(args: args, opts: opts)
142
+ cleanup_application!(args: args, opts: opts)
109
143
  end
144
+ action_on_packages :cleanup_packages!, as: :cleanup
145
+ dispatch_task :cleanup_application!, to: :constructor, as: :cleanup
110
146
 
111
- (Luban::Deployment::Command::Tasks::Install::Actions - %i(setup build destroy)).each do |action|
147
+ %i(show_current show_summary).each do |action|
112
148
  define_method(action) do |args:, opts:|
113
149
  show_app_environment
114
- send("#{action}!", args: args, opts: opts)
150
+ send("#{action}_packages!", args: args, opts: opts)
151
+ send("#{action}_application", args: args, opts: opts) if has_source?
115
152
  end
153
+ action_on_packages "#{action}_packages!", as: action
154
+ end
116
155
 
117
- define_method("#{action}!") do |args:, opts:|
118
- packages.each_value { |p| p.send(action, args: args, opts: opts) }
119
- end
120
- protected "#{action}!"
156
+ def show_current_application(args:, opts:)
157
+ print_summary(get_summary(args: args, opts: opts.merge(version: current_app)))
121
158
  end
122
159
 
123
- { show_current: :controller, show_summary: :controller,
124
- cleanup: :constructor }.each_pair do |action, worker|
125
- alias_method "#{action}_packages!", "#{action}!"
126
- define_method("#{action}!") do |args:, opts:|
127
- send("#{action}_application!", args: args, opts: opts) if has_source?
128
- send("#{action}_packages!", args: args, opts: opts)
160
+ def show_summary_application(args:, opts:)
161
+ versions.each do |version|
162
+ print_summary(get_summary(args: args, opts: opts.merge(version: version)))
129
163
  end
130
- protected "#{action}!"
131
- dispatch_task "#{action}_application!", to: worker, as: action
132
164
  end
165
+ dispatch_task :get_summary, to: :controller, as: :get_summary
133
166
 
134
167
  def deploy(args:, opts:)
135
168
  show_app_environment
136
- if has_source?
137
- release = deploy_release(args: args, opts: opts)
138
- opts = opts.merge(release: release)
139
- end
169
+ deploy_release(args: args, opts: opts) if has_source?
140
170
  deploy_profile(args: args, opts: opts) if has_profile?
141
171
  end
142
172
 
143
173
  Luban::Deployment::Command::Tasks::Control::Actions.each do |action|
144
174
  define_method(action) do |args:, opts:|
145
175
  show_app_environment
146
- send("#{action}!", args: args, opts: opts)
147
- end
148
-
149
- define_method("#{action}!") do |args:, opts:|
150
- send("application_#{action}!", args: args, opts: opts) if has_source?
151
176
  send("service_#{action}!", args: args, opts: opts)
177
+ send("application_#{action}", args: args, opts: opts) if has_source?
152
178
  end
153
- protected "#{action}!"
154
-
155
- dispatch_task "application_#{action}!", to: :controller, as: action
179
+ action_on_services "service_#{action}!", as: action
156
180
 
157
- define_method("service_#{action}!") do |args:, opts:|
158
- services.each_value { |s| s.send(action, args: args, opts: opts) }
181
+ define_method("application_#{action}") do |args:, opts:|
182
+ if current_app
183
+ send("application_#{action}!", args: args, opts: opts.merge(version: current_app))
184
+ else
185
+ abort "Aborted! No current version of #{display_name} is specified."
186
+ end
159
187
  end
160
- protected "service_#{action}!"
188
+ dispatch_task "application_#{action}!", to: :controller, as: action
161
189
  end
162
190
 
163
191
  def init_profiles(args:, opts:)
@@ -178,7 +206,7 @@ module Luban
178
206
  if services.has_key?(opts[:service])
179
207
  services[opts[:service]].init_profile(args: args, opts: opts)
180
208
  else
181
- services.values.each { |s| s.init_profile(args: args, opts: opts) }
209
+ services.each_value { |s| s.init_profile(args: args, opts: opts) }
182
210
  end
183
211
  end
184
212
 
@@ -190,7 +218,9 @@ module Luban
190
218
  @packages = {}
191
219
  @services = {}
192
220
  @source = {}
221
+ @release_opts = {}
193
222
  @profile = {}
223
+ @profile_opts = {}
194
224
  end
195
225
 
196
226
  def validate_parameters
@@ -214,7 +244,8 @@ module Luban
214
244
 
215
245
  def set_default_profile
216
246
  if config_finder[:application].has_profile?
217
- profile(config_finder[:application].stage_profile_path, scm: :rsync)
247
+ profile(config_finder[:application].stage_profile_path, scm: :rsync)
248
+ profile_release(stage, current: true)
218
249
  end
219
250
  end
220
251
 
@@ -246,10 +277,20 @@ module Luban
246
277
 
247
278
  def compose_task_options(opts)
248
279
  super.merge(name: name.to_s, packages: packages).tap do |o|
249
- o.merge!(version: source_version) if has_source?
280
+ version = o[:version]
281
+ unless version.nil?
282
+ o.merge!(release: release_opts[version])
283
+ update_release_tag(o)
284
+ end
250
285
  end
251
286
  end
252
287
 
288
+ def update_release_tag(version:, **opts)
289
+ opts[:release][:tag] ||=
290
+ release_tag(args: {}, opts: opts.merge(repository: source.merge(version: version)))
291
+ end
292
+ dispatch_task :release_tag, to: :repository, as: :release_tag, locally: true
293
+
253
294
  def show_app_environment
254
295
  puts "#{display_name} in #{parent.class.name}"
255
296
  end
@@ -262,31 +303,52 @@ module Luban
262
303
 
263
304
  def deploy_profile(args:, opts:)
264
305
  update_profile(args: args, opts: opts)
265
- deploy_profile!(args: args, opts: opts.merge(repository: profile))
306
+ deploy_profile!(args: args, opts: opts.merge(repository: profile.merge(version: current_profile)))
266
307
  end
267
308
 
268
309
  def update_profile(args:, opts:)
269
- update_profile!(args: args, opts: opts)
310
+ update_profile!(args: args, opts: opts.merge(version: current_app))
270
311
  services.each_value { |s| s.send(:update_profile, args: args, opts: opts) }
271
312
  end
272
313
  dispatch_task :update_profile!, to: :configurator, as: :update_profile, locally: true
273
314
 
274
315
  def deploy_release(args:, opts:)
275
- deploy_release!(args: args, opts: opts.merge(repository: source)).tap do
276
- binstubs!(args: args, opts: opts)
316
+ deployable_versions.each do |version|
317
+ deploy_release!(args: args, opts: opts.merge(repository: source.merge(version: version)))
318
+ end
319
+ deprecated_versions.each do |version|
320
+ deprecate_release!(args: args, opts: opts.merge(repository: source.merge(version: version)))
277
321
  end
278
322
  end
279
323
 
280
324
  def deploy_release!(args:, opts:)
281
- package_release!(args: args, opts: opts)[:release].tap do |release|
282
- unless release.nil?
283
- publish_release!(args: args, opts: opts.merge(release: release))
325
+ package_release!(args: args, opts: opts)[:release_pack].tap do |pack|
326
+ unless pack.nil?
327
+ publish_release!(args: args, opts: opts.merge(release_pack: pack))
284
328
  end
285
329
  end
286
330
  end
287
331
  alias_method :deploy_profile!, :deploy_release!
288
332
  dispatch_task :package_release!, to: :repository, as: :package, locally: true
289
333
  dispatch_task :publish_release!, to: :publisher, as: :publish
334
+
335
+ def deprecate_release!(args:, opts:)
336
+ deprecate_packaged_release!(args: args, opts: opts)[:release_pack].tap do |pack|
337
+ unless pack.nil?
338
+ deprecate_published_release!(args: args, opts: opts.merge(release_pack: pack))
339
+ end
340
+ end
341
+ end
342
+ dispatch_task :deprecate_packaged_release!, to: :repository, as: :deprecate, locally: true
343
+ dispatch_task :deprecate_published_release!, to: :publisher, as: :deprecate
344
+
345
+ def print_summary(result)
346
+ result.each do |entry|
347
+ s = entry[:summary]
348
+ puts " [#{entry[:hostname]}] #{s[:status]} #{s[:name]} (#{s[:published]})"
349
+ puts " [#{entry[:hostname]}] #{s[:alert]}" unless s[:alert].nil?
350
+ end
351
+ end
290
352
  end
291
353
  end
292
354
  end
@@ -3,13 +3,6 @@ module Luban
3
3
  class Application
4
4
  class Configurator < Worker
5
5
  include Luban::Deployment::Service::Configurator::Base
6
-
7
- def release_type; task.opts.release[:type]; end
8
- def release_tag; task.opts.release[:tag]; end
9
-
10
- def release_path
11
- @release_path ||= releases_path.join(release_type, release_tag)
12
- end
13
6
  end
14
7
  end
15
8
  end
@@ -4,52 +4,45 @@ module Luban
4
4
  class Controller < Worker
5
5
  include Luban::Deployment::Service::Controller::Base
6
6
 
7
- def current_release?(_release_tag)
8
- _release_tag =~ /^#{Regexp.escape(application_version)}/
9
- end
10
-
11
- def current_symlinked?(_release_tag)
12
- _release_tag == release_tag
13
- end
14
-
15
- def release_path
16
- @release_path ||= Pathname.new(readlink(current_app_path))
17
- end
18
-
19
- def releases_path
20
- @releases_path ||= release_path.dirname
21
- end
22
-
23
- def release_tag
24
- @release_tag ||= release_path.basename.to_s
25
- end
26
-
27
- def show_current
28
- update_result get_summary(release_tag)
29
- end
30
-
31
- def show_summary
32
- update_result get_summary(*get_releases)
33
- end
7
+ def current_configured?; !!task.opts.release[:current]; end
8
+ alias_method :current?, :current_configured?
34
9
 
35
- def get_releases
36
- capture(:ls, '-xt', releases_path).split
10
+ def current_symlinked?
11
+ release_tag == current_release_tag
37
12
  end
38
13
 
39
- protected
40
-
41
- def get_status(tag)
42
- if current_symlinked?(tag)
43
- current_release?(tag) ? " *" : "s*"
14
+ def current_release_tag
15
+ if symlink?(current_app_path)
16
+ File.basename(readlink(current_app_path))
44
17
  else
45
- (current_release?(tag) and !current_release?(release_tag)) ? "c*" : " "
18
+ nil
46
19
  end
47
20
  end
48
21
 
49
- def get_summary(*release_tags)
50
- release_tags.inject([]) do |r, tag|
51
- r.push "#{get_status(tag)} #{application_name}:#{tag} (published)"
52
- end.join("\n")
22
+ def published?; directory?(release_path); end
23
+ def deprecated?; !!task.opts.release[:deprecated]; end
24
+
25
+ def get_summary
26
+ status = if current_symlinked?
27
+ current? ? " *" : "s*"
28
+ else
29
+ current? ? "c*" : (deprecated? ? " d" : " ")
30
+ end
31
+
32
+ if published?
33
+ published = 'published'
34
+ alert = case status
35
+ when "s*"
36
+ "Alert! #{application_name}:#{release_tag} is not the current version but symlinked IMPROPERLY. "
37
+ when "c*"
38
+ "Alert! #{application_name}:#{release_tag} is set as current version but NOT symlinked properly. "
39
+ end
40
+ else
41
+ published = 'NOT published'
42
+ alert = nil
43
+ end
44
+ update_result summary: { name: "#{application_name}:#{release_tag}", published: published,
45
+ status: status, alert: alert }
53
46
  end
54
47
  end
55
48
  end
@@ -2,11 +2,12 @@ module Luban
2
2
  module Deployment
3
3
  class Application
4
4
  class Publisher < Worker
5
- def release_type; task.opts.release[:type]; end
6
- def release_tag; task.opts.release[:tag]; end
7
- def release_package_path; task.opts.release[:path]; end
8
- def release_md5; task.opts.release[:md5]; end
9
- def bundled_gems; task.opts.release[:bundled_gems]; end
5
+ def release_type; task.opts.release_pack[:type]; end
6
+ def release_version; task.opts.release_pack[:version]; end
7
+ def release_tag; task.opts.release_pack[:tag]; end
8
+ def release_package_path; task.opts.release_pack[:path]; end
9
+ def release_md5; task.opts.release_pack[:md5]; end
10
+ def bundled_gems; task.opts.release_pack[:bundled_gems]; end
10
11
  def locked_gemfile; bundled_gems[:locked_gemfile]; end
11
12
  def gems_source; bundled_gems[:gems_cache]; end
12
13
  def gems; bundled_gems[:gems]; end
@@ -14,16 +15,12 @@ module Luban
14
15
  def publish_app?; release_type == 'app'; end
15
16
  def publish_profile?; release_type == 'profile'; end
16
17
 
17
- def display_name
18
- @display_name ||= "#{application} #{release_type} (release: #{release_tag})"
18
+ def release_name
19
+ @release_name ||= "#{application}:#{release_type}:#{release_tag}"
19
20
  end
20
21
 
21
22
  def releases_path
22
- @releases_path ||= super.join(release_type)
23
- end
24
-
25
- def release_path
26
- @release_path ||= releases_path.join(release_tag)
23
+ @releases_path ||= super.dirname.join(release_type)
27
24
  end
28
25
 
29
26
  def releases_log_path
@@ -62,9 +59,7 @@ module Luban
62
59
  @bundle_linked_dirs ||= %w(.bundle vendor/cache vendor/bundle)
63
60
  end
64
61
 
65
- def published?
66
- get_releases.include?(release_tag)
67
- end
62
+ def published?; directory?(release_path); end
68
63
 
69
64
  def publish
70
65
  assure_dirs(releases_path)
@@ -72,7 +67,7 @@ module Luban
72
67
  if force?
73
68
  publish!
74
69
  else
75
- update_result "Skipped! #{display_name} has been published ALREADY.", status: :skipped
70
+ update_result "Skipped! ALREADY published #{release_name}.", status: :skipped
76
71
  return
77
72
  end
78
73
  else
@@ -80,9 +75,16 @@ module Luban
80
75
  end
81
76
 
82
77
  if published?
83
- update_result "Successfully published #{display_name}."
78
+ update_result "Successfully published #{release_name}."
84
79
  else
85
- update_result "Failed to publish #{display_name}", status: :failed, level: :error
80
+ update_result "FAILED to publish #{release_name}.", status: :failed, level: :error
81
+ end
82
+ end
83
+
84
+ def deprecate
85
+ if directory?(release_path)
86
+ rmdir(release_path)
87
+ update_result "Successfully deprecated published release #{release_name}."
86
88
  end
87
89
  end
88
90
 
@@ -93,10 +95,6 @@ module Luban
93
95
 
94
96
  protected
95
97
 
96
- def get_releases
97
- capture(:ls, '-xt', releases_path).split
98
- end
99
-
100
98
  def publish!
101
99
  rollout_release
102
100
  cleanup_releases
@@ -161,23 +159,13 @@ module Luban
161
159
  end
162
160
 
163
161
  def release_log_message
164
- "Release #{display_name} in #{stage} #{project} is published successfully."
162
+ "#{release_name} in #{stage} #{project} is published successfully."
165
163
  end
166
164
 
167
- def cleanup_releases
168
- releases = get_releases
169
- if releases.count > keep_releases
170
- releases_to_keep = releases.first(keep_releases)
171
- unless releases_to_keep.include?(release_tag)
172
- releases_to_keep[-1] = release_tag
173
- end
174
- releases_to_remove = releases - releases_to_keep
175
- releases_to_remove.each do |release|
176
- rmdir(releases_path.join(release))
177
- end
178
- info "Removed #{releases_to_remove.count} old releases."
179
- else
180
- info "No old releases to remove (keeping most recent #{keep_releases} releases)."
165
+ def cleanup_releases(keep_releases = 1)
166
+ files = capture(:ls, '-xtd', releases_path.join("#{release_version}-*")).split(" ")
167
+ if files.count > keep_releases
168
+ files.last(files.count - keep_releases).each { |f| rmdir(f) }
181
169
  end
182
170
  end
183
171
 
@@ -12,6 +12,7 @@ module Luban
12
12
  attr_reader :scm
13
13
  attr_reader :revision
14
14
  attr_reader :rev_size
15
+ attr_reader :version
15
16
 
16
17
  def scm_module
17
18
  require_relative "scm/#{scm}"
@@ -51,7 +52,11 @@ module Luban
51
52
  end
52
53
 
53
54
  def release_tag
54
- @release_tag ||= "#{stage}-#{revision}"
55
+ @release_tag ||= "#{version}-#{revision}"
56
+ end
57
+
58
+ def release_name
59
+ @release_name ||= "#{application}:#{type}:#{release_tag}"
55
60
  end
56
61
 
57
62
  def bundle_without
@@ -74,45 +79,65 @@ module Luban
74
79
  def build
75
80
  assure_dirs(clone_path, releases_path)
76
81
  if cloned? and !force?
77
- update_revision
78
- update_result "Skipped! Local #{type} repository has been built ALREADY (#{revision}).", status: :skipped
82
+ update_result "Skipped! Local #{type} repository has been built ALREADY.", status: :skipped
79
83
  else
80
- if available?
81
- if build!
82
- update_revision
83
- update_result "Successfully built local #{type} repository (#{revision})."
84
- else
85
- update_result "FAILED to build local #{type} repository!", status: :failed, level: :error
86
- end
84
+ abort "Aborted! Remote #{type} repository is NOT available." unless available?
85
+ if build!
86
+ update_result "Successfully built local #{type} repository."
87
87
  else
88
- update_result "Aborted! Remote #{type} repository is NOT available.", status: :failed, level: :error
88
+ abort "FAILED to build local #{type} repository!"
89
89
  end
90
90
  end
91
91
  end
92
92
 
93
+ def packaged?; file?(release_package_path); end
94
+
93
95
  def package
94
- if cloned?
95
- if package!
96
- cleanup_releases
97
- update_result "Successfully package local #{type} repository to #{release_package_path}.",
98
- release: { type: type, tag: release_tag,
99
- path: release_package_path,
100
- md5: md5_for_file(release_package_path),
101
- bundled_gems: bundle_gems }
102
- else
103
- update_result "FAILED to package local #{type} repository!", status: :failed, level: :error
104
- end
96
+ abort "Aborted! Local #{type} repository is NOT built yet!" unless cloned?
97
+ abort "Aborted! FAILED to update local #{type} repository!" unless update
98
+ update_revision
99
+ abort "Aborted! Version to package is MISSING!" if version.nil?
100
+ release_package = ->{ { type: type, version: version, tag: release_tag,
101
+ path: release_package_path,
102
+ md5: md5_for_file(release_package_path),
103
+ bundled_gems: bundle_gems } }
104
+ if packaged?
105
+ if force?
106
+ release
107
+ else
108
+ update_result "Skipped! ALREADY packaged #{release_name}.", status: :skipped,
109
+ release_pack: release_package.call
110
+ end
105
111
  else
106
- update_result "Aborted! Local #{type} package is NOT built yet!", status: :failed, level: :error
112
+ release
113
+ cleanup_releases
107
114
  end
115
+
116
+ if packaged?
117
+ update_result "Successfully packaged #{release_name} to #{release_package_path}."
118
+ else
119
+ abort "Aborted! FAILED to package #{release_name}!"
120
+ end
121
+ update_result release_pack: release_package.call
122
+ end
123
+
124
+ def deprecate
125
+ abort "Aborted! Local #{type} repository is NOT built yet!" unless cloned?
126
+ abort "Aborted! Version to deprecate is MISSING!" if version.nil?
127
+ if file?(release_package_path)
128
+ rm(release_package_path)
129
+ update_result "Successfully deprecated packaged release #{release_name}."
130
+ end
131
+ update_result release_pack: { type: type, version: version, tag: release_tag }
108
132
  end
109
133
 
110
134
  protected
111
135
 
112
136
  def init
113
137
  @rev_size = DefaultRevisionSize
114
- task.opts.repository.each_pair { |name, value| instance_variable_set("@#{name}", value) }
138
+ task.opts.repository.each_pair { |k, v| instance_variable_set("@#{k}", v) }
115
139
  load_scm
140
+ update_revision if cloned? and !version.nil?
116
141
  end
117
142
 
118
143
  def load_scm
@@ -124,23 +149,15 @@ module Luban
124
149
  clone
125
150
  end
126
151
 
127
- def package!
128
- if update
129
- update_revision
130
- release
131
- end
132
- end
133
-
134
152
  def update_revision
135
153
  @revision = fetch_revision
136
154
  end
137
155
 
138
- def cleanup_releases
139
- files = capture(:ls, '-xt', releases_path).split
156
+ def cleanup_releases(keep_releases = 1)
157
+ path = releases_path.join("#{release_prefix}-#{version}-*.#{release_package_extname}")
158
+ files = capture(:ls, '-xt', path).split(" ")
140
159
  if files.count > keep_releases
141
- within(releases_path) do
142
- files.last(files.count - keep_releases).each { |f| rm(f) }
143
- end
160
+ files.last(files.count - keep_releases).each { |f| rm(f) }
144
161
  end
145
162
  end
146
163
 
@@ -4,15 +4,8 @@ module Luban
4
4
  class Repository
5
5
  module SCM
6
6
  module Git
7
- attr_reader :tag
8
- attr_reader :branch
9
-
10
7
  def git_cmd; :git; end
11
8
 
12
- def ref
13
- tag || branch || @ref
14
- end
15
-
16
9
  def available?
17
10
  test(git_cmd, 'ls-remote --heads', from)
18
11
  end
@@ -22,8 +15,8 @@ module Luban
22
15
  end
23
16
 
24
17
  def fetch_revision
25
- within(clone_path) { capture(git_cmd, "rev-parse --short=#{rev_size} #{ref} 2>/dev/null") }
26
- #within(clone_path) { capture(git_cmd, "rev-list --max-count=1 --abbrev-commit --abbrev=rev_size #{ref}") }
18
+ within(clone_path) { capture(git_cmd, "rev-parse --short=#{rev_size} #{version} 2>/dev/null") }
19
+ #within(clone_path) { capture(git_cmd, "rev-list --max-count=1 --abbrev-commit --abbrev=rev_size #{version}") }
27
20
  end
28
21
 
29
22
  def clone
@@ -35,11 +28,23 @@ module Luban
35
28
  end
36
29
 
37
30
  def release
38
- within(clone_path) { test(git_cmd, :archive, ref, "--prefix=#{release_tag}/ -o #{release_package_path}") }
31
+ within(clone_path) { test(git_cmd, :archive, version, "--prefix=#{release_tag}/ -o #{release_package_path}") }
32
+ end
33
+
34
+ def branch?
35
+ within(clone_path) { test(git_cmd, :"show-ref", "--quite --verify refs/heads/#{version}") }
36
+ end
37
+
38
+ def tag?
39
+ within(clone_path) {test(git_cmd, :"show-ref", "--quite --verify refs/tags/#{version}") }
40
+ end
41
+
42
+ def commit?
43
+ version =~ /^\h+/ and !revision.nil?
39
44
  end
40
45
 
41
46
  def release_tag
42
- @release_tag ||= "#{ref}-#{revision}"
47
+ @release_tag ||= commit? ? "ref-#{revision}" : super
43
48
  end
44
49
  end
45
50
  end
@@ -25,6 +25,16 @@ module Luban
25
25
  def service_entry
26
26
  @service_entry ||= "#{env_name.gsub('/', '.')}.app"
27
27
  end
28
+
29
+ def release_tag; task.opts.release[:tag]; end
30
+
31
+ def releases_path
32
+ @releases_path ||= super.join('app')
33
+ end
34
+
35
+ def release_path
36
+ @release_path ||= releases_path.join(release_tag)
37
+ end
28
38
  end
29
39
  end
30
40
  end
@@ -84,6 +84,7 @@ module Luban
84
84
  def setup_deploy_tasks
85
85
  task :deploy do
86
86
  desc "Run deployment"
87
+ switch :force, "Force to deploy", short: :f
87
88
  action! :deploy
88
89
  end
89
90
  end
@@ -81,7 +81,7 @@ module Luban
81
81
  def package_options; @package_options ||= {}; end
82
82
 
83
83
  def update_package_options(version, **opts)
84
- unless package_options.has_key?(version)
84
+ unless has_version?(version)
85
85
  package_options[version] =
86
86
  { name: name.to_s }.merge!(self.class.decompose_version(version))
87
87
  end
@@ -242,7 +242,7 @@ module Luban
242
242
  def print_summary(result)
243
243
  result.each do |entry|
244
244
  s = entry[:summary]
245
- puts " [#{entry[:hostname]}] #{s[:status]} #{s[:name]} #{s[:installed]}"
245
+ puts " [#{entry[:hostname]}] #{s[:status]} #{s[:name]} (#{s[:installed]})"
246
246
  puts " [#{entry[:hostname]}] #{s[:executable]}" unless s[:executable].nil?
247
247
  puts " [#{entry[:hostname]}] #{s[:alert]}" unless s[:alert].nil?
248
248
  end
@@ -119,7 +119,7 @@ module Luban
119
119
  end
120
120
 
121
121
  if installed?
122
- installed = '(installed)'
122
+ installed = 'installed'
123
123
  alert = case status
124
124
  when "s*"
125
125
  "Alert! #{package_full_name} is not the current version but symlinked IMPROPERLY. " +
@@ -129,7 +129,7 @@ module Luban
129
129
  "Run \"binstubs\" to fix it."
130
130
  end
131
131
  else
132
- installed = '(NOT installed)'
132
+ installed = 'NOT installed'
133
133
  alert = nil
134
134
  end
135
135
  update_result summary: { name: package_full_name, installed: installed,
@@ -210,7 +210,7 @@ module Luban
210
210
  end
211
211
 
212
212
  def process_grep(pattern = process_pattern)
213
- capture(:pgrep, "-l -f \"#{pattern}\" 2>/dev/null").split("\n").inject({}) do |h, p|
213
+ capture(:pgrep, "-l -f -a \"#{pattern}\" 2>/dev/null").split("\n").inject({}) do |h, p|
214
214
  pid, pname = p.split(' ', 2)
215
215
  h[pid] = pname
216
216
  h
@@ -109,7 +109,6 @@ module Luban
109
109
 
110
110
  parameter :application
111
111
  parameter :scm_role
112
- parameter :keep_releases
113
112
  parameter :linked_dirs
114
113
  parameter :linked_files
115
114
  parameter :logrotate_files
@@ -118,7 +117,6 @@ module Luban
118
117
 
119
118
  def set_default_application_parameters
120
119
  set_default :scm_role, :scm
121
- set_default :keep_releases, 3
122
120
  set_default :linked_dirs, []
123
121
  set_default :linked_files, []
124
122
  set_default :logrotate_files, []
@@ -1,5 +1,5 @@
1
1
  module Luban
2
2
  module Deployment
3
- VERSION = "0.6.2"
3
+ VERSION = "0.6.5"
4
4
  end
5
5
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: luban
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.6.2
4
+ version: 0.6.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - Rubyist Lei
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-07-14 00:00:00.000000000 Z
11
+ date: 2016-07-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: luban-cli