xcode-install 2.4.0 → 2.6.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: fd49f95272394358487c0eed4f39884120ea0717
4
- data.tar.gz: f6dc4b73867986caaa06811a2c91e90f6741ec21
2
+ SHA256:
3
+ metadata.gz: 0fea81231fe9d81aed11e53e9340d8749cb90b12b61cf455ef216c4659beaf85
4
+ data.tar.gz: d385404265a3453ff25f3f6c2c532235ca7ed9769e0c1b808c64749f930f6eca
5
5
  SHA512:
6
- metadata.gz: 97e5d324c43f25f40f1b1682eac49544f6d695f44f2e27a942eb9782b635fb770bc271ef5ec81c93f4ace20523fa4cb2ad6dfb7dee03a446923d04feccae663e
7
- data.tar.gz: 3ee8b79219737c56cb9d9a8050be6bc88aa15d74b94329907ec742e11bf95341268517ce8aff4218a14192638b465441896bfbd77412fc28bae3615800d2dd9b
6
+ metadata.gz: 4147ef290648e0f0ac2122be32a2cc0d4fd26d3c9509767661107527fe20e58534bab89c505d992a876202a40effa7913b3901e24f504952839e5f416d011503
7
+ data.tar.gz: fa470926afe6472b552bd7be37619542024913101997df6e00a47064714199594c6c0dafbf1a41c07aa79ea1cb22e35f3cca75a1bbce8bb068b9453ec7bc6a6d
@@ -0,0 +1,33 @@
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
@@ -0,0 +1,36 @@
1
+ name: "CI"
2
+ on: [pull_request]
3
+
4
+ jobs:
5
+ build:
6
+ strategy:
7
+ fail-fast: false
8
+ matrix:
9
+ ruby: ["2.5", "2.6"]
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 ruby version
23
+ run: |
24
+ ruby --version
25
+ bundler --version
26
+
27
+ # Prepare
28
+ - name: Install bundler 1.7
29
+ run: gem install bundler -v "~> 1.7"
30
+ - name: Install ruby dependencies
31
+ run: bundle install -j4 --clean --path=vendor
32
+
33
+ - name: Run test
34
+ run: bundle exec rake spec
35
+ - name: Run lint
36
+ run: bundle exec rake rubocop
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/KrauseFx/xcode-install.svg?style=svg)](https://circleci.com/gh/KrauseFx/xcode-install)
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)
4
4
 
5
5
  Install and update your Xcodes automatically.
6
6
 
@@ -149,9 +149,11 @@ XcodeInstall automatically installs additional components so that it is immediat
149
149
  commandline. Unfortunately, Xcode will load third-party plugins even in that situation, which leads
150
150
  to a dialog popping up. Feel free to dupe [the radar][5]. 📡
151
151
 
152
- XcodeInstall uses the Spotlight index to locate installed versions of Xcode. If you use it while
152
+ XcodeInstall normally relies on the Spotlight index to locate installed versions of Xcode. If you use it while
153
153
  indexing is happening, it might show inaccurate results and it will not be able to see installed
154
- versions on unindexed volumes.
154
+ versions on unindexed volumes.
155
+
156
+ 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.
155
157
 
156
158
  ## Thanks
157
159
 
@@ -5,7 +5,10 @@ module XcodeInstall
5
5
  self.summary = 'Installs Xcode Command Line Tools.'
6
6
 
7
7
  def run
8
- fail Informative, 'Xcode CLI Tools are already installed.' if installed?
8
+ if installed?
9
+ print 'Xcode CLI Tools are already installed.'
10
+ exit(0)
11
+ end
9
12
  install
10
13
  end
11
14
 
@@ -17,12 +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
27
+ @version ||= File.read('.xcode-version') if File.exist?('.xcode-version')
26
28
  @url = argv.option('url')
27
29
  @force = argv.flag?('force', false)
28
30
  @should_clean = argv.flag?('clean', true)
@@ -30,6 +32,7 @@ module XcodeInstall
30
32
  @should_switch = argv.flag?('switch', true)
31
33
  @progress = argv.flag?('progress', true)
32
34
  @show_release_notes = argv.flag?('show-release-notes', true)
35
+ @retry_download_count = argv.option('retry-download-count', '3')
33
36
  super
34
37
  end
35
38
 
@@ -37,14 +40,18 @@ module XcodeInstall
37
40
  super
38
41
 
39
42
  help! 'A VERSION argument is required.' unless @version
40
- fail Informative, "Version #{@version} already installed." if @installer.installed?(@version) && !@force
43
+ if @installer.installed?(@version) && !@force
44
+ print "Version #{@version} already installed."
45
+ exit(0)
46
+ end
41
47
  fail Informative, "Version #{@version} doesn't exist." unless @url || @installer.exist?(@version)
42
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?
43
50
  end
44
51
 
45
52
  def run
46
53
  @installer.install_version(@version, @should_switch, @should_clean, @should_install,
47
- @progress, @url, @show_release_notes)
54
+ @progress, @url, @show_release_notes, nil, @retry_download_count.to_i)
48
55
  end
49
56
  end
50
57
  end
@@ -28,7 +28,7 @@ module XcodeInstall
28
28
 
29
29
  def run
30
30
  xcode = @installer.installed_versions.detect { |v| v.version == @version }
31
- `sudo xcode-select --switch #{xcode.path}`
31
+ `sudo xcode-select --switch "#{xcode.path}"`
32
32
  @installer.symlink xcode.version if @should_symlink
33
33
  end
34
34
  end
@@ -1,3 +1,3 @@
1
1
  module XcodeInstall
2
- VERSION = '2.4.0'.freeze
2
+ VERSION = '2.6.7'.freeze
3
3
  end
data/lib/xcode/install.rb CHANGED
@@ -8,7 +8,10 @@ require 'xcode/install/command'
8
8
  require 'xcode/install/version'
9
9
  require 'shellwords'
10
10
  require 'open3'
11
- require 'fileutils'
11
+ require 'fastlane'
12
+ require 'fastlane/helper/sh_helper'
13
+ require 'fastlane/action'
14
+ require 'fastlane/actions/verify_xcode'
12
15
 
13
16
  module XcodeInstall
14
17
  CACHE_DIR = Pathname.new("#{ENV['HOME']}/Library/Caches/XcodeInstall")
@@ -22,13 +25,15 @@ module XcodeInstall
22
25
  # @param progress: parse and show the progress?
23
26
  # @param progress_block: A block that's called whenever we have an updated progress %
24
27
  # 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
25
29
  # rubocop:disable Metrics/AbcSize
26
30
  def fetch(url: nil,
27
31
  directory: nil,
28
32
  cookies: nil,
29
33
  output: nil,
30
34
  progress: nil,
31
- progress_block: nil)
35
+ progress_block: nil,
36
+ retry_download_count: 3)
32
37
  options = cookies.nil? ? [] : ['--cookie', cookies, '--cookie-jar', COOKIES_PATH]
33
38
 
34
39
  uri = URI.parse(url)
@@ -57,6 +62,7 @@ module XcodeInstall
57
62
  retry_options = ['--retry', '3']
58
63
  command = [
59
64
  'curl',
65
+ '--disable',
60
66
  *options,
61
67
  *retry_options,
62
68
  '--location',
@@ -74,7 +80,7 @@ module XcodeInstall
74
80
  # "Partial file. Only a part of the file was transferred."
75
81
  # https://curl.haxx.se/mail/archive-2008-07/0098.html
76
82
  # https://github.com/KrauseFx/xcode-install/issues/210
77
- 3.times do
83
+ retry_download_count.times do
78
84
  # Non-blocking call of Open3
79
85
  # We're not using the block based syntax, as the bacon testing
80
86
  # library doesn't seem to support writing tests for it
@@ -95,7 +101,7 @@ module XcodeInstall
95
101
 
96
102
  # Call back the block for other processes that might be interested
97
103
  matched = progress_content.match(/^\s*(\d+)/)
98
- next unless matched.length == 2
104
+ next unless matched && matched.length == 2
99
105
  percent = matched[1].to_i
100
106
  progress_block.call(percent) if progress_block
101
107
  end
@@ -131,7 +137,7 @@ module XcodeInstall
131
137
  File.symlink?(SYMLINK_PATH) ? SYMLINK_PATH : nil
132
138
  end
133
139
 
134
- def download(version, progress, url = nil, progress_block = nil)
140
+ def download(version, progress, url = nil, progress_block = nil, retry_download_count = 3)
135
141
  xcode = find_xcode_version(version) if url.nil?
136
142
  return if url.nil? && xcode.nil?
137
143
 
@@ -143,7 +149,8 @@ module XcodeInstall
143
149
  cookies: url ? nil : spaceship.cookie,
144
150
  output: dmg_file,
145
151
  progress: progress,
146
- progress_block: progress_block
152
+ progress_block: progress_block,
153
+ retry_download_count: retry_download_count
147
154
  )
148
155
  result ? CACHE_DIR + dmg_file : nil
149
156
  end
@@ -164,8 +171,12 @@ module XcodeInstall
164
171
 
165
172
  seedlist.each do |current_seed|
166
173
  return current_seed if current_seed.name == version
174
+ end
175
+
176
+ seedlist.each do |current_seed|
167
177
  return current_seed if parsed_version && current_seed.version == parsed_version
168
178
  end
179
+
169
180
  nil
170
181
  end
171
182
 
@@ -206,18 +217,17 @@ module XcodeInstall
206
217
  current_xcode.installed = cached_installed_versions.include?(current_xcode.version)
207
218
  end
208
219
 
209
- all_xcodes.sort_by(&:version)
220
+ all_xcodes.sort_by { |seed| [seed.version, -seed.date_modified] }.reverse
210
221
  end
211
222
 
212
223
  def install_dmg(dmg_path, suffix = '', switch = true, clean = true)
213
- archive_util = '/System/Library/CoreServices/Applications/Archive Utility.app/Contents/MacOS/Archive Utility'
214
224
  prompt = "Please authenticate for Xcode installation.\nPassword: "
215
225
  xcode_path = "/Applications/Xcode#{suffix}.app"
216
226
 
217
227
  if dmg_path.extname == '.xip'
218
- `'#{archive_util}' #{dmg_path}`
219
- xcode_orig_path = dmg_path.dirname + 'Xcode.app'
220
- xcode_beta_path = dmg_path.dirname + 'Xcode-beta.app'
228
+ `xip -x #{dmg_path}`
229
+ xcode_orig_path = File.join(Dir.pwd, 'Xcode.app')
230
+ xcode_beta_path = File.join(Dir.pwd, 'Xcode-beta.app')
221
231
  if Pathname.new(xcode_orig_path).exist?
222
232
  `sudo -p "#{prompt}" mv "#{xcode_orig_path}" "#{xcode_path}"`
223
233
  elsif Pathname.new(xcode_beta_path).exist?
@@ -250,13 +260,14 @@ HELP
250
260
  `umount "/Volumes/Xcode"`
251
261
  end
252
262
 
253
- unless verify_integrity(xcode_path)
263
+ xcode = InstalledXcode.new(xcode_path)
264
+
265
+ unless xcode.verify_integrity
254
266
  `sudo rm -rf #{xcode_path}`
255
267
  return
256
268
  end
257
269
 
258
270
  enable_developer_mode
259
- xcode = InstalledXcode.new(xcode_path)
260
271
  xcode.approve_license
261
272
  xcode.install_components
262
273
 
@@ -272,12 +283,12 @@ HELP
272
283
  end
273
284
 
274
285
  # rubocop:disable Metrics/ParameterLists
275
- def install_version(version, switch = true, clean = true, install = true, progress = true, url = nil, show_release_notes = true, progress_block = nil)
276
- 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)
277
288
  fail Informative, "Failed to download Xcode #{version}." if dmg_path.nil?
278
289
 
279
290
  if install
280
- install_dmg(dmg_path, "-#{version.to_s.split(' ')[0]}", switch, clean)
291
+ install_dmg(dmg_path, "-#{version.to_s.split(' ').join('.')}", switch, clean)
281
292
  else
282
293
  puts "Downloaded Xcode #{version} to '#{dmg_path}'"
283
294
  end
@@ -292,12 +303,21 @@ HELP
292
303
  end
293
304
 
294
305
  def list_annotated(xcodes_list)
295
- installed = installed_versions.map(&:version)
296
- xcodes_list.map { |x| installed.include?(x) ? "#{x} (installed)" : x }.join("\n")
306
+ installed = installed_versions.map(&:appname_version)
307
+
308
+ xcodes_list.map do |x|
309
+ xcode_version = x.split(' ') # split version and "beta N", "for Lion"
310
+ xcode_version[0] << '.0' unless xcode_version[0].include?('.')
311
+
312
+ # to match InstalledXcode.appname_version format
313
+ version = Gem::Version.new(xcode_version.join('.'))
314
+
315
+ installed.include?(version) ? "#{x} (installed)" : x
316
+ end.join("\n")
297
317
  end
298
318
 
299
319
  def list
300
- list_annotated(list_versions.sort)
320
+ list_annotated(list_versions.sort { |first, second| compare_versions(first, second) })
301
321
  end
302
322
 
303
323
  def rm_list_cache
@@ -353,17 +373,18 @@ HELP
353
373
  `sudo /usr/sbin/dseditgroup -o edit -t group -a staff _developer`
354
374
  end
355
375
 
356
- 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)
357
377
  if url
358
378
  path = Pathname.new(url)
359
379
  return path if path.exist?
360
380
  end
361
381
  if ENV.key?('XCODE_INSTALL_CACHE_DIR')
362
- cache_path = Pathname.new(ENV['XCODE_INSTALL_CACHE_DIR']) + Pathname.new("xcode-#{version}.dmg")
363
- return cache_path if cache_path.exist?
382
+ Pathname.glob(ENV['XCODE_INSTALL_CACHE_DIR'] + '/*').each do |fpath|
383
+ return fpath if /^xcode_#{version}\.dmg|xip$/ =~ fpath.basename.to_s
384
+ end
364
385
  end
365
386
 
366
- download(version, progress, url, progress_block)
387
+ download(version, progress, url, progress_block, retry_download_count)
367
388
  end
368
389
 
369
390
  def fetch_seedlist
@@ -381,11 +402,13 @@ HELP
381
402
  end
382
403
 
383
404
  def installed
384
- unless (`mdutil -s /` =~ /disabled/).nil?
385
- raise 'Please enable Spotlight indexing for /Applications.'
405
+ result = `mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'" 2>/dev/null`.split("\n")
406
+ if result.empty?
407
+ result = `find /Applications -maxdepth 1 -name '*.app' -type d -exec sh -c \
408
+ 'if [ "$(/usr/libexec/PlistBuddy -c "Print :CFBundleIdentifier" \
409
+ "{}/Contents/Info.plist" 2>/dev/null)" == "com.apple.dt.Xcode" ]; then echo "{}"; fi' ';'`.split("\n")
386
410
  end
387
-
388
- `mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'" 2>/dev/null`.split("\n")
411
+ result
389
412
  end
390
413
 
391
414
  def parse_seedlist(seedlist)
@@ -433,7 +456,7 @@ HELP
433
456
  return [] if scan.empty?
434
457
 
435
458
  version = scan.first.gsub(/<.*?>/, '').gsub(/.*Xcode /, '')
436
- link = body.scan(%r{<button .*"(.+?.xip)".*</button>}).first.first
459
+ link = body.scan(%r{<button .*"(.+?.(dmg|xip))".*</button>}).first.first
437
460
  notes = body.scan(%r{<a.+?href="(/go/\?id=xcode-.+?)".*>(.*)</a>}).first.first
438
461
  links << Xcode.new(version, link, notes)
439
462
  end
@@ -441,9 +464,25 @@ HELP
441
464
  links
442
465
  end
443
466
 
444
- def verify_integrity(path)
445
- puts `/usr/sbin/spctl --assess --verbose=4 --type execute #{path}`
446
- $?.exitstatus.zero?
467
+ def compare_versions(first, second)
468
+ # Sort by version number
469
+ numeric_comparation = first.to_f <=> second.to_f
470
+ return numeric_comparation if numeric_comparation != 0
471
+
472
+ # Return beta versions before others
473
+ is_first_beta = first.include?('beta')
474
+ is_second_beta = second.include?('beta')
475
+ return -1 if is_first_beta && !is_second_beta
476
+ return 1 if !is_first_beta && is_second_beta
477
+
478
+ # Return GM versions before others
479
+ is_first_gm = first.include?('GM')
480
+ is_second_gm = second.include?('GM')
481
+ return -1 if is_first_gm && !is_second_gm
482
+ return 1 if !is_first_gm && is_second_gm
483
+
484
+ # Sort alphabetically
485
+ first <=> second
447
486
  end
448
487
 
449
488
  def hdiutil(*args)
@@ -497,12 +536,13 @@ HELP
497
536
  end
498
537
  end
499
538
 
500
- def download(progress, progress_block = nil)
539
+ def download(progress, progress_block = nil, retry_download_count = 3)
501
540
  result = Curl.new.fetch(
502
541
  url: source,
503
542
  directory: CACHE_DIR,
504
543
  progress: progress,
505
- progress_block: progress_block
544
+ progress_block: progress_block,
545
+ retry_download_count: retry_download_count
506
546
  )
507
547
  result ? dmg_path : nil
508
548
  end
@@ -587,7 +627,18 @@ HELP
587
627
  end
588
628
 
589
629
  def bundle_version
590
- @bundle_version ||= Gem::Version.new(plist_entry(':DTXcode').to_i.to_s.split(//).join('.'))
630
+ @bundle_version ||= Gem::Version.new(bundle_version_string)
631
+ end
632
+
633
+ def appname_version
634
+ appname = @path.basename('.app').to_s
635
+ version_string = appname.split('-').last
636
+ begin
637
+ Gem::Version.new(version_string)
638
+ rescue ArgumentError
639
+ puts 'Unable to determine Xcode version from path name, installed list may not correctly identify installed betas'
640
+ Gem::Version.new(nil)
641
+ end
591
642
  end
592
643
 
593
644
  def uuid
@@ -606,12 +657,18 @@ HELP
606
657
 
607
658
  def approve_license
608
659
  if Gem::Version.new(version) < Gem::Version.new('7.3')
609
- license_path = "#{@path}/Contents/Resources/English.lproj/License.rtf"
610
- license_id = IO.read(license_path).match(/\bEA\d{4}\b/)
660
+ license_info_path = File.join(@path, 'Contents/Resources/LicenseInfo.plist')
661
+ license_id = `/usr/libexec/PlistBuddy -c 'Print :licenseID' #{license_info_path}`
662
+ license_type = `/usr/libexec/PlistBuddy -c 'Print :licenseType' #{license_info_path}`
611
663
  license_plist_path = '/Library/Preferences/com.apple.dt.Xcode.plist'
612
664
  `sudo rm -rf #{license_plist_path}`
613
- `sudo /usr/libexec/PlistBuddy -c "add :IDELastGMLicenseAgreedTo string #{license_id}" #{license_plist_path}`
614
- `sudo /usr/libexec/PlistBuddy -c "add :IDEXcodeVersionForAgreedToGMLicense string #{@version}" #{license_plist_path}`
665
+ if license_type == 'GM'
666
+ `sudo /usr/libexec/PlistBuddy -c "add :IDELastGMLicenseAgreedTo string #{license_id}" #{license_plist_path}`
667
+ `sudo /usr/libexec/PlistBuddy -c "add :IDEXcodeVersionForAgreedToGMLicense string #{version}" #{license_plist_path}`
668
+ else
669
+ `sudo /usr/libexec/PlistBuddy -c "add :IDELastBetaLicenseAgreedTo string #{license_id}" #{license_plist_path}`
670
+ `sudo /usr/libexec/PlistBuddy -c "add :IDEXcodeVersionForAgreedToBetaLicense string #{version}" #{license_plist_path}`
671
+ end
615
672
  else
616
673
  `sudo #{@path}/Contents/Developer/usr/bin/xcodebuild -license accept`
617
674
  end
@@ -628,7 +685,7 @@ HELP
628
685
  def install_components
629
686
  # starting with Xcode 9, we have `xcodebuild -runFirstLaunch` available to do package
630
687
  # postinstalls using a documented option
631
- if Gem::Version.new(@version) >= Gem::Version.new('9')
688
+ if Gem::Version.new(version) >= Gem::Version.new('9')
632
689
  `sudo #{@path}/Contents/Developer/usr/bin/xcodebuild -runFirstLaunch`
633
690
  else
634
691
  Dir.glob("#{@path}/Contents/Resources/Packages/*.pkg").each do |pkg|
@@ -648,11 +705,36 @@ HELP
648
705
  output.split("\n").first.split(' ')[1]
649
706
  end
650
707
 
708
+ def verify_integrity
709
+ verify_app_security_assessment && verify_app_cert
710
+ end
711
+
651
712
  :private
652
713
 
714
+ def bundle_version_string
715
+ digits = plist_entry(':DTXcode').to_i.to_s
716
+ if digits.length < 3
717
+ digits.split(//).join('.')
718
+ else
719
+ "#{digits[0..-3]}.#{digits[-2]}.#{digits[-1]}"
720
+ end
721
+ end
722
+
653
723
  def plist_entry(keypath)
654
724
  `/usr/libexec/PlistBuddy -c "Print :#{keypath}" "#{path}/Contents/Info.plist"`.chomp
655
725
  end
726
+
727
+ def verify_app_security_assessment
728
+ puts `/usr/bin/codesign --verify --verbose #{@path}`
729
+ $?.exitstatus.zero?
730
+ end
731
+
732
+ def verify_app_cert
733
+ Fastlane::Actions::VerifyXcodeAction.run(xcode_path: @path.to_s)
734
+ true
735
+ rescue
736
+ false
737
+ end
656
738
  end
657
739
 
658
740
  # A version of Xcode we fetched from the Apple Developer Portal
@@ -660,7 +742,7 @@ HELP
660
742
  #
661
743
  # Sample object:
662
744
  # <XcodeInstall::Xcode:0x007fa1d451c390
663
- # @date_modified=2015,
745
+ # @date_modified=1573661580,
664
746
  # @name="6.4",
665
747
  # @path="/Developer_Tools/Xcode_6.4/Xcode_6.4.dmg",
666
748
  # @url=
@@ -683,7 +765,7 @@ HELP
683
765
 
684
766
  def initialize(json, url = nil, release_notes_url = nil)
685
767
  if url.nil?
686
- @date_modified = json['dateModified'].to_i
768
+ @date_modified = DateTime.strptime(json['dateModified'], '%m/%d/%y %H:%M').strftime('%s').to_i
687
769
  @name = json['name'].gsub(/^Xcode /, '')
688
770
  @path = json['files'].first['remotePath']
689
771
  url_prefix = 'https://developer.apple.com/devcenter/download.action?path='
@@ -715,6 +797,7 @@ HELP
715
797
 
716
798
  def self.new_prerelease(version, url, release_notes_path)
717
799
  new('name' => version,
800
+ 'dateModified' => '01/01/70 00:00',
718
801
  'files' => [{ 'remotePath' => url.split('=').last }],
719
802
  'release_notes_path' => release_notes_path)
720
803
  end
@@ -1 +1,30 @@
1
- {"active":true,"availableInMemberSite":true,"categories":[{"active":null,"dateCreated":1052825460000,"dateModified":1079108316000,"enabled":true,"id":187,"name":"Developer Tools","sortOrder":28}],"dateAvailable":null,"dateCreated":1413472373000,"dateDisabled":null,"dateModified":1413472373000,"description":"This package enables UNIX-style development via Terminal by installing command line developer tools, as well as Mac OS X SDK frameworks and headers. Many useful tools are included, such as the Apple LLVM compiler, linker, and Make. If you use Xcode, these tools are also embedded within the Xcode IDE.","files":[{"active":true,"dateCreated":1413472373000,"dateModified":1413472373000,"fileSize":107698152,"format":{"active":null,"dateCreated":1066327569000,"dateModified":null,"description":"Disk Image","extension":".dmg","id":12},"id":33285,"name":"Command Line Tools for OSX 10.9 for Xcode 6.1","remotePath":"/Developer_Tools/command_line_tools_os_x_10.9_for_xcode__xcode_6.1/command_line_tools_for_osx_10.9_for_xcode_6.1.dmg","sortOrder":1,"state":"ENABLED"}],"id":21958,"name":"Command Line Tools (OS X 10.9) for Xcode - Xcode 6.1","prerelease":false,"releasedSeed":true,"state":"ENABLED"}
1
+ {
2
+ "name": "Xcode 9.3",
3
+ "description": "This is the complete Xcode developer toolset for Apple Watch, Apple TV, iPhone, iPad, and Mac. It includes the Xcode IDE, iOS Simulator, and all required tools and frameworks for building iOS, watchOS, tvOS and macOS apps.",
4
+ "isReleased": 1,
5
+ "datePublished": "03/23/18 09:47",
6
+ "dateCreated": "11/01/19 12:00",
7
+ "dateModified": "11/01/19 12:58",
8
+ "categories": [
9
+ {
10
+ "id": 187,
11
+ "name": "Developer Tools",
12
+ "sortOrder": 28
13
+ }
14
+ ],
15
+ "files": [
16
+ {
17
+ "filename": "Xcode 9.3.xip",
18
+ "displayName": "Xcode 9.3",
19
+ "remotePath": "/Developer_Tools/Xcode_9.3/Xcode_9.3.xip",
20
+ "fileSize": 5235094775,
21
+ "sortOrder": 0,
22
+ "dateCreated": "11/01/19 19:00",
23
+ "dateModified": "11/01/19 19:58",
24
+ "fileFormat": {
25
+ "extension": ".xip",
26
+ "description": "XIP"
27
+ }
28
+ }
29
+ ]
30
+ }
@@ -1,46 +1,30 @@
1
1
  {
2
- "active": true,
3
- "availableInMemberSite": true,
4
- "categories": [
5
- {
6
- "active": null,
7
- "dateCreated": 1052825460000,
8
- "dateModified": 1079108316000,
9
- "enabled": true,
10
- "id": 187,
11
- "name": "Developer Tools",
12
- "sortOrder": 28
13
- }
14
- ],
15
- "dateAvailable": null,
16
- "dateCreated": 1425695047000,
17
- "dateDisabled": null,
18
- "dateModified": 1425943753000,
19
- "description": "This is the complete Xcode developer toolset for Mac, iPhone, and iPad. It includes the Xcode IDE, iOS Simulator, and all required tools and frameworks for building OS X and iOS apps.",
20
- "files": [
21
- {
22
- "active": true,
23
- "dateCreated": 1425696402000,
24
- "dateModified": 1425929405000,
25
- "fileSize": 2778059898,
26
- "format": {
27
- "active": null,
28
- "dateCreated": 1066327569000,
29
- "dateModified": null,
30
- "description": "Disk Image",
31
- "extension": ".dmg",
32
- "id": 12
33
- },
34
- "id": 35240,
35
- "name": "Xcode 6.3",
36
- "remotePath": "/Developer_Tools/Xcode_6.2/Xcode_6.2.dmg",
37
- "sortOrder": null,
38
- "state": "ENABLED"
39
- }
40
- ],
41
- "id": 23600,
42
- "name": "Xcode 6.3",
43
- "prerelease": false,
44
- "releasedSeed": true,
45
- "state": "ENABLED"
2
+ "name": "Xcode 6.3",
3
+ "description": "This is the complete Xcode developer toolset for Apple Watch, iPhone, iPad, and Mac. It includes the Xcode IDE, iOS Simulator, and all required tools and frameworks for building OS X and iOS apps.",
4
+ "isReleased": 1,
5
+ "datePublished": "04/08/15 14:36",
6
+ "dateCreated": "12/11/19 13:41",
7
+ "dateModified": "12/11/19 14:28",
8
+ "categories": [
9
+ {
10
+ "id": 187,
11
+ "name": "Developer Tools",
12
+ "sortOrder": 28
13
+ }
14
+ ],
15
+ "files": [
16
+ {
17
+ "filename": "Xcode 6.3.dmg",
18
+ "displayName": "Xcode 6.3",
19
+ "remotePath": "/Developer_Tools/Xcode_6.3/Xcode_6.3.dmg",
20
+ "fileSize": 2685818165,
21
+ "sortOrder": 0,
22
+ "dateCreated": "12/11/19 21:41",
23
+ "dateModified": "12/11/19 22:28",
24
+ "fileFormat": {
25
+ "extension": ".dmg",
26
+ "description": "Disk Image"
27
+ }
28
+ }
29
+ ]
46
30
  }