Section 10/171 menit
10. Plugin: Build Tool dan Command
10. Plugin: Build Tool dan Command
Sejak Swift 5.6, SPM mendukung plugin — Swift code yang dijalankan saat build atau on-demand.
Build Tool Plugin
Jalan otomatis saat build, biasanya untuk codegen.
Use case: generate Swift code dari .proto, .graphql, atau .json schema.
swift
// Package.swift
targets: [
.plugin(
name: "ProtobufGenerator",
capability: .buildTool(),
dependencies: ["protoc"]
),
.target(
name: "MyApp",
plugins: ["ProtobufGenerator"]
),
]
swift
// Plugins/ProtobufGenerator/plugin.swift
import PackagePlugin
@main
struct ProtobufGenerator: BuildToolPlugin {
func createBuildCommands(
context: PluginContext,
target: Target
) async throws -> [Command] {
guard let sourceTarget = target as? SourceModuleTarget else { return [] }
let protoFiles = sourceTarget.sourceFiles.filter { $0.path.extension == "proto" }
return protoFiles.map { file in
let outputPath = context.pluginWorkDirectory
.appending("\(file.path.stem).pb.swift")
return .buildCommand(
displayName: "Generating \(file.path.stem).pb.swift",
executable: try context.tool(named: "protoc").path,
arguments: [
"--swift_out=\(outputPath.removingLastComponent())",
file.path.string,
],
inputFiles: [file.path],
outputFiles: [outputPath]
)
}
}
}
Command Plugin
Dijalankan on-demand via swift package <plugin-name> atau dari menu Xcode → File → Packages → ...
Use case: linting, formatting, code generation manual.
swift
.plugin(
name: "SwiftFormatRun",
capability: .command(
intent: .sourceCodeFormatting(),
permissions: [.writeToPackageDirectory(reason: "Format files")]
)
)
swift
@main
struct SwiftFormatRun: CommandPlugin {
func performCommand(context: PluginContext, arguments: [String]) async throws {
let tool = try context.tool(named: "swiftformat")
let process = Process()
process.executableURL = URL(fileURLWithPath: tool.path.string)
process.arguments = ["."]
try process.run()
process.waitUntilExit()
}
}
Run:
swift
swift package plugin --allow-writing-to-package-directory SwiftFormatRun