lib/xcode/install.rb in xcode-install-0.9.6 vs lib/xcode/install.rb in xcode-install-1.0.0
- old
+ new
@@ -42,16 +42,16 @@
def current_symlink
File.symlink?(SYMLINK_PATH) ? SYMLINK_PATH : nil
end
- def download(version, progress)
- return unless exist?(version)
+ def download(version, progress, url = nil)
+ return unless exist?(version) || url
xcode = seedlist.find { |x| x.name == version }
- dmg_file = Pathname.new(File.basename(xcode.path))
+ dmg_file = Pathname.new(File.basename(url || xcode.path))
- result = Curl.new.fetch(xcode.url, CACHE_DIR, spaceship.cookie, dmg_file, progress)
+ result = Curl.new.fetch(url || xcode.url, CACHE_DIR, spaceship.cookie, dmg_file, progress)
result ? CACHE_DIR + dmg_file : nil
end
def exist?(version)
list_versions.include?(version)
@@ -73,15 +73,16 @@
`hdiutil mount -nobrowse -noverify #{dmgPath}`
puts 'Please authenticate for Xcode installation...'
source = Dir.glob('/Volumes/Xcode/Xcode*.app').first
if source.nil?
- $stderr.puts <<-HELP
+ out <<-HELP
No `Xcode.app` found in DMG. Please remove #{dmgPath} if you suspect a corrupted
-download or run `xcode-install update` to see if the version you tried to install
+download or run `xcversion update` to see if the version you tried to install
has been pulled by Apple. If none of this is true, please open a new GH issue.
HELP
+ $stderr.puts out.gsub("\n", ' ')
return
end
`sudo ditto "#{source}" "#{xcode_path}"`
`umount "/Volumes/Xcode"`
@@ -90,11 +91,11 @@
`sudo rm -f #{xcode_path}`
return
end
enable_developer_mode
- `sudo xcodebuild -license accept` unless xcode_license_approved?
+ InstalledXcode.new(xcode_path).approve_license
if switch
`sudo rm -f #{SYMLINK_PATH}` unless current_symlink.nil?
`sudo ln -sf #{xcode_path} #{SYMLINK_PATH}` unless SYMLINK_PATH.exist?
@@ -103,18 +104,25 @@
end
FileUtils.rm_f(dmgPath) if clean
end
- def install_version(version, switch = true, clean = true, install = true, progress = true)
- return if version.nil?
- dmg_path = get_dmg(version, progress)
+ def install_version(version, switch = true, clean = true, install = true, progress = true, url = nil)
+ dmg_path = get_dmg(version, progress, url)
fail Informative, "Failed to download Xcode #{version}." if dmg_path.nil?
install_dmg(dmg_path, "-#{version.split(' ')[0]}", switch, clean) if install
+
+ open_release_notes_url(version)
end
+ def open_release_notes_url(version)
+ return if version.nil?
+ xcode = seedlist.find { |x| x.name == version }
+ `open #{xcode.release_notes_url}` unless xcode.nil? || xcode.release_notes_url.nil?
+ end
+
def list_current
stable_majors = list_versions.reject { |v| /beta/i =~ v }.map { |v| v.split('.')[0] }.map { |v| v.split(' ')[0] }
latest_stable_major = stable_majors.select { |v| v.length == 1 }.uniq.sort.last.to_i
list_versions.select { |v| v.split('.')[0].to_i >= latest_stable_major }.sort.join("\n")
end
@@ -169,17 +177,21 @@
def enable_developer_mode
`sudo /usr/sbin/DevToolsSecurity -enable`
`sudo /usr/sbin/dseditgroup -o edit -t group -a staff _developer`
end
- def get_dmg(version, progress = true)
+ def get_dmg(version, progress = true, url = nil)
+ if url
+ path = Pathname.new(url)
+ return path if path.exist?
+ end
if ENV.key?('XCODE_INSTALL_CACHE_DIR')
cache_path = Pathname.new(ENV['XCODE_INSTALL_CACHE_DIR']) + Pathname.new("xcode-#{version}.dmg")
return cache_path if cache_path.exist?
end
- download(version, progress)
+ download(version, progress, url)
end
def fetch_seedlist
@xcodes = parse_seedlist(spaceship.send(:request, :get, '/services-account/QH65B2/downloadws/listDownloads.action', {
start: "0",
@@ -209,11 +221,11 @@
`mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'" 2>/dev/null`.split("\n")
end
def parse_seedlist(seedlist)
- seeds = seedlist['downloads'].select do |t|
+ seeds = Array(seedlist['downloads']).select do |t|
/^Xcode [0-9]/.match(t['name'])
end
xcodes = seeds.map { |x| Xcode.new(x) }.reject { |x| x.version < MINIMUM_VERSION }.sort do |a, b|
a.date_modified <=> b.date_modified
@@ -228,12 +240,20 @@
end
def prereleases
body=spaceship.send(:request, :get, '/xcode/download/').body
links=body.scan(/<a.+?href="(.+?.dmg)".*>(.*)<\/a>/)
-
- links.map { |pre| Xcode.new_prelease(pre[1].strip.gsub(/.*Xcode /, ''), pre[0]) }
+ links = links.map do |link|
+ parent = link[0].scan(/path=(\/.*\/.*\/)/).first.first
+ match = body.scan(/#{Regexp.quote(parent)}(.+?.pdf)/).first
+ if match
+ link += [parent + match.first]
+ else
+ link += [nil]
+ end
+ end
+ links.map { |pre| Xcode.new_prerelease(pre[1].strip.gsub(/.*Xcode /, ''), pre[0], pre[2]) }
end
def seedlist
@xcodes = Marshal.load(File.read(LIST_FILE)) if LIST_FILE.exist? && xcodes.nil?
xcodes || fetch_seedlist
@@ -241,14 +261,10 @@
def verify_integrity(path)
puts `/usr/sbin/spctl --assess --verbose=4 --type execute #{path}`
$?.exitstatus == 0
end
-
- def xcode_license_approved?
- !(`/usr/bin/xcrun clang 2>&1` =~ /license/ && !$CHILD_STATUS.success?)
- end
end
class InstalledXcode
attr_reader :path
attr_reader :version
@@ -256,10 +272,19 @@
def initialize(path)
@path = Pathname.new(path)
@version = get_version(path)
end
+ def approve_license
+ license_path = "#{@path}/Contents/Resources/English.lproj/License.rtf"
+ license_id = IO.read(license_path).match(/^EA\d{4}/)
+ license_plist_path = '/Library/Preferences/com.apple.dt.Xcode.plist'
+ `sudo rm -rf #{license_plist_path}`
+ `sudo /usr/libexec/PlistBuddy -c "add :IDELastGMLicenseAgreedTo string #{license_id}" #{license_plist_path}`
+ `sudo /usr/libexec/PlistBuddy -c "add :IDEXcodeVersionForAgreedToGMLicense string #{@version}" #{license_plist_path}`
+ end
+
:private
def get_version(xcode_path)
output = `DEVELOPER_DIR='' "#{xcode_path}/Contents/Developer/usr/bin/xcodebuild" -version`
return '0.0' if output.nil? # ¯\_(ツ)_/¯
@@ -271,16 +296,19 @@
attr_reader :date_modified
attr_reader :name
attr_reader :path
attr_reader :url
attr_reader :version
+ attr_reader :release_notes_url
def initialize(json)
@date_modified = json['dateModified'].to_i
@name = json['name'].gsub(/^Xcode /, '')
@path = json['files'].first['remotePath']
- @url = "https://developer.apple.com/devcenter/download.action?path=#{@path}"
+ url_prefix = 'https://developer.apple.com/devcenter/download.action?path='
+ @url = "#{url_prefix}#{@path}"
+ @release_notes_url = "#{url_prefix}#{json['release_notes_path']}" if json['release_notes_path']
begin
@version = Gem::Version.new(@name.split(' ')[0])
rescue
@version = Installer::MINIMUM_VERSION
@@ -294,12 +322,13 @@
def ==(other)
date_modified == other.date_modified && name == other.name && path == other.path && \
url == other.url && version == other.version
end
- def self.new_prelease(version, url)
+ def self.new_prerelease(version, url, release_notes_path)
new('name' => version,
'dateModified' => Time.now.to_i,
- 'files' => [{ 'remotePath' => url.split('=').last }])
+ 'files' => [{ 'remotePath' => url.split('=').last }],
+ 'release_notes_path' => release_notes_path)
end
end
end