@@ -123,24 +123,37 @@ struct MyPlugin: BuildToolPlugin {
123
123
124
124
func createBuildCommands (context : PluginContext,
125
125
target : Target) throws -> [Command] {
126
- guard let target = target.sourceModule else { return [] }
127
- let inputFiles = target.sourceFiles .filter (
128
- { $0 .path .extension == " dat" }
129
- )
130
- return try inputFiles.map {
131
- let inputFile = $0
132
- let inputPath = inputFile.path
133
- let outputName = inputPath.stem + " .swift"
134
- let outputPath = context.pluginWorkDirectory .appending (outputName)
135
- return .buildCommand (
136
- displayName : " Generating \( outputName ) from \( inputPath.lastComponent ) " ,
137
- executable : try context.tool (named : " SomeTool" ).path ,
138
- arguments : [ " --verbose" , " \( inputPath ) " , " \( outputPath ) " ],
139
- inputFiles : [ inputPath, ],
140
- outputFiles : [ outputPath ]
141
- )
126
+ // This plugin only runs for package targets that can have source files.
127
+ guard let sourceFiles = target.sourceModule? .sourceFiles else { return [] }
128
+
129
+ // Find the code generator tool to run (replace this with the actual one).
130
+ let generatorTool = try context.tool (named : " my-code-generator" )
131
+
132
+ // Construct a build command for each source file with a particular suffix.
133
+ return sourceFiles.map (\.url ).compactMap {
134
+ createBuildCommand (for : $0 , in : context.pluginWorkDirectoryURL , with : generatorTool.url )
142
135
}
143
136
}
137
+
138
+ func createBuildCommand (for inputPath : URL,
139
+ in outputDirectoryPath : URL,
140
+ with generatorToolPath : URL) -> Command? {
141
+ // Skip any file that doesn't have the extension we're looking for
142
+ // (replace this with the actual one).
143
+ guard inputPath.pathExtension == " my-input-suffix" else { return .none }
144
+
145
+ // Return a command that will run during the build to generate the output file.
146
+ let inputName = inputPath.lastPathComponent
147
+ let outputName = inputPath.deletingPathExtension ().lastPathComponent + " .swift"
148
+ let outputPath = outputDirectoryPath.appendingPathComponent (outputName)
149
+ return .buildCommand (
150
+ displayName : " Generating \( outputName ) from \( inputName ) " ,
151
+ executable : generatorToolPath,
152
+ arguments : [" \( inputPath ) " , " -o" , " \( outputPath ) " ],
153
+ inputFiles : [inputPath],
154
+ outputFiles : [outputPath]
155
+ )
156
+ }
144
157
}
145
158
```
146
159
@@ -163,9 +176,11 @@ struct MyBuildToolPlugin: BuildToolPlugin {
163
176
// This example configures `sometool` to write to a
164
177
// "GeneratedFiles" directory in the plugin work directory
165
178
// (which is unique for each plugin and target).
166
- let outputDir = context.pluginWorkDirectory .appending (" GeneratedFiles" )
167
- try FileManager.default .createDirectory (atPath : outputDir.string ,
168
- withIntermediateDirectories : true )
179
+ let outputDir = context.pluginWorkDirectoryURL
180
+ .appendingPathComponent (" GeneratedFiles" )
181
+ try FileManager.default .createDirectory (
182
+ at : outputDir,
183
+ withIntermediateDirectories : true )
169
184
170
185
// Return a command to run `sometool` as a prebuild command.
171
186
// It runs before every build and generates source files
@@ -217,26 +232,24 @@ In order to write a plugin that works with packages in every environment, and th
217
232
For example:
218
233
219
234
``` swift
220
- import PackagePlugin
221
-
222
- @main
223
- struct MyCommandPlugin : CommandPlugin {
224
- /// This entry point is called when operating on a Swift package.
225
- func performCommand (context : PluginContext,
226
- arguments : [String ]) throws {
227
- debugPrint (context)
228
- }
229
- }
230
-
231
235
#if canImport (XcodeProjectPlugin )
232
236
import XcodeProjectPlugin
233
237
234
238
extension MyCommandPlugin : XcodeCommandPlugin {
235
- /// This entry point is called when operating on an Xcode project.
236
- func performCommand (context : XcodePluginContext,
237
- arguments : [String ]) throws {
238
- debugPrint (context)
239
+
240
+ // Entry point for creating build commands for targets in Xcode projects.
241
+ func createBuildCommands (context : XcodePluginContext,
242
+ target : XcodeTarget) throws -> [Command] {
243
+ // Find the code generator tool to run (replace this with the actual one).
244
+ let generatorTool = try context.tool (named : " my-code-generator" )
245
+
246
+ // Construct a build command for each source file with a particular suffix.
247
+ return target.inputFiles .map (\.url ).compactMap {
248
+ createBuildCommand (for : $0 ,
249
+ in : context.pluginWorkDirectoryURL ,
250
+ with : generatorTool.url )
239
251
}
252
+ }
240
253
}
241
254
#endif
242
255
```
0 commit comments