Skip to content

Commit 7521678

Browse files
authored
Merge pull request #400 from freddi-kit/feature/retry-count-option
Add --retry-download-count for retrying installing Xcode xip/dmg
2 parents ac5be99 + e082ed5 commit 7521678

3 files changed

Lines changed: 24 additions & 17 deletions

File tree

lib/xcode/install.rb

Lines changed: 14 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,15 @@ class Curl
2525
# @param progress: parse and show the progress?
2626
# @param progress_block: A block that's called whenever we have an updated progress %
2727
# the parameter is a single number that's literally percent (e.g. 1, 50, 80 or 100)
28+
# @param retry_download_count: A count to retry the downloading Xcode dmg/xip
2829
# rubocop:disable Metrics/AbcSize
2930
def fetch(url: nil,
3031
directory: nil,
3132
cookies: nil,
3233
output: nil,
3334
progress: nil,
34-
progress_block: nil)
35+
progress_block: nil,
36+
retry_download_count: 3)
3537
options = cookies.nil? ? [] : ['--cookie', cookies, '--cookie-jar', COOKIES_PATH]
3638

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

138-
def download(version, progress, url = nil, progress_block = nil)
140+
def download(version, progress, url = nil, progress_block = nil, retry_download_count = 3)
139141
xcode = find_xcode_version(version) if url.nil?
140142
return if url.nil? && xcode.nil?
141143

@@ -147,7 +149,8 @@ def download(version, progress, url = nil, progress_block = nil)
147149
cookies: url ? nil : spaceship.cookie,
148150
output: dmg_file,
149151
progress: progress,
150-
progress_block: progress_block
152+
progress_block: progress_block,
153+
retry_download_count: retry_download_count
151154
)
152155
result ? CACHE_DIR + dmg_file : nil
153156
end
@@ -280,8 +283,8 @@ def install_dmg(dmg_path, suffix = '', switch = true, clean = true)
280283
end
281284

282285
# rubocop:disable Metrics/ParameterLists
283-
def install_version(version, switch = true, clean = true, install = true, progress = true, url = nil, show_release_notes = true, progress_block = nil)
284-
dmg_path = get_dmg(version, progress, url, progress_block)
286+
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)
287+
dmg_path = get_dmg(version, progress, url, progress_block, retry_download_count)
285288
fail Informative, "Failed to download Xcode #{version}." if dmg_path.nil?
286289

287290
if install
@@ -370,7 +373,7 @@ def enable_developer_mode
370373
`sudo /usr/sbin/dseditgroup -o edit -t group -a staff _developer`
371374
end
372375

373-
def get_dmg(version, progress = true, url = nil, progress_block = nil)
376+
def get_dmg(version, progress = true, url = nil, progress_block = nil, retry_download_count = 3)
374377
if url
375378
path = Pathname.new(url)
376379
return path if path.exist?
@@ -381,7 +384,7 @@ def get_dmg(version, progress = true, url = nil, progress_block = nil)
381384
end
382385
end
383386

384-
download(version, progress, url, progress_block)
387+
download(version, progress, url, progress_block, retry_download_count)
385388
end
386389

387390
def fetch_seedlist
@@ -512,12 +515,13 @@ def xcode
512515
end
513516
end
514517

515-
def download(progress, progress_block = nil)
518+
def download(progress, progress_block = nil, retry_download_count = 3)
516519
result = Curl.new.fetch(
517520
url: source,
518521
directory: CACHE_DIR,
519522
progress: progress,
520-
progress_block: progress_block
523+
progress_block: progress_block,
524+
retry_download_count: retry_download_count
521525
)
522526
result ? dmg_path : nil
523527
end

lib/xcode/install/install.rb

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,8 @@ def self.options
1717
['--no-install', 'Only download DMG, but do not install it.'],
1818
['--no-progress', 'Don’t show download progress.'],
1919
['--no-clean', 'Don’t delete DMG after installation.'],
20-
['--no-show-release-notes', 'Don’t open release notes in browser after installation.']].concat(super)
20+
['--no-show-release-notes', 'Don’t open release notes in browser after installation.'],
21+
['--retry-download-count', 'Count of retrying download when curl is failed.']].concat(super)
2122
end
2223

2324
def initialize(argv)
@@ -31,6 +32,7 @@ def initialize(argv)
3132
@should_switch = argv.flag?('switch', true)
3233
@progress = argv.flag?('progress', true)
3334
@show_release_notes = argv.flag?('show-release-notes', true)
35+
@retry_download_count = argv.option('retry-download-count', '3')
3436
super
3537
end
3638

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

4952
def run
5053
@installer.install_version(@version, @should_switch, @should_clean, @should_install,
51-
@progress, @url, @show_release_notes)
54+
@progress, @url, @show_release_notes, nil, @retry_download_count.to_i)
5255
end
5356
end
5457
end

spec/install_spec.rb

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,32 +12,32 @@ module XcodeInstall
1212
end
1313

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

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

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

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

3939
it 'reads .xcode-version' do
40-
Installer.any_instance.expects(:download).with('6.3', true, nil, nil).returns('/some/path')
40+
Installer.any_instance.expects(:download).with('6.3', true, nil, nil, 3).returns('/some/path')
4141
Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', true, true)
4242
File.expects(:exist?).with('.xcode-version').returns(true)
4343
File.expects(:read).returns('6.3')

0 commit comments

Comments
 (0)