Skip to content

Commit

Permalink
Merge pull request #400 from freddi-kit/feature/retry-count-option
Browse files Browse the repository at this point in the history
Add --retry-download-count for retrying installing Xcode xip/dmg
  • Loading branch information
jpsim authored Sep 9, 2020
2 parents ac5be99 + e082ed5 commit 7521678
Show file tree
Hide file tree
Showing 3 changed files with 24 additions and 17 deletions.
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

0 comments on commit 7521678

Please sign in to comment.