Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Swift Package Manager

Sponsored · Ship Features Fearlessly Turn features on and off without deploys. Used by thousands of Ruby developers.

Swift Package Manager

Avatar for Chiaote Ni

Chiaote Ni

July 01, 2022
Tweet

More Decks by Chiaote Ni

Other Decks in Programming

Transcript

  1. // 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"]), ] )
  2. swift package init OVERVIEW: Initialize a new package USAGE: swift

    package init <options> OPTIONS: --type <type> Package type: empty | library | executable | system-module | manifest (default: library) 
 --name <name> Provide custom package name --version Show the version. -help, -h, --help Show help information. swift package init --type library --name SPMDemo EX:
  3. It’s easy to declared the product you want to release:

    
 - library - executable 
 - plugin 
 
 Thanks for the interface which declared in framework PackageDescription 🙌
  4. // 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: []) ] )
  5. // 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.

  6. // 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") ] )
  7. 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
  8. 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
  9. 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" ) ] )
  10. 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"]), ]
  11. • Commands • Invoked by the command line, applied directly

    to a package, not during a build • Build tools • Invoked by the SPM targets
  12. 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
  13. 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] { // ... } }
  14. • 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.