releasy 0.2.0rc1 → 0.2.0rc2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/CHANGELOG.md +1 -1
  2. data/README.md +79 -65
  3. data/Rakefile +1 -1
  4. data/lib/releasy/builders.rb +1 -1
  5. data/lib/releasy/builders/builder.rb +6 -4
  6. data/lib/releasy/builders/osx_app.rb +49 -27
  7. data/lib/releasy/builders/source.rb +1 -3
  8. data/lib/releasy/builders/windows_builder.rb +3 -10
  9. data/lib/releasy/builders/windows_folder.rb +4 -6
  10. data/lib/releasy/builders/windows_installer.rb +3 -5
  11. data/lib/releasy/builders/windows_standalone.rb +1 -3
  12. data/lib/releasy/builders/{windows_folder_from_ruby_dist.rb → windows_wrapped.rb} +24 -22
  13. data/lib/releasy/cli/install_sfx.rb +3 -3
  14. data/lib/releasy/deployers.rb +12 -0
  15. data/lib/releasy/deployers/deployer.rb +28 -0
  16. data/lib/releasy/deployers/github.rb +109 -0
  17. data/lib/releasy/mixins/can_exclude_encoding.rb +22 -0
  18. data/lib/releasy/mixins/exec.rb +2 -2
  19. data/lib/releasy/mixins/has_gemspecs.rb +6 -6
  20. data/lib/releasy/mixins/has_packagers.rb +37 -0
  21. data/lib/releasy/mixins/log.rb +39 -0
  22. data/lib/releasy/mixins/register.rb +0 -1
  23. data/lib/releasy/packagers.rb +12 -0
  24. data/lib/releasy/{archivers → packagers}/dmg.rb +4 -4
  25. data/lib/releasy/{archivers → packagers}/exe.rb +4 -4
  26. data/lib/releasy/{archivers/archiver.rb → packagers/packager.rb} +20 -11
  27. data/lib/releasy/packagers/seven_zip.rb +12 -0
  28. data/lib/releasy/{archivers → packagers}/tar_bzip2.rb +4 -4
  29. data/lib/releasy/{archivers → packagers}/tar_gzip.rb +4 -4
  30. data/lib/releasy/{archivers/tar_archiver.rb → packagers/tar_packager.rb} +4 -4
  31. data/lib/releasy/{archivers → packagers}/zip.rb +4 -4
  32. data/lib/releasy/project.rb +105 -46
  33. data/lib/releasy/version.rb +1 -1
  34. data/lib/releasy/windows_wrapper_maker.rb +0 -3
  35. data/releasy.gemspec +1 -0
  36. data/test/releasy/builders/helpers/helper.rb +0 -1
  37. data/test/releasy/builders/osx_app_test.rb +18 -8
  38. data/test/releasy/builders/{windows_folder_from_ruby_dist_test.rb → windows_wrapped_test.rb} +16 -14
  39. data/test/releasy/deployers/github_test.rb +133 -0
  40. data/test/releasy/deployers/helpers/helper.rb +19 -0
  41. data/test/releasy/integration/source_test.rb +25 -6
  42. data/test/releasy/mixins/log_test.rb +15 -0
  43. data/test/releasy/mixins/register_test.rb +0 -1
  44. data/test/releasy/{archivers_test.rb → packagers_test.rb} +16 -19
  45. data/test/releasy/project_test.rb +33 -29
  46. data/test/teststrap.rb +3 -1
  47. data/test/yard_test.rb +1 -1
  48. metadata +55 -34
  49. data/lib/releasy/archivers.rb +0 -12
  50. data/lib/releasy/archivers/seven_zip.rb +0 -12
  51. data/lib/releasy/mixins/has_archivers.rb +0 -37
@@ -0,0 +1,37 @@
1
+ module Releasy
2
+ module Mixins
3
+ # An object that owns one or more instances of {Packagers::Packager}
4
+ module HasPackagers
5
+ # Add an archive type to be generated for each of your outputs.
6
+ # @see Project#initialize
7
+ # @param type [:exe, :"7z", :tar_bz2, :tar_gz, :zip]
8
+ # @return [Project] self
9
+ def add_package(type, &block)
10
+ raise ArgumentError, "Unsupported archive format #{type.inspect}" unless Packagers.has_type? type
11
+ raise ArgumentError, "Already have archive format #{type.inspect}" if packagers.any? {|a| a.type == type }
12
+
13
+ packager = Packagers[type].new(respond_to?(:project) ? project : self)
14
+ packagers << packager
15
+
16
+ if block_given?
17
+ if block.arity == 0
18
+ DSLWrapper.new(packager, &block)
19
+ else
20
+ yield packager
21
+ end
22
+ end
23
+
24
+ packager
25
+ end
26
+
27
+ protected
28
+ def packagers; @packagers ||= []; end
29
+
30
+ protected
31
+ # @return [Array<Packager>]
32
+ def active_packagers
33
+ packagers
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,39 @@
1
+ module Releasy::Mixins::Log
2
+ class << self
3
+ LOG_LEVELS = [:silent, :quiet, :verbose]
4
+ DEFAULT_LOG_LEVEL = :quiet
5
+
6
+ def log_level; @log_level ||= DEFAULT_LOG_LEVEL; end
7
+ def log_level=(level)
8
+ raise ArgumentError, "Bad log_level: #{level.inspect}" unless LOG_LEVELS.include? level
9
+ @log_level = level
10
+ end
11
+ end
12
+
13
+ def log_level; Releasy::Mixins::Log.log_level; end
14
+
15
+ # Options for fileutils commands, based on log_level.
16
+ def fileutils_options
17
+ { :verbose => log_level == :verbose }
18
+ end
19
+
20
+ # Heading message shown unless :silent
21
+ def heading(str)
22
+ puts "=== #{str}" unless log_level == :silent
23
+ end
24
+
25
+ # Heading message shown if :verbose
26
+ def info(str)
27
+ puts str if log_level == :verbose
28
+ end
29
+
30
+ # Warning message shown unless :silent
31
+ def warn(str)
32
+ puts "=== WARNING: #{str}" unless log_level == :silent
33
+ end
34
+
35
+ # Error message always shown.
36
+ def error(str)
37
+ puts "=== ERROR: #{str}"
38
+ end
39
+ end
@@ -35,7 +35,6 @@ module Releasy
35
35
  # @param klass [Object] Object, which is defined within the namespace being registered with.
36
36
  def register(klass)
37
37
  raise TypeError, "Can only register classes" unless klass.is_a? Class
38
- raise ArgumentError, "Can't register a class not within this module" unless klass.name.split('::')[0...-1].join('::') == name
39
38
  raise ArgumentError, "To register, a class must have TYPE defined" unless klass.const_defined? :TYPE
40
39
  registered[klass::TYPE] = klass
41
40
  end
@@ -0,0 +1,12 @@
1
+ require 'releasy/mixins/register'
2
+
3
+ module Releasy
4
+ # Contains all {Packager} types.
5
+ module Packagers
6
+ extend Mixins::Register
7
+ end
8
+ end
9
+
10
+ %w[dmg exe seven_zip tar_bzip2 tar_gzip zip].each do |packager|
11
+ require "releasy/packagers/#{packager}"
12
+ end
@@ -1,13 +1,13 @@
1
- require "releasy/archivers/archiver"
1
+ require "releasy/packagers/packager"
2
2
 
3
3
  module Releasy
4
- module Archivers
4
+ module Packagers
5
5
  # OS X .dmg format (self-extractor).
6
- class Dmg < Archiver
6
+ class Dmg < Packager
7
7
  TYPE = :dmg
8
8
  DEFAULT_EXTENSION = ".dmg"
9
9
 
10
- Archivers.register self
10
+ Packagers.register self
11
11
 
12
12
  protected
13
13
  def command(folder)
@@ -1,18 +1,18 @@
1
- require "releasy/archivers/archiver"
1
+ require "releasy/packagers/packager"
2
2
 
3
3
  module Releasy
4
- module Archivers
4
+ module Packagers
5
5
  # Windows self-extracting archive.
6
6
  #
7
7
  # If not on Windows, run "releasy install-sfx" after installing 7z, before you can use this.
8
- class Exe < Archiver
8
+ class Exe < Packager
9
9
  TYPE = :exe
10
10
  DEFAULT_EXTENSION = ".exe"
11
11
 
12
12
  SFX_NAME = "7z.sfx"
13
13
  SFX_FILE = File.expand_path("../../../../bin/#{SFX_NAME}", __FILE__)
14
14
 
15
- Archivers.register self
15
+ Packagers.register self
16
16
 
17
17
  protected
18
18
  def command(folder)
@@ -1,22 +1,30 @@
1
1
  require 'digest/md5'
2
2
 
3
3
  require "releasy/mixins/exec"
4
+ require "releasy/mixins/log"
4
5
 
5
6
  module Releasy
6
- module Archivers
7
+ module Packagers
7
8
  # Archives a build folder.
8
9
  #
9
10
  # @abstract
10
- class Archiver
11
+ # @attr extension [String] Extension of archive to be created (such as ".zip").
12
+ class Packager
11
13
  include Rake::DSL
12
14
  include Mixins::Exec
15
+ include Mixins::Log
13
16
 
14
17
  MD5_READ_SIZE = 128 * 64 # MD5 likes 128 byte chunks.
15
18
 
16
- # @return [Project] Project this Archiver was created by.
19
+ # @return [Project] Project this Packager was created by.
17
20
  attr_reader :project
18
- # @return [String] Extension of archive to be created (such as ".zip").
19
- attr_accessor :extension
21
+
22
+ attr_reader :extension
23
+ def extension=(extension)
24
+ raise TypeError "extension must be a String" unless extension.is_a? String
25
+ raise ArgumentError, "extension must be valid, such as '.zip'" unless extension =~ /^\.[a-z0-9\.]+$/
26
+ @extension = extension
27
+ end
20
28
 
21
29
  def type; self.class::TYPE; end
22
30
 
@@ -27,10 +35,12 @@ module Archivers
27
35
 
28
36
  protected
29
37
  # Generate tasks to create the archive of this file.
30
- def generate_tasks(output_task, folder)
38
+ def generate_tasks(output_task, folder, deployers)
31
39
  pkg = package folder
32
40
 
33
- desc "Create #{pkg}"
41
+ deployers.each {|d| d.send :generate_tasks, "#{output_task}:#{type}", folder, extension }
42
+
43
+ desc "Package #{output_task.tr(":", " ")} #{extension}"
34
44
  task "package:#{output_task}:#{type}" => pkg
35
45
 
36
46
  file pkg => folder do
@@ -41,10 +51,9 @@ module Archivers
41
51
  protected
42
52
  def archive(folder)
43
53
  pkg = package folder
44
- Rake::FileUtilsExt.verbose project.verbose?
45
54
 
46
- puts "Creating #{pkg}" if project.verbose?
47
- rm pkg if File.exist? pkg
55
+ heading "Creating #{pkg}"
56
+ rm pkg, fileutils_options if File.exist? pkg
48
57
  cd project.output_path do
49
58
  exec command(File.basename folder)
50
59
  end
@@ -53,7 +62,7 @@ module Archivers
53
62
  end
54
63
 
55
64
  protected
56
- def package(folder); "#{folder}#{extension[0, 1] == '.' ? '' : '.'}#{extension}"; end
65
+ def package(folder); "#{folder}#{extension}"; end
57
66
 
58
67
  protected
59
68
  def command(folder)
@@ -0,0 +1,12 @@
1
+ require "releasy/packagers/packager"
2
+
3
+ module Releasy
4
+ module Packagers
5
+ # 7z archive format (LZMA)
6
+ class SevenZip < Packager
7
+ TYPE = :"7z"
8
+ DEFAULT_EXTENSION = ".7z"
9
+ Packagers.register self
10
+ end
11
+ end
12
+ end
@@ -1,13 +1,13 @@
1
- require "releasy/archivers/tar_archiver"
1
+ require "releasy/packagers/tar_packager"
2
2
 
3
3
  module Releasy
4
- module Archivers
4
+ module Packagers
5
5
  # Archives with tar and Bzip2 formats.
6
- class TarBzip2 < TarArchiver
6
+ class TarBzip2 < TarPackager
7
7
  TYPE = :tar_bz2
8
8
  DEFAULT_EXTENSION = ".tar.bz2"
9
9
  FORMAT = "bzip2"
10
- Archivers.register self
10
+ Packagers.register self
11
11
  end
12
12
  end
13
13
  end
@@ -1,13 +1,13 @@
1
- require "releasy/archivers/tar_archiver"
1
+ require "releasy/packagers/tar_packager"
2
2
 
3
3
  module Releasy
4
- module Archivers
4
+ module Packagers
5
5
  # Archives with tar and Gzip formats.
6
- class TarGzip < TarArchiver
6
+ class TarGzip < TarPackager
7
7
  TYPE = :tar_gz
8
8
  DEFAULT_EXTENSION = ".tar.gz"
9
9
  FORMAT = "gzip"
10
- Archivers.register self
10
+ Packagers.register self
11
11
  end
12
12
  end
13
13
  end
@@ -1,10 +1,10 @@
1
- require "releasy/archivers/archiver"
1
+ require "releasy/packagers/packager"
2
2
 
3
3
  module Releasy
4
- module Archivers
5
- # An archiver that tars and then compresses the folder.
4
+ module Packagers
5
+ # An packager that tars and then compresses the folder.
6
6
  # @abstract
7
- class TarArchiver < Archiver
7
+ class TarPackager < Packager
8
8
  protected
9
9
  def command(folder)
10
10
  %[7z a -so -mmt -bd -ttar "#{folder}.tar" "#{folder}" | 7z a -si -bd -t#{self.class::FORMAT} -mx9 "#{folder}#{extension}"]
@@ -1,12 +1,12 @@
1
- require "releasy/archivers/archiver"
1
+ require "releasy/packagers/packager"
2
2
 
3
3
  module Releasy
4
- module Archivers
4
+ module Packagers
5
5
  # Archives with zip format. This isn't efficient, but can be decompressed on Windows Vista or later without requiring a 3rd party tool.
6
- class Zip < Archiver
6
+ class Zip < Packager
7
7
  TYPE = :zip
8
8
  DEFAULT_EXTENSION = ".zip"
9
- Archivers.register self
9
+ Packagers.register self
10
10
  end
11
11
  end
12
12
  end
@@ -1,7 +1,10 @@
1
1
  require 'releasy/dsl_wrapper'
2
2
  require 'releasy/builders'
3
- require 'releasy/archivers'
4
- require "releasy/mixins/has_archivers"
3
+ require 'releasy/packagers'
4
+ require 'releasy/deployers'
5
+ require "releasy/mixins/has_packagers"
6
+ require "releasy/mixins/can_exclude_encoding"
7
+ require "releasy/mixins/log"
5
8
 
6
9
  module Releasy
7
10
  # A description of the Ruby application that is being build for release and what packages to make from it.
@@ -14,7 +17,9 @@ module Releasy
14
17
  # @attr exposed_files [Rake::FileList] Files which should always be copied into the archive folder root, so they are always visible to the user. e.g readme, change-log and/or license files.
15
18
  class Project
16
19
  include Rake::DSL
17
- include Mixins::HasArchivers
20
+ include Mixins::HasPackagers
21
+ include Mixins::CanExcludeEncoding
22
+ include Mixins::Log
18
23
 
19
24
  DEFAULT_PACKAGE_FOLDER = "pkg"
20
25
 
@@ -29,11 +34,10 @@ module Releasy
29
34
 
30
35
  # Make the tasks give more detailed output.
31
36
  # @return [nil]
32
- def verbose; @verbose = true; nil; end
33
- # Make the tasks give less detailed output.
37
+ def verbose; Mixins::Log.log_level = :verbose; end
38
+ # Make the tasks give no output at all.
34
39
  # @return [nil]
35
- def quiet; @verbose = false; nil; end
36
- def verbose?; @verbose; end
40
+ def silent; Mixins::Log.log_level = :silent; end
37
41
 
38
42
  # Create MD5 hashes for created archives.
39
43
  # @return [nil]
@@ -41,10 +45,6 @@ module Releasy
41
45
  def create_md5s?; @create_md5s; end
42
46
  protected :create_md5s?
43
47
 
44
- # Verbosity of the console output.
45
- # @return [Boolean] True to make the tasks output more information.
46
- def verbose?; @verbose; end
47
-
48
48
  def exposed_files; @exposed_files; end
49
49
  def exposed_files=(files); @exposed_files = Rake::FileList.new files; end
50
50
 
@@ -89,7 +89,7 @@ module Releasy
89
89
  # name "My Application"
90
90
  # version "1.2.4"
91
91
  # add_build :source do
92
- # add_archive :tar_gz do
92
+ # add_package :tar_gz do
93
93
  # extension ".tgz"
94
94
  # end
95
95
  # end
@@ -106,7 +106,7 @@ module Releasy
106
106
  # p.name = "My Application"
107
107
  # p.version = "1.2.4"
108
108
  # p.add_build :source do |b|
109
- # b.add_archive :tar_gz do |a|
109
+ # b.add_package :tar_gz do |a|
110
110
  # a.extension = ".tgz"
111
111
  # end
112
112
  # end
@@ -122,19 +122,19 @@ module Releasy
122
122
  # project.name = "My Application"
123
123
  # project.version = "1.2.4"
124
124
  # builder = project.add_build :source
125
- # archiver = builder.add_archive :zip
126
- # archiver.extension = ".tgz"
125
+ # packager = builder.add_package :zip
126
+ # packager.extension = ".tgz"
127
127
  # project.generate_tasks # This has to be done manually.
128
128
  #
129
129
  def initialize(&block)
130
130
  super()
131
131
 
132
132
  @builders = []
133
+ @deployers = []
133
134
  @links = {}
134
135
  @files = Rake::FileList.new
135
136
  @exposed_files = Rake::FileList.new
136
137
  @output_path = DEFAULT_PACKAGE_FOLDER
137
- @verbose = true
138
138
  @create_md5s = false
139
139
  @name = @underscored_name = @underscored_version = nil
140
140
  @version = @executable = nil
@@ -152,13 +152,13 @@ module Releasy
152
152
  end
153
153
  end
154
154
 
155
- # Add a type of output to produce. Must define at least one of these.
155
+ # Add a type of build to produce. Must define at least one of these.
156
156
  # @see #initialize
157
- # @param type [:osx_app, :source, :windows_folder, :windows_folder_from_ruby_dist, :windows_installer, :windows_standalone]
157
+ # @param type [:osx_app, :source, :windows_folder, :windows_wrapped, :windows_installer, :windows_standalone]
158
158
  # @return [Project] self
159
159
  def add_build(type, &block)
160
160
  raise ArgumentError, "Unsupported output type #{type}" unless Builders.has_type? type
161
- raise ConfigError, "Already have output #{type.inspect}" if @builders.any? {|b| b.type == type }
161
+ raise ArgumentError, "Already have output #{type.inspect}" if @builders.any? {|b| b.type == type }
162
162
 
163
163
  builder = Builders[type].new(self)
164
164
  @builders << builder
@@ -174,6 +174,28 @@ module Releasy
174
174
  builder
175
175
  end
176
176
 
177
+ # Add a deployment method for archived packages.
178
+ # @see #initialize
179
+ # @param type [:github]
180
+ # @return [Project] self
181
+ def add_deploy(type, &block)
182
+ raise ArgumentError, "Unsupported deploy type #{type}" unless Deployers.has_type? type
183
+ raise ArgumentError, "Already have deploy #{type.inspect}" if @deployers.any? {|b| b.type == type }
184
+
185
+ deployer = Deployers[type].new(self)
186
+ @deployers << deployer
187
+
188
+ if block_given?
189
+ if block.arity == 0
190
+ DSLWrapper.new(deployer, &block)
191
+ else
192
+ yield deployer
193
+ end
194
+ end
195
+
196
+ deployer
197
+ end
198
+
177
199
  # Add a link file to be included in the win32 releases. Will create the file _title.url_ for you.
178
200
  #
179
201
  # @param url [String] Url to link to.
@@ -188,7 +210,7 @@ module Releasy
188
210
  # Generates all tasks required by the user. Automatically called at the end of the block, if {#initialize} is given a block.
189
211
  # @return [Project] self
190
212
  def generate_tasks
191
- raise ConfigError, "Must specify at least one valid output for this OS with #add_build before tasks can be generated" if @builders.empty?
213
+ raise ConfigError, "Must use #add_build at least once before tasks can be generated" if @builders.empty?
192
214
 
193
215
  # Even if there are builders specified, none may work on this platform.
194
216
  return if active_builders.empty?
@@ -210,11 +232,11 @@ module Releasy
210
232
  end
211
233
 
212
234
  build_groups.each_pair do |group, tasks|
213
- desc "Build all #{group} outputs"
235
+ desc "Build all #{group}"
214
236
  task "build:#{group}" => tasks
215
237
  end
216
238
 
217
- desc "Build all outputs"
239
+ desc "Build #{description}"
218
240
  task "build" => build_outputs
219
241
 
220
242
  generate_archive_tasks
@@ -222,10 +244,12 @@ module Releasy
222
244
  self
223
245
  end
224
246
 
225
-
226
- def folder_base
227
- File.join(output_path, "#{underscored_name}#{version ? "_#{underscored_version}" : ""}")
228
- end
247
+ # Full name of the project, including the version name E.g. "My Application" or "My Application 0.1"
248
+ def description; name ? "#{name}#{version ? " #{version}" : ""}" : nil; end
249
+ # Full underscored name of the project. E.g. "my_application" or "my_application_0_1"
250
+ def underscored_description; underscored_name ? "#{underscored_name}#{version ? "_#{underscored_version}" : ""}" : nil; end
251
+ # Base name of folders that will be created, such as "pkg/my_application" or "pkg/my_application_0_1"
252
+ def folder_base; File.join(output_path, underscored_description.to_s); end
229
253
 
230
254
  protected
231
255
  # Only allow access to this from Builder
@@ -249,52 +273,87 @@ module Releasy
249
273
  windows_tasks = []
250
274
  osx_tasks = []
251
275
  top_level_tasks = []
276
+
252
277
  active_builders.each do |builder|
253
278
  output_task = builder.type.to_s.sub '_', ':'
254
279
 
255
- archivers = active_archivers(builder)
256
- archivers.each do |archiver|
257
- archiver.send :generate_tasks, output_task, builder.send(:folder)
280
+ packagers = active_packagers(builder)
281
+ packagers.each do |packager|
282
+ packager.send :generate_tasks, output_task, builder.send(:folder), @deployers
283
+
284
+ task "deploy:#{output_task}:#{packager.type}" => @deployers.map {|d| "deploy:#{output_task}:#{packager.type}:#{d.type}" }
258
285
  end
259
286
 
260
- desc "Package all #{builder.type}"
261
- task "package:#{output_task}" => archivers.map {|c| "package:#{output_task}:#{c.type}" }
287
+ @deployers.each do |deployer|
288
+ task "deploy:#{output_task}:#{deployer.type}" => packagers.map {|a| "deploy:#{output_task}:#{a.type}:#{deployer.type}" }
289
+ end
290
+
291
+ task "package:#{output_task}" => packagers.map {|a| "package:#{output_task}:#{a.type}" }
262
292
 
263
293
  case output_task
264
294
  when /^windows:/
265
- windows_tasks << "package:#{output_task}"
266
- top_level_tasks << "package:windows" unless top_level_tasks.include? "package:windows"
295
+ windows_tasks << "#{output_task}"
296
+ top_level_tasks << "windows" unless top_level_tasks.include? "windows"
267
297
  when /^osx:/
268
298
  osx_tasks << "package:#{output_task}"
269
- top_level_tasks << "package:osx" unless top_level_tasks.include? "package:osx"
299
+ top_level_tasks << "osx" unless top_level_tasks.include? "osx"
270
300
  else
271
- top_level_tasks << "package:#{output_task}"
301
+ top_level_tasks << "#{output_task}"
272
302
  end
273
303
  end
274
304
 
305
+ # Windows tasks.
275
306
  unless windows_tasks.empty?
276
- desc "Package all Windows"
277
- task "package:windows" => windows_tasks
307
+ task "package:windows" => windows_tasks.map {|t| "package:#{t}" }
308
+
309
+ generate_deploy_tasks "windows", windows_tasks
278
310
  end
279
311
 
312
+ # OS X tasks.
280
313
  unless osx_tasks.empty?
281
- desc "Package all OS X"
282
- task "package:osx" => osx_tasks
314
+ task "package:osx" => osx_tasks.map {|t| "package:#{t}" }
315
+
316
+ generate_deploy_tasks "osx", osx_tasks
283
317
  end
284
318
 
285
- desc "Package all"
286
- task "package" => top_level_tasks
319
+ # Top level tasks.
320
+ desc "Package #{description}"
321
+ task "package" => top_level_tasks.map {|t| "package:#{t}" }
322
+
323
+ unless @deployers.empty?
324
+ desc "Deploy #{description}"
325
+ task "deploy" => top_level_tasks.map {|t| "deploy:#{t}" }
326
+
327
+ generate_deploy_tasks "", top_level_tasks
328
+ end
287
329
 
288
330
  self
289
331
  end
290
332
 
291
333
  protected
292
- def active_archivers(builder)
293
- # Use archivers specifically set on the builder and those set globally that aren't on the builder.
294
- archivers = builder.send(:active_archivers)
295
- archiver_types = archivers.map(&:type)
334
+ def generate_deploy_tasks(task_name, tasks)
335
+ deploy_task = task_name.empty? ? "deploy" : "deploy:#{task_name}"
336
+
337
+ unless @deployers.empty?
338
+ task deploy_task => tasks.map {|t| "deploy:#{t}" }
339
+
340
+ @deployers.each do |deployer|
341
+ task "#{deploy_task}:#{deployer.type}" => tasks.map {|t| "deploy:#{t}:#{deployer.type}" }
342
+ end
343
+
344
+ tasks.each do |t|
345
+ task "deploy:#{t}" => @deployers.map {|d| "deploy:#{t}:#{d.type}" }
346
+ end
347
+ end
348
+ end
349
+
350
+ protected
351
+ def active_packagers(builder)
352
+ # Use packagers specifically set on the builder and those set globally that aren't on the builder.
353
+ packagers = builder.send(:active_packagers)
354
+ packager_types = packagers.map(&:type)
296
355
 
297
- archivers + super().reject {|a| archiver_types.include? a.type }
356
+ packagers + super().reject {|a| packager_types.include? a.type }
298
357
  end
299
358
  end
300
359
  end