releasy 0.2.0 → 0.2.2
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.
- data/.yardopts +3 -1
- data/CHANGELOG.md +9 -0
- data/README.md +114 -41
- data/Rakefile +1 -1
- data/bin/7z_sfx_LICENSE.txt +56 -0
- data/bin/7za.exe +0 -0
- data/bin/7za_exe_LICENSE.txt +29 -0
- data/lib/releasy.rb +4 -1
- data/lib/releasy/builders/builder.rb +14 -6
- data/lib/releasy/builders/ocra_builder.rb +4 -2
- data/lib/releasy/builders/osx_app.rb +18 -6
- data/lib/releasy/builders/source.rb +9 -2
- data/lib/releasy/builders/windows_folder.rb +12 -3
- data/lib/releasy/builders/windows_installer.rb +2 -3
- data/lib/releasy/builders/windows_standalone.rb +13 -3
- data/lib/releasy/builders/windows_wrapped.rb +14 -4
- data/lib/releasy/cli/install_sfx.rb +1 -1
- data/lib/releasy/deployers.rb +1 -1
- data/lib/releasy/deployers/deployer.rb +22 -1
- data/lib/releasy/deployers/github.rb +31 -124
- data/lib/releasy/deployers/local.rb +55 -0
- data/lib/releasy/deployers/rsync.rb +59 -0
- data/lib/releasy/mixins/has_packagers.rb +1 -1
- data/lib/releasy/mixins/utilities.rb +34 -0
- data/lib/releasy/packagers/dmg.rb +17 -0
- data/lib/releasy/packagers/exe.rb +18 -1
- data/lib/releasy/packagers/packager.rb +22 -6
- data/lib/releasy/packagers/seven_zip.rb +17 -0
- data/lib/releasy/packagers/tar_bzip2.rb +19 -0
- data/lib/releasy/packagers/tar_gzip.rb +19 -0
- data/lib/releasy/packagers/tar_packager.rb +2 -1
- data/lib/releasy/packagers/zip.rb +17 -0
- data/lib/releasy/project.rb +45 -4
- data/lib/releasy/version.rb +1 -1
- data/releasy.gemspec +1 -1
- data/test/releasy/builders/data/Main.rb +3 -2
- data/test/releasy/builders/helpers/builder_helper.rb +35 -0
- data/test/releasy/builders/helpers/ocra_builder_helper.rb +31 -0
- data/test/releasy/builders/helpers/windows_builder_helper.rb +25 -0
- data/test/releasy/builders/osx_app_test.rb +6 -4
- data/test/releasy/builders/source_test.rb +7 -4
- data/test/releasy/builders/windows_folder_test.rb +3 -1
- data/test/releasy/builders/windows_installer_test.rb +6 -4
- data/test/releasy/builders/windows_standalone_test.rb +6 -4
- data/test/releasy/builders/windows_wrapped_test.rb +3 -1
- data/test/releasy/cli/install_sfx_test.rb +1 -1
- data/test/releasy/deployers/github_test.rb +30 -32
- data/test/releasy/deployers/local_test.rb +93 -0
- data/test/releasy/deployers/rsync_test.rb +55 -0
- data/test/releasy/integration/source_test.rb +6 -6
- data/test/releasy/mixins/utilities_test.rb +50 -0
- data/test/releasy/packagers/packager_test.rb +79 -0
- data/test/releasy/packagers_test.rb +12 -6
- data/test/releasy/project_test.rb +5 -5
- data/test/teststrap.rb +6 -0
- data/test/yard_test.rb +1 -1
- metadata +40 -28
- data/lib/releasy/mixins/exec.rb +0 -14
- data/test/releasy/builders/ocra_builder_test.rb +0 -37
- data/test/releasy/builders/windows_builder_test.rb +0 -26
@@ -6,6 +6,18 @@ module Releasy
|
|
6
6
|
module Builders
|
7
7
|
# Builds an OS X application bundle.
|
8
8
|
#
|
9
|
+
# @example
|
10
|
+
# Releasy::Project.new do
|
11
|
+
# name "My App"
|
12
|
+
# add_build :osx_app do
|
13
|
+
# wrapper "gosu-mac-wrapper-0.7.41.tar.gz" # Required, see {#wrapper=}.
|
14
|
+
# url "com.cheese.myapp" # Required
|
15
|
+
# icon "media/icon.icns" # Optional
|
16
|
+
# exclude_encoding # Optional
|
17
|
+
# add_package :dmg # Optional
|
18
|
+
# end
|
19
|
+
# end
|
20
|
+
#
|
9
21
|
# @attr icon [String] Optional filename of icon to show on executable/installer (.icns).
|
10
22
|
class OsxApp < Builder
|
11
23
|
include Mixins::HasGemspecs
|
@@ -49,13 +61,12 @@ module Releasy
|
|
49
61
|
raise ConfigError, "#wrapper not set" unless wrapper
|
50
62
|
raise ConfigError, "#wrapper not valid wrapper: #{wrapper}" unless File.basename(wrapper) =~ VALID_GOSU_WRAPPER
|
51
63
|
|
52
|
-
directory folder
|
53
|
-
|
54
64
|
desc "Build OS X app"
|
55
65
|
task "build:osx:app" => folder
|
56
66
|
|
57
67
|
file folder => project.files + [wrapper] do
|
58
|
-
|
68
|
+
mkdir_p folder, fileutils_options
|
69
|
+
build
|
59
70
|
end
|
60
71
|
end
|
61
72
|
|
@@ -66,7 +77,7 @@ module Releasy
|
|
66
77
|
new_app = File.join folder, app_name
|
67
78
|
|
68
79
|
# Copy the app files.
|
69
|
-
|
80
|
+
execute_command %[7z x -so -bd "#{wrapper}" 2>#{null_file} | 7z x -si -mmt -bd -ttar -o"#{folder}"]
|
70
81
|
mv File.join(folder, "RubyGosu App.app"), new_app, fileutils_options
|
71
82
|
|
72
83
|
## Copy my source files.
|
@@ -156,10 +167,11 @@ OSX_EXECUTABLE_FOLDER = File.expand_path("../../..", __FILE__)
|
|
156
167
|
|
157
168
|
# Really hacky fudge-fix for something oddly missing in the .app.
|
158
169
|
class Encoding
|
159
|
-
UTF_7 = UTF_16BE = UTF_16LE = UTF_32BE = UTF_32LE = Encoding.list.first
|
170
|
+
BINARY = UTF_7 = UTF_16BE = UTF_16LE = UTF_32BE = UTF_32LE = Encoding.list.first
|
160
171
|
end
|
161
172
|
|
162
|
-
|
173
|
+
Dir.chdir 'application'
|
174
|
+
load '#{project.executable}'
|
163
175
|
END_TEXT
|
164
176
|
end
|
165
177
|
end
|
@@ -3,6 +3,14 @@ require "releasy/builders/builder"
|
|
3
3
|
module Releasy
|
4
4
|
module Builders
|
5
5
|
# Creates a folder containing the application source.
|
6
|
+
#
|
7
|
+
# @example
|
8
|
+
# Releasy::Project.new do
|
9
|
+
# name "My App"
|
10
|
+
# add_build :source do
|
11
|
+
# add_package :zip # Optional.
|
12
|
+
# end
|
13
|
+
# end
|
6
14
|
class Source < Builder
|
7
15
|
TYPE = :source
|
8
16
|
Builders.register self
|
@@ -14,9 +22,8 @@ module Releasy
|
|
14
22
|
desc "Build source"
|
15
23
|
task "build:source" => folder
|
16
24
|
|
17
|
-
directory folder
|
18
|
-
|
19
25
|
file folder => project.files do
|
26
|
+
mkdir_p folder, fileutils_options
|
20
27
|
copy_files_relative project.files, folder
|
21
28
|
end
|
22
29
|
end
|
@@ -4,6 +4,16 @@ require 'releasy/windows_wrapper_maker'
|
|
4
4
|
module Releasy
|
5
5
|
module Builders
|
6
6
|
# Builds a folder containing Ruby + your source + a small Windows executable to run your executable script.
|
7
|
+
#
|
8
|
+
# @example
|
9
|
+
# Releasy::Project.new do
|
10
|
+
# name "My App"
|
11
|
+
# add_build :windows_folder do
|
12
|
+
# icon "media/icon.ico" # Optional
|
13
|
+
# exclude_encoding # Optional
|
14
|
+
# add_package :zip # Optional
|
15
|
+
# end
|
16
|
+
# end
|
7
17
|
class WindowsFolder < OcraBuilder
|
8
18
|
TYPE = :windows_folder
|
9
19
|
DEFAULT_FOLDER_SUFFIX = "WIN32"
|
@@ -13,12 +23,11 @@ module Releasy
|
|
13
23
|
protected
|
14
24
|
# FOLDER containing EXE, Ruby + source.
|
15
25
|
def generate_tasks
|
16
|
-
directory project.output_path
|
17
|
-
|
18
26
|
file folder => project.files do
|
27
|
+
mkdir_p project.output_path, fileutils_options
|
19
28
|
tmp_ocra_executable = "#{folder}.exe"
|
20
29
|
|
21
|
-
|
30
|
+
execute_command %[#{ocra_command} --output "#{tmp_ocra_executable}" --debug-extract]
|
22
31
|
|
23
32
|
# Extract the files from the executable.
|
24
33
|
system tmp_ocra_executable
|
@@ -21,9 +21,8 @@ module Releasy
|
|
21
21
|
protected
|
22
22
|
# Regular windows installer, but some users consider them evil.
|
23
23
|
def generate_tasks
|
24
|
-
directory folder
|
25
|
-
|
26
24
|
file folder => project.files do
|
25
|
+
mkdir_p folder, fileutils_options
|
27
26
|
create_link_files folder
|
28
27
|
project.exposed_files.each {|file| cp file, folder, fileutils_options }
|
29
28
|
|
@@ -51,7 +50,7 @@ module Releasy
|
|
51
50
|
protected
|
52
51
|
def create_installer(file, options = {})
|
53
52
|
generate_installer_script file, options
|
54
|
-
|
53
|
+
execute_command %[#{ocra_command} --chdir-first --no-lzma --innosetup "#{temp_installer_script}"]
|
55
54
|
end
|
56
55
|
|
57
56
|
# Generate innosetup script to build installer.
|
@@ -5,6 +5,16 @@ module Releasy
|
|
5
5
|
# Creates a completely standalone Windows executable.
|
6
6
|
#
|
7
7
|
# @note Startup of the executable created by this build takes a couple of seconds longer than running from the other windows builds, as the files are extracted into a temporary directory each time it is run. It is recommended to build with _:windows_folder_ or _:windows_installer_ instead of this, unless you really need to distribute the application as a single file.
|
8
|
+
#
|
9
|
+
# @example
|
10
|
+
# Releasy::Project.new do
|
11
|
+
# name "My App"
|
12
|
+
# add_build :windows_standalone do
|
13
|
+
# icon "media/icon.ico" # Optional
|
14
|
+
# exclude_encoding # Optional
|
15
|
+
# add_package :zip # Optional
|
16
|
+
# end
|
17
|
+
# end
|
8
18
|
class WindowsStandalone < OcraBuilder
|
9
19
|
TYPE = :windows_standalone
|
10
20
|
DEFAULT_FOLDER_SUFFIX = "WIN32_EXE"
|
@@ -14,14 +24,14 @@ module Releasy
|
|
14
24
|
protected
|
15
25
|
# Self-extracting standalone executable.
|
16
26
|
def generate_tasks
|
17
|
-
directory folder
|
18
|
-
|
19
27
|
file folder => project.files do
|
28
|
+
mkdir_p folder, fileutils_options
|
29
|
+
|
20
30
|
project.exposed_files.each {|file| cp file, folder, fileutils_options }
|
21
31
|
|
22
32
|
create_link_files folder
|
23
33
|
|
24
|
-
|
34
|
+
execute_command %[#{ocra_command} --output "#{folder}/#{executable_name}"]
|
25
35
|
end
|
26
36
|
|
27
37
|
desc "Build standalone exe #{project.version} [Ocra]"
|
@@ -11,6 +11,17 @@ 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
|
+
#
|
15
|
+
# @example
|
16
|
+
# Releasy::Project.new do
|
17
|
+
# name "My App"
|
18
|
+
# add_build :windows_wrapped do
|
19
|
+
# wrapper "ruby-1.9.3-p0-i386-mingw32.7z" # Required
|
20
|
+
# exclude_encoding # Optional
|
21
|
+
# exclude_tcl_tk # Optional
|
22
|
+
# add_package :zip # Optional
|
23
|
+
# end
|
24
|
+
# end
|
14
25
|
class WindowsWrapped < WindowsBuilder
|
15
26
|
include Mixins::HasGemspecs
|
16
27
|
|
@@ -48,9 +59,8 @@ module Releasy
|
|
48
59
|
raise ConfigError, "#wrapper not set" unless wrapper
|
49
60
|
raise ConfigError, "#wrapper not valid wrapper: #{wrapper}" unless File.basename(wrapper) =~ VALID_RUBY_DIST
|
50
61
|
|
51
|
-
directory project.output_path
|
52
|
-
|
53
62
|
file folder => project.files + [wrapper] do
|
63
|
+
mkdir_p project.output_path, fileutils_options
|
54
64
|
build
|
55
65
|
end
|
56
66
|
|
@@ -104,7 +114,7 @@ module Releasy
|
|
104
114
|
protected
|
105
115
|
def copy_ruby_distribution
|
106
116
|
archive_name = File.basename(wrapper).chomp(File.extname(wrapper))
|
107
|
-
|
117
|
+
execute_command %[7z x "#{wrapper}" -o"#{File.dirname folder}"]
|
108
118
|
mv File.join(File.dirname(folder), archive_name), folder, fileutils_options
|
109
119
|
rm_r File.join(folder, "share"), fileutils_options
|
110
120
|
rm_r File.join(folder, "include"), fileutils_options if File.exists? File.join(folder, "include")
|
@@ -138,7 +148,7 @@ module Releasy
|
|
138
148
|
# If we have a bundle file specified, then gem will _only_ install the version specified by it and not the one we request.
|
139
149
|
bundle_gemfile = ENV['BUNDLE_GEMFILE']
|
140
150
|
ENV['BUNDLE_GEMFILE'] = ''
|
141
|
-
|
151
|
+
execute_command %[gem install "#{spec.name}" --remote --no-rdoc --no-ri --force --ignore-dependencies --platform "#{windows_platform}" --version "#{spec.version}" --install-dir "#{destination}"]
|
142
152
|
ENV['BUNDLE_GEMFILE'] = bundle_gemfile
|
143
153
|
binary_gems << spec.name
|
144
154
|
end
|
@@ -53,7 +53,7 @@ Releasy::Cli.define_command do
|
|
53
53
|
if ENV["USER"] != "root"
|
54
54
|
command = %[sudo cp "#{sfx_path}" "#{assets_location}"]
|
55
55
|
puts "Copy failed, trying again as super-user:\n#{command}"
|
56
|
-
|
56
|
+
system command
|
57
57
|
if File.exists? destination_file
|
58
58
|
puts "#{sfx_file} copied to #{assets_location}"
|
59
59
|
else
|
data/lib/releasy/deployers.rb
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
require "releasy/mixins/log"
|
2
2
|
|
3
|
+
|
3
4
|
module Releasy
|
4
5
|
module Deployers
|
5
6
|
# @abstract
|
@@ -7,6 +8,9 @@ module Releasy
|
|
7
8
|
include Rake::DSL
|
8
9
|
include Mixins::Log
|
9
10
|
|
11
|
+
# Printed out while file is being transferred.
|
12
|
+
WORKING_CHARACTER = "."
|
13
|
+
|
10
14
|
attr_reader :project
|
11
15
|
|
12
16
|
def type; self.class::TYPE; end
|
@@ -20,9 +24,26 @@ module Releasy
|
|
20
24
|
def generate_tasks(archive_task, folder, extension)
|
21
25
|
desc "#{type} <= #{archive_task.split(":")[0..-2].join(" ")} #{extension}"
|
22
26
|
task "deploy:#{archive_task}:#{type}" => "package:#{archive_task}" do
|
23
|
-
|
27
|
+
do_deploy(folder + extension)
|
24
28
|
end
|
25
29
|
end
|
30
|
+
|
31
|
+
protected
|
32
|
+
def do_deploy(file)
|
33
|
+
heading "Deploying #{file} (#{(File.size(file).fdiv 1024).ceil}k) to #{self.class.name[/[^:]+$/]}"
|
34
|
+
|
35
|
+
t = Time.now
|
36
|
+
|
37
|
+
deploy file
|
38
|
+
|
39
|
+
minutes, seconds = (Time.now - t).ceil.divmod 60
|
40
|
+
hours, minutes = minutes.divmod 60
|
41
|
+
duration = "%d:%02d:%02d" % [hours, minutes, seconds]
|
42
|
+
|
43
|
+
heading "Successfully deployed file in #{duration}"
|
44
|
+
|
45
|
+
nil
|
46
|
+
end
|
26
47
|
end
|
27
48
|
end
|
28
49
|
end
|
@@ -4,131 +4,45 @@ module Releasy
|
|
4
4
|
module Deployers
|
5
5
|
# Deploys to a Github project's downloads page.
|
6
6
|
#
|
7
|
-
# @
|
8
|
-
#
|
9
|
-
#
|
10
|
-
#
|
7
|
+
# @example
|
8
|
+
# Releasy::Project.new do
|
9
|
+
# name "My App"
|
10
|
+
# add_build :source
|
11
|
+
# add_package :zip
|
12
|
+
# add_deploy :github # Should be enough if git is configured correctly.
|
13
|
+
# end
|
14
|
+
#
|
15
|
+
# @attr description [String] (project.description) Description of file.
|
16
|
+
# @attr user [String] (`git config github.user` or user name in `git config remote.origin.url`) Github user name that has write access to {#repository}
|
17
|
+
# @attr repository [String] (repository name in `git config remote.origin.url` or _project.underscored_name_) Name of Github repository.
|
18
|
+
# @attr token [String] (`git config github.token`) Github token associated with {#user} - a 32-digit hexadecimal string - DO NOT COMMIT A FILE CONTAINING YOUR GITHUB TOKEN!
|
11
19
|
class Github < Deployer
|
12
|
-
# Patch to add an asynchronous version of upload, that also yields every second and takes into account timeout.
|
13
|
-
module UploaderUploadAsync
|
14
|
-
def upload_async(info)
|
15
|
-
unless info[:repos]
|
16
|
-
raise "required repository name"
|
17
|
-
end
|
18
|
-
info[:repos] = @login + '/' + info[:repos] unless info[:repos].include? '/'
|
19
|
-
|
20
|
-
if info[:file]
|
21
|
-
file = info[:file]
|
22
|
-
unless File.exist?(file) && File.readable?(file)
|
23
|
-
raise "file does not exsits or readable"
|
24
|
-
end
|
25
|
-
info[:name] ||= File.basename(file)
|
26
|
-
end
|
27
|
-
unless info[:file] || info[:data]
|
28
|
-
raise "required file or data parameter to upload"
|
29
|
-
end
|
30
|
-
|
31
|
-
unless info[:name]
|
32
|
-
raise "required name parameter for filename with data parameter"
|
33
|
-
end
|
34
|
-
|
35
|
-
if info[:replace]
|
36
|
-
list_files(info[:repos]).each { |obj|
|
37
|
-
next unless obj[:name] == info[:name]
|
38
|
-
delete info[:repos], obj[:id]
|
39
|
-
}
|
40
|
-
elsif list_files(info[:repos]).any?{|obj| obj[:name] == info[:name]}
|
41
|
-
raise "file '#{info[:name]}' is already uploaded. please try different name"
|
42
|
-
end
|
43
|
-
|
44
|
-
info[:content_type] ||= 'application/octet-stream'
|
45
|
-
stat = HTTPClient.post("https://github.com/#{info[:repos]}/downloads", {
|
46
|
-
"file_size" => info[:file] ? File.stat(info[:file]).size : info[:data].size,
|
47
|
-
"content_type" => info[:content_type],
|
48
|
-
"file_name" => info[:name],
|
49
|
-
"description" => info[:description] || '',
|
50
|
-
"login" => @login,
|
51
|
-
"token" => @token
|
52
|
-
})
|
53
|
-
|
54
|
-
unless stat.code == 200
|
55
|
-
raise "Failed to post file info"
|
56
|
-
end
|
57
|
-
|
58
|
-
upload_info = JSON.parse(stat.content)
|
59
|
-
if info[:file]
|
60
|
-
f = File.open(info[:file], 'rb')
|
61
|
-
else
|
62
|
-
f = Tempfile.open('net-github-upload')
|
63
|
-
f << info[:data]
|
64
|
-
f.flush
|
65
|
-
end
|
66
|
-
|
67
|
-
client = HTTPClient.new
|
68
|
-
client.send_timeout = info[:upload_timeout] if info[:upload_timeout]
|
69
|
-
|
70
|
-
res = begin
|
71
|
-
connection = client.post_async("http://github.s3.amazonaws.com/", [
|
72
|
-
['Filename', info[:name]],
|
73
|
-
['policy', upload_info['policy']],
|
74
|
-
['success_action_status', 201],
|
75
|
-
['key', upload_info['path']],
|
76
|
-
['AWSAccessKeyId', upload_info['accesskeyid']],
|
77
|
-
['Content-Type', upload_info['content_type'] || 'application/octet-stream'],
|
78
|
-
['signature', upload_info['signature']],
|
79
|
-
['acl', upload_info['acl']],
|
80
|
-
['file', f]
|
81
|
-
])
|
82
|
-
|
83
|
-
until connection.finished?
|
84
|
-
yield if block_given?
|
85
|
-
sleep info[:yield_interval] || 1
|
86
|
-
end
|
87
|
-
|
88
|
-
connection.pop
|
89
|
-
ensure
|
90
|
-
f.close
|
91
|
-
end
|
92
|
-
|
93
|
-
if res.status == 201
|
94
|
-
return FasterXmlSimple.xml_in(res.body.read)['PostResponse']['Location']
|
95
|
-
else
|
96
|
-
raise 'Failed to upload' + extract_error_message(res.body)
|
97
|
-
end
|
98
|
-
end
|
99
|
-
end
|
100
|
-
|
101
|
-
|
102
20
|
TYPE = :github
|
103
21
|
# Maximum time to allow an upload to continue. An hour to upload a file isn't unreasonable. Better than the default 2 minutes, which uploads about 4MB for me.
|
104
22
|
UPLOAD_TIMEOUT = 60 * 60
|
105
23
|
|
106
24
|
Deployers.register self
|
107
25
|
|
108
|
-
def repository
|
109
|
-
@repository || project.underscored_name
|
110
|
-
end
|
26
|
+
def repository; @repository || project.underscored_name; end
|
111
27
|
def repository=(repository)
|
112
28
|
raise TypeError, "repository must be a String, but received #{repository.class}" unless repository.is_a? String
|
113
29
|
@repository = repository
|
114
30
|
end
|
115
31
|
|
116
|
-
|
32
|
+
def user; @user; end
|
117
33
|
def user=(user)
|
118
34
|
raise TypeError, "user must be a String, but received #{user.class}" unless user.is_a? String
|
119
35
|
@user = user
|
120
36
|
end
|
121
37
|
|
122
|
-
|
38
|
+
def token; @token; end
|
123
39
|
def token=(token)
|
124
40
|
raise TypeError, "token must be a String, but received #{token.class}" unless token.is_a? String
|
125
41
|
raise ArgumentError, "token invalid (expected 32-character hex string)" unless token =~ /^[0-9a-f]{32}$/i
|
126
42
|
@token = token
|
127
43
|
end
|
128
44
|
|
129
|
-
def description
|
130
|
-
@description || project.description
|
131
|
-
end
|
45
|
+
def description; @description || project.description; end
|
132
46
|
def description=(description)
|
133
47
|
raise TypeError, "description must be a String, but received #{description.class}" unless description.is_a? String
|
134
48
|
@description = description
|
@@ -164,44 +78,37 @@ module Releasy
|
|
164
78
|
# @param key [String] Name of setting in git config.
|
165
79
|
# @return [String, nil] Value of setting, else nil if it isn't defined.
|
166
80
|
def from_config(key)
|
167
|
-
|
81
|
+
Kernel.`("git config #{key}").chomp rescue nil
|
168
82
|
end
|
169
83
|
|
170
84
|
protected
|
171
85
|
# @param file [String] Path to file to deploy.
|
172
|
-
# @return [
|
173
|
-
# @raise SystemError If file fails to upload.
|
86
|
+
# @return [nil]
|
174
87
|
def deploy(file)
|
175
88
|
raise ConfigError, "#user must be set manually if it is not configured on the system" unless user
|
176
89
|
raise ConfigError, "#token must be set manually if it is not configured on the system" unless token
|
177
90
|
|
91
|
+
info %[Uploading to: https://github.com/downloads/#{user}/#{repository}/#{File.basename(file)}]
|
92
|
+
|
178
93
|
# Hold off requiring this unless needed, so it doesn't slow down creating tasks.
|
179
|
-
|
180
|
-
Net::GitHub::Upload.send :include, UploaderUploadAsync
|
181
|
-
end
|
94
|
+
require 'net/github-upload'
|
182
95
|
|
183
96
|
uploader = Net::GitHub::Upload.new(:login => user, :token => token)
|
184
97
|
|
185
|
-
heading "Deploying #{file} (#{(File.size(file).fdiv 1024).ceil}k) to Github"
|
186
|
-
|
187
|
-
t = Time.now
|
188
|
-
|
189
98
|
begin
|
190
|
-
uploader.
|
191
|
-
print
|
99
|
+
uploader.upload :repos => repository, :file => file, :description => description, :replace => @force_replace, :upload_timeout => UPLOAD_TIMEOUT do
|
100
|
+
print WORKING_CHARACTER unless log_level == :silent
|
101
|
+
end
|
102
|
+
info WORKING_CHARACTER
|
103
|
+
rescue RuntimeError => ex
|
104
|
+
if ex.message =~ /file .* is already uploaded/i
|
105
|
+
warn "Skipping '#{File.basename file}' as it is already uploaded. Use #replace! to force uploading"
|
106
|
+
else
|
107
|
+
raise ex
|
192
108
|
end
|
193
|
-
puts '.'
|
194
|
-
rescue => ex
|
195
|
-
# Probably failed to overwrite an existing file.
|
196
|
-
error "Error uploading file #{file}: #{ex.message}"
|
197
|
-
exit 1 # This is bad. Lets just die, die, die at this point.
|
198
109
|
end
|
199
110
|
|
200
|
-
|
201
|
-
time = "%d:%02d" % (Time.now - t).ceil.divmod(60)
|
202
|
-
heading %[Successfully uploaded to "#{link}" in #{time}]
|
203
|
-
|
204
|
-
link
|
111
|
+
nil
|
205
112
|
end
|
206
113
|
end
|
207
114
|
end
|