実践 Swift Package Manager

7ddcca09c00a2744b983974225447d19?s=47 Sho Ikeda
September 15, 2016

実践 Swift Package Manager

2016年度第4回iPhoneプログラミング勉強会京都での発表資料です #iphonekyoto http://iphonekyoto.connpass.com/event/38339/

7ddcca09c00a2744b983974225447d19?s=128

Sho Ikeda

September 15, 2016
Tweet

Transcript

  1. ࣮ફ Swift Package Manager @ikesyo 2016೥౓ୈ4ճiPhoneϓϩάϥϛϯάษڧձژ౎ 2016-09-14 Wed #iphonekyoto

  2. @ikesyo • ͍͚͠ΐʔʗ஑ా ᠳ • ͸ͯͳ@ژ౎ • https://twitter.com/ikesyo • https://github.com/ikesyo

  3. Swift Package Manager

  4. Swift Package Manager The Swift Package Manager is a tool

    for managing the distribution of Swift code. It’s integrated with the Swift build system to automate the process of downloading, compiling, and linking dependencies. The Package Manager will be released with Swift 3 and is currently only available with the Swift 3 development snapshots. — Swift.org - Package Manager
  5. Swift Package Manager • AppleެࣜʢʂʣɺSwiftඪ४ͷύοέʔδϚωʔδϟʔ • ґଘੑͷμ΢ϯϩʔυɺίϯύΠϧɺϦϯΫΛߦ͏ • தԝूݖͷύοέʔδͷΠϯσοΫε͸࣋ͨͳ͍ •

    Swift 3ͱڞʹϦϦʔε: macOS, Linuxͷ྆ϓϥοτϑΥʔϜͰαϙʔτ • αʔόʔαΠυɺίϚϯυϥΠϯπʔϧ͕ʢࠓͷʣϝΠϯλʔήοτ • swift package • swift build • swift test
  6. swift package

  7. swift package • swift package init: ύοέʔδΛ࡞੒͢Δ • --type •

    empty • library • executable • system-module
  8. swift package swift package init --type empty . ├── Package.swift

    ├── Sources └── Tests
  9. swift package swift package init --type library (same as no

    option) . ├── Package.swift ├── Sources │ └── SwiftPMDemo.swift └── Tests ├── LinuxMain.swift └── SwiftPMDemoTests └── SwiftPMDemoTests.swift
  10. swift package swift package init --type executable . ├── Package.swift

    ├── Sources │ └── main.swift └── Tests
  11. swift package swift package init --type system-module . ├── Package.swift

    └── module.modulemap // module.modulemap module SwiftPMDemo [system] { header "/usr/include/SwiftPMDemo.h" link "SwiftPMDemo" export * }
  12. Package.swift • Manifest file: SwiftʹΑΔDSL • ύοέʔδ໊ɺλʔήοτʢϞδϡʔϧʣɺґଘύοέʔ δɺআ֎ϑΝΠϧͳͲΛࢦఆ • ϦϙδτϦͷτοϓϨϕϧʹ഑ஔ

    • 1ϚχϑΣετͰ1ύοέʔδɺͭ·Γ1ϦϙδτϦͰ1ύοέ ʔδ
  13. Package.swift // ReactiveSwift/Package.swift import PackageDescription let package = Package( name:

    "ReactiveSwift", dependencies: [ .Package( url: "https://github.com/antitypical/Result.git", majorVersion: 3, minor: 0 ) ], exclude: [ "Sources/Deprecations+Removals.swift", ] )
  14. Package.swift Package( name: String, pkgConfig: String? = nil, providers: [SystemPackageProvider]?

    = nil, targets: [Target] = [], dependencies: [Package.Dependency] = [], exclude: [String] = [] )
  15. Package.swift • ґଘύοέʔδ • ηϚϯςΟοΫόʔδϣχϯάͷλάͷΈɻͦΕҎ֎ͷλάɺίϛοτɺϒϥϯν͸ݱࡏ࢖༻Ͱ͖ͳ͍ɻ • ςετ༻͚ͩͷґଘੑ͸ݱࡏ࢖༻Ͱ͖ͳ͍ɻҎલ testDependencies ͕͕͋ͬͨɺকདྷతʹ෮׆͢ΔՄ ೳੑ͕͋Δɻ

    • Handling version-specific logic • ಛఆͷSwiftόʔδϣϯ޲͚ͷόʔδϣχϯάɻ࠷৽όʔδϣϯ޲͚ʹ͸࢖͏΂͖Ͱ͸ͳ͍ɻ • Version-specific tag selection: 1.2.0@swift-3 • Version-specific manifest selection: Package@swift-3.swift It is not expected the packages would ever use this feature unless absolutely necessary to support existing clients. In particular, packages should not adopt this syntax for tagging versions supporting the latest GM Swift version.
  16. swift package • swift package fetch / swift package update

    • ґଘύοέʔδͷϑΣονɺΞοϓσʔτ • swift package generate-xcodeproj • XcodeϓϩδΣΫτϑΝΠϧ (.xcodeproj) ͷੜ੒ • macOS, iOS, tvOS, watchOSͷ4ϓϥοτϑΥʔϜରԠͷ frameworkλʔήοτ • CarthageͰ΋ͦͷ··ϏϧυͰ͖ͨ !
  17. swift build

  18. swift build • Sources/഑Լͷ֤λʔήοτΛϏϧυ͢Δ • Sources/௚Լʹ௚઀ιʔε͕͋Δ৔߹ɺύοέʔδ໊ͱಉ໊ͷλʔήοτ͕ ͋Δͱݟͳ͞ΕΔ • Sources/A/A.swift, Sources/B/B.swift

    ͱ͢ΔͱɺλʔήοτAɺλʔήο τBͷ2͕ͭϏϧυ͞ΕΔ • λʔήοτؒͷґଘఆٛ • ґଘ͞Ε͍ͯΔλʔήοτ͔ΒઌʹϏϧυ͞ΕΔ • λʔήοτͱରԠ͢Δςετλʔήοτʹ͸҉໧ͷґଘੑ͕͋Δ
  19. swift build // swift-package-manager/Package.swift // MARK: Commands Target( /** High-level

    commands */ name: "Commands", dependencies: ["Basic", "Build", "Get", "PackageGraph", "SourceControl", "Xcodeproj"]), Target( /** The main executable provided by SwiftPM */ name: "swift-package", dependencies: ["Commands"]), Target( /** Builds packages */ name: "swift-build", dependencies: ["Commands"]), Target( /** Runs package tests */ name: "swift-test", dependencies: ["Commands"]),
  20. swift build • swift build --clean • ϏϧυύεͷΫϦΞʢσϑΥϧτ͸./.buildɺ--build- pathΦϓγϣϯͰมߋՄೳʣ •

    swift build -c (debug|release) • Ϗϧυઃఆͷࢦఆʢσόοά or ϦϦʔεʣ
  21. // --type libraryͷ৔߹ . ├── .build │ ├── build.db │

    ├── debug │ │ ├── ModuleCache │ │ │ ├── CGC1TPJT37OH │ │ │ │ └── SwiftShims-1HJGLIW7H35BO.pcm │ │ │ └── modules.timestamp │ │ ├── SwiftPMDemo.build │ │ │ ├── SwiftPMDemo.d │ │ │ ├── SwiftPMDemo.swift.o │ │ │ ├── SwiftPMDemo.swiftdeps │ │ │ ├── SwiftPMDemo~partial.swiftdoc │ │ │ ├── SwiftPMDemo~partial.swiftmodule │ │ │ ├── master.swiftdeps │ │ │ └── output-file-map.json │ │ ├── SwiftPMDemo.swiftdoc │ │ ├── SwiftPMDemo.swiftmodule │ │ └── SwiftPMDemoPackageTests.xctest │ │ └── Contents │ │ ├── Info.plist │ │ └── MacOS │ └── debug.yaml
  22. // --type executableͷ৔߹ . ├── .build │ ├── build.db │

    ├── debug │ │ ├── ModuleCache │ │ │ ├── CGC1TPJT37OH │ │ │ │ └── SwiftShims-1HJGLIW7H35BO.pcm │ │ │ └── modules.timestamp │ │ ├── SwiftPMDemo │ │ ├── SwiftPMDemo.build │ │ │ ├── main.d │ │ │ ├── main.swift.o │ │ │ ├── main.swiftdeps │ │ │ ├── main~partial.swiftdoc │ │ │ ├── main~partial.swiftmodule │ │ │ ├── master.swiftdeps │ │ │ └── output-file-map.json │ │ ├── SwiftPMDemo.dSYM │ │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── Resources │ │ │ └── DWARF │ │ │ └── SwiftPMDemo │ │ ├── SwiftPMDemo.swiftdoc │ │ └── SwiftPMDemo.swiftmodule │ └── debug.yaml
  23. swift test

  24. swift test • Tests/഑ԼͷςετλʔήοτΛϏϧυɺ࣮ߦͯ͠ςετ͢Δ • Tests/TargetNameTestsͱ͍͏໋໊ن໿͕͋Δ • Testsͱ͍͏઀ඌ͕ࣙඞཁ • ͦͷͨΊɺSources/ͱҟͳΓ҉໧ͷςετλʔήοτ͸ଘࡏ͠ͳ͍

    • ґଘ͢Δςετର৅ͷλʔήοτ͕·ͩϏϧυ͞Ε͍ͯͳ͍ʢઌʹ swift build͞Ε͍ͯͳ͍ʣ৔߹ɺswift test͚ͩͰͦͷλʔήοτ ΋Ϗϧυ͞ΕΔ
  25. swift test • swift test --skip-build • ϏϧυࡁΈͷςετλʔήοτΛςετ͚ͩ͢Δ • Xcode

    8ͷxcodebuild test-without-buildingͱҰॹ ☺ • swift test -l (--list-tests) • ςετϝιουͷϦετΛग़ྗ͢Δ • SwiftPMDemoTests.SwiftPMDemoTests/testExample • swift test -s, --specifier <test-module>.<test-case> • swift test -s, --specifier <test-module>.<test-case>/<test> • ಛఆͷςετΫϥεɺςετϝιου͚ͩΛ࣮ߦ͢Δ • swift test -s SwiftPMDemoTests.SwiftPMDemoTests/testExample
  26. . ├── .build │ ├── build.db │ ├── debug │

    │ ├── SwiftPMDemo.swiftdoc │ │ ├── SwiftPMDemo.swiftmodule │ │ ├── SwiftPMDemoPackageTests.xctest │ │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── MacOS │ │ │ ├── SwiftPMDemoPackageTests │ │ │ └── SwiftPMDemoPackageTests.dSYM │ │ │ └── Contents │ │ │ ├── Info.plist │ │ │ └── Resources │ │ │ └── DWARF │ │ │ └── SwiftPMDemoPackageTests │ │ ├── SwiftPMDemoTests.build │ │ │ ├── SwiftPMDemoTests.d │ │ │ ├── SwiftPMDemoTests.swift.o │ │ │ ├── SwiftPMDemoTests.swiftdeps │ │ │ ├── SwiftPMDemoTests~partial.swiftdoc │ │ │ ├── SwiftPMDemoTests~partial.swiftmodule │ │ │ ├── master.swiftdeps │ │ │ └── output-file-map.json │ │ ├── SwiftPMDemoTests.swiftdoc │ │ └── SwiftPMDemoTests.swiftmodule │ └── debug.yaml
  27. Tests/LinuxMain.swift • Linux༻ʹɺςετର৅ͷϝιουΛϦετΞοϓͯ͋͛͠Δ ඞཁ͕͋Δ • macOSͰ͸Objective-C൛ͷXCTest͕࢖༻͞ΕɺϥϯλΠ ϜͰಈతʹςετର৅ΛൃݟͰ͖Δ͕ɺObjective-Cϥϯ λΠϜΛ࣋ͨͳ͍ɺ࢖༻͠ͳ͍Linux (swift-corelibs-xctest) Ͱ͸ͦΕ͕ෆՄೳͳͨΊ

  28. Tests/LinuxMain.swift // Tests/LinuxMain.swift import XCTest @testable import SwiftPMDemoTests XCTMain([ testCase(SwiftPMDemoTests.allTests),

    ])
  29. Tests/LinuxMain.swift // Tests/SwiftPMDemoTests/SwiftPMDemoTests.swift import XCTest @testable import SwiftPMDemo class SwiftPMDemoTests:

    XCTestCase { func testExample() { // This is an example of a functional test case. // Use XCTAssert and related functions to verify your tests produce the correct results. XCTAssertEqual(SwiftPMDemo().text, "Hello, World!") } static var allTests : [(String, (SwiftPMDemoTests) -> () throws -> Void)] { return [ ("testExample", testExample), ] } }
  30. swift test $ swift test Test Suite 'All tests' started

    at 2016-09-14 00:01:00.333 Test Suite 'SwiftPMDemoPackageTests.xctest' started at 2016-09-14 00:01:00.334 Test Suite 'SwiftPMDemoTests' started at 2016-09-14 00:01:00.334 Test Case '-[SwiftPMDemoTests.SwiftPMDemoTests testExample]' started. Test Case '-[SwiftPMDemoTests.SwiftPMDemoTests testExample]' passed (0.001 seconds). Test Suite 'SwiftPMDemoTests' passed at 2016-09-14 00:01:00.335. Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.001) seconds Test Suite 'SwiftPMDemoPackageTests.xctest' passed at 2016-09-14 00:01:00.335. Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.001) seconds Test Suite 'All tests' passed at 2016-09-14 00:01:00.335. Executed 1 test, with 0 failures (0 unexpected) in 0.001 (0.002) seconds
  31. Package.swift Examples • ikesyo/Himotoki • ReactiveCocoa/ReactiveSwift • antitypical/Result • Quick/Quick

    • Quick/Nimble
  32. References • Swift.org - Package Manager • swift-package-manager/Documentation • swift-package-manager/

    PackageManagerCommunityProposal.md • swift-package-manager/Reference.md • swift-package-manager/Resources.md • swift-package-manager/Usage.md
  33. ! Happy Swift Packaging!! !

  34. Thank you❗"