Package Generator 是一个 Swift Package Manager 插件,用于简单且一致地更新你的 Package.swift
文件。对于高度模块化或使用 TCA 并因此依赖于干净且更新的 Package.swift
的项目来说,这是一个很棒的工具。
Package Generator 将从源代码文件中读取的 imports 添加到 Package.swift
中的目标 (target) 中。 这将有助于减少 SwiftUI Preview 的编译问题。
在安装它之后,你将能够运行它,但为了使其正常工作,它需要被配置。 默认情况下,它将以 dry-run
设置为 true 运行,这将创建一个文件 Package_generated.swift
以允许你预览将要发生的事情。 在正确配置并测试 Package_generated.swift
生成了正确的内容之后,你将需要在配置中将 dry-run
设置为 false,以写入真实的 Package.swift
文件。
每次你需要添加模块时,请记住将其添加到配置文件中。
Package Generator 会进入配置中设置的所有文件夹,然后读取所有 Swift 文件,以查找所有 imports,从而创建一个目标 (target) 添加到 Package.swift 中。
代码分析部分是使用 swift-syntax 完成的,因为我找不到将其链接到插件的方法,所以我必须将其打包在 CLI 中,该 CLI 用于执行解析部分。
添加到你的依赖项中: .package(url: "https://github.com/mackoj/PackageGeneratorPlugin.git", from: "0.5.0"),
插件将在 Xcode Report navigator 中显示消息和错误。
步骤 | 描述 | 图片 |
---|---|---|
0 | 要运行它,请右键单击要运行它的 package。 | ![]() |
1 | 它将建议你运行它,你可以在参数窗格中提供一个可选参数 (--confFile newName.json ),这将允许你更改配置文件的名称。 一旦更改,新的配置文件名将被存储 |
![]() |
2 | 首次启动时,它将请求写入项目目录的权限,为了使其工作,你必须选择 “允许命令更改文件”。 | ![]() |
默认情况下,为了防止任何意外,它将执行 dry-run(不修改你的 Package.swift
,而是创建一个 Package_generated.swift
),以便你有时间在使用它之前进行审查。
要使用它,你必须在项目的根目录中设置一个名为 packageGenerator.json
的配置文件。 此文件包含以下键:
packageDirectories
: 字符串数组,表示模块所在的目录headerFileURL
: 字符串,表示将在 Package.swift
顶部复制的文件的路径spaces
: 整数,表示 Package.swift
生成器在添加内容时应使用的空格数verbose
: 布尔值,表示是否应在控制台中打印更多信息pragmaMark
: 布尔值,表示是否应在生成的文件中添加 // MARK: -
dryRun
: 布尔值,表示生成器应替换 Package.swift
文件还是创建 Package_generated.swift
mappers.targets
: 字典,用于处理目标 (target) 重命名,键表示目标 path
和 /
,值表示要应用的名称。 例如,在 packageDirectories
中,我有 Sources/App/Helpers/Foundation
,但在我的代码中,我 import FoundationHelpers
。mappers.imports
: 字典,表示如何映射需要在 SPM 中使用 .product
的 import,例如 ComposableArchitecture
需要在 Package.swift
中被称为 .product(name: "ComposableArchitecture", package: "swift-composable-architecture")
。exclusions
: 对象,表示所有不应作为依赖项添加到目标 (target) 或 Package.swift
中目标的 importsexclusions.apple
: 字符串数组,表示所有不应作为依赖项添加到目标 (target) 的 Apple SDKexclusions.imports
: 字符串数组,表示所有不应作为依赖项添加到目标 (target) 的其他 SDKexclusions.targets
: 字符串数组,表示所有不应添加到生成的 Package.swift
中的目标 (target)targetsParameters
: 字典,表示要添加到目标 (target) 的自定义参数{
"packageDirectories": [
"Sources/App/Clients/Analytics",
"Sources/App/Clients/AnalyticsLive",
"Sources/App/Daemons/Notification",
"Sources/App/Helpers/Foundation"
],
"headerFileURL": "header.swift",
"targetsParameters": {
"Analytics": ["exclude: [\"__Snapshots__\"]", "resources: [.copy(\"Fonts/\")]"],
"target2": ["resources: [.copy(\"Dictionaries/\")]"]
},
"verbose": false,
"pragmaMark": false,
"spaces": 2,
"dryRun": true,
"mappers": {
"targets": {
"Sources/App/Helpers/Foundation/": "FoundationHelpers",
},
"imports": {
"ComposableArchitecture": ".product(name: \"ComposableArchitecture\", package: \"swift-composable-architecture\")"
}
},
"exclusions": {
"apple": [
"ARKit",
"AVFoundation"
],
"imports": [
"PurchasesCoreSwift"
],
"targets": [
"ParserCLI"
]
}
}
如果使用了新的配置文件名(如 #basic-usage 步骤 1 中所述)。 它将被保存,以便你无需在每次启动时都输入配置文件名。
来自配置的 headerFileURL
的内容将被添加到生成的 Package.swift
的顶部。
我建议添加所有必需的 dependencies
和 Test Targets(测试目标), System Librarys(系统库), Executable Targets(可执行目标) 和 Binary Targets(二进制目标)(#8)。
// swift-tools-version:5.7
// The swift-tools-version declares the minimum version of Swift required to build this package.
import Foundation
import PackageDescription
var package = Package(
name: "project",
defaultLocalization: "en",
platforms: [
.macOS(.v12),
.iOS("15.0")
],
products: [
.executable(name: "server", targets: ["server"]),
.executable(name: "parse", targets: ["ParserRunner"]),
],
dependencies: [
.package(url: "https://github.com/mackoj/PackageGeneratorPlugin.git", from: "0.3.0"),
.package(url: "https://github.com/mackoj/SchemeGeneratorPlugin.git", from: "0.5.5"),
.package(url: "https://github.com/pointfreeco/swift-composable-architecture.git", from: "0.45.0"),
],
targets: [
// MARK: -
// MARK: Test Targets
.testTarget(
name: "MyProjectTests",
dependencies: [
"MyProject",
]
),
// MARK: -
// MARK: Executables
.executableTarget(
name: "server",
path: "Sources/Backend/Sources/Run"
),
.executableTarget(
name: "ParserRunner",
path: "Sources/App/Parsers/Runner"
),
]
)
你可以在 CI 中使用它来自动生成你的 Package.swift
。
swift package plugin --allow-writing-to-package-directory package-generator
为什么在 Xcode 中看不到该插件?
如果你右键单击你的项目 package,并且仅当 Resolves Packages
没有问题时,插件才能工作。
为什么插件有可执行依赖项?
因为我们无法在 SPM 插件中导入其他 package,并且我们需要 swift-syntax 来解析代码并提取 imports。
它总是创建一个无效的
Package.swift
文件。
查看 Xcode 中的 Report Navigator
,这可能是由于不存在的 imports 或需要使用 mappers-imports 导致的。
为什么它不使用像
.packageGenerator
这样的隐藏文件来配置工具?
因为它在 Xcode 中不可见,并且此文件可能需要经常编辑。 但是,如果你想这样做,可以在使用该工具时提供 --confFile
参数来更改此设置。