Slide 1

Slide 1 text

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

Slide 2

Slide 2 text

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

Slide 3

Slide 3 text

Swift Package Manager

Slide 4

Slide 4 text

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

Slide 5

Slide 5 text

Swift Package Manager • AppleެࣜʢʂʣɺSwiftඪ४ͷύοέʔδϚωʔδϟʔ • ґଘੑͷμ΢ϯϩʔυɺίϯύΠϧɺϦϯΫΛߦ͏ • தԝूݖͷύοέʔδͷΠϯσοΫε͸࣋ͨͳ͍ • Swift 3ͱڞʹϦϦʔε: macOS, Linuxͷ྆ϓϥοτϑΥʔϜͰαϙʔτ • αʔόʔαΠυɺίϚϯυϥΠϯπʔϧ͕ʢࠓͷʣϝΠϯλʔήοτ • swift package • swift build • swift test

Slide 6

Slide 6 text

swift package

Slide 7

Slide 7 text

swift package • swift package init: ύοέʔδΛ࡞੒͢Δ • --type • empty • library • executable • system-module

Slide 8

Slide 8 text

swift package swift package init --type empty . ├── Package.swift ├── Sources └── Tests

Slide 9

Slide 9 text

swift package swift package init --type library (same as no option) . ├── Package.swift ├── Sources │ └── SwiftPMDemo.swift └── Tests ├── LinuxMain.swift └── SwiftPMDemoTests └── SwiftPMDemoTests.swift

Slide 10

Slide 10 text

swift package swift package init --type executable . ├── Package.swift ├── Sources │ └── main.swift └── Tests

Slide 11

Slide 11 text

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 * }

Slide 12

Slide 12 text

Package.swift • Manifest file: SwiftʹΑΔDSL • ύοέʔδ໊ɺλʔήοτʢϞδϡʔϧʣɺґଘύοέʔ δɺআ֎ϑΝΠϧͳͲΛࢦఆ • ϦϙδτϦͷτοϓϨϕϧʹ഑ஔ • 1ϚχϑΣετͰ1ύοέʔδɺͭ·Γ1ϦϙδτϦͰ1ύοέ ʔδ

Slide 13

Slide 13 text

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", ] )

Slide 14

Slide 14 text

Package.swift Package( name: String, pkgConfig: String? = nil, providers: [SystemPackageProvider]? = nil, targets: [Target] = [], dependencies: [Package.Dependency] = [], exclude: [String] = [] )

Slide 15

Slide 15 text

Package.swift • ґଘύοέʔδ • ηϚϯςΟοΫόʔδϣχϯάͷλάͷΈɻͦΕҎ֎ͷλάɺίϛοτɺϒϥϯν͸ݱࡏ࢖༻Ͱ͖ͳ͍ɻ • ςετ༻͚ͩͷґଘੑ͸ݱࡏ࢖༻Ͱ͖ͳ͍ɻҎલ testDependencies ͕͕͋ͬͨɺকདྷతʹ෮׆͢ΔՄ ೳੑ͕͋Δɻ • Handling version-specific logic • ಛఆͷSwiftόʔδϣϯ޲͚ͷόʔδϣχϯάɻ࠷৽όʔδϣϯ޲͚ʹ͸࢖͏΂͖Ͱ͸ͳ͍ɻ • Version-specific tag selection: 1.2.0@swift-3 • Version-specific manifest selection: [email protected] 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.

Slide 16

Slide 16 text

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

Slide 17

Slide 17 text

swift build

Slide 18

Slide 18 text

swift build • Sources/഑Լͷ֤λʔήοτΛϏϧυ͢Δ • Sources/௚Լʹ௚઀ιʔε͕͋Δ৔߹ɺύοέʔδ໊ͱಉ໊ͷλʔήοτ͕ ͋Δͱݟͳ͞ΕΔ • Sources/A/A.swift, Sources/B/B.swift ͱ͢ΔͱɺλʔήοτAɺλʔήο τBͷ2͕ͭϏϧυ͞ΕΔ • λʔήοτؒͷґଘఆٛ • ґଘ͞Ε͍ͯΔλʔήοτ͔ΒઌʹϏϧυ͞ΕΔ • λʔήοτͱରԠ͢Δςετλʔήοτʹ͸҉໧ͷґଘੑ͕͋Δ

Slide 19

Slide 19 text

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"]),

Slide 20

Slide 20 text

swift build • swift build --clean • ϏϧυύεͷΫϦΞʢσϑΥϧτ͸./.buildɺ--build- pathΦϓγϣϯͰมߋՄೳʣ • swift build -c (debug|release) • Ϗϧυઃఆͷࢦఆʢσόοά or ϦϦʔεʣ

Slide 21

Slide 21 text

// --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

Slide 22

Slide 22 text

// --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

Slide 23

Slide 23 text

swift test

Slide 24

Slide 24 text

swift test • Tests/഑ԼͷςετλʔήοτΛϏϧυɺ࣮ߦͯ͠ςετ͢Δ • Tests/TargetNameTestsͱ͍͏໋໊ن໿͕͋Δ • Testsͱ͍͏઀ඌ͕ࣙඞཁ • ͦͷͨΊɺSources/ͱҟͳΓ҉໧ͷςετλʔήοτ͸ଘࡏ͠ͳ͍ • ґଘ͢Δςετର৅ͷλʔήοτ͕·ͩϏϧυ͞Ε͍ͯͳ͍ʢઌʹ swift build͞Ε͍ͯͳ͍ʣ৔߹ɺswift test͚ͩͰͦͷλʔήοτ ΋Ϗϧυ͞ΕΔ

Slide 25

Slide 25 text

swift test • swift test --skip-build • ϏϧυࡁΈͷςετλʔήοτΛςετ͚ͩ͢Δ • Xcode 8ͷxcodebuild test-without-buildingͱҰॹ ☺ • swift test -l (--list-tests) • ςετϝιουͷϦετΛग़ྗ͢Δ • SwiftPMDemoTests.SwiftPMDemoTests/testExample • swift test -s, --specifier . • swift test -s, --specifier ./ • ಛఆͷςετΫϥεɺςετϝιου͚ͩΛ࣮ߦ͢Δ • swift test -s SwiftPMDemoTests.SwiftPMDemoTests/testExample

Slide 26

Slide 26 text

. ├── .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

Slide 27

Slide 27 text

Tests/LinuxMain.swift • Linux༻ʹɺςετର৅ͷϝιουΛϦετΞοϓͯ͋͛͠Δ ඞཁ͕͋Δ • macOSͰ͸Objective-C൛ͷXCTest͕࢖༻͞ΕɺϥϯλΠ ϜͰಈతʹςετର৅ΛൃݟͰ͖Δ͕ɺObjective-Cϥϯ λΠϜΛ࣋ͨͳ͍ɺ࢖༻͠ͳ͍Linux (swift-corelibs-xctest) Ͱ͸ͦΕ͕ෆՄೳͳͨΊ

Slide 28

Slide 28 text

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

Slide 29

Slide 29 text

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), ] } }

Slide 30

Slide 30 text

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

Slide 31

Slide 31 text

Package.swift Examples • ikesyo/Himotoki • ReactiveCocoa/ReactiveSwift • antitypical/Result • Quick/Quick • Quick/Nimble

Slide 32

Slide 32 text

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

Slide 33

Slide 33 text

! Happy Swift Packaging!! !

Slide 34

Slide 34 text

Thank you❗"