xcode-install 2.6.4 → 2.7.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.github/workflows/ci.yml +42 -0
- data/.gitignore +1 -0
- data/README.md +13 -3
- data/XCODE_VERSION.md +49 -0
- data/lib/xcode/install.rb +104 -51
- data/lib/xcode/install/install.rb +6 -3
- data/lib/xcode/install/version.rb +1 -1
- data/spec/fixtures/xcode.json +30 -1
- data/spec/fixtures/xcode_63.json +28 -44
- data/spec/fixtures/yolo.json +1 -1
- data/spec/install_spec.rb +5 -5
- data/spec/installer_spec.rb +109 -104
- data/spec/json_spec.rb +14 -4
- data/spec/list_spec.rb +32 -3
- data/xcode-install.gemspec +2 -2
- metadata +19 -13
- data/.circleci/config.yml +0 -33
- data/.github/workflows/e2e.yml +0 -47
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: f5f95c1ec6494fb1482c6862a786fd3f149327096468dbfd01886d6a320ab31f
|
4
|
+
data.tar.gz: ef0e89795d7a5169a97adb29467025693644db1a8805e1ae395cd76066ae2569
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 4fa023f63479190d92da8f7a54d9ac0a9556eab534e4e4ea4a784f6bbd10837678910570dd9665d409214d52e47432ebafa99aaae0a9022097bde4540d42390f
|
7
|
+
data.tar.gz: 73c28ae14d7081a62376ce4611cae869987b8e2681325770b20d8d5f3be153abc02c7c0e3b94828c703ab786dd5960a62c6f3b097b162b82be39cf197e031d99
|
@@ -0,0 +1,42 @@
|
|
1
|
+
name: "CI"
|
2
|
+
on: [push, pull_request]
|
3
|
+
|
4
|
+
jobs:
|
5
|
+
build:
|
6
|
+
strategy:
|
7
|
+
fail-fast: false
|
8
|
+
matrix:
|
9
|
+
ruby: ["2.5", "2.6", "2.7"]
|
10
|
+
|
11
|
+
runs-on: macos-latest
|
12
|
+
steps:
|
13
|
+
# Setup env
|
14
|
+
- uses: actions/checkout@v2
|
15
|
+
- uses: actions/setup-ruby@v1
|
16
|
+
with:
|
17
|
+
ruby-version: "${{ matrix.ruby }}"
|
18
|
+
|
19
|
+
# Show env
|
20
|
+
- name: Show macOS version
|
21
|
+
run: sw_vers
|
22
|
+
- name: Show env versions
|
23
|
+
run: |
|
24
|
+
ruby --version
|
25
|
+
bundler --version
|
26
|
+
echo $HOME
|
27
|
+
|
28
|
+
# Prepare
|
29
|
+
- name: Install bundler 2.2.14
|
30
|
+
run: gem install bundler -v "~> 2.2.14"
|
31
|
+
- name: Install ruby dependencies
|
32
|
+
run: |
|
33
|
+
bundle config --local clean 'true'
|
34
|
+
bundle config --local path '.vendor'
|
35
|
+
bundle config --local jobs 8
|
36
|
+
bundle config --local without 'system_tests'
|
37
|
+
bundle install
|
38
|
+
|
39
|
+
- name: Run test
|
40
|
+
run: bundle exec rake spec
|
41
|
+
- name: Run lint
|
42
|
+
run: bundle exec rake rubocop
|
data/.gitignore
CHANGED
data/README.md
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Xcode::Install
|
2
2
|
|
3
|
-
[![Gem Version](http://img.shields.io/gem/v/xcode-install.svg?style=flat)](http://badge.fury.io/rb/xcode-install) [![
|
3
|
+
[![Gem Version](http://img.shields.io/gem/v/xcode-install.svg?style=flat)](http://badge.fury.io/rb/xcode-install) [![Build Status](https://github.com/xcpretty/xcode-install/actions/workflows/ci.yml/badge.svg)](https://github.com/xcpretty/xcode-install/actions)
|
4
4
|
|
5
5
|
Install and update your Xcodes automatically.
|
6
6
|
|
@@ -87,6 +87,16 @@ $ xcversion list
|
|
87
87
|
|
88
88
|
They have to be installed using the full name, e.g. `xcversion install '7 GM seed'`.
|
89
89
|
|
90
|
+
#### `.xcode-version`
|
91
|
+
|
92
|
+
We recommend the creation of a `.xcode-version` file to explicitly declare and store the Xcode version to be used by your CI environment as well as your team.
|
93
|
+
|
94
|
+
```
|
95
|
+
12.5
|
96
|
+
```
|
97
|
+
|
98
|
+
Read [the proposal](/XCODE_VERSION.md) of `.xcode-version`.
|
99
|
+
|
90
100
|
### Select
|
91
101
|
|
92
102
|
To see the currently selected version, run
|
@@ -151,7 +161,7 @@ to a dialog popping up. Feel free to dupe [the radar][5]. 📡
|
|
151
161
|
|
152
162
|
XcodeInstall normally relies on the Spotlight index to locate installed versions of Xcode. If you use it while
|
153
163
|
indexing is happening, it might show inaccurate results and it will not be able to see installed
|
154
|
-
versions on unindexed volumes.
|
164
|
+
versions on unindexed volumes.
|
155
165
|
|
156
166
|
To workaround the Spotlight limitation, XcodeInstall searches `/Applications` folder to locate Xcodes when Spotlight is disabled on the machine, or when Spotlight query for Xcode does not return any results. But it still won't work if your Xcodes are not located under `/Applications` folder.
|
157
167
|
|
@@ -165,7 +175,7 @@ project, especially [@henrikhodne][6] and [@lacostej][7] for making XcodeInstall
|
|
165
175
|
|
166
176
|
## Contributing
|
167
177
|
|
168
|
-
1. Fork it ( https://github.com/
|
178
|
+
1. Fork it ( https://github.com/xcpretty/xcode-install/fork )
|
169
179
|
2. Create your feature branch (`git checkout -b my-new-feature`)
|
170
180
|
3. Commit your changes (`git commit -am 'Add some feature'`)
|
171
181
|
4. Push to the branch (`git push origin my-new-feature`)
|
data/XCODE_VERSION.md
ADDED
@@ -0,0 +1,49 @@
|
|
1
|
+
# `.xcode-version`
|
2
|
+
|
3
|
+
## Introduction
|
4
|
+
|
5
|
+
This is a proposal for a new standard for the iOS community: a text-based file that defines the Xcode version to use to compile and package a given iOS project.
|
6
|
+
|
7
|
+
This will be used by this gem, however it's designed in a way that any tool in the future can pick it up, no matter if it's Ruby based, Swift, JavaScript, etc.
|
8
|
+
|
9
|
+
Similar to the [.ruby-version file](https://en.wikipedia.org/wiki/Ruby_Version_Manager), the `.xcode-version` file allows any CI system or IDE to automatically install and switch to the Xcode version needed for a given project to successfully compile your project.
|
10
|
+
|
11
|
+
## Filename
|
12
|
+
|
13
|
+
The filename must always be `.xcode-version`.
|
14
|
+
|
15
|
+
## File location
|
16
|
+
|
17
|
+
The file must be located in the same directory as your Xcode project/workspace, and you should add it to your versioning system (e.g. git).
|
18
|
+
|
19
|
+
## File content
|
20
|
+
|
21
|
+
The file content must be a simple string in a text file. The file may or may not end with an empty new line, this gem is responsible for stripping out the trailing `\n` (if used).
|
22
|
+
|
23
|
+
### Sample files
|
24
|
+
|
25
|
+
To define an official Xcode release
|
26
|
+
|
27
|
+
```
|
28
|
+
9.3
|
29
|
+
```
|
30
|
+
|
31
|
+
```
|
32
|
+
7.2.1
|
33
|
+
```
|
34
|
+
|
35
|
+
You can also use pre-releases
|
36
|
+
|
37
|
+
```
|
38
|
+
11.5 GM Seed
|
39
|
+
```
|
40
|
+
|
41
|
+
```
|
42
|
+
12 beta 6
|
43
|
+
```
|
44
|
+
|
45
|
+
Always following the same version naming listed by `xcversion list`.
|
46
|
+
|
47
|
+
**Note**: Be aware that pre-releases might be eventually taken down from Apple's servers, meaning that it won't allow you to have fully reproducible builds as you won't be able to download the Xcode release once it's gone.
|
48
|
+
|
49
|
+
It is recommended to only use non-beta releases in an `.xcode-version` file to have fully reproducible builds that you'll be able to run in a few years also.
|
data/lib/xcode/install.rb
CHANGED
@@ -25,13 +25,14 @@ module XcodeInstall
|
|
25
25
|
# @param progress: parse and show the progress?
|
26
26
|
# @param progress_block: A block that's called whenever we have an updated progress %
|
27
27
|
# the parameter is a single number that's literally percent (e.g. 1, 50, 80 or 100)
|
28
|
-
#
|
28
|
+
# @param retry_download_count: A count to retry the downloading Xcode dmg/xip
|
29
29
|
def fetch(url: nil,
|
30
30
|
directory: nil,
|
31
31
|
cookies: nil,
|
32
32
|
output: nil,
|
33
33
|
progress: nil,
|
34
|
-
progress_block: nil
|
34
|
+
progress_block: nil,
|
35
|
+
retry_download_count: 3)
|
35
36
|
options = cookies.nil? ? [] : ['--cookie', cookies, '--cookie-jar', COOKIES_PATH]
|
36
37
|
|
37
38
|
uri = URI.parse(url)
|
@@ -78,38 +79,8 @@ module XcodeInstall
|
|
78
79
|
# "Partial file. Only a part of the file was transferred."
|
79
80
|
# https://curl.haxx.se/mail/archive-2008-07/0098.html
|
80
81
|
# https://github.com/KrauseFx/xcode-install/issues/210
|
81
|
-
|
82
|
-
|
83
|
-
# We're not using the block based syntax, as the bacon testing
|
84
|
-
# library doesn't seem to support writing tests for it
|
85
|
-
stdin, stdout, stderr, wait_thr = Open3.popen3(command_string)
|
86
|
-
|
87
|
-
# Poll the file and see if we're done yet
|
88
|
-
while wait_thr.alive?
|
89
|
-
sleep(0.5) # it's not critical for this to be real-time
|
90
|
-
next unless File.exist?(progress_log_file) # it might take longer for it to be created
|
91
|
-
|
92
|
-
progress_content = File.read(progress_log_file).split("\r").last
|
93
|
-
|
94
|
-
# Print out the progress for the CLI
|
95
|
-
if progress
|
96
|
-
print "\r#{progress_content}%"
|
97
|
-
$stdout.flush
|
98
|
-
end
|
99
|
-
|
100
|
-
# Call back the block for other processes that might be interested
|
101
|
-
matched = progress_content.match(/^\s*(\d+)/)
|
102
|
-
next unless matched && matched.length == 2
|
103
|
-
percent = matched[1].to_i
|
104
|
-
progress_block.call(percent) if progress_block
|
105
|
-
end
|
106
|
-
|
107
|
-
# as we're not making use of the block-based syntax
|
108
|
-
# we need to manually close those
|
109
|
-
stdin.close
|
110
|
-
stdout.close
|
111
|
-
stderr.close
|
112
|
-
|
82
|
+
retry_download_count.times do
|
83
|
+
wait_thr = poll_file(command_string: command_string, progress_log_file: progress_log_file, progress: progress, progress_block: progress_block)
|
113
84
|
return wait_thr.value.success? if wait_thr.value.success?
|
114
85
|
end
|
115
86
|
false
|
@@ -117,6 +88,41 @@ module XcodeInstall
|
|
117
88
|
FileUtils.rm_f(COOKIES_PATH)
|
118
89
|
FileUtils.rm_f(progress_log_file)
|
119
90
|
end
|
91
|
+
|
92
|
+
def poll_file(command_string:, progress_log_file:, progress: nil, progress_block: nil)
|
93
|
+
# Non-blocking call of Open3
|
94
|
+
# We're not using the block based syntax, as the bacon testing
|
95
|
+
# library doesn't seem to support writing tests for it
|
96
|
+
stdin, stdout, stderr, wait_thr = Open3.popen3(command_string)
|
97
|
+
|
98
|
+
# Poll the file and see if we're done yet
|
99
|
+
while wait_thr.alive?
|
100
|
+
sleep(0.5) # it's not critical for this to be real-time
|
101
|
+
next unless File.exist?(progress_log_file) # it might take longer for it to be created
|
102
|
+
|
103
|
+
progress_content = File.read(progress_log_file).split("\r").last || ''
|
104
|
+
|
105
|
+
# Print out the progress for the CLI
|
106
|
+
if progress
|
107
|
+
print "\r#{progress_content}%"
|
108
|
+
$stdout.flush
|
109
|
+
end
|
110
|
+
|
111
|
+
# Call back the block for other processes that might be interested
|
112
|
+
matched = progress_content.match(/^\s*(\d+)/)
|
113
|
+
next unless matched && matched.length == 2
|
114
|
+
percent = matched[1].to_i
|
115
|
+
progress_block.call(percent) if progress_block
|
116
|
+
end
|
117
|
+
|
118
|
+
# as we're not making use of the block-based syntax
|
119
|
+
# we need to manually close those
|
120
|
+
stdin.close
|
121
|
+
stdout.close
|
122
|
+
stderr.close
|
123
|
+
|
124
|
+
wait_thr
|
125
|
+
end
|
120
126
|
end
|
121
127
|
|
122
128
|
# rubocop:disable Metrics/ClassLength
|
@@ -135,7 +141,7 @@ module XcodeInstall
|
|
135
141
|
File.symlink?(SYMLINK_PATH) ? SYMLINK_PATH : nil
|
136
142
|
end
|
137
143
|
|
138
|
-
def download(version, progress, url = nil, progress_block = nil)
|
144
|
+
def download(version, progress, url = nil, progress_block = nil, retry_download_count = 3)
|
139
145
|
xcode = find_xcode_version(version) if url.nil?
|
140
146
|
return if url.nil? && xcode.nil?
|
141
147
|
|
@@ -147,7 +153,8 @@ module XcodeInstall
|
|
147
153
|
cookies: url ? nil : spaceship.cookie,
|
148
154
|
output: dmg_file,
|
149
155
|
progress: progress,
|
150
|
-
progress_block: progress_block
|
156
|
+
progress_block: progress_block,
|
157
|
+
retry_download_count: retry_download_count
|
151
158
|
)
|
152
159
|
result ? CACHE_DIR + dmg_file : nil
|
153
160
|
end
|
@@ -173,7 +180,7 @@ module XcodeInstall
|
|
173
180
|
seedlist.each do |current_seed|
|
174
181
|
return current_seed if parsed_version && current_seed.version == parsed_version
|
175
182
|
end
|
176
|
-
|
183
|
+
|
177
184
|
nil
|
178
185
|
end
|
179
186
|
|
@@ -214,7 +221,7 @@ module XcodeInstall
|
|
214
221
|
current_xcode.installed = cached_installed_versions.include?(current_xcode.version)
|
215
222
|
end
|
216
223
|
|
217
|
-
all_xcodes.sort_by
|
224
|
+
all_xcodes.sort_by { |seed| [seed.version, -seed.date_modified] }.reverse
|
218
225
|
end
|
219
226
|
|
220
227
|
def install_dmg(dmg_path, suffix = '', switch = true, clean = true)
|
@@ -280,8 +287,8 @@ HELP
|
|
280
287
|
end
|
281
288
|
|
282
289
|
# 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)
|
290
|
+
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)
|
291
|
+
dmg_path = get_dmg(version, progress, url, progress_block, retry_download_count)
|
285
292
|
fail Informative, "Failed to download Xcode #{version}." if dmg_path.nil?
|
286
293
|
|
287
294
|
if install
|
@@ -300,17 +307,21 @@ HELP
|
|
300
307
|
end
|
301
308
|
|
302
309
|
def list_annotated(xcodes_list)
|
303
|
-
installed = installed_versions.map(&:
|
310
|
+
installed = installed_versions.map(&:appname_version)
|
311
|
+
|
304
312
|
xcodes_list.map do |x|
|
305
|
-
xcode_version = x.split(' ')
|
306
|
-
xcode_version << '.0' unless xcode_version.include?('.')
|
313
|
+
xcode_version = x.split(' ') # split version and "beta N", "for Lion"
|
314
|
+
xcode_version[0] << '.0' unless xcode_version[0].include?('.')
|
315
|
+
|
316
|
+
# to match InstalledXcode.appname_version format
|
317
|
+
version = Gem::Version.new(xcode_version.join('.'))
|
307
318
|
|
308
|
-
installed.include?(
|
319
|
+
installed.include?(version) ? "#{x} (installed)" : x
|
309
320
|
end.join("\n")
|
310
321
|
end
|
311
322
|
|
312
323
|
def list
|
313
|
-
list_annotated(list_versions.
|
324
|
+
list_annotated(list_versions.sort { |first, second| compare_versions(first, second) })
|
314
325
|
end
|
315
326
|
|
316
327
|
def rm_list_cache
|
@@ -366,7 +377,7 @@ HELP
|
|
366
377
|
`sudo /usr/sbin/dseditgroup -o edit -t group -a staff _developer`
|
367
378
|
end
|
368
379
|
|
369
|
-
def get_dmg(version, progress = true, url = nil, progress_block = nil)
|
380
|
+
def get_dmg(version, progress = true, url = nil, progress_block = nil, retry_download_count = 3)
|
370
381
|
if url
|
371
382
|
path = Pathname.new(url)
|
372
383
|
return path if path.exist?
|
@@ -377,7 +388,7 @@ HELP
|
|
377
388
|
end
|
378
389
|
end
|
379
390
|
|
380
|
-
download(version, progress, url, progress_block)
|
391
|
+
download(version, progress, url, progress_block, retry_download_count)
|
381
392
|
end
|
382
393
|
|
383
394
|
def fetch_seedlist
|
@@ -457,6 +468,35 @@ HELP
|
|
457
468
|
links
|
458
469
|
end
|
459
470
|
|
471
|
+
# rubocop:disable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
472
|
+
def compare_versions(first, second)
|
473
|
+
# Sort by version number
|
474
|
+
numeric_comparation = first.to_f <=> second.to_f
|
475
|
+
return numeric_comparation if numeric_comparation != 0
|
476
|
+
|
477
|
+
# Return beta versions before others
|
478
|
+
is_first_beta = first.include?('beta')
|
479
|
+
is_second_beta = second.include?('beta')
|
480
|
+
return -1 if is_first_beta && !is_second_beta
|
481
|
+
return 1 if !is_first_beta && is_second_beta
|
482
|
+
|
483
|
+
# Return GM versions before others
|
484
|
+
is_first_gm = first.include?('GM')
|
485
|
+
is_second_gm = second.include?('GM')
|
486
|
+
return -1 if is_first_gm && !is_second_gm
|
487
|
+
return 1 if !is_first_gm && is_second_gm
|
488
|
+
|
489
|
+
# Return Release Candidate versions before others
|
490
|
+
is_first_rc = first.include?('RC') || first.include?('Release Candidate')
|
491
|
+
is_second_rc = second.include?('RC') || second.include?('Release Candidate')
|
492
|
+
return -1 if is_first_rc && !is_second_rc
|
493
|
+
return 1 if !is_first_rc && is_second_rc
|
494
|
+
|
495
|
+
# Sort alphabetically
|
496
|
+
first <=> second
|
497
|
+
end
|
498
|
+
# rubocop:enable Metrics/CyclomaticComplexity, Metrics/PerceivedComplexity
|
499
|
+
|
460
500
|
def hdiutil(*args)
|
461
501
|
io = IO.popen(['hdiutil', *args])
|
462
502
|
result = io.read
|
@@ -508,12 +548,13 @@ HELP
|
|
508
548
|
end
|
509
549
|
end
|
510
550
|
|
511
|
-
def download(progress, progress_block = nil)
|
551
|
+
def download(progress, progress_block = nil, retry_download_count = 3)
|
512
552
|
result = Curl.new.fetch(
|
513
553
|
url: source,
|
514
554
|
directory: CACHE_DIR,
|
515
555
|
progress: progress,
|
516
|
-
progress_block: progress_block
|
556
|
+
progress_block: progress_block,
|
557
|
+
retry_download_count: retry_download_count
|
517
558
|
)
|
518
559
|
result ? dmg_path : nil
|
519
560
|
end
|
@@ -601,6 +642,17 @@ HELP
|
|
601
642
|
@bundle_version ||= Gem::Version.new(bundle_version_string)
|
602
643
|
end
|
603
644
|
|
645
|
+
def appname_version
|
646
|
+
appname = @path.basename('.app').to_s
|
647
|
+
version_string = appname.split('-').last
|
648
|
+
begin
|
649
|
+
Gem::Version.new(version_string)
|
650
|
+
rescue ArgumentError
|
651
|
+
puts 'Unable to determine Xcode version from path name, installed list may not correctly identify installed betas'
|
652
|
+
Gem::Version.new(nil)
|
653
|
+
end
|
654
|
+
end
|
655
|
+
|
604
656
|
def uuid
|
605
657
|
@uuid ||= plist_entry(':DVTPlugInCompatibilityUUID')
|
606
658
|
end
|
@@ -702,7 +754,7 @@ HELP
|
|
702
754
|
#
|
703
755
|
# Sample object:
|
704
756
|
# <XcodeInstall::Xcode:0x007fa1d451c390
|
705
|
-
# @date_modified=
|
757
|
+
# @date_modified=1573661580,
|
706
758
|
# @name="6.4",
|
707
759
|
# @path="/Developer_Tools/Xcode_6.4/Xcode_6.4.dmg",
|
708
760
|
# @url=
|
@@ -725,7 +777,7 @@ HELP
|
|
725
777
|
|
726
778
|
def initialize(json, url = nil, release_notes_url = nil)
|
727
779
|
if url.nil?
|
728
|
-
@date_modified = json['dateModified'].to_i
|
780
|
+
@date_modified = DateTime.strptime(json['dateModified'], '%m/%d/%y %H:%M').strftime('%s').to_i
|
729
781
|
@name = json['name'].gsub(/^Xcode /, '')
|
730
782
|
@path = json['files'].first['remotePath']
|
731
783
|
url_prefix = 'https://developer.apple.com/devcenter/download.action?path='
|
@@ -757,6 +809,7 @@ HELP
|
|
757
809
|
|
758
810
|
def self.new_prerelease(version, url, release_notes_path)
|
759
811
|
new('name' => version,
|
812
|
+
'dateModified' => '01/01/70 00:00',
|
760
813
|
'files' => [{ 'remotePath' => url.split('=').last }],
|
761
814
|
'release_notes_path' => release_notes_path)
|
762
815
|
end
|
@@ -17,13 +17,14 @@ module XcodeInstall
|
|
17
17
|
['--no-install', 'Only download DMG, but do not install it.'],
|
18
18
|
['--no-progress', 'Don’t show download progress.'],
|
19
19
|
['--no-clean', 'Don’t delete DMG after installation.'],
|
20
|
-
['--no-show-release-notes', 'Don’t open release notes in browser after installation.']
|
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)
|
21
22
|
end
|
22
23
|
|
23
24
|
def initialize(argv)
|
24
25
|
@installer = Installer.new
|
25
26
|
@version = argv.shift_argument
|
26
|
-
@version ||= File.read('.xcode-version') if File.exist?('.xcode-version')
|
27
|
+
@version ||= File.read('.xcode-version').strip if File.exist?('.xcode-version')
|
27
28
|
@url = argv.option('url')
|
28
29
|
@force = argv.flag?('force', false)
|
29
30
|
@should_clean = argv.flag?('clean', true)
|
@@ -31,6 +32,7 @@ module XcodeInstall
|
|
31
32
|
@should_switch = argv.flag?('switch', true)
|
32
33
|
@progress = argv.flag?('progress', true)
|
33
34
|
@show_release_notes = argv.flag?('show-release-notes', true)
|
35
|
+
@retry_download_count = argv.option('retry-download-count', '3')
|
34
36
|
super
|
35
37
|
end
|
36
38
|
|
@@ -44,11 +46,12 @@ module XcodeInstall
|
|
44
46
|
end
|
45
47
|
fail Informative, "Version #{@version} doesn't exist." unless @url || @installer.exist?(@version)
|
46
48
|
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?
|
47
50
|
end
|
48
51
|
|
49
52
|
def run
|
50
53
|
@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)
|
52
55
|
end
|
53
56
|
end
|
54
57
|
end
|