Skip to content

Commit f78d1e9

Browse files
committed
Enable KnitBuildPlugin to work inside an SPM package
1 parent aa98631 commit f78d1e9

1 file changed

Lines changed: 60 additions & 22 deletions

File tree

Plugins/KnitBuildPlugin/KnitBuildPlugin.swift

Lines changed: 60 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,22 +5,32 @@
55
import Foundation
66
import PackagePlugin
77

8-
@main
8+
@main @available(macOS 13.0, *)
99
struct KnitBuildPlugin: BuildToolPlugin {
1010

1111
func createBuildCommands(
1212
context: PluginContext,
1313
target: any Target
1414
) async throws -> [Command] {
15-
// This method is only invoked when the plugin is consumed by an SPM-only project
16-
fatalError("Unexpected project type. Please add plugin to an Xcode project.")
15+
let jsonFile = context.package.directory.appending(subpath: "knitconfig.json")
16+
17+
return [
18+
try KnitBuildPlugin.createCommand(
19+
type: .source,
20+
toolPath: try context.tool(named: "knit-cli").path,
21+
configFilePath: jsonFile,
22+
workingDirectory: context.pluginWorkDirectory
23+
)
24+
]
25+
1726
}
1827

1928
}
2029

2130
#if canImport(XcodeProjectPlugin)
2231
import XcodeProjectPlugin
2332

33+
@available(macOS 13.0, *)
2434
extension KnitBuildPlugin: XcodeBuildToolPlugin {
2535

2636
func createBuildCommands(
@@ -50,29 +60,60 @@ extension XcodePluginContext {
5060
from configFilePath: Path,
5161
target: XcodeTarget
5262
) throws -> Command {
53-
let configFileData = try Data(contentsOf: URL(filePath: configFilePath.string))
54-
55-
let config = try JSONDecoder().decode(KnitPluginConfig.self, from: configFileData)
56-
57-
let typeSafetyOutputPath: Path?
58-
let unitTestOutputPath: Path?
63+
let command: CommandType
5964
switch target.product?.kind {
6065
case .application:
61-
typeSafetyOutputPath = self.pluginWorkDirectory.appending("KnitDITypeSafety.swift")
62-
unitTestOutputPath = nil
66+
command = .source
6367
case .other("com.apple.product-type.bundle.unit-test"):
64-
typeSafetyOutputPath = nil
65-
unitTestOutputPath = self.pluginWorkDirectory.appending(subpath: "KnitDIRegistrationTests.swift")
66-
68+
command = .tests
6769
default:
68-
typeSafetyOutputPath = nil
69-
unitTestOutputPath = nil
70+
command = .unknown
7071
}
72+
73+
return try KnitBuildPlugin.createCommand(
74+
type: command,
75+
toolPath: try self.tool(named: "knit-cli").path,
76+
configFilePath: configFilePath,
77+
workingDirectory: self.pluginWorkDirectory
78+
)
79+
}
80+
81+
}
7182

83+
#endif
84+
85+
fileprivate enum CommandType {
86+
case source, tests, unknown
87+
}
88+
89+
@available(macOS 13.0, *)
90+
extension KnitBuildPlugin {
91+
fileprivate static func createCommand(
92+
type: CommandType,
93+
toolPath: Path,
94+
configFilePath: Path,
95+
workingDirectory: Path
96+
) throws -> Command {
97+
let configFileData = try Data(contentsOf: URL(filePath: configFilePath.string))
98+
let config = try JSONDecoder().decode(KnitPluginConfig.self, from: configFileData)
7299
let assemblyInputPaths = config.makeInputPaths(
73100
configFilePath: configFilePath
74101
)
75-
102+
103+
let typeSafetyOutputPath: Path?
104+
let unitTestOutputPath: Path?
105+
switch type {
106+
case .source:
107+
typeSafetyOutputPath = workingDirectory.appending("KnitDITypeSafety.swift")
108+
unitTestOutputPath = nil
109+
case .tests:
110+
typeSafetyOutputPath = nil
111+
unitTestOutputPath = workingDirectory.appending(subpath: "KnitDIRegistrationTests.swift")
112+
case .unknown:
113+
unitTestOutputPath = nil
114+
typeSafetyOutputPath = nil
115+
}
116+
76117
let assemblyInputArgs: [String] = assemblyInputPaths.flatMap { path in
77118
[
78119
"--assembly-input-path",
@@ -101,18 +142,15 @@ extension XcodePluginContext {
101142
unitTestArgs
102143

103144
return .buildCommand(
104-
displayName: "Knit Plugin: Generate Knit files based on config \(configFilePath.description)",
105-
executable: try self.tool(named: "knit-cli").path,
145+
displayName: "Knit Plugin: Generate Knit files based on config \(configFilePath.description). Output folder: \(workingDirectory.description)",
146+
executable: toolPath,
106147
arguments: arguments,
107148
inputFiles: assemblyInputPaths,
108149
outputFiles: [typeSafetyOutputPath, unitTestOutputPath].compactMap { $0 }
109150
)
110151
}
111-
112152
}
113153

114-
#endif
115-
116154
/// Corresponds to the `knitconfig.json` file.
117155
/// That JSON data will be decoded into a `KnitPluginConfig` instance.
118156
struct KnitPluginConfig: Decodable {

0 commit comments

Comments
 (0)