Skip to content

Commit 3f7d2bb

Browse files
authored
Adjust SE-0332 to reflect the removal of the targets parameter (#1562)
* Adjust SE-0332 to reflect the removal of the `targets` parameter, which was considered redundant (too specialized for general-purpose command plugins) - names of targets are available to the plugin in the `arguments` array if the user passes it on the command line. * Fix a few syntax errors in the manifests of the examples (not relevant to the content of the proposal).
1 parent 8e690f2 commit 3f7d2bb

File tree

1 file changed

+14
-28
lines changed

1 file changed

+14
-28
lines changed

proposals/0332-swiftpm-command-plugins.md

Lines changed: 14 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -133,11 +133,6 @@ public protocol CommandPlugin: Plugin {
133133
/// directories, etc.
134134
context: PluginContext,
135135

136-
/// The targets to which the command should be applied. If the invoker of
137-
/// the command has not specified particular targets, this will be a list
138-
/// of all the targets in the package to which the command is applied.
139-
targets: [Target],
140-
141136
/// Any literal arguments passed after the verb in the command invocation.
142137
arguments: [String],
143138
) async throws
@@ -148,7 +143,7 @@ public protocol CommandPlugin: Plugin {
148143
}
149144
```
150145

151-
This defines a basic entry point for a command plugin, passing it information about the context in which the plugin is invoked (including information about the package graph), the set of targets on which the command should operate, and the arguments passed by the user after the verb in the `swift` `package` invocation.
146+
This defines a basic entry point for a command plugin, passing it information about the context in which the plugin is invoked (including information about the package graph) and the arguments passed by the user after the verb in the `swift` `package` invocation.
152147

153148
The `context` parameter provides access to the package to which the user applies the plugin, including any dependencies, and it also provides access to a working directory that the plugin can use for any purposes, as well as a way to look up command line tools with a given name. This is the same as the support that is available to all plugins via SE-0325.
154149

@@ -158,6 +153,8 @@ Many command plugins will invoke tools using subprocesses in order to do the act
158153

159154
Plugins can also use Foundation APIs for reading and writing files, encoding and decoding JSON, and other actions.
160155

156+
The arguments are a literal array of strings that the user specified when invoking the plugin. Plugins that operate on individual targets or products would typically support a `--target` or `--product` option that allows users to specify the names of targets or products to operate on in the package to which the plugin command is applied.
157+
161158
#### Accessing Package Manager Services
162159

163160
In addition to invoking invoking tool executables and using Foundation APIs, command plugins can use the `packageManager` property to obtain more specialized information and to invoke certain SwiftPM services. This is a proxy to SwiftPM or to the IDE that is hosting the plugin, and provides access to some of its functionality. The set of services provided in this API is expected to grow over time, and would ideally, over time, comprise most of the SwiftPM functionality available in its CLI.
@@ -414,19 +411,13 @@ In the SwiftPM CLI, command plugins provided by a package or its direct dependen
414411

415412
This will invoke the plugin and only return when it completes. Since no other options were provided, this will pass all regular targets in the package to the plugin ("special" targets such as those that define plugins will be excluded).
416413

417-
To pass a subset of the targets to the plugin, one or more `--target` options can be used in the invocation:
414+
Any parameters passed after the name of the plugin command are passed verbatim to the entry point of the plugin. For example, if a plugin accepts a `--target` option, a subset of the targets to operate on can be passed on the command line that invokes the plugin:
418415

419416
```shell
420-
❯ swift package --target Foo --target Bar do-something
417+
❯ swift package do-something --target Foo --target Bar --someOtherFlag
421418
```
422419

423-
This will pass the `Foo` and `Bar` targets to the plugin (assuming those are names of regular targets defined in the package — if they are not, an error is emitted).
424-
425-
The user can also provide additional arguments that are passed directly to the plugin. In the following example, the plugin will receive the arguments `aParam` and `-aFlag`, in addition to the targets named `Foo` and `Bar`.
426-
427-
```shell
428-
❯ swift package --target Foo --target Bar do-something aParam -aFlag
429-
```
420+
It is the responsibility of the plugin to interpret any command line arguments passed to it.
430421

431422
Arguments are currently passed to the plugin exactly as they are written after the command’s verb. A future proposal could allow the plugin to define parameters (using SwiftArgumentParser) that SwiftPM could interpret and that would integrate better with SwiftPM’s own command line arguments.
432423

@@ -503,7 +494,6 @@ import Foundation
503494
struct MyDocCPlugin: CommandPlugin {
504495
func performCommand(
505496
context: PluginContext,
506-
targets: [Target],
507497
arguments: [String]
508498
) async throws {
509499
// We'll be creating commands that invoke `docc`, so start by locating it.
@@ -512,8 +502,8 @@ struct MyDocCPlugin: CommandPlugin {
512502
// Construct the path of the directory in which to emit documentation.
513503
let outputDir = context.pluginWorkDirectory.appending("Outputs")
514504

515-
// Iterate over the targets we were given.
516-
for target in targets {
505+
// Iterate over the targets in the package.
506+
for target in context.package.targets {
517507
// Only consider those kinds of targets that can have source files.
518508
guard let target = target as? SourceModuleTarget else { continue }
519509

@@ -582,8 +572,6 @@ Users can then invoke this command plugin using the `swift` `package` invocation
582572
❯ swift package generate-documentation
583573
```
584574

585-
Since no `--target` options are provided, SwiftPM passes all the package’s regular targets to the plugin (in this simple example, just the `MyLibrary` target).
586-
587575
The plugin would usually print the path at which it generated the documentation.
588576

589577
## Example 2: Formatting Source Code
@@ -603,7 +591,7 @@ let package = Package(
603591
],
604592
targets: [
605593
.plugin(
606-
"MyFormatterPlugin",
594+
name: "MyFormatterPlugin",
607595
capability: .command(
608596
intent: .sourceCodeFormatting(),
609597
permissions: [
@@ -628,7 +616,6 @@ import Foundation
628616
struct MyFormatterPlugin: CommandPlugin {
629617
func performCommand(
630618
context: PluginContext,
631-
targets: [Target],
632619
arguments: [String]
633620
) async throws {
634621
// We'll be invoking `swift-format`, so start by locating it.
@@ -637,8 +624,8 @@ struct MyFormatterPlugin: CommandPlugin {
637624
// By convention, use a configuration file in the package directory.
638625
let configFile = context.package.directory.appending(".swift-format.json")
639626

640-
// Iterate over the targets we've been asked to format.
641-
for target in targets {
627+
// Iterate over the targets in the package.
628+
for target in context.package.targets {
642629
// Skip any type of target that doesn't have source files.
643630
// Note: We could choose to instead emit a warning or error here.
644631
guard let target = target as? SourceModuleTarget else { continue }
@@ -694,17 +681,17 @@ let package = Package(
694681
targets: [
695682
// This is the hypothetical executable we want to distribute.
696683
.executableTarget(
697-
"MyExec"
684+
name: "MyExec"
698685
),
699686
// This is the plugin that defines a custom command to distribute the executable.
700687
.plugin(
701-
"MyDistributionArchiveCreator",
688+
name: "MyDistributionArchiveCreator",
702689
capability: .command(
703690
intent: .custom(
704691
verb: "create-distribution-archive",
705692
description: "Creates a .zip containing release builds of products"
706693
)
707-
),
694+
)
708695
)
709696
]
710697
)
@@ -720,7 +707,6 @@ import Foundation
720707
struct MyDistributionArchiveCreator: CommandPlugin {
721708
func performCommand(
722709
context: PluginContext,
723-
targets: [Target],
724710
arguments: [String]
725711
) async throws {
726712
// Check that we were given the name of a product as the first argument

0 commit comments

Comments
 (0)