Slide 1

Slide 1 text

xcrun Essentials 2020/09/21 16:30~ @iOSDC Japan 2020 Yutaro Muta @yutailang0119

Slide 2

Slide 2 text

• Yutaro Muta @yutailang0119 • Hatena Co., Ltd. @Kyoto • Conference Staff Who am I ?

Slide 3

Slide 3 text

https://fortee.jp/iosdc-japan-2020/proposal/5a9f8fa1-8c89-470b-b72c-502f3a4a6f66

Slide 4

Slide 4 text

Q: ޷͖ͳxcrunίϚϯυ͸ʁ • χίੜ΍Twitterʹ౤ߘ͠·͠ΐ͏ • ར༻͍ͯ͠Δਓ ίϚϯυ໊ • Θ͔Βͳ͍ਓ ޷͖ͳ͓ण࢘ωλ

Slide 5

Slide 5 text

Goal • xcrunΛ஌Δ • xcrunΛ࢖͏

Slide 6

Slide 6 text

Agenda • xcrunͱ͸Կ͔? • ར༻͍ͯ͠Δπʔϧ • Documentation Archive / Technical Note • man xcrun • xcrunΛ࢖͏ • ར༻ՄೳͳγϛϡϨʔλΛҰཡ • ίϚϯυϥΠϯ͔ΒTest CoverageΛऔಘ • FAQ • ·ͱΊ

Slide 7

Slide 7 text

xcrunͱ͸Կ͔?

Slide 8

Slide 8 text

ར༻͍ͯ͠Δπʔϧ

Slide 9

Slide 9 text

ར༻͍ͯ͠Δπʔϧ • Carthage/Carthage • fastlane/fastlane • apple/swift -> utils • apple/swift-tools-support-core -> Utilities • apple/sourcekit-lsp -> xcrun sourcekit-lsp • etc...

Slide 10

Slide 10 text

Technical Note TN2339 Building from the Command Line with Xcode FAQ https://developer.apple.com/library/archive/technotes/tn2339/_index.html

Slide 11

Slide 11 text

Technical Note TN2339 Building from the Command Line with Xcode FAQ • Downloading command-line tools is not available in Xcode for macOS 10.9. How can I install them on my machine? > If Xcode is installed on your machine, then there is no need to install them. Xcode comes bundled with all your command-line tools. macOS 10.9 and later includes shims or wrapper executables. These shims, installed in /usr/bin, can map any tool included in /usr/bin to the corresponding one inside Xcode. xcrun is one of such shims, which allows you to find or run any tool inside Xcode from the command line. Use it to invoke any tool within Xcode from the command line as shown in Listing 1

Slide 12

Slide 12 text

Technical Note TN2339 Building from the Command Line with Xcode FAQ • Downloading command-line tools is not available in Xcode for macOS 10.9. How can I install them on my machine? > If Xcode is installed on your machine, then there is no need to install them. Xcode comes bundled with all your command-line tools. macOS 10.9 and later includes shims or wrapper executables. These shims, installed in /usr/bin, can map any tool included in /usr/bin to the corresponding one inside Xcode. xcrun is one of such shims, which allows you to find or run any tool inside Xcode from the command line. Use it to invoke any tool within Xcode from the command line as shown in Listing 1

Slide 13

Slide 13 text

man xcrun

Slide 14

Slide 14 text

man xcrun XCRUN(1) BSD General Commands Manual XCRUN(1) NAME xcrun - Run or locate development tools and properties. SYNOPSIS xcrun [--sdk ] --find xcrun [--sdk ] ... tool arguments ... ... tool arguments ... DESCRIPTION xcrun provides a means to locate or invoke developer tools from the command-line, without requiring users to modify Makefiles or otherwise take inconvenient measures to support multiple Xcode tool chains. The tool xcode-select(1) is used to set a system default for the active developer directory, and may be overridden by the DEVELOPER_DIR environment variable (see ENVIRONMENT). The SDK which will be searched defaults to the most recent available SDK, and can be specified by the SDKROOT environment variable or the --sdk option (which takes precedences over SDKROOT). When used to invoke another tool (as opposed to simply finding it), xcrun will provide the absolute path to the selected SDK in the SDKROOT environment variable. See ENVIRONMENT for more information. ......

Slide 15

Slide 15 text

man xcrun XCRUN(1) BSD General Commands Manual XCRUN(1) NAME xcrun - Run or locate development tools and properties. SYNOPSIS xcrun [--sdk ] --find xcrun [--sdk ] ... tool arguments ... ... tool arguments ... DESCRIPTION xcrun provides a means to locate or invoke developer tools from the command-line, without requiring users to modify Makefiles or otherwise take inconvenient measures to support multiple Xcode tool chains. The tool xcode-select(1) is used to set a system default for the active developer directory, and may be overridden by the DEVELOPER_DIR environment variable (see ENVIRONMENT). The SDK which will be searched defaults to the most recent available SDK, and can be specified by the SDKROOT environment variable or the --sdk option (which takes precedences over SDKROOT). When used to invoke another tool (as opposed to simply finding it), xcrun will provide the absolute path to the selected SDK in the SDKROOT environment variable. See ENVIRONMENT for more information. ......

Slide 16

Slide 16 text

xcrunͱ͸Կ͔? • shimͷ1ͭ • ෳ਺ͷXcodeπʔϧνΣʔϯͷαϙʔτΛҙࣝ͢Δ͜ͱͳ͘ɺίϚϯυϥΠ ϯ͔ΒXcode಺ͷ೚ҙͷπʔϧΛݕࡧ·ͨ͸࣮ߦ͢ΔखஈΛఏڙ

Slide 17

Slide 17 text

[ྫ֎] ಛघͳxcrunίϚϯυͨͪ • shellͷpath͕௨Δlocation ( /usr/bin ) ʹ΋shim͕഑ஔ͞ΕɺxcrunΛܦ༝ͤͣʹ࣮ߦՄೳ • xcodebuid • xed • IDEͱͯ͠ͷXcodeҎ֎ͷػೳ΁ϦϯΫ • xcrun sourcekit-lsp (Xcode 11.4+) • xcrun safari-web-extension-converter (Xcode 12+) • https://developer.apple.com/documentation/safariservices/safari_web_extensions/converting_a_web_extension_for_safari

Slide 18

Slide 18 text

xcrunΛ࢖͏

Slide 19

Slide 19 text

man xcrun

Slide 20

Slide 20 text

man xcrun XCRUN(1) BSD General Commands Manual XCRUN(1) DESCRIPTION xcrun provides a means to locate or invoke developer tools from the command-line, without requiring users to modify Makefiles or otherwise take inconvenient measures to support multiple Xcode tool chains. The tool xcode-select(1) is used to set a system default for the active developer directory, and may be overridden by the DEVELOPER_DIR environment variable (see ENVIRONMENT). The SDK which will be searched defaults to the most recent available SDK, and can be specified by the SDKROOT environment variable or the --sdk option (which takes precedences over SDKROOT). When used to invoke another tool (as opposed to simply finding it), xcrun will provide the absolute path to the selected SDK in the SDKROOT environment variable. See ENVIRONMENT for more information. Usage xcrun supports several different usages, to both look up the paths to tools as well as execute them. When used with the --find argument, as in xcrun [--sdk ] --find , the absolute path to the tool (in the provided SDK, if given) will be printed. When used without --find, the name of a tool is required and the tool will be executed with the provided arguments. When used as the target of a symbolic link, it derives the tool name to use from the name it was invoked under, and then executes that tool. ......

Slide 21

Slide 21 text

1. ར༻ՄೳͳγϛϡϨʔλΛҰཡ

Slide 22

Slide 22 text

xcrun simctl

Slide 23

Slide 23 text

ར༻ՄೳͳγϛϡϨʔλΛҰཡ $ xcrun simctl list devices == Devices == -- iOS 14.0 -- iPhone 8 (30D89693-D53D-4461-93E0-4BE0877DE2AD) (Shutdown) iPhone 8 Plus (0F2B88B5-F8E0-496E-8603-BBE451D0D2C0) (Shutdown) iPhone 11 (990DABBE-9358-43E7-98DD-8A78A7A30340) (Shutdown) iPhone 11 Pro (9F4628C6-F133-4D3B-8902-9B555F032D22) (Shutdown) ...... -- tvOS 14.0 -- -- watchOS 7.0 -- -- Unavailable: com.apple.CoreSimulator.SimRuntime.iOS-13-6 -- ...... nbv -- Unavailable: com.apple.CoreSimulator.SimRuntime.iOS-13-7 -- ...... -- Unavailable: com.apple.CoreSimulator.SimRuntime.tvOS-13-7 -- ...... -- Unavailable: com.apple.CoreSimulator.SimRuntime.watchOS-6-2 -- ......

Slide 24

Slide 24 text

[Ԡ༻] CI্ͰͷςετͰ ςετσόΠεΛOSࢦఆ

Slide 25

Slide 25 text

fastlane.scan Ͱ͸ɺ ςετσόΠεͷॊೈͳࢦఆ͕͠ʹ͍͘

Slide 26

Slide 26 text

ςετσόΠεͷॊೈͳࢦఆ͕͠ʹ͍͘ • fastlane.scan ͷςετσόΠε͸ɺ ୺຤Ϟσϧ໊ (OSόʔδϣϯ) [iPhone 8 (14.0)] Ͱࢦఆ͢Δ • xcodebuild ͷ࢓༷ -destination 'platform=iOS Simulator,name=iPhone 8,OS=14.0' • ࢦఆͨ͠σόΠε͕ଘࡏ͠ͳ͍৔߹ɺద౰ͳσόΠεʹϑΥʔϧόοΫ • ྫ͑͹ɺϝδϟʔOS 2όʔδϣϯͷςετΛCIͰ࣮ߦ͢ΔͨΊʹ͸ɺ XcodeͷϚΠφʔΞοϓσʔτ͝ͱʹࢦఆͷมߋ͕ඞཁ

Slide 27

Slide 27 text

ςετσόΠεͷॊೈͳࢦఆ͕͠ʹ͍͘ lane :test do |options| scan( ...... devices: [ "iPhone 8 (13.7)", # ϚγϯʹΠϯετʔϧ͞Ε͍ͯͳ͍σόΠε "iOS 14", # OSόʔδϣϯͷΈͷࢦఆ͸Ͱ͖ͳ͍ "iPhone 8" # OSόʔδϣϯΛࢦఆͤͣʹ࣮ߦɺ͜ͷϞσϧ͕ར༻Մೳ͔͸ෆ໌ ], ...... ) end [HH:mm:ss]: No simulators found that are equal to the version of specifier (13.7) and greater than or equal to the version of deployment target (0) [HH:mm:ss]: Ignoring 'iPhone 8 (13.7)', couldn’t find matching simulator [HH:mm:ss]: Ignoring 'iOS 14', couldn’t find matching simulator [HH:mm:ss]: Couldn't find any matching simulators for '["iPhone 8 (13.7)", "iOS 14"]' - falling back to default simulator [HH:mm:ss]: Found simulator "iPhone 8 (14.0)"

Slide 28

Slide 28 text

xcrun simctl list devices Ͱར༻ՄೳͳσόΠεΛߜΓࠐΉ

Slide 29

Slide 29 text

ར༻ՄೳͳσόΠεΛߜΓࠐΉ def self.run(params) require 'open3' require "json" stdout, stderr, status = Open3.capture3(*['xcrun', 'simctl', 'list', 'devices', '--json']) # JSONܗࣜͰऔಘ json = JSON.parse(stdout) devices = json['devices'].flat_map { |runtime, metas| metas.map { |meta| Device.new(runtime, meta) # σόΠεܕʹϚοϓ } } devices.filter! { |device| # ৚݅ʹ߹ΘͤͯϑΟϧλ device.os_version.start_with?(*params[:os_versions]) } unless params[:os_versions].empty? devices.filter! { |device| device.name.start_with?(*params[:models]) } unless params[:models].empty? devices.map { |device| device.hash } end https://gist.github.com/yutailang0119/fb9b2df0814575083931f3ed87733d23

Slide 30

Slide 30 text

iOS 14ͷiPhoneΛࢦఆ͢Δ lane :test do |options| ios_14_device = xcode_simulator_devices( os_versions: ['iOS 14'], models: ['iPhone'] ).last devices = [ios_14_device] if devices.include?(nil) then UI.user_error! "The specified devices is not available: #{devices}" end device_identifiers = devices.map { |device| device[:identifier] } scan( ...... devices: device_identifiers, # ["iPhone 8 (14.0)"] ...... ) end

Slide 31

Slide 31 text

2. ίϚϯυϥΠϯ͔Β Test CoverageΛऔಘ

Slide 32

Slide 32 text

Test Coverage in Xcode

Slide 33

Slide 33 text

Test Coverage in Xcode

Slide 34

Slide 34 text

Test Coverage in Xcode • Build Scheme > Test > Options > Code Coverage: Gather coverage for... Λ Φϯ • ςετΛ࣮ߦ࣌ɺDerivedData/{schemeName}/Logs/Test ҎԼʹɺςετΧ όϨοδ৘ใͳͲΛؚΉ .xcresult ͕ੜ੒͞ΕΔ • Xcode্ͰϏδϡΞϥΠζͯ͠ɺݟΔ͜ͱ͕Ͱ͖Δ • .xcresult ࣗମ͸ɺώϡʔϚϯϦʔμϒϧͰ͸ͳ͍

Slide 35

Slide 35 text

CI্ͷςετͰ΋ ςετΧόϨοδΛऔಘ͍ͨ͠

Slide 36

Slide 36 text

CI্ͷςετͰ΋ɺςετΧόϨοδΛऔಘ͍ͨ͠ • CIͰςετΧόϨοδΛऔಘ͠ɺه࿥͢Δ • GitHub Pull RequestʹίϝϯτܗࣜͰՄࢹԽ • MackerelͷService Metricsʹ౤ߘ͢Δ͜ͱͰɺมԽΛه࿥ • hatena/fastlane-plugin-mackerel_actions > mackerel_post_xcresult

Slide 37

Slide 37 text

GitHub Pull RequestʹίϝϯτܗࣜͰՄࢹԽ

Slide 38

Slide 38 text

.xcresult ͔ΒTest CoverageΛऔಘ

Slide 39

Slide 39 text

xcrun xccov

Slide 40

Slide 40 text

.xcresult ͔ΒTest CoverageΛऔಘ def self.run(params) require 'open3' require 'json' scan() xcresult_file = Dir["#{ENV["PWD"]}/build/**/Logs/Test/*.xcresult"].last stdout, stderr, = Open3.capture3('xcrun', 'xccov', 'view', '--report', xcresult_file, '--json') JSON.parse(stdout) end https://github.com/yutailang0119/fastlane-plugin-xcresult_actions

Slide 41

Slide 41 text

FAQ

Slide 42

Slide 42 text

Q: Xcodeͷػೳ͕ xcrunͷͲͷίϚϯυʹରԠ͍ͯ͠Δ͔ Ͳ͏΍ͬͯ୳͢ͷʁ

Slide 43

Slide 43 text

A: جຊ͸ҎԼʹ͋ΔίϚϯυ • $ ls /Applications/Xcode.app/Contents/Developer/usr/bin • $ ls /Applications/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/bin

Slide 44

Slide 44 text

xcrunͷา͖ํ • ໢ཏతͳυΩϡϝϯτ͸͓ͦΒ͘ͳ͍ • man xcrun ΍ xcrun --help ʹ΋ɺ֤ػೳ΁ͷݴٴ͸ͳ͍ • લड़ͷpathʹ͋ΔίϚϯυͷhelpΛࢀর • https://developer.apple.com/documentation ͔Βɺ࣮ݱ͍ͨ͠಺༰Λݟͭ ͚ɺxcrunͷهࡌ͕ͳ͍͔୳͢

Slide 45

Slide 45 text

·ͱΊ

Slide 46

Slide 46 text

·ͱΊ • xcrun͸ɺίϚϯυϥΠϯ͔ΒXcode಺ͷ೚ҙͷπʔϧΛݕࡧɺ࣮ߦͰ͖Δ • IDEͱͯ͠ͷXcodeʹͳ͍πʔϧ΋͋Δ • CIͰXcodeͷػೳΛར༻͍ͨ͠৔߹ʹ༗༻ • xcrun͕ࢀর͢ΔpathͷҰཡΛோΊͯΈΔ • ئΘ͘͸ɺπʔϧ͕૿͑ͯཉ͍͠

Slide 47

Slide 47 text

Q: xcrunΘ͔ͬͨʁ • χίੜ΍Twitterʹ౤ߘ͠·͠ΐ͏ • ࢖͑ͦ͏ͳਓ "xcrunŧŔŕŪũƄŝſ"

Slide 48

Slide 48 text

Enjoy iOSDC, Thanks!!! • [email protected] • https://twitter.com/yutailang0119 • https://github.com/yutailang0119

Slide 49

Slide 49 text

Reference • https://fortee.jp/iosdc-japan-2020/proposal/5a9f8fa1-8c89-470b-b72c-502f3a4a6f66 • https://developer.apple.com/library/archive/technotes/tn2339/_index.html • https://developer.apple.com/documentation/safariservices/safari_web_extensions/ converting_a_web_extension_for_safari • https://gist.github.com/yutailang0119/fb9b2df0814575083931f3ed87733d23 • https://swet.dena.com/entry/2019/10/23/080000 • https://github.com/yutailang0119/fastlane-plugin-xcresult_actions • https://github.com/hatena/fastlane-plugin-mackerel_actions