xcode-install 2.6.6 → 2.8.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5cd94bd1afd9e9d5fc6d01b1f167635f58159086547a8d571e4f57a76b1761b8
4
- data.tar.gz: 0f4c8b091b0aef11748f63e2dc93f8245820083916c33107575c2a9cab80a4b0
3
+ metadata.gz: 04e0e30f2230e52da44a3710cf8277f8d5e82e67d2a18d4dfa98fb9a3f40570e
4
+ data.tar.gz: 5c058cb7d8adcb3e4f800091cf7531ad8ad2010c243e8e685639df1feb658e04
5
5
  SHA512:
6
- metadata.gz: 64c8de1910492324f460a076e535f344c29f7ccde90e1e57221ec7ff08f497abccbf4c448526306cd9d5a81289cf1a74f851b092ac201a3a2037004cac4b9907
7
- data.tar.gz: 9861106b901b9ebdfb8b4cd2196e1469bedb401f9e00e9844149c935ca4d737cc4552a36f1bfe2f3605e146bcab79e92752c846a755bd7e25e526355a81a8603
6
+ metadata.gz: 21b099ccd6dd22bf8e7e652ea6ef8e1084260486784662c5781f8fa5ff169b75ec2d2dfb2cb855ba93de7a0e16519a73d9c0a07596e5b5c1d8eb70a0f2d3aae6
7
+ data.tar.gz: 5a14cef0170a25cdcc0d8dfd845f21463e0f7c38ae810a5e3328ce5f72a79eaa5fe380a70eee2c470b5395f791bce3e52ad551370491fd742e22718e8ce81626
@@ -1,34 +1,40 @@
1
1
  name: "CI"
2
- on: [pull_request]
2
+ on: [push, pull_request]
3
3
 
4
4
  jobs:
5
5
  build:
6
6
  strategy:
7
7
  fail-fast: false
8
8
  matrix:
9
- ruby: ["2.5", "2.6"]
9
+ ruby: ["2.5", "2.6", "2.7", "3.0"]
10
10
 
11
11
  runs-on: macos-latest
12
12
  steps:
13
13
  # Setup env
14
14
  - uses: actions/checkout@v2
15
- - uses: actions/setup-ruby@v1
15
+ - uses: ruby/setup-ruby@v1
16
16
  with:
17
17
  ruby-version: "${{ matrix.ruby }}"
18
18
 
19
19
  # Show env
20
20
  - name: Show macOS version
21
21
  run: sw_vers
22
- - name: Show ruby version
22
+ - name: Show env versions
23
23
  run: |
24
24
  ruby --version
25
25
  bundler --version
26
+ echo $HOME
26
27
 
27
28
  # Prepare
28
- - name: Install bundler 1.7
29
- run: gem install bundler -v "~> 1.7"
29
+ - name: Install bundler 2.2.20
30
+ run: gem install bundler -v "~> 2.2.20"
30
31
  - name: Install ruby dependencies
31
- run: bundle install -j4 --clean --path=vendor
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
32
38
 
33
39
  - name: Run test
34
40
  run: bundle exec rake spec
data/.gitignore CHANGED
@@ -14,3 +14,4 @@
14
14
  mkmf.log
15
15
  .DS_Store
16
16
  test
17
+ .vendor
data/.rubocop_todo.yml CHANGED
@@ -1,78 +1,213 @@
1
1
  # This configuration was generated by
2
2
  # `rubocop --auto-gen-config`
3
- # on 2017-08-24 11:09:20 +0200 using RuboCop version 0.49.1.
3
+ # on 2021-07-06 16:06:45 UTC using RuboCop version 1.12.1.
4
4
  # The point is for the user to remove these configuration records
5
5
  # one by one as the offenses are removed from the code base.
6
6
  # Note that changes in the inspected code, or installation of new
7
7
  # versions of RuboCop, may require this file to be generated again.
8
8
 
9
+ # Offense count: 1
10
+ # Configuration parameters: Include.
11
+ # Include: **/*.gemspec
12
+ Gemspec/RequiredRubyVersion:
13
+ Exclude:
14
+ - 'xcode-install.gemspec'
15
+
9
16
  # Offense count: 3
10
17
  # Cop supports --auto-correct.
11
- # Configuration parameters: EnforcedStyle, SupportedStyles.
12
- # SupportedStyles: auto_detection, squiggly, active_support, powerpack, unindent
13
- Layout/IndentHeredoc:
18
+ Layout/ClosingHeredocIndentation:
14
19
  Exclude:
15
20
  - 'lib/xcode/install.rb'
16
21
 
17
22
  # Offense count: 12
23
+ # Cop supports --auto-correct.
24
+ Layout/EmptyLineAfterGuardClause:
25
+ Exclude:
26
+ - 'lib/xcode/install.rb'
27
+ - 'lib/xcode/install/cleanup.rb'
28
+ - 'lib/xcode/install/simulators.rb'
29
+ - 'lib/xcode/install/uninstall.rb'
30
+
31
+ # Offense count: 3
32
+ # Cop supports --auto-correct.
33
+ Layout/HeredocIndentation:
34
+ Exclude:
35
+ - 'lib/xcode/install.rb'
36
+
37
+ # Offense count: 3
38
+ # Cop supports --auto-correct.
39
+ Lint/BooleanSymbol:
40
+ Exclude:
41
+ - 'lib/xcode/install/install.rb'
42
+ - 'lib/xcode/install/select.rb'
43
+ - 'lib/xcode/install/uninstall.rb'
44
+
45
+ # Offense count: 6
46
+ Lint/DuplicateMethods:
47
+ Exclude:
48
+ - 'lib/xcode/install.rb'
49
+
50
+ # Offense count: 2
51
+ # Configuration parameters: MaximumRangeSize.
52
+ Lint/MissingCopEnableDirective:
53
+ Exclude:
54
+ - 'lib/xcode/install.rb'
55
+
56
+ # Offense count: 1
57
+ # Cop supports --auto-correct.
58
+ Lint/UriRegexp:
59
+ Exclude:
60
+ - 'lib/xcode/install/install.rb'
61
+
62
+ # Offense count: 12
63
+ # Configuration parameters: IgnoredMethods, CountRepeatedAttributes.
18
64
  Metrics/AbcSize:
19
- Max: 44
65
+ Max: 45
20
66
 
21
- # Offense count: 4
22
- # Configuration parameters: CountComments, ExcludedMethods.
67
+ # Offense count: 5
68
+ # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
69
+ # IgnoredMethods: refine
23
70
  Metrics/BlockLength:
24
71
  Max: 76
25
72
 
26
- # Offense count: 1
27
- # Configuration parameters: CountComments.
28
- Metrics/ClassLength:
29
- Max: 246
30
-
31
- # Offense count: 3
73
+ # Offense count: 6
74
+ # Configuration parameters: IgnoredMethods.
32
75
  Metrics/CyclomaticComplexity:
33
76
  Max: 10
34
77
 
35
- # Offense count: 11
36
- # Configuration parameters: CountComments.
78
+ # Offense count: 17
79
+ # Configuration parameters: CountComments, CountAsOne, ExcludedMethods, IgnoredMethods.
37
80
  Metrics/MethodLength:
38
- Max: 51
81
+ Max: 50
39
82
 
40
83
  # Offense count: 1
41
- # Configuration parameters: CountKeywordArgs.
84
+ # Configuration parameters: CountKeywordArgs, MaxOptionalParameters.
42
85
  Metrics/ParameterLists:
43
86
  Max: 7
44
87
 
45
- # Offense count: 3
88
+ # Offense count: 2
89
+ # Configuration parameters: IgnoredMethods.
46
90
  Metrics/PerceivedComplexity:
47
91
  Max: 12
48
92
 
49
93
  # Offense count: 1
94
+ Security/MarshalLoad:
95
+ Exclude:
96
+ - 'lib/xcode/install.rb'
97
+
98
+ # Offense count: 16
99
+ # Cop supports --auto-correct.
100
+ # Configuration parameters: EnforcedStyle.
101
+ # SupportedStyles: separated, grouped
102
+ Style/AccessorGrouping:
103
+ Exclude:
104
+ - 'lib/xcode/install.rb'
105
+
106
+ # Offense count: 1
107
+ Style/CombinableLoops:
108
+ Exclude:
109
+ - 'lib/xcode/install.rb'
110
+
111
+ # Offense count: 1
112
+ # Cop supports --auto-correct.
113
+ Style/Encoding:
114
+ Exclude:
115
+ - 'xcode-install.gemspec'
116
+
117
+ # Offense count: 14
50
118
  # Cop supports --auto-correct.
51
- Performance/CompareWithBlock:
119
+ Style/ExpandPathArguments:
120
+ Exclude:
121
+ - 'bin/xcversion'
122
+ - 'bin/🎉'
123
+ - 'spec/cli_spec.rb'
124
+ - 'spec/curl_spec.rb'
125
+ - 'spec/install_spec.rb'
126
+ - 'spec/installed_spec.rb'
127
+ - 'spec/installer_spec.rb'
128
+ - 'spec/json_spec.rb'
129
+ - 'spec/list_spec.rb'
130
+ - 'spec/prerelease_spec.rb'
131
+ - 'spec/spec_helper.rb'
132
+ - 'spec/uninstall_spec.rb'
133
+ - 'xcode-install.gemspec'
134
+
135
+ # Offense count: 28
136
+ # Cop supports --auto-correct.
137
+ # Configuration parameters: EnforcedStyle.
138
+ # SupportedStyles: always, always_true, never
139
+ Style/FrozenStringLiteralComment:
140
+ Enabled: false
141
+
142
+ # Offense count: 2
143
+ # Cop supports --auto-correct.
144
+ Style/IfUnlessModifier:
145
+ Exclude:
146
+ - 'lib/xcode/install.rb'
147
+
148
+ # Offense count: 8
149
+ # Configuration parameters: AllowedMethods.
150
+ # AllowedMethods: respond_to_missing?
151
+ Style/OptionalBooleanParameter:
52
152
  Exclude:
53
153
  - 'lib/xcode/install.rb'
54
154
 
55
155
  # Offense count: 1
56
156
  # Cop supports --auto-correct.
57
- # Configuration parameters: IncludeActiveSupportAliases.
58
- Performance/DoubleStartEndWith:
157
+ Style/RedundantBegin:
158
+ Exclude:
159
+ - 'lib/xcode/install.rb'
160
+
161
+ # Offense count: 2
162
+ # Cop supports --auto-correct.
163
+ Style/RedundantRegexpEscape:
59
164
  Exclude:
60
165
  - 'lib/xcode/install.rb'
61
166
 
62
167
  # Offense count: 1
63
- Security/MarshalLoad:
168
+ # Cop supports --auto-correct.
169
+ # Configuration parameters: AllowMultipleReturnValues.
170
+ Style/RedundantReturn:
64
171
  Exclude:
65
172
  - 'lib/xcode/install.rb'
66
173
 
67
- # Offense count: 15
174
+ # Offense count: 2
68
175
  # Cop supports --auto-correct.
69
- # Configuration parameters: EnforcedStyle, SupportedStyles.
176
+ # Configuration parameters: EnforcedStyle.
177
+ # SupportedStyles: implicit, explicit
178
+ Style/RescueStandardError:
179
+ Exclude:
180
+ - 'lib/xcode/install.rb'
181
+
182
+ # Offense count: 1
183
+ # Cop supports --auto-correct.
184
+ # Configuration parameters: ConvertCodeThatCanStartToReturnNil, AllowedMethods.
185
+ # AllowedMethods: present?, blank?, presence, try, try!
186
+ Style/SafeNavigation:
187
+ Exclude:
188
+ - 'lib/xcode/install.rb'
189
+
190
+ # Offense count: 14
191
+ # Cop supports --auto-correct.
192
+ # Configuration parameters: EnforcedStyle.
70
193
  # SupportedStyles: only_raise, only_fail, semantic
71
194
  Style/SignalException:
72
195
  Exclude:
73
196
  - 'lib/xcode/install.rb'
74
- - 'lib/xcode/install/cli.rb'
75
197
  - 'lib/xcode/install/install.rb'
76
198
  - 'lib/xcode/install/select.rb'
77
199
  - 'lib/xcode/install/simulators.rb'
78
200
  - 'lib/xcode/install/uninstall.rb'
201
+
202
+ # Offense count: 2
203
+ # Cop supports --auto-correct.
204
+ Style/StderrPuts:
205
+ Exclude:
206
+ - 'lib/xcode/install.rb'
207
+
208
+ # Offense count: 4
209
+ # Cop supports --auto-correct.
210
+ Style/StringConcatenation:
211
+ Exclude:
212
+ - 'lib/xcode/install.rb'
213
+ - 'spec/spec_helper.rb'
data/Gemfile CHANGED
@@ -8,5 +8,5 @@ group :development do
8
8
  gem 'mocha', '~> 0.11.4'
9
9
  gem 'mocha-on-bacon'
10
10
  gem 'prettybacon'
11
- gem 'rubocop', '~> 0.49.1', require: false
11
+ gem 'rubocop', '~> 1.18', require: false
12
12
  end
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) [![CircleCI](https://circleci.com/gh/xcpretty/xcode-install.svg?style=svg)](https://circleci.com/gh/xcpretty/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/KrauseFx/xcode-install/fork )
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.
@@ -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.']].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)
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
@@ -1,3 +1,3 @@
1
1
  module XcodeInstall
2
- VERSION = '2.6.6'.freeze
2
+ VERSION = '2.8.0'.freeze
3
3
  end
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
- # rubocop:disable Metrics/AbcSize
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
- 3.times do
82
- # Non-blocking call of Open3
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
@@ -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
@@ -314,7 +321,7 @@ HELP
314
321
  end
315
322
 
316
323
  def list
317
- list_annotated(list_versions.sort_by(&:to_f))
324
+ list_annotated(list_versions.sort { |first, second| compare_versions(first, second) })
318
325
  end
319
326
 
320
327
  def rm_list_cache
@@ -370,7 +377,7 @@ HELP
370
377
  `sudo /usr/sbin/dseditgroup -o edit -t group -a staff _developer`
371
378
  end
372
379
 
373
- 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)
374
381
  if url
375
382
  path = Pathname.new(url)
376
383
  return path if path.exist?
@@ -381,7 +388,7 @@ HELP
381
388
  end
382
389
  end
383
390
 
384
- download(version, progress, url, progress_block)
391
+ download(version, progress, url, progress_block, retry_download_count)
385
392
  end
386
393
 
387
394
  def fetch_seedlist
@@ -461,6 +468,35 @@ HELP
461
468
  links
462
469
  end
463
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
+
464
500
  def hdiutil(*args)
465
501
  io = IO.popen(['hdiutil', *args])
466
502
  result = io.read
@@ -512,12 +548,13 @@ HELP
512
548
  end
513
549
  end
514
550
 
515
- def download(progress, progress_block = nil)
551
+ def download(progress, progress_block = nil, retry_download_count = 3)
516
552
  result = Curl.new.fetch(
517
553
  url: source,
518
554
  directory: CACHE_DIR,
519
555
  progress: progress,
520
- progress_block: progress_block
556
+ progress_block: progress_block,
557
+ retry_download_count: retry_download_count
521
558
  )
522
559
  result ? dmg_path : nil
523
560
  end
@@ -673,11 +710,10 @@ HELP
673
710
  `touch #{cache_dir}com.apple.dt.Xcode.InstallCheckCache_#{osx_build_version}_#{tools_version}`
674
711
  end
675
712
 
676
- # This method might take a few ms, this could be improved by implementing https://github.com/KrauseFx/xcode-install/issues/273
677
713
  def fetch_version
678
- output = `DEVELOPER_DIR='' "#{@path}/Contents/Developer/usr/bin/xcodebuild" -version`
714
+ output = `/usr/libexec/PlistBuddy -c "Print :CFBundleShortVersionString" "#{@path}/Contents/version.plist"`
679
715
  return '0.0' if output.nil? || output.empty? # ¯\_(ツ)_/¯
680
- output.split("\n").first.split(' ')[1]
716
+ output.sub("\n", '')
681
717
  end
682
718
 
683
719
  def verify_integrity
data/spec/install_spec.rb CHANGED
@@ -12,32 +12,32 @@ module XcodeInstall
12
12
  end
13
13
 
14
14
  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')
16
16
  Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', true, true)
17
17
  Command::Install.run(['6.3'])
18
18
  end
19
19
 
20
20
  it 'downloads and installs with custom HTTP URL' do
21
21
  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')
23
23
  Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', true, true)
24
24
  Command::Install.run(['6.3', "--url=#{url}"])
25
25
  end
26
26
 
27
27
  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')
29
29
  Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', false, true)
30
30
  Command::Install.run(['6.3', '--no-switch'])
31
31
  end
32
32
 
33
33
  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')
35
35
  Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', true, true)
36
36
  Command::Install.run(['6.3', '--no-progress'])
37
37
  end
38
38
 
39
39
  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')
41
41
  Installer.any_instance.expects(:install_dmg).with('/some/path', '-6.3', true, true)
42
42
  File.expects(:exist?).with('.xcode-version').returns(true)
43
43
  File.expects(:read).returns('6.3')
@@ -5,13 +5,13 @@ module XcodeInstall
5
5
 
6
6
  describe InstalledXcode do
7
7
  it 'finds the current Xcode version with whitespace chars' do
8
- InstalledXcode.any_instance.expects(:`).with("DEVELOPER_DIR='' \"#{xcode_path}/Contents/Developer/usr/bin/xcodebuild\" -version").returns("Xcode 6.3.1\nBuild version 6D1002")
8
+ InstalledXcode.any_instance.expects(:`).with("/usr/libexec/PlistBuddy -c \"Print :CFBundleShortVersionString\" \"#{xcode_path}/Contents/version.plist\"").returns('6.3.1')
9
9
  installed = InstalledXcode.new(xcode_path)
10
10
  installed.version.should == '6.3.1'
11
11
  end
12
12
 
13
13
  it 'is robust against broken Xcode installations' do
14
- InstalledXcode.any_instance.expects(:`).with("DEVELOPER_DIR='' \"#{xcode_path}/Contents/Developer/usr/bin/xcodebuild\" -version").returns(nil)
14
+ InstalledXcode.any_instance.expects(:`).with("/usr/libexec/PlistBuddy -c \"Print :CFBundleShortVersionString\" \"#{xcode_path}/Contents/version.plist\"").returns(nil)
15
15
  installed = InstalledXcode.new(xcode_path)
16
16
  installed.version.should == '0.0'
17
17
  end
data/spec/json_spec.rb CHANGED
@@ -20,14 +20,14 @@ module XcodeInstall
20
20
  installer.stubs(:xcodes).returns(seedlist)
21
21
 
22
22
  versions = [
23
- '4.3 for Lion', '4.3.1 for Lion', '4.3.2 for Lion', '4.3.3 for Lion', '4.4.1', '4.5', '4.6.2', '4.6', '4.6.1', '4.6.3',
24
- '5.0.1', '5', '5.0.2', '5.1', '5.1.1',
23
+ '4.3 for Lion', '4.3.1 for Lion', '4.3.2 for Lion', '4.3.3 for Lion', '4.4.1', '4.5', '4.6', '4.6.1', '4.6.2', '4.6.3',
24
+ '5', '5.0.1', '5.0.2', '5.1', '5.1.1',
25
25
  '6.0.1', '6.1', '6.1.1', '6.2', '6.3', '6.3.1', '6.3.2', '6.4',
26
- '7', '7.0.1', '7.1', '7.1.1', '7.2.1', '7.2', '7.3', '7.3.1',
27
- '8', '8.1', '8.2', '8.2.1', '8.3.2', '8.3.3', '8.3',
26
+ '7', '7.0.1', '7.1', '7.1.1', '7.2', '7.2.1', '7.3', '7.3.1',
27
+ '8', '8.1', '8.2', '8.2.1', '8.3', '8.3.2', '8.3.3',
28
28
  '9', '9.0.1', '9.1', '9.2', '9.3', '9.3.1', '9.4', '9.4.1',
29
- '10', '10.1', '10.2.1', '10.2', '10.3',
30
- '11', '11.1', '11.2', '11.2.1', '11.3 beta', '11.3', '11.3.1', '11.4 beta', '11.4', '11.4 beta 3', '11.4 beta 2', '11.4.1', '11.5 beta 2', '11.5', '11.5 GM Seed', '11.5 beta'
29
+ '10', '10.1', '10.2', '10.2.1', '10.3',
30
+ '11', '11.1', '11.2', '11.2.1', '11.3 beta', '11.3', '11.3.1', '11.4 beta', '11.4 beta 2', '11.4 beta 3', '11.4', '11.4.1', '11.5 beta', '11.5 beta 2', '11.5 GM Seed', '11.5'
31
31
  ]
32
32
  installer.list.split("\n").should == versions
33
33
  end
data/spec/list_spec.rb CHANGED
@@ -43,7 +43,23 @@ module XcodeInstall
43
43
  it 'lists all versions' do
44
44
  fake_xcodes '1', '2.3', '2.3.1', '2.3.2', '3 some', '4 beta', '10 beta'
45
45
  fake_installed_xcodes
46
- installer.list.should == "1\n2.3.2\n2.3.1\n2.3\n3 some\n4 beta\n10 beta"
46
+ installer.list.should == "1\n2.3\n2.3.1\n2.3.2\n3 some\n4 beta\n10 beta"
47
+ end
48
+
49
+ it 'lists all versions in the correct order' do
50
+ fake_xcodes(
51
+ '12 beta 4', '12 beta 3', '12 beta 2', '12 for macOS Universal Apps beta 2',
52
+ '12 beta', '12 for macOS Universal Apps beta', '12.0.1', '12', '12 beta 6',
53
+ '12 beta 5', '12.1 GM seed', '12.2 beta 3', '12.2 beta', '12.2 beta 2'
54
+ )
55
+ fake_installed_xcodes
56
+
57
+ versions = [
58
+ '12 beta', '12 beta 2', '12 beta 3', '12 beta 4', '12 beta 5', '12 beta 6',
59
+ '12 for macOS Universal Apps beta', '12 for macOS Universal Apps beta 2',
60
+ '12', '12.0.1', '12.1 GM seed', '12.2 beta', '12.2 beta 2', '12.2 beta 3'
61
+ ]
62
+ installer.list.split("\n").should == versions
47
63
  end
48
64
  end
49
65
 
@@ -51,7 +67,7 @@ module XcodeInstall
51
67
  it 'lists all versions with annotations' do
52
68
  fake_xcodes '1', '2.3', '2.3.1', '2.3.2', '3 some', '4.3.1 for Lion', '9.4.1', '10 beta'
53
69
  fake_installed_xcodes '2.3', '4.3.1 for Lion', '10 beta'
54
- installer.list.should == "1\n2.3.2\n2.3.1\n2.3 (installed)\n3 some\n4.3.1 for Lion (installed)\n9.4.1\n10 beta (installed)"
70
+ installer.list.should == "1\n2.3 (installed)\n2.3.1\n2.3.2\n3 some\n4.3.1 for Lion (installed)\n9.4.1\n10 beta (installed)"
55
71
  end
56
72
 
57
73
  it 'distinguish between beta and official_version' do
@@ -61,9 +77,9 @@ module XcodeInstall
61
77
  end
62
78
 
63
79
  it 'distinguish each beta versions' do
64
- fake_xcodes '11.4 beta', '11.4 beta 3'
80
+ fake_xcodes '11.4 beta 3', '11.4 beta'
65
81
  fake_installed_xcodes '11.4 beta'
66
- installer.list.should == "11.4 beta 3\n11.4 beta (installed)"
82
+ installer.list.should == "11.4 beta (installed)\n11.4 beta 3"
67
83
  end
68
84
  end
69
85
  end
@@ -27,6 +27,6 @@ Gem::Specification.new do |spec|
27
27
  # contains spaceship, which is used for auth and dev portal interactions
28
28
  spec.add_dependency 'fastlane', '>= 2.1.0', '< 3.0.0'
29
29
 
30
- spec.add_development_dependency 'bundler', '~> 1.7'
30
+ spec.add_development_dependency 'bundler', '>= 2.0.0', '< 3.0.0'
31
31
  spec.add_development_dependency 'rake', '>= 12.3.3'
32
32
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: xcode-install
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.6.6
4
+ version: 2.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Boris Bügling
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2020-06-24 00:00:00.000000000 Z
11
+ date: 2021-09-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: claide
@@ -54,16 +54,22 @@ dependencies:
54
54
  name: bundler
55
55
  requirement: !ruby/object:Gem::Requirement
56
56
  requirements:
57
- - - "~>"
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: 2.0.0
60
+ - - "<"
58
61
  - !ruby/object:Gem::Version
59
- version: '1.7'
62
+ version: 3.0.0
60
63
  type: :development
61
64
  prerelease: false
62
65
  version_requirements: !ruby/object:Gem::Requirement
63
66
  requirements:
64
- - - "~>"
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: 2.0.0
70
+ - - "<"
65
71
  - !ruby/object:Gem::Version
66
- version: '1.7'
72
+ version: 3.0.0
67
73
  - !ruby/object:Gem::Dependency
68
74
  name: rake
69
75
  requirement: !ruby/object:Gem::Requirement
@@ -87,7 +93,6 @@ executables:
87
93
  extensions: []
88
94
  extra_rdoc_files: []
89
95
  files:
90
- - ".circleci/config.yml"
91
96
  - ".gitattributes"
92
97
  - ".github/workflows/ci.yml"
93
98
  - ".gitignore"
@@ -97,6 +102,7 @@ files:
97
102
  - LICENSE
98
103
  - README.md
99
104
  - Rakefile
105
+ - XCODE_VERSION.md
100
106
  - bin/xcversion
101
107
  - "bin/\U0001F389"
102
108
  - lib/xcode/install.rb
@@ -145,7 +151,7 @@ homepage: https://github.com/neonichu/xcode-install
145
151
  licenses:
146
152
  - MIT
147
153
  metadata: {}
148
- post_install_message:
154
+ post_install_message:
149
155
  rdoc_options: []
150
156
  require_paths:
151
157
  - lib
@@ -160,8 +166,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
160
166
  - !ruby/object:Gem::Version
161
167
  version: '0'
162
168
  requirements: []
163
- rubygems_version: 3.0.6
164
- signing_key:
169
+ rubygems_version: 3.2.19
170
+ signing_key:
165
171
  specification_version: 4
166
172
  summary: Xcode installation manager.
167
173
  test_files:
data/.circleci/config.yml DELETED
@@ -1,33 +0,0 @@
1
- version: 2
2
-
3
- jobs:
4
- build:
5
- macos:
6
- xcode: "9.0"
7
- working_directory: ~/xcode-install
8
- shell: /bin/bash --login -eo pipefail
9
- steps:
10
- - checkout
11
-
12
- # See Also: https://discuss.circleci.com/t/circleci-2-0-ios-error-installing-gems/23291/4
13
- - run:
14
- name: Set Ruby Version
15
- command: echo "ruby-2.4" > ~/.ruby-version
16
-
17
- - run:
18
- name: Install ruby dependencies
19
- command: bundle install
20
-
21
- - run:
22
- name: Run test
23
- command: bundle exec rake spec
24
-
25
- - run:
26
- name: Run lint
27
- command: bundle exec rake rubocop
28
-
29
- workflows:
30
- version: 2
31
- build_and_test:
32
- jobs:
33
- - build