@@ -29,7 +29,6 @@ import protocol TSCUtility.ProgressAnimationProtocol
29
29
@_implementationOnly import SwiftDriver
30
30
31
31
public final class BuildOperation : PackageStructureDelegate , SPMBuildCore . BuildSystem , BuildErrorAdviceProvider {
32
-
33
32
/// The delegate used by the build system.
34
33
public weak var delegate : SPMBuildCore . BuildSystemDelegate ?
35
34
@@ -39,14 +38,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
39
38
/// The closure for loading the package graph.
40
39
let packageGraphLoader : ( ) throws -> PackageGraph
41
40
42
- /// Entity responsible for compiling and running plugin scripts.
43
- let pluginScriptRunner : PluginScriptRunner
44
-
45
- /// Directory where plugin intermediate files are stored.
46
- let pluginWorkDirectory : AbsolutePath
47
-
48
- /// Whether to sandbox commands from build tool plugins.
49
- public let disableSandboxForPluginCommands : Bool
41
+ /// the plugin configuration for build plugins
42
+ let pluginConfiguration : PluginConfiguration ?
50
43
51
44
/// The llbuild build delegate reference.
52
45
private var buildSystemDelegate : BuildOperationBuildSystemDelegateHandler ?
@@ -99,10 +92,8 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
99
92
buildParameters: BuildParameters ,
100
93
cacheBuildManifest: Bool ,
101
94
packageGraphLoader: @escaping ( ) throws -> PackageGraph ,
95
+ pluginConfiguration: PluginConfiguration ? = . none,
102
96
additionalFileRules: [ FileRuleDescription ] ,
103
- pluginScriptRunner: PluginScriptRunner ,
104
- pluginWorkDirectory: AbsolutePath ,
105
- disableSandboxForPluginCommands: Bool ,
106
97
outputStream: OutputByteStream ,
107
98
logLevel: Basics . Diagnostic . Severity ,
108
99
fileSystem: TSCBasic . FileSystem ,
@@ -116,9 +107,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
116
107
self . cacheBuildManifest = cacheBuildManifest
117
108
self . packageGraphLoader = packageGraphLoader
118
109
self . additionalFileRules = additionalFileRules
119
- self . pluginScriptRunner = pluginScriptRunner
120
- self . pluginWorkDirectory = pluginWorkDirectory
121
- self . disableSandboxForPluginCommands = disableSandboxForPluginCommands
110
+ self . pluginConfiguration = pluginConfiguration
122
111
self . outputStream = outputStream
123
112
self . logLevel = logLevel
124
113
self . fileSystem = fileSystem
@@ -323,6 +312,10 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
323
312
// Compiles a single plugin, emitting its output and throwing an error if it
324
313
// fails.
325
314
func compilePlugin( _ plugin: PluginDescription ) throws {
315
+ guard let pluginConfiguration = self . pluginConfiguration else {
316
+ throw InternalError ( " unknown plugin script runner " )
317
+
318
+ }
326
319
// Compile the plugin, getting back a PluginCompilationResult.
327
320
class Delegate : PluginScriptCompilerDelegate {
328
321
let preparationStepName : String
@@ -351,7 +344,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
351
344
}
352
345
let delegate = Delegate ( preparationStepName: " Compiling plugin \( plugin. targetName) " , buildSystemDelegate: self . buildSystemDelegate)
353
346
let result = try tsc_await {
354
- self . pluginScriptRunner . compilePluginScript (
347
+ pluginConfiguration . scriptRunner . compilePluginScript (
355
348
sourceFiles: plugin. sources. paths,
356
349
pluginName: plugin. targetName,
357
350
toolsVersion: plugin. toolsVersion,
@@ -393,40 +386,47 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
393
386
// Load the package graph.
394
387
let graph = try getPackageGraph ( )
395
388
389
+ let buildToolPluginInvocationResults : [ ResolvedTarget : [ BuildToolPluginInvocationResult ] ]
390
+ let prebuildCommandResults : [ ResolvedTarget : [ PrebuildCommandResult ] ]
396
391
// Invoke any build tool plugins in the graph to generate prebuild commands and build commands.
397
- let buildToolPluginInvocationResults = try graph. invokeBuildToolPlugins (
398
- outputDir: self . pluginWorkDirectory. appending ( component: " outputs " ) ,
399
- builtToolsDir: self . buildParameters. buildPath,
400
- buildEnvironment: self . buildParameters. buildEnvironment,
401
- toolSearchDirectories: [ self . buildParameters. toolchain. swiftCompilerPath. parentDirectory] ,
402
- pluginScriptRunner: self . pluginScriptRunner,
403
- observabilityScope: self . observabilityScope,
404
- fileSystem: self . fileSystem
405
- )
406
-
407
- // Surface any diagnostics from build tool plugins.
408
- for (target, results) in buildToolPluginInvocationResults {
409
- // There is one result for each plugin that gets applied to a target.
410
- for result in results {
411
- let diagnosticsEmitter = self . observabilityScope. makeDiagnosticsEmitter {
412
- var metadata = ObservabilityMetadata ( )
413
- metadata. targetName = target. name
414
- metadata. pluginName = result. plugin. name
415
- return metadata
416
- }
417
- for line in result. textOutput. split ( separator: " \n " ) {
418
- diagnosticsEmitter. emit ( info: line)
419
- }
420
- for diag in result. diagnostics {
421
- diagnosticsEmitter. emit ( diag)
392
+ if let pluginConfiguration = self . pluginConfiguration {
393
+ buildToolPluginInvocationResults = try graph. invokeBuildToolPlugins (
394
+ outputDir: pluginConfiguration. workDirectory. appending ( component: " outputs " ) ,
395
+ builtToolsDir: self . buildParameters. buildPath,
396
+ buildEnvironment: self . buildParameters. buildEnvironment,
397
+ toolSearchDirectories: [ self . buildParameters. toolchain. swiftCompilerPath. parentDirectory] ,
398
+ pluginScriptRunner: pluginConfiguration. scriptRunner,
399
+ observabilityScope: self . observabilityScope,
400
+ fileSystem: self . fileSystem
401
+ )
402
+
403
+ // Surface any diagnostics from build tool plugins.
404
+ for (target, results) in buildToolPluginInvocationResults {
405
+ // There is one result for each plugin that gets applied to a target.
406
+ for result in results {
407
+ let diagnosticsEmitter = self . observabilityScope. makeDiagnosticsEmitter {
408
+ var metadata = ObservabilityMetadata ( )
409
+ metadata. targetName = target. name
410
+ metadata. pluginName = result. plugin. name
411
+ return metadata
412
+ }
413
+ for line in result. textOutput. split ( separator: " \n " ) {
414
+ diagnosticsEmitter. emit ( info: line)
415
+ }
416
+ for diag in result. diagnostics {
417
+ diagnosticsEmitter. emit ( diag)
418
+ }
422
419
}
423
420
}
424
- }
425
421
426
- // Run any prebuild commands provided by build tool plugins. Any failure stops the build.
427
- let prebuildCommandResults = try graph. reachableTargets. reduce ( into: [ : ] , { partial, target in
428
- partial [ target] = try buildToolPluginInvocationResults [ target] . map { try self . runPrebuildCommands ( for: $0) }
429
- } )
422
+ // Run any prebuild commands provided by build tool plugins. Any failure stops the build.
423
+ prebuildCommandResults = try graph. reachableTargets. reduce ( into: [ : ] , { partial, target in
424
+ partial [ target] = try buildToolPluginInvocationResults [ target] . map { try self . runPrebuildCommands ( for: $0) }
425
+ } )
426
+ } else {
427
+ buildToolPluginInvocationResults = [ : ]
428
+ prebuildCommandResults = [ : ]
429
+ }
430
430
431
431
// Emit warnings about any unhandled files in authored packages. We do this after applying build tool plugins, once we know what files they handled.
432
432
for package in graph. rootPackages where package . manifest. toolsVersion >= . v5_3 {
@@ -472,7 +472,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
472
472
473
473
let ( buildDescription, buildManifest) = try BuildDescription . create (
474
474
with: plan,
475
- disableSandboxForPluginCommands: self . disableSandboxForPluginCommands ,
475
+ disableSandboxForPluginCommands: self . pluginConfiguration ? . disableSandbox ?? false ,
476
476
fileSystem: self . fileSystem,
477
477
observabilityScope: self . observabilityScope
478
478
)
@@ -526,7 +526,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
526
526
buildFile: buildParameters. llbuildManifest. pathString,
527
527
databaseFile: databasePath,
528
528
delegate: buildSystemDelegate,
529
- schedulerLanes: buildParameters. jobs
529
+ schedulerLanes: buildParameters. workers
530
530
)
531
531
532
532
// TODO: this seems fragile, perhaps we replace commandFailureHandler by adding relevant calls in the delegates chain
@@ -541,6 +541,10 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
541
541
/// Runs any prebuild commands associated with the given list of plugin invocation results, in order, and returns the
542
542
/// results of running those prebuild commands.
543
543
private func runPrebuildCommands( for pluginResults: [ BuildToolPluginInvocationResult ] ) throws -> [ PrebuildCommandResult ] {
544
+ guard let pluginConfiguration = self . pluginConfiguration else {
545
+ throw InternalError ( " unknown plugin script runner " )
546
+
547
+ }
544
548
// Run through all the commands from all the plugin usages in the target.
545
549
return try pluginResults. map { pluginResult in
546
550
// As we go we will collect a list of prebuild output directories whose contents should be input to the build,
@@ -553,7 +557,7 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
553
557
// Run the command configuration as a subshell. This doesn't return until it is done.
554
558
// TODO: We need to also use any working directory, but that support isn't yet available on all platforms at a lower level.
555
559
var commandLine = [ command. configuration. executable. pathString] + command. configuration. arguments
556
- if !self . disableSandboxForPluginCommands {
560
+ if !pluginConfiguration . disableSandbox {
557
561
commandLine = try Sandbox . apply ( command: commandLine, strictness: . writableTemporaryDirectory, writableDirectories: [ pluginResult. pluginOutputDirectory] )
558
562
}
559
563
let processResult = try TSCBasic . Process. popen ( arguments: commandLine, environment: command. configuration. environment)
@@ -613,6 +617,25 @@ public final class BuildOperation: PackageStructureDelegate, SPMBuildCore.BuildS
613
617
}
614
618
}
615
619
620
+ extension BuildOperation {
621
+ public struct PluginConfiguration {
622
+ /// Entity responsible for compiling and running plugin scripts.
623
+ let scriptRunner : PluginScriptRunner
624
+
625
+ /// Directory where plugin intermediate files are stored.
626
+ let workDirectory : AbsolutePath
627
+
628
+ /// Whether to sandbox commands from build tool plugins.
629
+ let disableSandbox : Bool
630
+
631
+ public init ( scriptRunner: PluginScriptRunner , workDirectory: AbsolutePath , disableSandbox: Bool ) {
632
+ self . scriptRunner = scriptRunner
633
+ self . workDirectory = workDirectory
634
+ self . disableSandbox = disableSandbox
635
+ }
636
+ }
637
+ }
638
+
616
639
extension BuildDescription {
617
640
static func create( with plan: BuildPlan , disableSandboxForPluginCommands: Bool , fileSystem: TSCBasic . FileSystem , observabilityScope: ObservabilityScope ) throws -> ( BuildDescription , LLBuildManifest . BuildManifest ) {
618
641
// Generate the llbuild manifest.
0 commit comments