Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 14 additions & 10 deletions lib/xcode/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -25,13 +25,15 @@ class Curl
# @param progress: parse and show the progress?
# @param progress_block: A block that's called whenever we have an updated progress %
# the parameter is a single number that's literally percent (e.g. 1, 50, 80 or 100)
# @param retry_download_count: A count to retry the downloading Xcode dmg/xip
# rubocop:disable Metrics/AbcSize
def fetch(url: nil,
directory: nil,
cookies: nil,
output: nil,
progress: nil,
progress_block: nil)
progress_block: nil,
retry_download_count: 3)
options = cookies.nil? ? [] : ['--cookie', cookies, '--cookie-jar', COOKIES_PATH]

uri = URI.parse(url)
Expand Down Expand Up @@ -78,7 +80,7 @@ def fetch(url: nil,
# "Partial file. Only a part of the file was transferred."
# https://curl.haxx.se/mail/archive-2008-07/0098.html
# https://github.com/KrauseFx/xcode-install/issues/210
3.times do
retry_download_count.times do
# Non-blocking call of Open3
# We're not using the block based syntax, as the bacon testing
# library doesn't seem to support writing tests for it
Expand Down Expand Up @@ -135,7 +137,7 @@ def current_symlink
File.symlink?(SYMLINK_PATH) ? SYMLINK_PATH : nil
end

def download(version, progress, url = nil, progress_block = nil)
def download(version, progress, url = nil, progress_block = nil, retry_download_count = 3)
xcode = find_xcode_version(version) if url.nil?
return if url.nil? && xcode.nil?

Expand All @@ -147,7 +149,8 @@ def download(version, progress, url = nil, progress_block = nil)
cookies: url ? nil : spaceship.cookie,
output: dmg_file,
progress: progress,
progress_block: progress_block
progress_block: progress_block,
retry_download_count: retry_download_count
)
result ? CACHE_DIR + dmg_file : nil
end
Expand Down Expand Up @@ -280,8 +283,8 @@ def install_dmg(dmg_path, suffix = '', switch = true, clean = true)
end

# rubocop:disable Metrics/ParameterLists
def install_version(version, switch = true, clean = true, install = true, progress = true, url = nil, show_release_notes = true, progress_block = nil)
dmg_path = get_dmg(version, progress, url, progress_block)
def install_version(version, switch = true, clean = true, install = true, progress = true, url = nil, show_release_notes = true, progress_block = nil, retry_download_count = 3)
dmg_path = get_dmg(version, progress, url, progress_block, retry_download_count)
fail Informative, "Failed to download Xcode #{version}." if dmg_path.nil?

if install
Expand Down Expand Up @@ -370,7 +373,7 @@ def enable_developer_mode
`sudo /usr/sbin/dseditgroup -o edit -t group -a staff _developer`
end

def get_dmg(version, progress = true, url = nil, progress_block = nil)
def get_dmg(version, progress = true, url = nil, progress_block = nil, retry_download_count = 3)
if url
path = Pathname.new(url)
return path if path.exist?
Expand All @@ -381,7 +384,7 @@ def get_dmg(version, progress = true, url = nil, progress_block = nil)
end
end

download(version, progress, url, progress_block)
download(version, progress, url, progress_block, retry_download_count)
end

def fetch_seedlist
Expand Down Expand Up @@ -512,12 +515,13 @@ def xcode
end
end

def download(progress, progress_block = nil)
def download(progress, progress_block = nil, retry_download_count = 3)
result = Curl.new.fetch(
url: source,
directory: CACHE_DIR,
progress: progress,
progress_block: progress_block
progress_block: progress_block,
retry_download_count: retry_download_count
)
result ? dmg_path : nil
end
Expand Down
7 changes: 5 additions & 2 deletions lib/xcode/install/install.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ def self.options
['--no-install', 'Only download DMG, but do not install it.'],
['--no-progress', 'Don’t show download progress.'],
['--no-clean', 'Don’t delete DMG after installation.'],
['--no-show-release-notes', 'Don’t open release notes in browser after installation.']].concat(super)
['--no-show-release-notes', 'Don’t open release notes in browser after installation.'],
['--retry-download-count', 'Count of retrying download when curl is failed.']].concat(super)
end

def initialize(argv)
Expand All @@ -31,6 +32,7 @@ def initialize(argv)
@should_switch = argv.flag?('switch', true)
@progress = argv.flag?('progress', true)
@show_release_notes = argv.flag?('show-release-notes', true)
@retry_download_count = argv.option('retry-download-count', '3')
super
end

Expand All @@ -44,11 +46,12 @@ def validate!
end
fail Informative, "Version #{@version} doesn't exist." unless @url || @installer.exist?(@version)
fail Informative, "Invalid URL: `#{@url}`" unless !@url || @url =~ /\A#{URI.regexp}\z/
fail Informative, "Invalid Retry: `#{@retry_download_count} is not positive number.`" if (@retry_download_count =~ /\A[0-9]*\z/).nil?
end

def run
@installer.install_version(@version, @should_switch, @should_clean, @should_install,
@progress, @url, @show_release_notes)
@progress, @url, @show_release_notes, nil, @retry_download_count.to_i)
end
end
end
Expand Down
10 changes: 5 additions & 5 deletions spec/install_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -12,32 +12,32 @@ module XcodeInstall
end

it 'downloads and installs' do
Installer.any_instance.expects(:download).with('6.3', true, nil, nil).returns('/some/path')
Installer.any_instance.expects(:download).with('6.3', true, nil, nil, 3).returns('/some/path')
Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', true, true)
Command::Install.run(['6.3'])
end

it 'downloads and installs with custom HTTP URL' do
url = 'http://yolo.com/xcode.dmg'
Installer.any_instance.expects(:download).with('6.3', true, url, nil).returns('/some/path')
Installer.any_instance.expects(:download).with('6.3', true, url, nil, 3).returns('/some/path')
Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', true, true)
Command::Install.run(['6.3', "--url=#{url}"])
end

it 'downloads and installs and does not switch if --no-switch given' do
Installer.any_instance.expects(:download).with('6.3', true, nil, nil).returns('/some/path')
Installer.any_instance.expects(:download).with('6.3', true, nil, nil, 3).returns('/some/path')
Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', false, true)
Command::Install.run(['6.3', '--no-switch'])
end

it 'downloads without progress if switch --no-progress is given' do
Installer.any_instance.expects(:download).with('6.3', false, nil, nil).returns('/some/path')
Installer.any_instance.expects(:download).with('6.3', false, nil, nil, 3).returns('/some/path')
Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', true, true)
Command::Install.run(['6.3', '--no-progress'])
end

it 'reads .xcode-version' do
Installer.any_instance.expects(:download).with('6.3', true, nil, nil).returns('/some/path')
Installer.any_instance.expects(:download).with('6.3', true, nil, nil, 3).returns('/some/path')
Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', true, true)
File.expects(:exist?).with('.xcode-version').returns(true)
File.expects(:read).returns('6.3')
Expand Down