@@ -52,95 +52,107 @@ extension PluginTarget {
52
52
scriptRunner: PluginScriptRunner ,
53
53
outputDirectory: AbsolutePath ,
54
54
toolNamesToPaths: [ String : AbsolutePath ] ,
55
+ fileSystem: FileSystem ,
55
56
observabilityScope: ObservabilityScope ,
56
- fileSystem: FileSystem
57
- ) throws -> PluginInvocationResult {
57
+ on queue: DispatchQueue ,
58
+ completion: @escaping ( Result < PluginInvocationResult , Error > ) -> Void
59
+ ) {
58
60
// Create the plugin working directory if needed (but don't do anything with it if it already exists).
59
61
do {
60
62
try fileSystem. createDirectory ( outputDirectory, recursive: true )
61
63
}
62
64
catch {
63
- throw PluginEvaluationError . outputDirectoryCouldNotBeCreated ( path: outputDirectory, underlyingError: error)
65
+ return completion ( . failure ( PluginEvaluationError . couldNotCreateOuputDirectory ( path: outputDirectory, underlyingError: error) ) )
64
66
}
65
67
66
68
// Create the input context to send to the plugin.
67
69
// TODO: Some of this could probably be cached.
68
70
var serializer = PluginScriptRunnerInputSerializer ( buildEnvironment: buildEnvironment)
69
- let inputStruct = try serializer. makePluginScriptRunnerInput (
70
- rootPackage: package ,
71
- pluginWorkDir: outputDirectory,
72
- builtProductsDir: outputDirectory, // FIXME — what is this parameter needed for?
73
- toolNamesToPaths: toolNamesToPaths,
74
- pluginAction: action)
71
+ let inputStruct : PluginScriptRunnerInput
72
+ do {
73
+ inputStruct = try serializer. makePluginScriptRunnerInput (
74
+ rootPackage: package ,
75
+ pluginWorkDir: outputDirectory,
76
+ builtProductsDir: outputDirectory, // FIXME — what is this parameter needed for?
77
+ toolNamesToPaths: toolNamesToPaths,
78
+ pluginAction: action)
79
+ }
80
+ catch {
81
+ return completion ( . failure( PluginEvaluationError . couldNotSerializePluginInput ( underlyingError: error) ) )
82
+ }
75
83
76
84
// Call the plugin script runner to actually invoke the plugin.
77
- // TODO: This should be asynchronous.
78
85
var outputText = Data ( )
79
- let outputStruct = try scriptRunner. runPluginScript (
86
+ scriptRunner. runPluginScript (
80
87
sources: sources,
81
88
input: inputStruct,
82
89
toolsVersion: self . apiVersion,
83
90
writableDirectories: [ outputDirectory] ,
91
+ fileSystem: fileSystem,
84
92
observabilityScope: observabilityScope,
85
- textOutputHandler: { data in
93
+ on: DispatchQueue ( label: " plugin-invocation " ) ,
94
+ outputHandler: { data in
86
95
outputText. append ( contentsOf: data)
87
- } ,
88
- handlerQueue: DispatchQueue ( label: " plugin-invocation " ) ,
89
- fileSystem: fileSystem)
90
-
91
- // Generate emittable Diagnostics from the plugin output.
92
- let diagnostics : [ Diagnostic ] = try outputStruct. diagnostics. map { diag in
93
- let metadata : ObservabilityMetadata ? = try diag. file. map {
94
- var metadata = ObservabilityMetadata ( )
95
- metadata. fileLocation = try . init( . init( validating: $0) , line: diag. line)
96
- return metadata
97
- }
98
-
99
- switch diag. severity {
100
- case . error:
101
- return . error( diag. message, metadata: metadata)
102
- case . warning:
103
- return . warning( diag. message, metadata: metadata)
104
- case . remark:
105
- return . info( diag. message, metadata: metadata)
106
- }
107
- }
96
+ } ) { result in
97
+ switch result {
98
+ case . success( let output) :
99
+ // Generate emittable Diagnostics from the plugin output.
100
+ let diagnostics : [ Diagnostic ] = output. diagnostics. map { diag in
101
+ let metadata : ObservabilityMetadata ? = diag. file. map {
102
+ var metadata = ObservabilityMetadata ( )
103
+ metadata. fileLocation = try ? . init( . init( validating: $0) , line: diag. line)
104
+ return metadata
105
+ }
106
+
107
+ switch diag. severity {
108
+ case . error:
109
+ return . error( diag. message, metadata: metadata)
110
+ case . warning:
111
+ return . warning( diag. message, metadata: metadata)
112
+ case . remark:
113
+ return . info( diag. message, metadata: metadata)
114
+ }
115
+ }
108
116
109
- // FIXME: Validate the plugin output structure here, e.g. paths, etc.
110
-
111
- // Generate commands from the plugin output. This is where we translate from the transport JSON to our
112
- // internal form. We deal with BuildCommands and PrebuildCommands separately.
113
- // FIXME: This feels a bit too specific to have here.
114
- // FIXME: Also there is too much repetition here, need to unify it.
115
- let buildCommands = outputStruct . buildCommands. map { cmd in
116
- PluginInvocationResult . BuildCommand (
117
- configuration: . init(
118
- displayName: cmd. displayName,
119
- executable: cmd. executable,
120
- arguments: cmd. arguments,
121
- environment: cmd. environment,
122
- workingDirectory: cmd. workingDirectory. map { AbsolutePath ( $0) } ) ,
123
- inputFiles: cmd. inputFiles. map { AbsolutePath ( $0) } ,
124
- outputFiles: cmd. outputFiles. map { AbsolutePath ( $0) } )
125
- }
126
- let prebuildCommands = outputStruct . prebuildCommands. map { cmd in
127
- PluginInvocationResult . PrebuildCommand (
128
- configuration: . init(
129
- displayName: cmd. displayName,
130
- executable: cmd. executable,
131
- arguments: cmd. arguments,
132
- environment: cmd. environment,
133
- workingDirectory: cmd. workingDirectory. map { AbsolutePath ( $0) } ) ,
134
- outputFilesDirectory: AbsolutePath ( cmd. outputFilesDirectory) )
135
- }
117
+ // FIXME: Validate the plugin output structure here, e.g. paths, etc.
118
+
119
+ // Generate commands from the plugin output. This is where we translate from the transport JSON to our
120
+ // internal form. We deal with BuildCommands and PrebuildCommands separately.
121
+ // FIXME: This feels a bit too specific to have here.
122
+ // FIXME: Also there is too much repetition here, need to unify it.
123
+ let buildCommands = output . buildCommands. map { cmd in
124
+ PluginInvocationResult . BuildCommand (
125
+ configuration: . init(
126
+ displayName: cmd. displayName,
127
+ executable: cmd. executable,
128
+ arguments: cmd. arguments,
129
+ environment: cmd. environment,
130
+ workingDirectory: cmd. workingDirectory. map { AbsolutePath ( $0) } ) ,
131
+ inputFiles: cmd. inputFiles. map { AbsolutePath ( $0) } ,
132
+ outputFiles: cmd. outputFiles. map { AbsolutePath ( $0) } )
133
+ }
134
+ let prebuildCommands = output . prebuildCommands. map { cmd in
135
+ PluginInvocationResult . PrebuildCommand (
136
+ configuration: . init(
137
+ displayName: cmd. displayName,
138
+ executable: cmd. executable,
139
+ arguments: cmd. arguments,
140
+ environment: cmd. environment,
141
+ workingDirectory: cmd. workingDirectory. map { AbsolutePath ( $0) } ) ,
142
+ outputFilesDirectory: AbsolutePath ( cmd. outputFilesDirectory) )
143
+ }
136
144
137
- // Create and return an evaluation result for the invocation.
138
- return PluginInvocationResult (
139
- plugin: self ,
140
- diagnostics: diagnostics,
141
- textOutput: String ( decoding: outputText, as: UTF8 . self) ,
142
- buildCommands: buildCommands,
143
- prebuildCommands: prebuildCommands)
145
+ // Create and return an evaluation result for the invocation.
146
+ completion ( . success( PluginInvocationResult (
147
+ plugin: self ,
148
+ diagnostics: diagnostics,
149
+ textOutput: String ( decoding: outputText, as: UTF8 . self) ,
150
+ buildCommands: buildCommands,
151
+ prebuildCommands: prebuildCommands) ) )
152
+ case . failure( let error) :
153
+ completion ( . failure( error) )
154
+ }
155
+ }
144
156
}
145
157
}
146
158
@@ -223,15 +235,17 @@ extension PackageGraph {
223
235
let pluginOutputDir = outputDir. appending ( components: package . identity. description, target. name, pluginTarget. name)
224
236
225
237
// Invoke the plugin.
226
- let result = try pluginTarget. invoke (
238
+ let result = try tsc_await { pluginTarget. invoke (
227
239
action: . createBuildToolCommands( target: target) ,
228
240
package : package ,
229
241
buildEnvironment: buildEnvironment,
230
242
scriptRunner: pluginScriptRunner,
231
243
outputDirectory: pluginOutputDir,
232
244
toolNamesToPaths: toolNamesToPaths,
245
+ fileSystem: fileSystem,
233
246
observabilityScope: observabilityScope,
234
- fileSystem: fileSystem)
247
+ on: DispatchQueue ( label: " plugin-invocation " ) ,
248
+ completion: $0) }
235
249
pluginResults. append ( result)
236
250
}
237
251
@@ -342,7 +356,8 @@ public struct PluginInvocationResult {
342
356
343
357
/// An error in plugin evaluation.
344
358
public enum PluginEvaluationError : Swift . Error {
345
- case outputDirectoryCouldNotBeCreated( path: AbsolutePath , underlyingError: Error )
359
+ case couldNotCreateOuputDirectory( path: AbsolutePath , underlyingError: Error )
360
+ case couldNotSerializePluginInput( underlyingError: Error )
346
361
case runningPluginFailed( underlyingError: Error )
347
362
case decodingPluginOutputFailed( json: Data , underlyingError: Error )
348
363
}
@@ -366,11 +381,12 @@ public protocol PluginScriptRunner {
366
381
input: PluginScriptRunnerInput ,
367
382
toolsVersion: ToolsVersion ,
368
383
writableDirectories: [ AbsolutePath ] ,
384
+ fileSystem: FileSystem ,
369
385
observabilityScope: ObservabilityScope ,
370
- textOutputHandler : @escaping ( Data ) -> Void ,
371
- handlerQueue : DispatchQueue ,
372
- fileSystem : FileSystem
373
- ) throws -> PluginScriptRunnerOutput
386
+ on queue : DispatchQueue ,
387
+ outputHandler : @escaping ( Data ) -> Void ,
388
+ completion : @escaping ( Result < PluginScriptRunnerOutput , Error > ) -> Void
389
+ )
374
390
375
391
/// Returns the Triple that represents the host for which plugin script tools should be built, or for which binary
376
392
/// tools should be selected.
0 commit comments