PackageDSL

SwiftPM DocC

GitHub Repo stars GitHub GitHub issues GitHub Workflow Status

Twitter Follow Mastodon Follow YouTube Channel Subscribers

GitHub Downloads (specific asset, latest release)

使用类型安全、模块化的 DSL 简化 Package.swift 文件的管理

import PackageDescription

let package = Package(
  name: "MyApp",
  entries: {
    AppTarget()
    NetworkingModule()
    DatabaseModule()
  },
  dependencies: {
    Alamofire()
    SQLite()
  },
  testTargets: {
    AppTests()
    NetworkingTests()
  },
  swiftSettings: {
    InternalImportsByDefault()
  }
)
.supportedPlatforms {
  WWDC2023()
}
.defaultLocalization(.english)

为什么选择 PackageDSL?

目录

真实世界示例

查看 BushelKit,它使用 PackageDSL 来管理其具有多个产品和依赖项的复杂 package 结构。它的 Package/Sources 目录演示了如何组织

Package
└── Sources
    ├── Dependencies
    │   ├── ArgumentParser.swift
    │   ├── DocC.swift
    │   ├── RadiantKit
    │   │   ├── RadiantDocs.swift
    │   │   ├── RadiantPaging.swift
    │   │   └── RadiantProgress.swift
    │   └── RadiantKit.swift
    ├── Index.swift
    ├── Platforms
    │   └── WWDC2023.swift
    ├── Products
    │   ├── BushelCommand.swift
    │   ├── BushelDocs.swift
    │   └── ... more products ...
    ├── Targets
    │   ├── BushelArgs.swift
    │   └── ... more targets ...
    └── Tests
        ├── BushelFactoryTests.swift
        └── ... more tests ...

快速入门

1. 基本设置

创建一个最小的 package 结构

MyPackage/
└── Package/
    └── Sources/
        ├── Products/
        │   └── AppTarget.swift
        ├── Dependencies/
        │   └── Alamofire.swift
        └── Index.swift

2. 定义你的组件

Package/Sources/Products/AppTarget.swift:

struct AppTarget: Product, Target {
  var dependencies: any Dependencies {
    Alamofire()
    CoreModule()
  }
}

Package/Sources/Dependencies/Alamofire.swift:

struct Alamofire: PackageDependency {
  var dependency: Package.Dependency {
    .package(
      url: "https://github.com/Alamofire/Alamofire.git", 
      from: "5.8.0"
    )
  }
}

Package/Sources/Index.swift:

let package = Package(
  entries: {
    AppTarget()
  }
)

3. 生成 Package.swift

./package.sh . --version 5.9

安装

  1. 从我们的最新版本下载 package.sh 脚本

    或者使用 curl

    curl -LO https://github.com/brightdigit/PackageDSL/releases/latest/download/package.sh
  2. 使脚本可执行

chmod +x package.sh

用法

该脚本接受以下参数

./package.sh [PACKAGE_DIR] [OPTIONS]

参数

选项

示例

使用 Swift 5.9 为当前目录生成 Package.swift

./package.sh . --version 5.9

为特定 package 生成最小化的 Package.swift

./package.sh ~/Projects/MyPackage --version 5.9 --minimize

常见问题解答

如何处理测试目标?

你可以使用 TestTarget 协议创建一个测试目标

struct BushelCoreTests: TestTarget {
  var dependencies: any Dependencies {
    BushelCore()
  }
}

然后使用 testTarget 参数将其添加到测试目标列表中

let package = Package {
  BushelCommand()
  BushelLibraryApp()
  BushelMachineApp()
  BushelSettingsApp()
  BushelApp()
}
testTargets: {
  BushelCoreTests() // right here
}

如何处理自定义 Swift 设置?

可以使用 Package 构造函数上的 swiftSettings 参数将 Swift 设置添加到所有目标,或者通过实现 swiftSettings 属性将其添加到特定目标

struct BushelFactory: Target {
  var dependencies: any Dependencies {
    BushelCore()
    BushelMachine()
    BushelLibrary()
    BushelLogging()
    BushelData()
  }
  
  var swiftSettings: [SwiftSetting] {
    InternalImportsByDefault()
  }
}

有关更多详细信息,请查看以下文档:

如何添加资源?

要添加资源,只需在 Target 上实现 resources 属性

struct BushelLocalization: Target {
  var resources : [Resource] {
    .process("Styling/Colors/Colors.xcassets")
    .process("Styling/Fonts/FontsFiles")
    .process("Images/Images.xcassets")
    .process("Images/whiteLoading.json")
    .process("Images/primaryLoading.json")
  }
}

现在有两种修饰方法可以做到这一点。 defaultLocalization 接受一个 LanguageTag,以及 supportedPlatforms 可以接受平台列表或 PlatformSet。 如果您使用 a 来定义特定年份(例如)的平台集,则 PlatformSet 非常有用

struct WWDC2023: PlatformSet {
  var body: any SupportedPlatforms {
    .macOS(.v14)
    .iOS(.v17)
    .watchOS(.v10)
    .tvOS(.v17)
  }
}

而不是将你的平台定义为

let package = Package {
  ...
}
.supportedPlatforms {
  .macOS(.v14)
  .iOS(.v17)
  .watchOS(.v10)
  .tvOS(.v17)
}

如何指定目标特定的平台?

每个目标都可以实现 platforms 属性

struct MacOnlyTarget: Target {
  var platforms: [SupportedPlatform] {
    SupportedPlatform.macOS(.v13)
  }
}

性能影响是什么?

DSL 仅在开发时用于生成你的 Package.swift。 对你的 package 或其用户没有任何运行时影响。

如何迁移现有的 package?

  1. 创建 Package 目录结构
  2. 将每个产品、目标和依赖项移动到单独的文件中
  3. 运行生成器脚本以创建新的 Package.swift
  4. 将生成的文件与你的原始文件进行比较,以确保一切都正确传输

感谢