forked from CocoaPods/CocoaPods
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Rakefile
394 lines (307 loc) · 11.8 KB
/
Rakefile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
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
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
def execute_command(command)
if ENV['VERBOSE']
sh(command)
else
output = `#{command} 2>&1`
raise output unless $?.success?
end
end
#-----------------------------------------------------------------------------#
namespace :gem do
def gem_version
require File.expand_path('../lib/cocoapods/gem_version.rb', __FILE__)
Pod::VERSION
end
def gem_filename
"cocoapods-#{gem_version}.gem"
end
#--------------------------------------#
desc "Build a gem for the current version"
task :build do
sh "gem build cocoapods.gemspec"
end
#--------------------------------------#
desc "Install a gem version of the current code"
task :install => :build do
sh "gem install #{gem_filename}"
end
#--------------------------------------#
def silent_sh(command)
output = `#{command} 2>&1`
unless $?.success?
puts output
exit 1
end
output
end
desc "Run all specs, build and install gem, commit version change, tag version change, and push everything"
task :release do
unless ENV['SKIP_CHECKS']
if `git symbolic-ref HEAD 2>/dev/null`.strip.split('/').last != 'master'
$stderr.puts "[!] You need to be on the `master' branch in order to be able to do a release."
exit 1
end
if `git tag`.strip.split("\n").include?(gem_version)
$stderr.puts "[!] A tag for version `#{gem_version}' already exists. Change the version in lib/cocoapods/gem_version.rb"
silent_sh "open lib/cocoapods/gem_version.rb"
exit 1
end
diff_lines = `git diff --name-only`.strip.split("\n")
diff_lines.delete('CHANGELOG.md')
diff_lines.delete('Gemfile.lock')
if diff_lines.size == 0
$stderr.puts "[!] Change the version number yourself in lib/cocoapods/gem_version.rb"
exit 1
end
if diff_lines != ['lib/cocoapods/gem_version.rb']
$stderr.puts "[!] Only change the version number in a release commit!"
exit 1
end
puts "You are about to release `#{gem_version}', is that correct? [y/n]"
exit if $stdin.gets.strip.downcase != 'y'
end
require 'date'
# First check if the required gems have been pushed
gem_spec = eval(File.read(File.expand_path('../cocoapods.gemspec', __FILE__)))
gem_names = ['xcodeproj', 'cocoapods-core', 'cocoapods-downloader', 'claide']
gem_names.each do |gem_name|
gem = gem_spec.dependencies.find { |d| d.name == gem_name }
required_version = gem.requirement.requirements.first.last.to_s
puts "* Checking if #{gem_name} #{required_version} exists on the gem host"
search_result = silent_sh("gem search --all --pre --remote #{gem_name}")
remote_versions = search_result.match(/#{gem_name} \((.*)\)/m)[1].split(', ')
unless remote_versions.include?(required_version)
$stderr.puts "[!] The #{gem_name} version `#{required_version}' required by " \
"this version of CocoaPods does not exist on the gem host. " \
"Either push that first, or fix the version requirement."
exit 1
end
end
# Ensure that the branches are up to date with the remote
sh "git pull"
puts "* Updating Bundle"
silent_sh('bundle update')
unless ENV['SKIP_SPECS']
puts "* Running specs"
silent_sh('rake spec:all')
end
tmp = File.expand_path('../tmp', __FILE__)
tmp_gems = File.join(tmp, 'gems')
Rake::Task['gem:build'].invoke
puts "* Testing gem installation (tmp/gems)"
silent_sh "rm -rf '#{tmp}'"
silent_sh "gem install --install-dir='#{tmp_gems}' #{gem_filename}"
# Then release
sh "git commit lib/cocoapods/gem_version.rb CHANGELOG.md Gemfile.lock -m 'Release #{gem_version}'"
sh "git tag -a #{gem_version} -m 'Release #{gem_version}'"
sh "git push origin master"
sh "git push origin --tags"
sh "gem push #{gem_filename}"
# Update the last version in CocoaPods-version.yml
puts "* Updating last known version in Specs repo"
specs_branch = 'master'
Dir.chdir('../Specs') do
puts Dir.pwd
sh "git checkout #{specs_branch}"
sh "git pull"
yaml_file = 'CocoaPods-version.yml'
unless File.exist?(yaml_file)
$stderr.puts "[!] Unable to find #{yaml_file}!"
exit 1
end
require 'yaml'
cocoapods_version = YAML.load_file(yaml_file)
cocoapods_version['last'] = gem_version
File.open(yaml_file, "w") do |f|
f.write(cocoapods_version.to_yaml)
end
sh "git commit #{yaml_file} -m 'CocoaPods release #{gem_version}'"
sh "git push"
end
end
end
#-----------------------------------------------------------------------------#
namespace :spec do
def specs(dir)
FileList["spec/#{dir}/*_spec.rb"].shuffle.join(' ')
end
#--------------------------------------#
desc "Automatically run specs for updated files"
task :kick do
exec "bundle exec kicker -c"
end
#--------------------------------------#
unit_specs_command = "bundle exec bacon #{specs('unit/**')}"
desc "Run the unit specs"
task :unit => :unpack_fixture_tarballs do
sh unit_specs_command
end
desc "Run the unit specs quietly (fail fast, display only one failure)"
task :unit_quiet => :unpack_fixture_tarballs do
sh "#{unit_specs_command} -q"
end
#--------------------------------------#
desc "Run the functional specs"
task :functional => :unpack_fixture_tarballs do
sh "bundle exec bacon #{specs('functional/**')}"
end
#--------------------------------------#
desc "Run the integration spec"
task :integration do
unless File.exists?('spec/cocoapods-integration-specs')
$stderr.puts "Integration files not checked out. Run `rake bootstrap`"
exit 1
end
sh "bundle exec bacon spec/integration.rb"
end
# Default task
#--------------------------------------#
#
# The specs helper interfere with the integration 2 specs and thus they need
# to be run separately.
#
task :all => :unpack_fixture_tarballs do
ENV['GENERATE_COVERAGE'] = 'true'
title 'Running the specs'
sh "bundle exec bacon #{specs('**')}"
title 'Running Integration tests'
sh "bundle exec bacon spec/integration.rb"
title 'Running examples'
Rake::Task['examples:build'].invoke
end
# Travis
#--------------------------------------#
#
# The integration 2 tests and the examples use the normal CocoaPods setup.
#
desc "Run all specs and build all examples"
task :ci => :unpack_fixture_tarballs do
title 'Running the specs'
sh "bundle exec bacon #{specs('**')}"
require 'pathname'
unless Pathname.new(ENV['HOME']+'/.cocoapods/repos/master').exist?
title 'Ensuring specs repo is up to date'
sh "./bin/pod setup"
end
title 'Running Integration tests'
sh "bundle exec bacon spec/integration.rb"
title 'Running examples'
Rake::Task['examples:build'].invoke
end
#--------------------------------------#
desc "Rebuild all the fixture tarballs"
task :rebuild_fixture_tarballs do
tarballs = FileList['spec/fixtures/**/*.tar.gz']
tarballs.each do |tarball|
basename = File.basename(tarball)
sh "cd #{File.dirname(tarball)} && rm #{basename} && env COPYFILE_DISABLE=1 tar -zcf #{basename} #{basename[0..-8]}"
end
end
#--------------------------------------#
desc "Unpacks all the fixture tarballs"
task :unpack_fixture_tarballs do
tarballs = FileList['spec/fixtures/**/*.tar.gz']
tarballs.each do |tarball|
basename = File.basename(tarball)
Dir.chdir(File.dirname(tarball)) do
sh "rm -rf #{basename[0..-8]} && tar zxf #{basename}"
end
end
end
#--------------------------------------#
desc "Removes the stored VCR fixture"
task :clean_vcr do
sh "rm -f spec/fixtures/vcr/tarballs.yml"
end
#--------------------------------------#
desc "Rebuilds integration fixtures"
task :rebuild_integration_fixtures do
title 'Running Integration tests'
`bundle exec bacon spec/integration.rb`
title 'Storing fixtures'
# Copy the files to the files produced by the specs to the after folders
FileList['tmp/*'].each do |source|
destination = "spec/cocoapods-integration-specs/#{source.gsub('tmp/','')}/after"
if File.exists?(destination)
sh "rm -rf #{destination}"
sh "mv #{source} #{destination}"
end
end
# Remove files not used for the comparison
# To keep the git diff clean
files_to_delete = FileList['spec/cocoapods-integration-specs/*/after/{Podfile,*.podspec,**/*.xcodeproj,PodTest-hg-source}']
files_to_delete.exclude('/spec/cocoapods-integration-specs/init_single_platform/**/*.*')
files_to_delete.each do |file_to_delete|
sh "rm -rf #{file_to_delete}"
end
puts
puts "Integration fixtures updated, commit and push in the `spec/cocoapods-integration-specs` submodule"
end
#--------------------------------------#
task :clean_env => [:clean_vcr, :unpack_fixture_tarballs, "ext:cleanbuild"]
end
#-----------------------------------------------------------------------------#
task :examples => "examples:build"
namespace :examples do
desc "Open all example workspaces in Xcode, which recreates the schemes."
task :recreate_workspace_schemes do
examples.each do |example|
Dir.chdir(example.to_s) do
# TODO we need to open the workspace in Xcode at least once, otherwise it might not contain schemes.
# The schemes do not seem to survive a SCM round-trip.
sh "open '#{example.basename}.xcworkspace'"
sleep 5
end
end
end
#--------------------------------------#
desc "Build all examples"
task :build do
Dir.chdir("examples/AFNetworking Example") do
puts "Installing Pods"
pod_command = ENV['FROM_GEM'] ? 'sandbox-pod' : 'bundle exec ../../bin/sandbox-pod'
execute_command "rm -rf Pods"
execute_command "#{pod_command} install --verbose --no-repo-update"
puts "Building example: AFNetworking Mac Example'"
execute_command "xcodebuild -workspace 'AFNetworking Examples.xcworkspace' -scheme 'AFNetworking Example' clean install"
puts "Building example: AFNetworking iOS Example'"
xcode_version = `xcodebuild -version`.scan(/Xcode (.*)\n/).first.first
major_version = xcode_version.split('.').first.to_i
# Specifically build against the simulator SDK so we don't have to deal with code signing.
if major_version > 4
execute_command "xcodebuild -workspace 'AFNetworking Examples.xcworkspace' -scheme 'AFNetworking iOS Example' clean install ONLY_ACTIVE_ARCH=NO -destination 'platform=iOS Simulator,name=iPhone Retina (4-inch)'"
else
sdk = Dir.glob("#{`xcode-select -print-path`.chomp}/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator*.sdk").last
execute_command "xcodebuild -workspace 'AFNetworking Examples.xcworkspace' -scheme 'AFNetworking iOS Example' clean install ONLY_ACTIVE_ARCH=NO -sdk #{sdk}"
end
end
end
#--------------------------------------#
end
#-----------------------------------------------------------------------------#
desc "Initializes your working copy to run the specs"
task :bootstrap, :use_bundle_dir? do |t, args|
title "Environment bootstrap"
puts "Updating submodules"
execute_command "git submodule update --init --recursive"
puts "Installing gems"
if args[:use_bundle_dir?]
execute_command "env XCODEPROJ_BUILD=1 bundle install --path ./travis_bundle_dir"
else
execute_command "env XCODEPROJ_BUILD=1 bundle install"
end
end
#-----------------------------------------------------------------------------#
desc "Run all specs"
task :spec => 'spec:all'
task :default => :spec
#-----------------------------------------------------------------------------#
# group helpers
def title(title)
cyan_title = "\033[0;36m#{title}\033[0m"
puts
puts "-" * 80
puts cyan_title
puts "-" * 80
puts
end