releasy 0.2.0 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (60) hide show
  1. data/.yardopts +3 -1
  2. data/CHANGELOG.md +9 -0
  3. data/README.md +114 -41
  4. data/Rakefile +1 -1
  5. data/bin/7z_sfx_LICENSE.txt +56 -0
  6. data/bin/7za.exe +0 -0
  7. data/bin/7za_exe_LICENSE.txt +29 -0
  8. data/lib/releasy.rb +4 -1
  9. data/lib/releasy/builders/builder.rb +14 -6
  10. data/lib/releasy/builders/ocra_builder.rb +4 -2
  11. data/lib/releasy/builders/osx_app.rb +18 -6
  12. data/lib/releasy/builders/source.rb +9 -2
  13. data/lib/releasy/builders/windows_folder.rb +12 -3
  14. data/lib/releasy/builders/windows_installer.rb +2 -3
  15. data/lib/releasy/builders/windows_standalone.rb +13 -3
  16. data/lib/releasy/builders/windows_wrapped.rb +14 -4
  17. data/lib/releasy/cli/install_sfx.rb +1 -1
  18. data/lib/releasy/deployers.rb +1 -1
  19. data/lib/releasy/deployers/deployer.rb +22 -1
  20. data/lib/releasy/deployers/github.rb +31 -124
  21. data/lib/releasy/deployers/local.rb +55 -0
  22. data/lib/releasy/deployers/rsync.rb +59 -0
  23. data/lib/releasy/mixins/has_packagers.rb +1 -1
  24. data/lib/releasy/mixins/utilities.rb +34 -0
  25. data/lib/releasy/packagers/dmg.rb +17 -0
  26. data/lib/releasy/packagers/exe.rb +18 -1
  27. data/lib/releasy/packagers/packager.rb +22 -6
  28. data/lib/releasy/packagers/seven_zip.rb +17 -0
  29. data/lib/releasy/packagers/tar_bzip2.rb +19 -0
  30. data/lib/releasy/packagers/tar_gzip.rb +19 -0
  31. data/lib/releasy/packagers/tar_packager.rb +2 -1
  32. data/lib/releasy/packagers/zip.rb +17 -0
  33. data/lib/releasy/project.rb +45 -4
  34. data/lib/releasy/version.rb +1 -1
  35. data/releasy.gemspec +1 -1
  36. data/test/releasy/builders/data/Main.rb +3 -2
  37. data/test/releasy/builders/helpers/builder_helper.rb +35 -0
  38. data/test/releasy/builders/helpers/ocra_builder_helper.rb +31 -0
  39. data/test/releasy/builders/helpers/windows_builder_helper.rb +25 -0
  40. data/test/releasy/builders/osx_app_test.rb +6 -4
  41. data/test/releasy/builders/source_test.rb +7 -4
  42. data/test/releasy/builders/windows_folder_test.rb +3 -1
  43. data/test/releasy/builders/windows_installer_test.rb +6 -4
  44. data/test/releasy/builders/windows_standalone_test.rb +6 -4
  45. data/test/releasy/builders/windows_wrapped_test.rb +3 -1
  46. data/test/releasy/cli/install_sfx_test.rb +1 -1
  47. data/test/releasy/deployers/github_test.rb +30 -32
  48. data/test/releasy/deployers/local_test.rb +93 -0
  49. data/test/releasy/deployers/rsync_test.rb +55 -0
  50. data/test/releasy/integration/source_test.rb +6 -6
  51. data/test/releasy/mixins/utilities_test.rb +50 -0
  52. data/test/releasy/packagers/packager_test.rb +79 -0
  53. data/test/releasy/packagers_test.rb +12 -6
  54. data/test/releasy/project_test.rb +5 -5
  55. data/test/teststrap.rb +6 -0
  56. data/test/yard_test.rb +1 -1
  57. metadata +40 -28
  58. data/lib/releasy/mixins/exec.rb +0 -14
  59. data/test/releasy/builders/ocra_builder_test.rb +0 -37
  60. data/test/releasy/builders/windows_builder_test.rb +0 -26
@@ -0,0 +1,55 @@
1
+ require 'releasy/deployers/deployer'
2
+
3
+ module Releasy
4
+ module Deployers
5
+ # Deploys (copies) to a local destination, such as into your Dropbox folder.
6
+ #
7
+ # @example
8
+ # Releasy::Project.new do
9
+ # name "My App"
10
+ # add_build :source
11
+ # add_package :zip
12
+ # add_deploy :local do
13
+ # path "C:/Users/X/Dropbox/Public" # Required.
14
+ # end
15
+ # end
16
+ #
17
+ # @attr path [String] Path to copy files to.
18
+ class Local < Deployer
19
+ TYPE = :local
20
+
21
+ Deployers.register self
22
+
23
+ attr_reader :path
24
+ def path=(path)
25
+ raise TypeError, "path must be a String, but received #{path.class}" unless path.is_a? String
26
+ @path = path
27
+ end
28
+
29
+ protected
30
+ def setup
31
+ @path = nil
32
+ end
33
+
34
+ protected
35
+ # @param file [String] Path to file to deploy.
36
+ # @return [nil]
37
+ def deploy(file)
38
+ raise ConfigError, "#path must be set" unless path
39
+
40
+ destination = File.join path, File.basename(file)
41
+ raise ConfigError, "#path is same as build directory" if File.expand_path(destination) == File.expand_path(file)
42
+
43
+ # If destination file already exists or is as new as the one we are going to copy over it, don't bother.
44
+ if (not File.exists?(destination)) or (File.ctime(destination) < File.ctime(file))
45
+ mkdir_p path, fileutils_options unless File.exists? path
46
+ cp file, path, fileutils_options.merge(:force => File.exists?(destination))
47
+ else
48
+ warn "Skipping '#{File.basename(file)}' because it already exists in '#{path}'"
49
+ end
50
+
51
+ nil
52
+ end
53
+ end
54
+ end
55
+ end
@@ -0,0 +1,59 @@
1
+ require 'releasy/deployers/deployer'
2
+ require "releasy/mixins/utilities"
3
+
4
+ module Releasy
5
+ module Deployers
6
+ # Deploys to a remote server, using the rsync command.
7
+ #
8
+ # @example
9
+ # Releasy::Project.new do
10
+ # name "My App"
11
+ # add_build :source
12
+ # add_package :zip
13
+ # add_deploy :rsync do
14
+ # destination "example.com:/var/www/sites/mysite/downloads" # Required.
15
+ # end
16
+ # end
17
+ #
18
+ # @attr destination [String] Location to deploy to, such as "example.com:/var/www/sites/mysite/downloads".
19
+ # @attr options [String] ('-glpPrtvz') Options to pass to rsync.
20
+ class Rsync < Deployer
21
+ include Mixins::Utilities
22
+
23
+ TYPE = :rsync
24
+ DEFAULT_OPTIONS = '-glpPrtvz'
25
+
26
+ Deployers.register self
27
+
28
+ attr_reader :destination
29
+ def destination=(destination)
30
+ raise TypeError, "destination must be a String, but received #{destination.inspect}" unless destination.is_a? String
31
+ raise ArgumentError, 'destination requires no trailing slash' if destination[-1,1] == '/'
32
+ @destination = destination
33
+ end
34
+
35
+ attr_reader :options
36
+ def options=(options)
37
+ raise TypeError, "options must be a String, but received #{options.inspect}" unless options.is_a? String
38
+ @options = options
39
+ end
40
+
41
+ protected
42
+ def setup
43
+ @destination = nil
44
+ @options = DEFAULT_OPTIONS
45
+ end
46
+
47
+ protected
48
+ # @param file [String] Path to file to deploy.
49
+ # @return [nil]
50
+ def deploy(file)
51
+ raise ConfigError, "#destination must be set" unless destination
52
+
53
+ execute_command %[rsync #{options} "#{File.expand_path file}" "#{destination.chomp "/"}"]
54
+
55
+ nil
56
+ end
57
+ end
58
+ end
59
+ end
@@ -14,7 +14,7 @@ module Mixins
14
14
  packagers << packager
15
15
 
16
16
  if block_given?
17
- if block.arity == 0
17
+ if block.arity <= 0
18
18
  DSLWrapper.new(packager, &block)
19
19
  else
20
20
  yield packager
@@ -0,0 +1,34 @@
1
+ module Releasy
2
+ module Mixins
3
+ module Utilities
4
+ protected
5
+ # Executes command, and prints out command and result only if the project is verbose.
6
+ # Requires {Log} to be included.
7
+ # Returns true if the command succeeded. False if it failed.
8
+ def execute_command(command)
9
+ info command
10
+
11
+ begin
12
+ IO.popen command do |output|
13
+ info output.gets.strip until output.eof?
14
+ end
15
+
16
+ true
17
+ rescue Errno::ENOENT
18
+ false
19
+ end
20
+ end
21
+
22
+ protected
23
+ # Is a particular command available on this system?
24
+ def command_available?(command)
25
+ find = Releasy.win_platform? ? "where" : "which"
26
+ !!Kernel.`("#{find} #{command}")
27
+ end
28
+
29
+ protected
30
+ def null_file; Releasy.win_platform? ? "NUL" : "/dev/null"; end
31
+
32
+ end
33
+ end
34
+ end
@@ -3,6 +3,23 @@ require "releasy/packagers/packager"
3
3
  module Releasy
4
4
  module Packagers
5
5
  # OS X .dmg format (self-extractor).
6
+ #
7
+ # @example Package a particular build.
8
+ # Releasy::Project.new do
9
+ # name "My App"
10
+ # add_build :source do
11
+ # add_package :dmg
12
+ # end
13
+ # end
14
+ #
15
+ # @example Package all builds.
16
+ # Releasy::Project.new do
17
+ # name "My App"
18
+ # add_build :source
19
+ # add_build :windows_folder
20
+ # add_package :dmg
21
+ # end
22
+ #
6
23
  class Dmg < Packager
7
24
  TYPE = :dmg
8
25
  DEFAULT_EXTENSION = ".dmg"
@@ -5,6 +5,23 @@ module Releasy
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
+ #
9
+ # @example Package a particular build.
10
+ # Releasy::Project.new do
11
+ # name "My App"
12
+ # add_build :source do
13
+ # add_package :exe
14
+ # end
15
+ # end
16
+ #
17
+ # @example Package all builds.
18
+ # Releasy::Project.new do
19
+ # name "My App"
20
+ # add_build :source
21
+ # add_build :windows_folder
22
+ # add_package :exe
23
+ # end
24
+ #
8
25
  class Exe < Packager
9
26
  TYPE = :exe
10
27
  DEFAULT_EXTENSION = ".exe"
@@ -16,7 +33,7 @@ module Releasy
16
33
 
17
34
  protected
18
35
  def command(folder)
19
- %[7z a -mmt -bd -t7z -mx9 -sfx#{SFX_NAME} "#{package(folder)}" "#{folder}"]
36
+ %[#{seven_zip_command} a -mmt -bd -t7z -mx9 -sfx#{SFX_NAME} "#{package(folder)}" "#{folder}"]
20
37
  end
21
38
  end
22
39
  end
@@ -1,6 +1,6 @@
1
1
  require 'digest/md5'
2
2
 
3
- require "releasy/mixins/exec"
3
+ require "releasy/mixins/utilities"
4
4
  require "releasy/mixins/log"
5
5
 
6
6
  module Releasy
@@ -11,7 +11,7 @@ module Packagers
11
11
  # @attr extension [String] Extension of archive to be created (such as ".zip").
12
12
  class Packager
13
13
  include Rake::DSL
14
- include Mixins::Exec
14
+ include Mixins::Utilities
15
15
  include Mixins::Log
16
16
 
17
17
  MD5_READ_SIZE = 128 * 64 # MD5 likes 128 byte chunks.
@@ -21,7 +21,7 @@ module Packagers
21
21
 
22
22
  attr_reader :extension
23
23
  def extension=(extension)
24
- raise TypeError "extension must be a String" unless extension.is_a? String
24
+ raise TypeError, "extension must be a String" unless extension.is_a? String
25
25
  raise ArgumentError, "extension must be valid, such as '.zip'" unless extension =~ /^\.[a-z0-9\.]+$/
26
26
  @extension = extension
27
27
  end
@@ -33,6 +33,22 @@ module Packagers
33
33
  @extension = self.class::DEFAULT_EXTENSION
34
34
  end
35
35
 
36
+ protected
37
+ # Finds
38
+ def seven_zip_command
39
+ @seven_zip_command ||= begin
40
+ if command_available? "7za"
41
+ "7za" # Installed standalone command line version. Included with CLI and GUI releases.
42
+ elsif command_available? "7z"
43
+ "7z" # Installed CLI version only included with gui version.
44
+ elsif Releasy.win_platform?
45
+ %["#{File.expand_path("../../../../bin/7za.exe", __FILE__)}"]
46
+ else
47
+ raise CommandNotFoundError, "Failed to find 7-ZIP; see readme for details of how to install"
48
+ end
49
+ end
50
+ end
51
+
36
52
  protected
37
53
  # Generate tasks to create the archive of this file.
38
54
  def generate_tasks(output_task, folder, deployers)
@@ -54,8 +70,8 @@ module Packagers
54
70
 
55
71
  heading "Creating #{pkg}"
56
72
  rm pkg, fileutils_options if File.exist? pkg
57
- cd project.output_path do
58
- exec command(File.basename folder)
73
+ cd project.output_path, fileutils_options do
74
+ execute_command command(File.basename folder)
59
75
  end
60
76
 
61
77
  File.open("#{pkg}.MD5", "w") {|f| f.puts checksum(pkg) } if project.send :create_md5s?
@@ -66,7 +82,7 @@ module Packagers
66
82
 
67
83
  protected
68
84
  def command(folder)
69
- %[7z a -mmt -bd -t#{type} -mx9 "#{package(folder)}" "#{folder}"]
85
+ %[#{seven_zip_command} a -mmt -bd -t#{type} -mx9 "#{package(folder)}" "#{folder}"]
70
86
  end
71
87
 
72
88
  protected
@@ -3,6 +3,23 @@ require "releasy/packagers/packager"
3
3
  module Releasy
4
4
  module Packagers
5
5
  # 7z archive format (LZMA)
6
+ #
7
+ # @example Package a particular build.
8
+ # Releasy::Project.new do
9
+ # name "My App"
10
+ # add_build :source do
11
+ # add_package :"7z"
12
+ # end
13
+ # end
14
+ #
15
+ # @example Package all builds.
16
+ # Releasy::Project.new do
17
+ # name "My App"
18
+ # add_build :source
19
+ # add_build :windows_folder
20
+ # add_package :"7z"
21
+ # end
22
+ #
6
23
  class SevenZip < Packager
7
24
  TYPE = :"7z"
8
25
  DEFAULT_EXTENSION = ".7z"
@@ -3,6 +3,25 @@ require "releasy/packagers/tar_packager"
3
3
  module Releasy
4
4
  module Packagers
5
5
  # Archives with tar and Bzip2 formats.
6
+ #
7
+ # @example Package a particular build and change extension.
8
+ # Releasy::Project.new do
9
+ # name "My App"
10
+ # add_build :source do
11
+ # add_package :tar_bz2 do
12
+ # extension ".tbz"
13
+ # end
14
+ # end
15
+ # end
16
+ #
17
+ # @example Package all builds.
18
+ # Releasy::Project.new do
19
+ # name "My App"
20
+ # add_build :source
21
+ # add_build :windows_folder
22
+ # add_package :tar_bz2
23
+ # end
24
+ #
6
25
  class TarBzip2 < TarPackager
7
26
  TYPE = :tar_bz2
8
27
  DEFAULT_EXTENSION = ".tar.bz2"
@@ -3,6 +3,25 @@ require "releasy/packagers/tar_packager"
3
3
  module Releasy
4
4
  module Packagers
5
5
  # Archives with tar and Gzip formats.
6
+ #
7
+ # @example Package a particular build and change extension.
8
+ # Releasy::Project.new do
9
+ # name "My App"
10
+ # add_build :source do
11
+ # add_package :tar_gz do
12
+ # extension ".tgz"
13
+ # end
14
+ # end
15
+ # end
16
+ #
17
+ # @example Package all builds.
18
+ # Releasy::Project.new do
19
+ # name "My App"
20
+ # add_build :source
21
+ # add_build :windows_folder
22
+ # add_package :tar_gz
23
+ # end
24
+ #
6
25
  class TarGzip < TarPackager
7
26
  TYPE = :tar_gz
8
27
  DEFAULT_EXTENSION = ".tar.gz"
@@ -7,7 +7,8 @@ module Packagers
7
7
  class TarPackager < Packager
8
8
  protected
9
9
  def command(folder)
10
- %[7z a -so -mmt -bd -ttar "#{folder}.tar" "#{folder}" | 7z a -si -bd -t#{self.class::FORMAT} -mx9 "#{folder}#{extension}"]
10
+
11
+ %[#{seven_zip_command} a -so -mmt -bd -ttar "#{folder}.tar" "#{folder}" 2>#{null_file} | #{seven_zip_command} a -si -bd -t#{self.class::FORMAT} -mx9 "#{folder}#{extension}"]
11
12
  end
12
13
  end
13
14
  end
@@ -3,6 +3,23 @@ require "releasy/packagers/packager"
3
3
  module Releasy
4
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
+ #
7
+ # @example Package a particular build.
8
+ # Releasy::Project.new do
9
+ # name "My App"
10
+ # add_build :source do
11
+ # add_package :zip
12
+ # end
13
+ # end
14
+ #
15
+ # @example Package all builds.
16
+ # Releasy::Project.new do
17
+ # name "My App"
18
+ # add_build :source
19
+ # add_build :windows_folder
20
+ # add_package :zip
21
+ # end
22
+ #
6
23
  class Zip < Packager
7
24
  TYPE = :zip
8
25
  DEFAULT_EXTENSION = ".zip"
@@ -11,6 +11,47 @@ require "releasy/mixins/log"
11
11
  module Releasy
12
12
  # A description of the Ruby application that is being build for release and what packages to make from it.
13
13
  #
14
+ # @example
15
+ # Releasy::Project.new do
16
+ # name "My Application"
17
+ # version MyApplication::VERSION
18
+ #
19
+ # executable "bin/my_application.rbw"
20
+ # files `git ls-files`.split("\n")
21
+ # files.exclude '.gitignore'
22
+ #
23
+ # exposed_files ["README.html", "LICENSE.txt"]
24
+ # add_link "http://my_application.github.com", "My Application website"
25
+ # exclude_encoding
26
+ #
27
+ # # Create a variety of releases, for all platforms.
28
+ # add_build :osx_app do
29
+ # url "com.github.my_application"
30
+ # wrapper "../osx_app/gosu-mac-wrapper-0.7.41.tar.gz"
31
+ # icon "media/icon.icns"
32
+ # add_package :tar_gz
33
+ # end
34
+ #
35
+ # add_build :source do
36
+ # add_package :"7z"
37
+ # end
38
+ #
39
+ # add_build :windows_folder do
40
+ # icon "media/icon.ico"
41
+ # add_package :exe
42
+ # end
43
+ #
44
+ # add_build :windows_installer do
45
+ # icon "media/icon.ico"
46
+ # start_menu_group "Spooner Games"
47
+ # readme "README.html" # User asked if they want to view readme after install.
48
+ # license "LICENSE.txt" # User asked to read this and confirm before installing.
49
+ # add_package :zip
50
+ # end
51
+ #
52
+ # add_deploy :github # Upload to a github project.
53
+ # end
54
+ #
14
55
  # @attr underscored_name [String] Project name underscored (as used in file names), which will be derived from {#name}, but can be manually set.
15
56
  # @attr underscored_version [String] Version number, underscored so it can be used in file names, which will be derived from {#version}, but can be manually set.
16
57
  # @attr executable [String] Name of executable to run (defaults to 'bin/<underscored_name>')
@@ -144,7 +185,7 @@ module Releasy
144
185
  setup
145
186
 
146
187
  if block_given?
147
- if block.arity == 0
188
+ if block.arity <= 0
148
189
  DSLWrapper.new(self, &block)
149
190
  else
150
191
  yield self
@@ -166,7 +207,7 @@ module Releasy
166
207
  @builders << builder
167
208
 
168
209
  if block_given?
169
- if block.arity == 0
210
+ if block.arity <= 0
170
211
  DSLWrapper.new(builder, &block)
171
212
  else
172
213
  yield builder
@@ -178,7 +219,7 @@ module Releasy
178
219
 
179
220
  # Add a deployment method for archived packages.
180
221
  # @see #initialize
181
- # @param type [:github]
222
+ # @param type [:github, :local, :rsync]
182
223
  # @return [Project] self
183
224
  def add_deploy(type, &block)
184
225
  raise ArgumentError, "Unsupported deploy type #{type}" unless Deployers.has_type? type
@@ -188,7 +229,7 @@ module Releasy
188
229
  @deployers << deployer
189
230
 
190
231
  if block_given?
191
- if block.arity == 0
232
+ if block.arity <= 0
192
233
  DSLWrapper.new(deployer, &block)
193
234
  else
194
235
  yield deployer