luban 0.6.2 → 0.6.5

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.
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