require 'xcjobs' require 'json' def xcode_version `xcodebuild -version`.split("\n").first.scan(/\d+/).join('.') end def destinations(platform: 'iphonesimulator') if platform == 'iphonesimulator' if xcode_version.start_with?('11') [ 'name=iPhone 11 Pro,OS=13.0' ] elsif xcode_version.start_with?('10') [ 'name=iPhone 5s,OS=12.0', 'name=iPhone 6,OS=12.0', 'name=iPhone 6s Plus,OS=12.0', 'name=iPhone SE,OS=12.0', 'name=iPad Air 2,OS=12.0', 'name=iPad Pro (9.7-inch),OS=12.0', 'name=iPad Pro (12.9-inch),OS=12.0' ] elsif xcode_version.start_with?('9.4') [ 'name=iPhone 5s,OS=11.4', 'name=iPhone 6,OS=11.4', 'name=iPhone 6s Plus,OS=11.4', 'name=iPhone SE,OS=11.4', 'name=iPad Air 2,OS=11.4', 'name=iPad Pro (9.7-inch),OS=11.4', 'name=iPad Pro (12.9-inch),OS=11.4' ] elsif xcode_version.start_with?('9.3') [ 'name=iPhone 5s,OS=11.0.1', 'name=iPhone 5s,OS=11.1', 'name=iPhone 6,OS=11.2', 'name=iPhone 6s Plus,OS=11.3', 'name=iPhone SE,OS=11.0.1', 'name=iPad Air 2,OS=11.1', 'name=iPad Pro (9.7-inch),OS=11.2', 'name=iPad Pro (12.9-inch),OS=11.3' ] elsif xcode_version.start_with?('9.2') [ 'name=iPhone 5s,OS=11.2', 'name=iPhone 5s,OS=11.2', 'name=iPhone 6,OS=11.2', 'name=iPhone 6s Plus,OS=11.2', 'name=iPhone SE,OS=11.2', 'name=iPad Air 2,OS=11.2', 'name=iPad Pro (9.7-inch),OS=11.2', 'name=iPad Pro (12.9-inch),OS=11.2' ] elsif xcode_version.start_with?('9.1') [ 'name=iPhone 5s,OS=11.1', 'name=iPhone 5s,OS=11.1', 'name=iPhone 6,OS=11.1', 'name=iPhone 6s Plus,OS=11.1', 'name=iPhone SE,OS=11.1', 'name=iPad Air 2,OS=11.1', 'name=iPad Pro (9.7-inch),OS=11.1', 'name=iPad Pro (12.9-inch),OS=11.1' ] elsif xcode_version.start_with?('9') [ 'name=iPhone 5,OS=10.0', 'name=iPhone 5s,OS=10.0', 'name=iPhone 6,OS=10.0', 'name=iPhone 6s Plus,OS=10.3.1', 'name=iPhone SE,OS=10.3.1', 'name=iPhone 7,OS=11.0', 'name=iPad Air 2,OS=10.0', 'name=iPad Pro (9.7-inch),OS=10.0', 'name=iPad Pro (12.9-inch),OS=10.0', 'name=iPad Pro (10.5-inch),OS=11.0' ] else [ 'name=iPhone 5,OS=10.0', 'name=iPhone 5s,OS=10.0', 'name=iPhone 6,OS=10.0', 'name=iPhone 6s Plus,OS=10.3.1', 'name=iPhone SE,OS=10.3.1', 'name=iPad Air 2,OS=10.0', 'name=iPad Pro (9.7-inch),OS=10.0', 'name=iPad Pro (12.9-inch),OS=10.0' ] end elsif platform == 'watchsimulator' if xcode_version.start_with?('11') [ 'name=Apple Watch Series 4 - 44mm,OS=6.0' ] elsif xcode_version.start_with?('10') [ 'name=Apple Watch Series 4 - 40mm,OS=5.0', 'name=Apple Watch Series 4 - 44mm,OS=5.0' ] elsif xcode_version.start_with?('9.4') [ 'name=Apple Watch Series 3 - 38mm,OS=4.3', 'name=Apple Watch Series 3 - 42mm,OS=4.3' ] elsif xcode_version.start_with?('9.3') [ 'name=Apple Watch - 38mm,OS=4.3', 'name=Apple Watch - 42mm,OS=4.3', 'name=Apple Watch Series 2 - 42mm,OS=4.3' ] elsif xcode_version.start_with?('9.2') [ 'name=Apple Watch - 38mm,OS=4.2', 'name=Apple Watch - 42mm,OS=4.2', 'name=Apple Watch Series 2 - 42mm,OS=4.2' ] elsif xcode_version.start_with?('9.1') [ 'name=Apple Watch - 38mm,OS=4.1', 'name=Apple Watch - 42mm,OS=4.1', 'name=Apple Watch Series 2 - 42mm,OS=4.1' ] elsif xcode_version.start_with?('9') [ 'name=Apple Watch - 38mm,OS=3.2', 'name=Apple Watch - 42mm,OS=4.0', 'name=Apple Watch Series 2 - 42mm,OS=4.0' ] else [ 'name=Apple Watch - 38mm,OS=3.2', 'name=Apple Watch Series 2 - 42mm,OS=3.2' ] end elsif platform == 'appletvsimulator' if xcode_version.start_with?('11') [ 'name=Apple TV 4K,OS=13.0' ] elsif xcode_version.start_with?('10') [ 'name=Apple TV 4K,OS=12.0' ] elsif xcode_version.start_with?('9.4') [ 'name=Apple TV 4K,OS=11.4' ] elsif xcode_version.start_with?('9.3') [ 'name=Apple TV 4K,OS=11.3' ] elsif xcode_version.start_with?('9.2') [ 'name=Apple TV 4K,OS=11.2' ] elsif xcode_version.start_with?('9.1') [ 'name=Apple TV 4K,OS=11.1' ] elsif xcode_version.start_with?('9') [ 'name=Apple TV 1080p,OS=10.2', 'name=Apple TV 1080p,OS=11.0' ] else [ 'name=Apple TV 1080p,OS=10.2' ] end else [ 'platform=OS X,arch=x86_64' ] end end def supportedPlatforms ['macosx', 'iphoneos', 'iphonesimulator', 'watchos', 'watchsimulator', 'appletvos', 'appletvsimulator'] end def configurations ['Debug', 'Release'] end desc "build for all platforms" task :build do |t| supportedPlatforms .product(configurations) .map { |platform, configuration| Rake::Task["build:#{platform}:#{configuration.downcase}"] } .map(&:invoke) end namespace :build do supportedPlatforms.product(configurations).each do |platform, configuration| XCJobs::Build.new("#{platform}:#{configuration.downcase}") do |t| t.project = 'KeychainAccess' t.scheme = 'KeychainAccess' t.sdk = platform t.configuration = configuration t.build_dir = 'build' t.hide_shell_script_environment = true t.formatter = 'xcpretty -c' if ENV['CI'] t.add_build_setting('CODE_SIGN_IDENTITY', '') t.add_build_setting('CODE_SIGNING_REQUIRED', 'NO') end if xcode_version.start_with?('11') t.add_build_setting('SWIFT_VERSION', '5.1') if platform == 'iphonesimulator' t.add_destination('name=iPhone 11,OS=13.0') elsif platform == 'watchsimulator' t.add_destination('name=Apple Watch Series 4 - 44mm,OS=6.0') elsif platform == 'appletvsimulator' t.add_destination('name=Apple TV 4K,OS=13.0') end elsif xcode_version.start_with?('10.3') t.add_build_setting('SWIFT_VERSION', '5.0') if platform == 'iphonesimulator' t.add_destination('name=iPhone 7,OS=12.0') elsif platform == 'watchsimulator' t.add_destination('name=Apple Watch Series 4 - 44mm,OS=5.0') elsif platform == 'appletvsimulator' t.add_destination('name=Apple TV 4K,OS=12.0') end elsif xcode_version.start_with?('10') t.add_build_setting('SWIFT_VERSION', '4.2') if platform == 'iphonesimulator' t.add_destination('name=iPhone 7,OS=12.0') elsif platform == 'watchsimulator' t.add_destination('name=Apple Watch Series 4 - 44mm,OS=5.0') elsif platform == 'appletvsimulator' t.add_destination('name=Apple TV 4K,OS=12.0') end elsif xcode_version.start_with?('9.4') t.add_build_setting('SWIFT_VERSION', '4.1') if platform == 'iphonesimulator' t.add_destination('name=iPhone 7,OS=11.4') elsif platform == 'watchsimulator' t.add_destination('name=Apple Watch Series 3 - 42mm,OS=4.3') elsif platform == 'appletvsimulator' t.add_destination('name=Apple TV 4K,OS=11.4') end elsif xcode_version.start_with?('9.3') t.add_build_setting('SWIFT_VERSION', '4.1') if platform == 'iphonesimulator' t.add_destination('name=iPhone 7,OS=11.3') elsif platform == 'watchsimulator' t.add_destination('name=Apple Watch - 42mm,OS=4.3') elsif platform == 'appletvsimulator' t.add_destination('name=Apple TV 4K,OS=11.3') end elsif xcode_version.start_with?('9.2') t.add_build_setting('SWIFT_VERSION', '4.0') if platform == 'iphonesimulator' t.add_destination('name=iPhone 7,OS=11.2') elsif platform == 'watchsimulator' t.add_destination('name=Apple Watch - 42mm,OS=4.2') elsif platform == 'appletvsimulator' t.add_destination('name=Apple TV 4K,OS=11.2') end elsif xcode_version.start_with?('9.1') t.add_build_setting('SWIFT_VERSION', '4.0') if platform == 'iphonesimulator' t.add_destination('name=iPhone 7,OS=11.1') elsif platform == 'watchsimulator' t.add_destination('name=Apple Watch - 42mm,OS=4.1') elsif platform == 'appletvsimulator' t.add_destination('name=Apple TV 4K,OS=11.1') end elsif xcode_version.start_with?('9') t.add_build_setting('SWIFT_VERSION', '4.0') if platform == 'iphonesimulator' t.add_destination('name=iPhone 7,OS=11.0') elsif platform == 'watchsimulator' t.add_destination('name=Apple Watch - 42mm,OS=4.0') elsif platform == 'appletvsimulator' t.add_destination('name=Apple TV 1080p,OS=11.0') end else t.add_build_setting('SWIFT_VERSION', '3.0') if platform == 'iphonesimulator' t.add_destination('name=iPhone 7,OS=10.3.1') elsif platform == 'watchsimulator' t.add_destination('name=Apple Watch - 42mm,OS=3.2') elsif platform == 'appletvsimulator' t.add_destination('name=Apple TV 1080p,OS=10.0') end end end end task :carthage do sh %[echo 'github \"kishikawakatsumi/KeychainAccess\"' > Cartfile] if xcode_version.start_with?('11') sh %[echo SWIFT_VERSION=\"5.1\" > swift.xcconfig] elsif xcode_version.start_with?('10.3') sh %[echo SWIFT_VERSION=\"5.0\" > swift.xcconfig] elsif xcode_version.start_with?('10') sh %[echo SWIFT_VERSION=\"4.2\" > swift.xcconfig] elsif xcode_version.start_with?('9.4') sh %[echo SWIFT_VERSION=\"4.1\" > swift.xcconfig] elsif xcode_version.start_with?('9.3') sh %[echo SWIFT_VERSION=\"4.1\" > swift.xcconfig] elsif xcode_version.start_with?('9') sh %[echo SWIFT_VERSION=\"4.0\" > swift.xcconfig] else sh %[echo SWIFT_VERSION=\"3.0\" > swift.xcconfig] end sh %[XCODE_XCCONFIG_FILE=`pwd`/swift.xcconfig carthage update --no-use-binaries] sh %[find . -name '*.bcsymbolmap' | xargs grep swiftlang] end end namespace :test do supportedPlatforms .select { |platform| platform == 'macosx' || platform == 'iphonesimulator' || platform == 'appletvsimulator' } .each do |platform| task platform do |t| configurations.each do |configuration| destinations(platform: platform) .map { |destination| Rake::Task["test:#{platform}:#{configuration.downcase}:#{destination}"] } .map(&:invoke) end end end end namespace :test do supportedPlatforms .select { |platform| platform == 'macosx' || platform == 'iphonesimulator' || platform == 'appletvsimulator' } .product(configurations) .each do |platform, configuration| destinations(platform: platform).each do |destination| XCJobs::Test.new("#{platform}:#{configuration.downcase}:#{destination}") do |t| t.project = 'KeychainAccess' t.scheme = 'KeychainAccess' t.sdk = platform t.configuration = configuration t.add_destination(destination) t.coverage = true t.build_dir = 'build' t.hide_shell_script_environment = true if xcode_version.start_with?('11') t.add_build_setting('SWIFT_VERSION', '5.1') elsif xcode_version.start_with?('10.3') t.add_build_setting('SWIFT_VERSION', '5.0') elsif xcode_version.start_with?('10') t.add_build_setting('SWIFT_VERSION', '4.2') elsif xcode_version.start_with?('9.4') t.add_build_setting('SWIFT_VERSION', '4.1') elsif xcode_version.start_with?('9.3') t.add_build_setting('SWIFT_VERSION', '4.1') elsif xcode_version.start_with?('9') t.add_build_setting('SWIFT_VERSION', '4.0') else t.add_build_setting('SWIFT_VERSION', '3.0') end t.after_action do build_coverage_reports() puts `curl -L https://codecov.io/bash | bash -s -- -f 'coverage.txt'` end end end end end def build_coverage_reports() project_name = 'KeychainAccess' profdata = Dir.glob(File.join('build', '/**/Coverage.profdata')).first Dir.glob(File.join('build', "/**/#{project_name}")) do |target| output = `xcrun llvm-cov report -instr-profile "#{profdata}" "#{target}" -arch=x86_64` if $?.success? puts output `xcrun llvm-cov show -instr-profile "#{profdata}" "#{target}" -arch=x86_64 -use-color=0 > coverage.txt` break end end end