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