releasy 0.2.0rc1 → 0.2.0rc2

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.
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
@@ -1,4 +1,5 @@
1
1
  require "releasy/builders/builder"
2
+ require "releasy/mixins/can_exclude_encoding"
2
3
 
3
4
  module Releasy
4
5
  module Builders
@@ -6,20 +7,13 @@ module Builders
6
7
  # @abstract
7
8
  # @attr icon [String] Optional filename of icon to show on executable/installer (.ico).
8
9
  class WindowsBuilder < Builder
10
+ include Mixins::CanExcludeEncoding
11
+
9
12
  EXECUTABLE_TYPES = [:auto, :windows, :console]
10
13
 
11
14
  # @return [:auto, :windows, :console] Type of ruby to run executable with. :console means run with 'ruby.exe', :windows means run with 'rubyw.exe', :auto means determine type from executable extension (.rb => :console or .rbw => :windows).
12
15
  attr_accessor :executable_type
13
16
 
14
- # Excludes encoding files from 1.9 releases (equivalent to using '--no-enc' in Ocra).
15
- def exclude_encoding
16
- @exclude_encoding = true
17
- end
18
-
19
- # Should encoding files be excluded?
20
- def encoding_excluded?; @exclude_encoding; end
21
- protected :encoding_excluded?
22
-
23
17
  # Executable type, resolving :auto if possible.
24
18
  # @return [:windows, :console]
25
19
  def effective_executable_type
@@ -39,7 +33,6 @@ module Builders
39
33
 
40
34
  protected
41
35
  def setup
42
- @exclude_encoding = false
43
36
  @executable_type = :auto
44
37
  super
45
38
  end
@@ -16,27 +16,25 @@ module Releasy
16
16
  directory project.output_path
17
17
 
18
18
  file folder => project.files do
19
- Rake::FileUtilsExt.verbose project.verbose?
20
-
21
19
  tmp_ocra_executable = "#{folder}.exe"
22
20
 
23
21
  exec %[#{ocra_command} --output "#{tmp_ocra_executable}" --debug-extract]
24
22
 
25
23
  # Extract the files from the executable.
26
24
  system tmp_ocra_executable
27
- rm tmp_ocra_executable
25
+ rm tmp_ocra_executable, fileutils_options
28
26
 
29
- mv Dir["#{File.dirname(folder)}/ocr*\.tmp"].first, folder
27
+ mv Dir["#{File.dirname(folder)}/ocr*\.tmp"].first, folder, fileutils_options
30
28
 
31
29
  maker = Releasy::WindowsWrapperMaker.new
32
30
  maker.build_executable("#{folder}/#{executable_name}", "src/#{project.executable}",
33
31
  :icon => icon, :windows => (effective_executable_type == :windows))
34
32
 
35
33
  create_link_files folder
36
- project.exposed_files.each {|file| cp file, folder }
34
+ project.exposed_files.each {|file| cp file, folder, fileutils_options }
37
35
  end
38
36
 
39
- desc "Build source/exe folder #{project.version}"
37
+ desc "Build windows folder"
40
38
  task "build:windows:folder" => folder
41
39
  end
42
40
 
@@ -24,17 +24,15 @@ module Releasy
24
24
  directory folder
25
25
 
26
26
  file folder => project.files do
27
- Rake::FileUtilsExt.verbose project.verbose?
28
-
29
27
  create_link_files folder
30
- project.exposed_files.each {|file| cp file, folder }
28
+ project.exposed_files.each {|file| cp file, folder, fileutils_options }
31
29
 
32
30
  create_installer installer_name, :links => true
33
31
 
34
- rm temp_installer_script
32
+ rm temp_installer_script, fileutils_options
35
33
  end
36
34
 
37
- desc "Build installer #{project.version} [Innosetup]"
35
+ desc "Build windows installer"
38
36
  task "build:windows:installer" => folder
39
37
  end
40
38
 
@@ -17,9 +17,7 @@ module Releasy
17
17
  directory folder
18
18
 
19
19
  file folder => project.files do
20
- Rake::FileUtilsExt.verbose project.verbose?
21
-
22
- project.exposed_files.each {|file| cp file, folder }
20
+ project.exposed_files.each {|file| cp file, folder, fileutils_options }
23
21
 
24
22
  create_link_files folder
25
23
 
@@ -11,10 +11,10 @@ module Releasy
11
11
  # Limitations:
12
12
  # * Does not DLLs loaded from the system, which will have to be included manually if any are required by the application and no universally available in Windows installations.
13
13
  # * Unless a gem is in pure Ruby or available as a pre-compiled binary gem, it won't work!
14
- class WindowsFolderFromRubyDist < WindowsBuilder
14
+ class WindowsWrapped < WindowsBuilder
15
15
  include Mixins::HasGemspecs
16
16
 
17
- TYPE = :windows_folder_from_ruby_dist
17
+ TYPE = :windows_wrapped
18
18
  DEFAULT_FOLDER_SUFFIX = "WIN32"
19
19
 
20
20
  # Files that are required for Tcl/Tk, but which are unlikely to be used in many applications.
@@ -28,10 +28,12 @@ module Releasy
28
28
  # Encoding files that are required, even if we don't need most of them if we select to {#exclude_encoding}.
29
29
  REQUIRED_ENCODING_FILES = %w[encdb.so iso_8859_1.so utf_16le.so trans/single_byte.so trans/transdb.so trans/utf_16_32.so]
30
30
 
31
+ VALID_RUBY_DIST = /ruby-1\.[89]\.\d-p\d+-i386-mingw32.7z/
32
+
31
33
  Builders.register self
32
34
 
33
35
  # @return [String] Path to windows distribution archive that has been manually downloaded from http://rubyinstaller.org/downloads/ (e.g. "rubies/ruby-1.9.2-p290-i386-mingw32.7z").
34
- attr_accessor :ruby_dist
36
+ attr_accessor :wrapper
35
37
 
36
38
  # Remove TCL/TK from package, which can save a significant amount of space if the application does not require them.
37
39
  # This is over 6MB uncompressed, which is a saving of 1.6MB when compressed with 7z format (LZMA).
@@ -43,22 +45,22 @@ module Releasy
43
45
  protected
44
46
  # FOLDER containing EXE, Ruby + source.
45
47
  def generate_tasks
46
- raise ConfigError, "#ruby_dist not set" unless ruby_dist
47
- raise ConfigError, "#ruby_dist not valid: #{ruby_dist}" unless File.exist?(ruby_dist) and File.extname(ruby_dist) == ".7z"
48
+ raise ConfigError, "#wrapper not set" unless wrapper
49
+ raise ConfigError, "#wrapper not valid wrapper: #{wrapper}" unless File.basename(wrapper) =~ VALID_RUBY_DIST
48
50
 
49
51
  directory project.output_path
50
52
 
51
- file folder => project.files + [ruby_dist] do
53
+ file folder => project.files + [wrapper] do
52
54
  build
53
55
  end
54
56
 
55
57
  desc "Build source/exe folder #{project.version} from wrapper"
56
- task "build:windows:folder_from_ruby_dist" => folder
58
+ task "build:windows:wrapped" => folder
57
59
  end
58
60
 
59
61
  protected
60
62
  def build
61
- Rake::FileUtilsExt.verbose project.verbose?
63
+ raise ConfigError, "#wrapper does not exist: #{wrapper}" unless File.exist?(wrapper)
62
64
 
63
65
  copy_ruby_distribution
64
66
  delete_excluded_files
@@ -66,7 +68,7 @@ module Releasy
66
68
  copy_files_relative project.files, File.join(folder, 'src')
67
69
 
68
70
  create_link_files folder
69
- project.exposed_files.each {|file| cp file, folder }
71
+ project.exposed_files.each {|file| cp file, folder, fileutils_options }
70
72
 
71
73
  create_executable
72
74
 
@@ -79,20 +81,20 @@ module Releasy
79
81
  protected
80
82
  def delete_excluded_files
81
83
  # Remove TCL/TK dlls, lib folder and source.
82
- rm_r Dir[*(TCL_TK_FILES.map {|f| File.join(folder, f) })].uniq.sort if @exclude_tcl_tk
84
+ rm_r Dir[*(TCL_TK_FILES.map {|f| File.join(folder, f) })].uniq.sort, fileutils_options if @exclude_tcl_tk
83
85
 
84
86
  # Remove Encoding files on Ruby 1.9
85
- if encoding_excluded? and ruby_dist =~ /1\.9\.\d/
87
+ if encoding_excluded? and wrapper =~ /1\.9\.\d/
86
88
  encoding_files = Dir[File.join folder, "lib/ruby/1.9.1/i386-mingw32/enc/**/*.so"]
87
89
  required_encoding_files = REQUIRED_ENCODING_FILES.map {|f| File.join folder, "lib/ruby/1.9.1/i386-mingw32/enc", f }
88
- rm_r encoding_files - required_encoding_files
90
+ rm_r encoding_files - required_encoding_files, fileutils_options
89
91
  end
90
92
  end
91
93
 
92
94
  protected
93
95
  def setup
94
96
  @exclude_tcl_tk = false
95
- @ruby_dist = nil
97
+ @wrapper = nil
96
98
  super
97
99
  end
98
100
 
@@ -101,13 +103,13 @@ module Releasy
101
103
 
102
104
  protected
103
105
  def copy_ruby_distribution
104
- archive_name = File.basename(ruby_dist).chomp(File.extname(ruby_dist))
105
- exec %[7z x "#{ruby_dist}" -o"#{File.dirname folder}"]
106
- mv File.join(File.dirname(folder), archive_name), folder
107
- rm_r File.join(folder, "share")
108
- rm_r File.join(folder, "include") if File.exists? File.join(folder, "include")
106
+ archive_name = File.basename(wrapper).chomp(File.extname(wrapper))
107
+ exec %[7z x "#{wrapper}" -o"#{File.dirname folder}"]
108
+ mv File.join(File.dirname(folder), archive_name), folder, fileutils_options
109
+ rm_r File.join(folder, "share"), fileutils_options
110
+ rm_r File.join(folder, "include"), fileutils_options if File.exists? File.join(folder, "include")
109
111
  unused_exe = effective_executable_type == :windows ? "ruby.exe" : "rubyw.exe"
110
- rm File.join(folder, "bin", unused_exe)
112
+ rm File.join(folder, "bin", unused_exe), fileutils_options
111
113
  end
112
114
 
113
115
  protected
@@ -119,10 +121,10 @@ module Releasy
119
121
 
120
122
  protected
121
123
  def install_binary_gems(destination)
122
- puts "Checking gems to see if any are binary" if project.verbose?
124
+ info "Checking gems to see if any are binary"
123
125
  binary_gems = []
124
126
  gemspecs.reject {|s| false }.each do |spec|
125
- puts "Checking gem #{spec.name} #{spec.version} to see if there is a Windows binary version" if project.verbose?
127
+ info "Checking gem #{spec.name} #{spec.version} to see if there is a Windows binary version"
126
128
  # Find out what versions are available and if the required version is available as a windows binary, download and install that.
127
129
  versions = %x[gem list "#{spec.name}" --remote --all --prerelease]
128
130
  if versions =~ /#{spec.name} \(([^\)]*)\)/m
@@ -132,7 +134,7 @@ module Releasy
132
134
  raise "Gem #{spec.name} is binary, but #{spec.version} does not have a published binary" if version_string =~ /mingw|mswin/ and not windows_platform
133
135
 
134
136
  if windows_platform
135
- puts "Installing Windows version of binary gem #{spec.name} #{spec.version}"
137
+ info "Installing Windows version of binary gem #{spec.name} #{spec.version}"
136
138
  # If we have a bundle file specified, then gem will _only_ install the version specified by it and not the one we request.
137
139
  bundle_gemfile = ENV['BUNDLE_GEMFILE']
138
140
  ENV['BUNDLE_GEMFILE'] = ''
@@ -1,9 +1,9 @@
1
1
  require 'cri'
2
- require "releasy/archivers/exe"
2
+ require "releasy/packagers/exe"
3
3
 
4
4
  command = 'install-sfx'
5
- sfx_file = Releasy::Archivers::Exe::SFX_NAME
6
- sfx_path = Releasy::Archivers::Exe::SFX_FILE
5
+ sfx_file = Releasy::Packagers::Exe::SFX_NAME
6
+ sfx_path = Releasy::Packagers::Exe::SFX_FILE
7
7
 
8
8
  Releasy::Cli.define_command do
9
9
  name command
@@ -0,0 +1,12 @@
1
+ require 'releasy/mixins/register'
2
+
3
+ module Releasy
4
+ # Contains all {Deployer} types.
5
+ module Deployers
6
+ extend Mixins::Register
7
+ end
8
+ end
9
+
10
+ %w[github].each do |deployer|
11
+ require "releasy/deployers/#{deployer}"
12
+ end
@@ -0,0 +1,28 @@
1
+ require "releasy/mixins/log"
2
+
3
+ module Releasy
4
+ module Deployers
5
+ # @abstract
6
+ class Deployer
7
+ include Rake::DSL
8
+ include Mixins::Log
9
+
10
+ attr_reader :project
11
+
12
+ def type; self.class::TYPE; end
13
+
14
+ def initialize(project)
15
+ @project = project
16
+ setup
17
+ end
18
+
19
+ protected
20
+ def generate_tasks(archive_task, folder, extension)
21
+ desc "#{type} <= #{archive_task.split(":")[0..-2].join(" ")} #{extension}"
22
+ task "deploy:#{archive_task}:#{type}" => "package:#{archive_task}" do
23
+ deploy(folder + extension)
24
+ end
25
+ end
26
+ end
27
+ end
28
+ end
@@ -0,0 +1,109 @@
1
+ require 'releasy/deployers/deployer'
2
+
3
+ module Releasy
4
+ module Deployers
5
+ # Deploys to a Github project's downloads page.
6
+ #
7
+ # @attr description [String] Description of file (defaults to: "#{project.description")
8
+ # @attr login [String] Github user name that has write access to {#repository} (defaults to: `git config github.user` or user name in `git config remote.origin.url`).
9
+ # @attr repository [String] Name of Github repository (defaults to: the repository name in `git config remote.origin.url` or _project.underscored_name_).
10
+ # @attr token [String] Github token associated with {#login} - a 32-digit hexadecimal string - DO NOT COMMIT A FILE CONTAINING YOUR GITHUB TOKEN (defaults to: `git config github.token`)
11
+ class Github < Deployer
12
+ TYPE = :github
13
+
14
+ Deployers.register self
15
+
16
+ def repository
17
+ @repository || project.underscored_name
18
+ end
19
+ def repository=(repository)
20
+ raise TypeError, "repository must be a String, but received #{repository.class}" unless repository.is_a? String
21
+ @repository = repository
22
+ end
23
+
24
+ attr_reader :user
25
+ def user=(user)
26
+ raise TypeError, "user must be a String, but received #{user.class}" unless user.is_a? String
27
+ @user = user
28
+ end
29
+
30
+ attr_reader :token
31
+ def token=(token)
32
+ raise TypeError, "token must be a String, but received #{token.class}" unless token.is_a? String
33
+ raise ArgumentError, "token invalid (expected 32-character hex string)" unless token =~ /^[0-9a-f]{32}$/i
34
+ @token = token
35
+ end
36
+
37
+ def description
38
+ @description || project.description
39
+ end
40
+ def description=(description)
41
+ raise TypeError, "description must be a String, but received #{description.class}" unless description.is_a? String
42
+ @description = description
43
+ end
44
+
45
+ # Force replacement of existing uploaded files.
46
+ def replace!
47
+ @force_replace = true
48
+ end
49
+
50
+ protected
51
+ def setup
52
+ @force_replace = false
53
+ @description = nil
54
+
55
+ # Get username from github.user, otherwise use the name taken from the git_url.
56
+ @user = from_config 'github.user'
57
+ @token = from_config 'github.token'
58
+
59
+ # Try to guess the repository name from git config.
60
+ git_url = from_config 'remote.origin.url'
61
+ if git_url and git_url =~ %r<^git@github.com:(.+)/([^/]+)\.git$>
62
+ @user ||= $1 # May have already been set from github.user
63
+ @repository = $2
64
+ else
65
+ @repository = nil
66
+ end
67
+ end
68
+
69
+ protected
70
+ # Get a value from git config.
71
+ #
72
+ # @param key [String] Name of setting in git config.
73
+ # @return [String, nil] Value of setting, else nil if it isn't defined.
74
+ def from_config(key)
75
+ `git config #{key}`.chomp rescue nil
76
+ end
77
+
78
+ protected
79
+ # @param file [String] Path to file to deploy.
80
+ # @return [String] A link to download the file.
81
+ # @raise SystemError If file fails to upload.
82
+ def deploy(file)
83
+ raise ConfigError, "#user must be set manually if it is not configured on the system" unless user
84
+ raise ConfigError, "#token must be set manually if it is not configured on the system" unless token
85
+
86
+ require 'net/github-upload' # Hold off requiring this unless needed, so it doesn't slow down creating tasks.
87
+
88
+ uploader = Net::GitHub::Upload.new(:login => user, :token => token)
89
+
90
+ heading "Deploying #{file} (#{(File.size(file).fdiv 1024).ceil}k) to Github"
91
+
92
+ t = Time.now
93
+
94
+ begin
95
+ uploader.upload(:repos => repository, :file => file, :description => description, :replace => @force_replace)
96
+ rescue => ex
97
+ # Probably failed to overwrite an existing file.
98
+ error "Error uploading file #{file}: #{ex.message}"
99
+ exit 1 # This is bad. Lets just die, die, die at this point.
100
+ end
101
+
102
+ link = "https://github.com/downloads/#{user}/#{repository}/#{File.basename(file)}"
103
+ heading %[Successfully uploaded to "#{link}" in #{(Time.now - t).ceil}s]
104
+
105
+ link
106
+ end
107
+ end
108
+ end
109
+ end
@@ -0,0 +1,22 @@
1
+ module Releasy
2
+ module Mixins
3
+ module CanExcludeEncoding
4
+ # Exclude unnecessary encoding files, only keeping those that sufficient for basic use of Ruby.
5
+ def exclude_encoding
6
+ @encoding_excluded = true
7
+ end
8
+
9
+ protected
10
+ # Has encoding been excluded from builds?
11
+ def encoding_excluded?
12
+ @encoding_excluded ||= false
13
+
14
+ if is_a? Project
15
+ @encoding_excluded
16
+ else
17
+ @encoding_excluded || project.send(:encoding_excluded?)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -4,9 +4,9 @@ module Releasy
4
4
  module Exec
5
5
  protected
6
6
  def exec(command)
7
- puts command if project.verbose?
7
+ info command
8
8
  result = %x[#{command}]
9
- puts result if project.verbose?
9
+ info result
10
10
  result
11
11
  end
12
12
  end
@@ -21,20 +21,20 @@ module Mixins
21
21
 
22
22
  protected
23
23
  def copy_gems(gems, destination)
24
- puts "Copying source gems from system" if project.verbose?
24
+ info "Copying source gems from system"
25
25
 
26
26
  gems_dir = "#{destination}/gems"
27
27
  specs_dir = "#{destination}/specifications"
28
- mkdir_p gems_dir
29
- mkdir_p specs_dir
28
+ mkdir_p gems_dir, fileutils_options
29
+ mkdir_p specs_dir, fileutils_options
30
30
 
31
31
  gems.each do |gem|
32
32
  spec = gemspecs.find {|g| g.name == gem }
33
33
  gem_dir = spec.full_gem_path
34
- puts "Copying gem: #{spec.name} #{spec.version}" if project.verbose?
35
- cp_r gem_dir, gems_dir
34
+ info "Copying gem: #{spec.name} #{spec.version}"
35
+ cp_r gem_dir, gems_dir, fileutils_options
36
36
  spec_file = File.expand_path("../../specifications/#{File.basename gem_dir}.gemspec", gem_dir)
37
- cp_r spec_file, specs_dir
37
+ cp_r spec_file, specs_dir, fileutils_options
38
38
  end
39
39
  end
40
40
  end