#!/usr/bin/env ruby $LOAD_PATH << File.join(File.dirname(__FILE__), '..', 'lib') require 'xcselect' require 'optparse' class String def red; colorize(self, "\e[1m\e[31m"); end def dark_red; colorize(self, "\e\[31m"); end def green; colorize(self, "\e[1m\e[32m"); end def dark_green; colorize(self, "\e[32m"); end def yellow; colorize(self, "\e[1m\e[33m"); end def dark_yellow; colorize(self, "\e[33m"); end def blue; colorize(self, "\e[1m\e[34m"); end def dark_blue; colorize(self, "\e[34m"); end def pur; colorize(self, "\e[1m\e[35m"); end def dark_pur; colorize(self, "\e[35m"); end def colorize(text, color_code) (STDIN.tty?) ? "#{color_code}#{text}\e[0m" : text end def numeric? true if Float(self) rescue false end end include Xcselect class Main attr_accessor :xcodes, :current attr_reader :exit_code def initialize @exit_code = 0 optparse = OptionParser.new do |opts| opts.on('-h', '--help', "Display this !!") { puts opts; exit } opts.on('-a', '--alt' , "Alternate through all installs") { select_next() ;exit} opts.on('-s', '--show' , "Show Current") { show_current(); exit } opts.on('-o', '--open' , "Open *.xcodeproj") { open_xcode(); exit } end begin optparse.parse! rescue OptionParser::InvalidOption => e puts "Invalid Option" puts optparse exit 2 end optparse.parse! begin load_xcodes show_menu rescue OptionParser::MissingArgument => e puts e return nil rescue Exception => e puts e puts e.backtrace return end end def select_next load_xcodes if xcodes.size > 1 cur_index = xcodes.index(current) next_index = (cur_index + 1) % xcodes.size set_current xcodes[next_index] end exit end def open_xcode xcodepath = "#{Xcode.current_xcode}/Applications/Xcode.app" puts "Opening Xcode in #{Xcode.current_xcode}" `open -a #{xcodepath} *.xcodeproj` end # don't show line to ask for sudo pass def self.require_sudo_pass? `sudo -n echo 1 2>&1`.chomp != "1" end def set_current xc cmd = "sudo xcode-select -switch #{xc.folder}" if Main.require_sudo_pass? puts "Enter sudo password to select #{xc}" puts "$ #{cmd}" end `#{cmd}` puts "Set Xcode to #{xc}" end def show_current() cur = Xcode.new(Xcode.current_xcode) puts cur puts cur.sdks end def console_availale STDIN.tty? end def select_line x "#{x.version} (#{x.build}) #{x.folder} #{'[current]'.red if x.eql? current}" end def show_menu puts "Please Select an Xcode install ?\n\n" i = 0; xopts = xcodes.each do |x| select_no = "[#{i+=1}]" puts " #{select_no} Xcode #{select_line x}" end print "\nSelection: " begin return unless console_availale input = STDIN.gets input = input.to_i if input.zero? or input > xcodes.size puts "Invalid Selection" @exit_code = 1 elsif xcodes[input - 1].eql?(current) puts "Already Current" @exit_code = 2 else set_current xcodes[input - 1] end rescue SystemExit, Interrupt puts "" return end end def find_all_with_activity_indicator tmp_xcodes = nil; search_thread = Thread.new { tmp_xcodes = Xcode.find_all } display_thread = Thread.new do sleep 0.4 if tmp_xcodes.nil? print "Searching Spotlight " while tmp_xcodes.nil? print "." sleep 0.4 end print "\n" end end search_thread.join display_thread.join return tmp_xcodes end def load_xcodes @xcodes = find_all_with_activity_indicator @current = xcodes.select {|x| x.folder == Xcode.current_xcode}.first end def to_s "xcodes = #{xcodes}\n current = #{current}" end end main = Main.new exit main.exit_code