Rakefile 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356
  1. require 'xcjobs'
  2. require 'json'
  3. def xcode_version
  4. `xcodebuild -version`.split("\n").first.scan(/\d+/).join('.')
  5. end
  6. def destinations(platform: 'iphonesimulator')
  7. if platform == 'iphonesimulator'
  8. if xcode_version.start_with?('11')
  9. [ 'name=iPhone 11 Pro,OS=13.0'
  10. ]
  11. elsif xcode_version.start_with?('10')
  12. [ 'name=iPhone 5s,OS=12.0',
  13. 'name=iPhone 6,OS=12.0',
  14. 'name=iPhone 6s Plus,OS=12.0',
  15. 'name=iPhone SE,OS=12.0',
  16. 'name=iPad Air 2,OS=12.0',
  17. 'name=iPad Pro (9.7-inch),OS=12.0',
  18. 'name=iPad Pro (12.9-inch),OS=12.0'
  19. ]
  20. elsif xcode_version.start_with?('9.4')
  21. [ 'name=iPhone 5s,OS=11.4',
  22. 'name=iPhone 6,OS=11.4',
  23. 'name=iPhone 6s Plus,OS=11.4',
  24. 'name=iPhone SE,OS=11.4',
  25. 'name=iPad Air 2,OS=11.4',
  26. 'name=iPad Pro (9.7-inch),OS=11.4',
  27. 'name=iPad Pro (12.9-inch),OS=11.4'
  28. ]
  29. elsif xcode_version.start_with?('9.3')
  30. [ 'name=iPhone 5s,OS=11.0.1',
  31. 'name=iPhone 5s,OS=11.1',
  32. 'name=iPhone 6,OS=11.2',
  33. 'name=iPhone 6s Plus,OS=11.3',
  34. 'name=iPhone SE,OS=11.0.1',
  35. 'name=iPad Air 2,OS=11.1',
  36. 'name=iPad Pro (9.7-inch),OS=11.2',
  37. 'name=iPad Pro (12.9-inch),OS=11.3'
  38. ]
  39. elsif xcode_version.start_with?('9.2')
  40. [ 'name=iPhone 5s,OS=11.2',
  41. 'name=iPhone 5s,OS=11.2',
  42. 'name=iPhone 6,OS=11.2',
  43. 'name=iPhone 6s Plus,OS=11.2',
  44. 'name=iPhone SE,OS=11.2',
  45. 'name=iPad Air 2,OS=11.2',
  46. 'name=iPad Pro (9.7-inch),OS=11.2',
  47. 'name=iPad Pro (12.9-inch),OS=11.2'
  48. ]
  49. elsif xcode_version.start_with?('9.1')
  50. [ 'name=iPhone 5s,OS=11.1',
  51. 'name=iPhone 5s,OS=11.1',
  52. 'name=iPhone 6,OS=11.1',
  53. 'name=iPhone 6s Plus,OS=11.1',
  54. 'name=iPhone SE,OS=11.1',
  55. 'name=iPad Air 2,OS=11.1',
  56. 'name=iPad Pro (9.7-inch),OS=11.1',
  57. 'name=iPad Pro (12.9-inch),OS=11.1'
  58. ]
  59. elsif xcode_version.start_with?('9')
  60. [ 'name=iPhone 5,OS=10.0',
  61. 'name=iPhone 5s,OS=10.0',
  62. 'name=iPhone 6,OS=10.0',
  63. 'name=iPhone 6s Plus,OS=10.3.1',
  64. 'name=iPhone SE,OS=10.3.1',
  65. 'name=iPhone 7,OS=11.0',
  66. 'name=iPad Air 2,OS=10.0',
  67. 'name=iPad Pro (9.7-inch),OS=10.0',
  68. 'name=iPad Pro (12.9-inch),OS=10.0',
  69. 'name=iPad Pro (10.5-inch),OS=11.0'
  70. ]
  71. else
  72. [ 'name=iPhone 5,OS=10.0',
  73. 'name=iPhone 5s,OS=10.0',
  74. 'name=iPhone 6,OS=10.0',
  75. 'name=iPhone 6s Plus,OS=10.3.1',
  76. 'name=iPhone SE,OS=10.3.1',
  77. 'name=iPad Air 2,OS=10.0',
  78. 'name=iPad Pro (9.7-inch),OS=10.0',
  79. 'name=iPad Pro (12.9-inch),OS=10.0'
  80. ]
  81. end
  82. elsif platform == 'watchsimulator'
  83. if xcode_version.start_with?('11')
  84. [ 'name=Apple Watch Series 4 - 44mm,OS=6.0'
  85. ]
  86. elsif xcode_version.start_with?('10')
  87. [ 'name=Apple Watch Series 4 - 40mm,OS=5.0',
  88. 'name=Apple Watch Series 4 - 44mm,OS=5.0'
  89. ]
  90. elsif xcode_version.start_with?('9.4')
  91. [ 'name=Apple Watch Series 3 - 38mm,OS=4.3',
  92. 'name=Apple Watch Series 3 - 42mm,OS=4.3'
  93. ]
  94. elsif xcode_version.start_with?('9.3')
  95. [ 'name=Apple Watch - 38mm,OS=4.3',
  96. 'name=Apple Watch - 42mm,OS=4.3',
  97. 'name=Apple Watch Series 2 - 42mm,OS=4.3'
  98. ]
  99. elsif xcode_version.start_with?('9.2')
  100. [ 'name=Apple Watch - 38mm,OS=4.2',
  101. 'name=Apple Watch - 42mm,OS=4.2',
  102. 'name=Apple Watch Series 2 - 42mm,OS=4.2'
  103. ]
  104. elsif xcode_version.start_with?('9.1')
  105. [ 'name=Apple Watch - 38mm,OS=4.1',
  106. 'name=Apple Watch - 42mm,OS=4.1',
  107. 'name=Apple Watch Series 2 - 42mm,OS=4.1'
  108. ]
  109. elsif xcode_version.start_with?('9')
  110. [ 'name=Apple Watch - 38mm,OS=3.2',
  111. 'name=Apple Watch - 42mm,OS=4.0',
  112. 'name=Apple Watch Series 2 - 42mm,OS=4.0'
  113. ]
  114. else
  115. [ 'name=Apple Watch - 38mm,OS=3.2',
  116. 'name=Apple Watch Series 2 - 42mm,OS=3.2'
  117. ]
  118. end
  119. elsif platform == 'appletvsimulator'
  120. if xcode_version.start_with?('11')
  121. [ 'name=Apple TV 4K,OS=13.0'
  122. ]
  123. elsif xcode_version.start_with?('10')
  124. [ 'name=Apple TV 4K,OS=12.0'
  125. ]
  126. elsif xcode_version.start_with?('9.4')
  127. [ 'name=Apple TV 4K,OS=11.4'
  128. ]
  129. elsif xcode_version.start_with?('9.3')
  130. [ 'name=Apple TV 4K,OS=11.3'
  131. ]
  132. elsif xcode_version.start_with?('9.2')
  133. [ 'name=Apple TV 4K,OS=11.2'
  134. ]
  135. elsif xcode_version.start_with?('9.1')
  136. [ 'name=Apple TV 4K,OS=11.1'
  137. ]
  138. elsif xcode_version.start_with?('9')
  139. [ 'name=Apple TV 1080p,OS=10.2',
  140. 'name=Apple TV 1080p,OS=11.0'
  141. ]
  142. else
  143. [ 'name=Apple TV 1080p,OS=10.2'
  144. ]
  145. end
  146. else
  147. [
  148. 'platform=OS X,arch=x86_64'
  149. ]
  150. end
  151. end
  152. def supportedPlatforms
  153. ['macosx', 'iphoneos', 'iphonesimulator', 'watchos', 'watchsimulator', 'appletvos', 'appletvsimulator']
  154. end
  155. def configurations
  156. ['Debug', 'Release']
  157. end
  158. desc "build for all platforms"
  159. task :build do |t|
  160. supportedPlatforms
  161. .product(configurations)
  162. .map { |platform, configuration| Rake::Task["build:#{platform}:#{configuration.downcase}"] }
  163. .map(&:invoke)
  164. end
  165. namespace :build do
  166. supportedPlatforms.product(configurations).each do |platform, configuration|
  167. XCJobs::Build.new("#{platform}:#{configuration.downcase}") do |t|
  168. t.project = 'KeychainAccess'
  169. t.scheme = 'KeychainAccess'
  170. t.sdk = platform
  171. t.configuration = configuration
  172. t.build_dir = 'build'
  173. t.hide_shell_script_environment = true
  174. t.formatter = 'xcpretty -c'
  175. if ENV['CI']
  176. t.add_build_setting('CODE_SIGN_IDENTITY', '')
  177. t.add_build_setting('CODE_SIGNING_REQUIRED', 'NO')
  178. end
  179. if xcode_version.start_with?('11')
  180. t.add_build_setting('SWIFT_VERSION', '5.1')
  181. if platform == 'iphonesimulator'
  182. t.add_destination('name=iPhone 11,OS=13.0')
  183. elsif platform == 'watchsimulator'
  184. t.add_destination('name=Apple Watch Series 4 - 44mm,OS=6.0')
  185. elsif platform == 'appletvsimulator'
  186. t.add_destination('name=Apple TV 4K,OS=13.0')
  187. end
  188. elsif xcode_version.start_with?('10.3')
  189. t.add_build_setting('SWIFT_VERSION', '5.0')
  190. if platform == 'iphonesimulator'
  191. t.add_destination('name=iPhone 7,OS=12.0')
  192. elsif platform == 'watchsimulator'
  193. t.add_destination('name=Apple Watch Series 4 - 44mm,OS=5.0')
  194. elsif platform == 'appletvsimulator'
  195. t.add_destination('name=Apple TV 4K,OS=12.0')
  196. end
  197. elsif xcode_version.start_with?('10')
  198. t.add_build_setting('SWIFT_VERSION', '4.2')
  199. if platform == 'iphonesimulator'
  200. t.add_destination('name=iPhone 7,OS=12.0')
  201. elsif platform == 'watchsimulator'
  202. t.add_destination('name=Apple Watch Series 4 - 44mm,OS=5.0')
  203. elsif platform == 'appletvsimulator'
  204. t.add_destination('name=Apple TV 4K,OS=12.0')
  205. end
  206. elsif xcode_version.start_with?('9.4')
  207. t.add_build_setting('SWIFT_VERSION', '4.1')
  208. if platform == 'iphonesimulator'
  209. t.add_destination('name=iPhone 7,OS=11.4')
  210. elsif platform == 'watchsimulator'
  211. t.add_destination('name=Apple Watch Series 3 - 42mm,OS=4.3')
  212. elsif platform == 'appletvsimulator'
  213. t.add_destination('name=Apple TV 4K,OS=11.4')
  214. end
  215. elsif xcode_version.start_with?('9.3')
  216. t.add_build_setting('SWIFT_VERSION', '4.1')
  217. if platform == 'iphonesimulator'
  218. t.add_destination('name=iPhone 7,OS=11.3')
  219. elsif platform == 'watchsimulator'
  220. t.add_destination('name=Apple Watch - 42mm,OS=4.3')
  221. elsif platform == 'appletvsimulator'
  222. t.add_destination('name=Apple TV 4K,OS=11.3')
  223. end
  224. elsif xcode_version.start_with?('9.2')
  225. t.add_build_setting('SWIFT_VERSION', '4.0')
  226. if platform == 'iphonesimulator'
  227. t.add_destination('name=iPhone 7,OS=11.2')
  228. elsif platform == 'watchsimulator'
  229. t.add_destination('name=Apple Watch - 42mm,OS=4.2')
  230. elsif platform == 'appletvsimulator'
  231. t.add_destination('name=Apple TV 4K,OS=11.2')
  232. end
  233. elsif xcode_version.start_with?('9.1')
  234. t.add_build_setting('SWIFT_VERSION', '4.0')
  235. if platform == 'iphonesimulator'
  236. t.add_destination('name=iPhone 7,OS=11.1')
  237. elsif platform == 'watchsimulator'
  238. t.add_destination('name=Apple Watch - 42mm,OS=4.1')
  239. elsif platform == 'appletvsimulator'
  240. t.add_destination('name=Apple TV 4K,OS=11.1')
  241. end
  242. elsif xcode_version.start_with?('9')
  243. t.add_build_setting('SWIFT_VERSION', '4.0')
  244. if platform == 'iphonesimulator'
  245. t.add_destination('name=iPhone 7,OS=11.0')
  246. elsif platform == 'watchsimulator'
  247. t.add_destination('name=Apple Watch - 42mm,OS=4.0')
  248. elsif platform == 'appletvsimulator'
  249. t.add_destination('name=Apple TV 1080p,OS=11.0')
  250. end
  251. else
  252. t.add_build_setting('SWIFT_VERSION', '3.0')
  253. if platform == 'iphonesimulator'
  254. t.add_destination('name=iPhone 7,OS=10.3.1')
  255. elsif platform == 'watchsimulator'
  256. t.add_destination('name=Apple Watch - 42mm,OS=3.2')
  257. elsif platform == 'appletvsimulator'
  258. t.add_destination('name=Apple TV 1080p,OS=10.0')
  259. end
  260. end
  261. end
  262. end
  263. task :carthage do
  264. sh %[echo 'github \"kishikawakatsumi/KeychainAccess\"' > Cartfile]
  265. if xcode_version.start_with?('11')
  266. sh %[echo SWIFT_VERSION=\"5.1\" > swift.xcconfig]
  267. elsif xcode_version.start_with?('10.3')
  268. sh %[echo SWIFT_VERSION=\"5.0\" > swift.xcconfig]
  269. elsif xcode_version.start_with?('10')
  270. sh %[echo SWIFT_VERSION=\"4.2\" > swift.xcconfig]
  271. elsif xcode_version.start_with?('9.4')
  272. sh %[echo SWIFT_VERSION=\"4.1\" > swift.xcconfig]
  273. elsif xcode_version.start_with?('9.3')
  274. sh %[echo SWIFT_VERSION=\"4.1\" > swift.xcconfig]
  275. elsif xcode_version.start_with?('9')
  276. sh %[echo SWIFT_VERSION=\"4.0\" > swift.xcconfig]
  277. else
  278. sh %[echo SWIFT_VERSION=\"3.0\" > swift.xcconfig]
  279. end
  280. sh %[XCODE_XCCONFIG_FILE=`pwd`/swift.xcconfig carthage update --no-use-binaries]
  281. sh %[find . -name '*.bcsymbolmap' | xargs grep swiftlang]
  282. end
  283. end
  284. namespace :test do
  285. supportedPlatforms
  286. .select { |platform| platform == 'macosx' || platform == 'iphonesimulator' || platform == 'appletvsimulator' }
  287. .each do |platform|
  288. task platform do |t|
  289. configurations.each do |configuration|
  290. destinations(platform: platform)
  291. .map { |destination| Rake::Task["test:#{platform}:#{configuration.downcase}:#{destination}"] }
  292. .map(&:invoke)
  293. end
  294. end
  295. end
  296. end
  297. namespace :test do
  298. supportedPlatforms
  299. .select { |platform| platform == 'macosx' || platform == 'iphonesimulator' || platform == 'appletvsimulator' }
  300. .product(configurations)
  301. .each do |platform, configuration|
  302. destinations(platform: platform).each do |destination|
  303. XCJobs::Test.new("#{platform}:#{configuration.downcase}:#{destination}") do |t|
  304. t.project = 'KeychainAccess'
  305. t.scheme = 'KeychainAccess'
  306. t.sdk = platform
  307. t.configuration = configuration
  308. t.add_destination(destination)
  309. t.coverage = true
  310. t.build_dir = 'build'
  311. t.hide_shell_script_environment = true
  312. if xcode_version.start_with?('11')
  313. t.add_build_setting('SWIFT_VERSION', '5.1')
  314. elsif xcode_version.start_with?('10.3')
  315. t.add_build_setting('SWIFT_VERSION', '5.0')
  316. elsif xcode_version.start_with?('10')
  317. t.add_build_setting('SWIFT_VERSION', '4.2')
  318. elsif xcode_version.start_with?('9.4')
  319. t.add_build_setting('SWIFT_VERSION', '4.1')
  320. elsif xcode_version.start_with?('9.3')
  321. t.add_build_setting('SWIFT_VERSION', '4.1')
  322. elsif xcode_version.start_with?('9')
  323. t.add_build_setting('SWIFT_VERSION', '4.0')
  324. else
  325. t.add_build_setting('SWIFT_VERSION', '3.0')
  326. end
  327. t.after_action do
  328. build_coverage_reports()
  329. puts `curl -L https://codecov.io/bash | bash -s -- -f 'coverage.txt'`
  330. end
  331. end
  332. end
  333. end
  334. end
  335. def build_coverage_reports()
  336. project_name = 'KeychainAccess'
  337. profdata = Dir.glob(File.join('build', '/**/Coverage.profdata')).first
  338. Dir.glob(File.join('build', "/**/#{project_name}")) do |target|
  339. output = `xcrun llvm-cov report -instr-profile "#{profdata}" "#{target}" -arch=x86_64`
  340. if $?.success?
  341. puts output
  342. `xcrun llvm-cov show -instr-profile "#{profdata}" "#{target}" -arch=x86_64 -use-color=0 > coverage.txt`
  343. break
  344. end
  345. end
  346. end