Slide 1

Slide 1 text

Aaron Ni Swift Package Manager

Slide 2

Slide 2 text

Init with SPM

Slide 3

Slide 3 text

// swift-tools-version:5.5 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "SPMDemo", products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( name: "SPMDemo", targets: ["SPMDemo"]), ], dependencies: [ // Dependencies declare other packages that this package depends on. // .package(url: /* package url */, from: "1.0.0"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "SPMDemo", dependencies: []), .testTarget( name: "SPMDemoTests", dependencies: ["SPMDemo"]), ] )

Slide 4

Slide 4 text

swift package init OVERVIEW: Initialize a new package USAGE: swift package init OPTIONS: --type Package type: empty | library | executable | system-module | manifest (default: library) 
 --name Provide custom package name --version Show the version. -help, -h, --help Show help information. swift package init --type library --name SPMDemo EX:

Slide 5

Slide 5 text

It’s easy to declared the product you want to release: 
 - library - executable 
 - plugin 
 
 Thanks for the interface which declared in framework PackageDescription 🙌

Slide 6

Slide 6 text

// swift-tools-version:5.5 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "SPMDemo", products: [ .library( name: "SPMDemo", targets: [“SPMDemo"] ), ], dependencies: [], targets: [ .target( name: "SPMDemo", dependencies: []) ] )

Slide 7

Slide 7 text

// swift-tools-version:5.5 // The swift-tools-version declares the minimum version of Swift required to build this package. import PackageDescription let package = Package( name: "SPMDemo", products: [ .library( name: "SPMDemo", targets: [“SPMDemo"] ), ], dependencies: [], targets: [ .target( name: "SPMDemo", dependencies: []) ] ) Remember to modify the tool version here if needed. 
 Some new features of SPM PlugIn are based on versions 5.6 - 5.7.


Slide 8

Slide 8 text

Project / Target / Dependencies

Slide 9

Slide 9 text

// swift-tools-version:5.5 // The swift-tools-version declares the minimum version of Swift requir import PackageDescription let package = Package( name: "Utilities", products: [ // Products define the executables and libraries a package prod .library( name: "Extensions", targets: ["Extensions"] ), .library( name: "BuilderHelper", targets: ["Buildable", "KeyPathConstraints"] ), .library( name: "Buildable", targets: ["Buildable"] ) ], targets: [ // Targets are the basic building blocks of a package. A target // Targets can depend on other targets in this package, and on .target(name: "Extensions"), .target(name: "Buildable"), .target(name: "KeyPathConstraints") ] )

Slide 10

Slide 10 text

import PackageDescription let package = Package( name: "ExampleLogger", products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( name: "ExampleLogger", targets: ["ExampleLogger"]), ], dependencies: [ .package(name: "Utilities", path: "../Utilities"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "ExampleLogger", dependencies: [ .product(name: "Extensions", package: "Utilities", condition: .none), .product(name: "Buildable", package: "Utilities", condition: .none) ]), .testTarget( name: "ExampleLoggerTests", dependencies: ["ExampleLogger"]), ] ) Buildable only

Slide 11

Slide 11 text

import PackageDescription let package = Package( name: "ExampleLogger", products: [ // Products define the executables and libraries a package produces, and make them visible to other packages. .library( name: "ExampleLogger", targets: ["ExampleLogger"]), ], dependencies: [ .package(name: "Utilities", path: "../Utilities"), ], targets: [ // Targets are the basic building blocks of a package. A target can define a module or a test suite. // Targets can depend on other targets in this package, and on products in packages this package depends on. .target( name: "ExampleLogger", dependencies: [ .product(name: "Extensions", package: "Utilities", condition: .none), .product(name: "BuilderHelper", package: "Utilities", condition: .none) ]), .testTarget( name: "ExampleLoggerTests", dependencies: ["ExampleLogger"]), ] ) Buildable + KeyPathConstraints

Slide 12

Slide 12 text

let package = Package( name: "ExampleLogger", products: [ // Products define the executables and libraries a package produces, and make them visib to other packages. .library( name: "ExampleLogger", targets: ["ExampleLogger"]), ], dependencies: [ .package( name: "Utilities", path: "../Utilities" ), .package( name: "PathView", url: "https://[email protected]/aaronni19/pathview.git", branch: "feat/simple-demo" ), .package( name: "StarPage", url: "https://[email protected]/aaronni19/starpage.git", from: "1.0.0" ) ] )

Slide 13

Slide 13 text

No content

Slide 14

Slide 14 text

PlugIns

Slide 15

Slide 15 text

targets: [ .target( name: "PathView", dependencies: [] ), .plugin( name: "CodeGenerator", capability: .command( intent: .custom( verb: "generate-code", description: "Generator the source code from D-Paths" ), permissions: [ .writeToPackageDirectory(reason: "blahblahblah") ] ) ), .testTarget( name: "PathViewTests", dependencies: ["PathView"]), ]

Slide 16

Slide 16 text

• Commands • Invoked by the command line, applied directly to a package, not during a build • Build tools • Invoked by the SPM targets

Slide 17

Slide 17 text

import PackagePlugin @main // main entry point struct CodeGenerator: CommandPlugin { /// - Parameters: /// - context: Provides information about the package for which the plugin is invoked, /// as well as contextual information based on the plugin's stated intent /// and requirements. /// - arguments: arguments func performCommand( context: PackagePlugin.PluginContext, arguments: [String] ) async throws { //... } } source code formatting

Slide 18

Slide 18 text

import PackagePlugin @main // main entry point struct CodeGenerator: BuildToolPlugin { /// - Parameters: /// - context:You can get some information about the package to which the plugin is being /// applied, pluginWorkDirectory, and a named command line executable tool /// - target: some information of the current target (name, directory, dependencies) /// - Returns: command to run during the build, you can return the build and prebuild /// commands here func createBuildCommands( context: PackagePlugin.PluginContext, target: PackagePlugin.Target ) async throws -> [PackagePlugin.Command] { // ... } }

Slide 19

Slide 19 text

• Commands • source code formatting • documentation generation • custom

Slide 20

Slide 20 text

• In-build command • Your tool has a de fi ned set of outputs. • Re-run when outputs are missing or inputs change • Pre-build command • Don't have a clear set of outputs • Runs at the start of every build • Be careful about doing expensive work in it.