Class: XcodeInstall::Installer

Inherits:
Object
  • Object
show all
Defined in:
lib/xcode/install.rb

Constant Summary collapse

CACHE_DIR =
Pathname.new("#{ENV['HOME']}/Library/Caches/XcodeInstall")
LIST_FILE =
CACHE_DIR + Pathname.new('xcodes.bin')
MINIMUM_VERSION =
Gem::Version.new('4.3')
Pathname.new('/Applications/Xcode.app')

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initializeInstaller



62
63
64
# File 'lib/xcode/install.rb', line 62

def initialize
	FileUtils.mkdir_p(CACHE_DIR)
end

Instance Attribute Details

#xcodesObject (readonly)

Returns the value of attribute xcodes.



60
61
62
# File 'lib/xcode/install.rb', line 60

def xcodes
  @xcodes
end

Instance Method Details

#cache_dirObject



66
67
68
# File 'lib/xcode/install.rb', line 66

def cache_dir
	CACHE_DIR
end


70
71
72
# File 'lib/xcode/install.rb', line 70

def current_symlink
	File.symlink?(SYMLINK_PATH) ? SYMLINK_PATH : nil
end

#devcenterObject



156
157
158
# File 'lib/xcode/install.rb', line 156

def devcenter
	@devcenter ||= FastlaneCore::DeveloperCenter.new
end

#download(version) ⇒ Object



74
75
76
77
78
79
80
81
# File 'lib/xcode/install.rb', line 74

def download(version)
	return unless exist?(version)
	xcode = seedlist.select { |x| x.name == version }.first
	dmg_file = Pathname.new(File.basename(xcode.path))

	result = Curl.new.fetch(xcode.url, CACHE_DIR, devcenter.cookies, dmg_file)
	result ? CACHE_DIR + dmg_file : nil
end

#enable_developer_modeObject



160
161
162
163
# File 'lib/xcode/install.rb', line 160

def enable_developer_mode
	`sudo /usr/sbin/DevToolsSecurity -enable`
	`sudo /usr/sbin/dseditgroup -o edit -t group -a staff _developer`
end

#exist?(version) ⇒ Boolean



83
84
85
# File 'lib/xcode/install.rb', line 83

def exist?(version)
	list_versions.include?(version)
end

#get_seedlistObject



165
166
167
168
169
170
171
172
173
174
# File 'lib/xcode/install.rb', line 165

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

#install_dmg(dmgPath, suffix = '', switch = true, clean = true) ⇒ Object



97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
# File 'lib/xcode/install.rb', line 97

def install_dmg(dmgPath, suffix = '', switch = true, clean = true)
	xcode_path = "/Applications/Xcode#{suffix}.app"

	`hdiutil mount -nobrowse -noverify #{dmgPath}`
	puts 'Please authenticate for Xcode installation...'
	source =  Dir.glob('/Volumes/Xcode/Xcode*.app').first

	if source.nil?
		puts 'No `Xcode.app` found in DMG.'
		return
	end

	`sudo ditto "#{source}" "#{xcode_path}"`
	`umount "/Volumes/Xcode"`

	enable_developer_mode
	`sudo xcodebuild -license` unless xcode_license_approved?

	if switch
		`sudo rm -f #{SYMLINK_PATH}` unless current_symlink.nil?
		`sudo ln -sf #{xcode_path} #{SYMLINK_PATH}` unless SYMLINK_PATH.exist?
		
		`sudo xcode-select --switch #{xcode_path}`
		puts `xcodebuild -version`
	end

	FileUtils.rm_f(dmgPath) if clean
end

#installedObject



176
177
178
# File 'lib/xcode/install.rb', line 176

def installed
	`mdfind "kMDItemCFBundleIdentifier == 'com.apple.dt.Xcode'" 2>/dev/null`.split("\n")
end

#installed?(version) ⇒ Boolean



87
88
89
# File 'lib/xcode/install.rb', line 87

def installed?(version)
	installed_versions.map { |x| x.version }.include?(version)
end

#installed_versionsObject



91
92
93
94
95
# File 'lib/xcode/install.rb', line 91

def installed_versions
	@installed ||= installed.map { |x| InstalledXcode.new(x) }.sort { 
		|a,b| Gem::Version.new(a.version) <=> Gem::Version.new(b.version)
	}
end

#listObject



131
132
133
# File 'lib/xcode/install.rb', line 131

def list
	list_versions.join("\n")
end

#list_currentObject



126
127
128
129
# File 'lib/xcode/install.rb', line 126

def list_current
	majors = list_versions.map { |v| v.split('.')[0] }.select { |v| v.length == 1 }.uniq
	list_versions.select { |v| v.start_with?(majors.last) }.join("\n")
end

#list_versionsObject



188
189
190
191
# File 'lib/xcode/install.rb', line 188

def list_versions
	installed = installed_versions.map { |x| x.version }
	seedlist.map { |x| x.name }.reject { |x| installed.include?(x) }
end

#parse_seedlist(seedlist) ⇒ Object



180
181
182
183
184
185
186
# File 'lib/xcode/install.rb', line 180

def parse_seedlist(seedlist)
	seedlist['data'].select { 
		|t| /^Xcode [0-9]/.match(t['name'])
	}.map { |x| Xcode.new(x) }.reject { |x| x.version < MINIMUM_VERSION }.sort { 
		|a,b| a.dateModified <=> b.dateModified
	}
end

#prereleasesObject



193
194
195
196
197
198
# File 'lib/xcode/install.rb', line 193

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

#rm_list_cacheObject



135
136
137
# File 'lib/xcode/install.rb', line 135

def rm_list_cache
	FileUtils.rm_f(LIST_FILE)
end

#seedlistObject



200
201
202
203
# File 'lib/xcode/install.rb', line 200

def seedlist
	@xcodes = Marshal.load(File.read(LIST_FILE)) if LIST_FILE.exist? && xcodes.nil?
	xcodes || get_seedlist
end


139
140
141
142
143
# File 'lib/xcode/install.rb', line 139

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


145
146
147
# File 'lib/xcode/install.rb', line 145

def symlinks_to
	File.absolute_path(File.readlink(current_symlink), SYMLINK_PATH.dirname) if current_symlink
end

#xcode_license_approved?Boolean



205
206
207
# File 'lib/xcode/install.rb', line 205

def xcode_license_approved?
	!(`/usr/bin/xcrun clang 2>&1` =~ /license/ && !$?.success?)
end