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