lib/xcode/install.rb in xcode-install-0.0.1 vs lib/xcode/install.rb in xcode-install-0.0.2
- old
+ new
@@ -1,7 +1,8 @@
require "fastlane_core"
require "fastlane_core/developer_center/developer_center"
+require "nokogiri"
require "xcode/install/command"
require "xcode/install/version"
module FastlaneCore
class DeveloperCenter
@@ -59,10 +60,14 @@
def initialize
FileUtils.mkdir_p(CACHE_DIR)
end
+ def current_symlink
+ File.symlink?(SYMLINK_PATH) ? SYMLINK_PATH : nil
+ end
+
def download(version)
return unless exist?(version)
xcode = seedlist.select { |x| x.name == version }.first
dmg_file = Pathname.new(File.basename(xcode.path))
@@ -72,16 +77,24 @@
def exist?(version)
list_versions.include?(version)
end
+ def installed?(version)
+ installed_versions.map { |x| x.version }.include?(version)
+ end
+
+ def installed_versions
+ @installed ||= installed.map { |x| InstalledXcode.new(x) }
+ end
+
def install_dmg(dmgPath, suffix = '')
xcode_path = "/Applications/Xcode#{suffix}.app"
- `hdiutil mount -noverify #{dmgPath}`
+ `hdiutil mount -nobrowse -noverify #{dmgPath}`
puts 'Please authenticate for Xcode installation...'
- `sudo cp -R "/Volumes/Xcode/Xcode.app" "#{xcode_path}"`
+ `sudo ditto "/Volumes/Xcode/Xcode.app" "#{xcode_path}"`
`umount "/Volumes/Xcode"`
`sudo xcode-select -s #{xcode_path}`
puts `xcodebuild -version`
end
@@ -93,45 +106,90 @@
def list
list_versions.join("\n")
end
+ def rm_list_cache
+ FileUtils.rm_f(LIST_FILE)
+ end
+
+ def symlink(version)
+ xcode = installed_versions.select { |x| x.version == version }.first
+ `sudo rm -f #{SYMLINK_PATH}` unless current_symlink.nil?
+ `sudo ln -sf #{xcode.path} #{SYMLINK_PATH}` unless xcode.nil? || SYMLINK_PATH.exist?
+ end
+
+ def symlinks_to
+ File.absolute_path(File.readlink(current_symlink), SYMLINK_PATH.dirname) if current_symlink
+ end
+
:private
CACHE_DIR = Pathname.new("#{ENV['HOME']}/Library/Caches/XcodeInstall")
LIST_FILE = CACHE_DIR + Pathname.new('xcodes.bin')
+ SYMLINK_PATH = Pathname.new('/Applications/Xcode.app')
def devcenter
@devcenter ||= FastlaneCore::DeveloperCenter.new
end
def get_seedlist
@xcodes = parse_seedlist(devcenter.download_seedlist)
+ @xcodes += prereleases
File.open(LIST_FILE,'w') do |f|
f << Marshal.dump(xcodes)
end
xcodes
end
+ def installed
+ `mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'" 2>/dev/null`.split("\n")
+ end
+
def parse_seedlist(seedlist)
seedlist['data'].select {
|t| /^Xcode [0-9]/.match(t['name'])
}.map { |x| Xcode.new(x) }.sort { |a,b| a.dateModified <=> b.dateModified }
end
def list_versions
- seedlist.map { |x| x.name }
+ installed = installed_versions.map { |x| x.version }
+ seedlist.map { |x| x.name }.reject { |x| installed.include?(x) }
end
+ def prereleases
+ page = Nokogiri::HTML.parse(devcenter.download_file('/xcode/downloads/'))
+ links = page.xpath('//a').select { |link| link['href'].end_with?('.dmg') }
+
+ links.map { |pre| Xcode.new_prelease(pre.text.strip.gsub(/.*Xcode /, ''), pre['href']) }
+ end
+
def seedlist
@xcodes = Marshal.load(File.read(LIST_FILE)) if LIST_FILE.exist? && xcodes.nil?
xcodes || get_seedlist
end
end
+ class InstalledXcode
+ attr_reader :path
+ attr_reader :version
+
+ def initialize(path)
+ @path = Pathname.new(path)
+ @version = get_version(path)
+ end
+
+ :private
+
+ def get_version(xcode_path)
+ output = `DEVELOPER_DIR='' #{xcode_path}/Contents/Developer/usr/bin/xcodebuild -version`
+ output.split("\n").first.split(' ')[1]
+ end
+ end
+
class Xcode
attr_reader :dateModified
attr_reader :name
attr_reader :path
attr_reader :url
@@ -139,8 +197,14 @@
def initialize(json)
@dateModified = json['dateModified'].to_i
@name = json['name'].gsub(/^Xcode /, '')
@path = json['files'].first['remotePath']
@url = "https://developer.apple.com/devcenter/download.action?path=#{@path}"
+ end
+
+ def self.new_prelease(version, url)
+ self.new({'name' => version,
+ 'dateModified' => Time.now.to_i,
+ 'files' => [{'remotePath' => url.split('=').last}]})
end
end
end
\ No newline at end of file