Skip to content

Commit

Permalink
Add arguments to Plugins
Browse files Browse the repository at this point in the history
  • Loading branch information
BarredEwe committed May 29, 2024
1 parent 4dc41b0 commit 41083ef
Show file tree
Hide file tree
Showing 14 changed files with 54 additions and 33 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ enum Serialization {
}

enum PluginUsage: Codable {
case plugin(name: String, package: String?)
case plugin(name: String, package: String?, arguments: [String])
}

struct Target: Codable {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -274,7 +274,7 @@ extension Serialization.PluginNetworkPermissionScope {
extension Serialization.PluginUsage {
init(_ usage: PackageDescription.Target.PluginUsage) {
switch usage {
case .plugin(let name, let package): self = .plugin(name: name, package: package)
case .plugin(let name, let package, let arguments): self = .plugin(name: name, package: package, arguments: arguments)
}
}
}
Expand Down
12 changes: 6 additions & 6 deletions Sources/PackageDescription/Target.swift
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ public final class Target {
/// The plug-in to apply to each target that uses it, and creates commands
/// that run before or during the build of the target.
@available(_PackageDescription, introduced: 5.5)
case buildTool
case buildTool(arguments: [String])

/// Specifies that the plug-in provides a user command capability.
///
Expand Down Expand Up @@ -227,7 +227,7 @@ public final class Target {
/// - Parameters:
/// - name: The name of the plug-in target.
/// - package: The name of the package that defines the plug-in target.
case plugin(name: String, package: String?)
case plugin(name: String, package: String?, arguments: [String])
}

/// Construct a target.
Expand Down Expand Up @@ -1398,7 +1398,7 @@ extension Target.PluginCapability {
/// - Returns: A plug-in capability that defines a build tool.
@available(_PackageDescription, introduced: 5.5)
public static func buildTool() -> Target.PluginCapability {
return .buildTool
return .buildTool(arguments: [])
}
}

Expand Down Expand Up @@ -1507,8 +1507,8 @@ extension Target.PluginUsage {
/// - Parameter name: The name of the plugin target.
/// - Returns: A `PluginUsage` instance.
@available(_PackageDescription, introduced: 5.5)
public static func plugin(name: String) -> Target.PluginUsage {
return .plugin(name: name, package: nil)
public static func plugin(name: String, arguments: [String]) -> Target.PluginUsage {
return .plugin(name: name, package: nil, arguments: arguments)
}
}

Expand All @@ -1535,7 +1535,7 @@ extension Target.PluginUsage: ExpressibleByStringLiteral {
///
/// - Parameter value: A string literal.
public init(stringLiteral value: String) {
self = .plugin(name: value, package: nil)
self = .plugin(name: value, package: nil, arguments: [])
}
}

4 changes: 2 additions & 2 deletions Sources/PackageLoading/ManifestJSONParser.swift
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,8 @@ extension TargetDescription.PluginNetworkPermissionScope {
extension TargetDescription.PluginUsage {
init(_ usage: Serialization.PluginUsage) {
switch usage {
case .plugin(let name, let package):
self = .plugin(name: name, package: package)
case .plugin(let name, let package, let arguments):
self = .plugin(name: name, package: package, arguments: arguments)
}
}
}
Expand Down
15 changes: 10 additions & 5 deletions Sources/PackageLoading/PackageBuilder.swift
Original file line number Diff line number Diff line change
Expand Up @@ -672,7 +672,7 @@ public final class PackageBuilder {
let potentialModuleMap = Dictionary(potentialModules.map { ($0.name, $0) }, uniquingKeysWith: { $1 })
let successors: (PotentialModule) -> [PotentialModule] = {
// No reference of this target in manifest, i.e. it has no dependencies.
guard let target = self.manifest.targetMap[$0.name] else { return [] }
guard let target: TargetDescription = self.manifest.targetMap[$0.name] else { return [] }
// Collect the successors from declared dependencies.
var successors: [PotentialModule] = target.dependencies.compactMap {
switch $0 {
Expand All @@ -692,9 +692,9 @@ public final class PackageBuilder {
if let pluginUsages = target.pluginUsages {
successors += pluginUsages.compactMap {
switch $0 {
case .plugin(_, .some(_)):
case .plugin(_, .some(_), _):
nil
case .plugin(let name, nil):
case .plugin(let name, nil, _):
if let potentialModule = potentialModuleMap[name] {
potentialModule
} else if let targetName = pluginTargetName(for: name),
Expand Down Expand Up @@ -766,13 +766,17 @@ public final class PackageBuilder {
let pluginUsages: [Target.PluginUsage] = manifestTarget?.pluginUsages.map {
$0.compactMap { usage in
switch usage {
case .plugin(let name, let package):
case .plugin(let name, let package, let arguments):
if let package {
return .product(Target.ProductReference(name: name, package: package), conditions: [])
} else {
if let target = targets[name] {
if let arguments {
(target as? PluginTarget)?.arguments = arguments
}
return .target(target, conditions: [])
} else if let targetName = pluginTargetName(for: name), let target = targets[targetName] {
// TODO: Check
return .target(target, conditions: [])
} else {
self.observabilityScope.emit(.pluginNotFound(name: name))
Expand Down Expand Up @@ -960,7 +964,8 @@ public final class PackageBuilder {
apiVersion: self.manifest.toolsVersion,
pluginCapability: PluginCapability(from: declaredCapability),
dependencies: dependencies,
packageAccess: potentialModule.packageAccess
packageAccess: potentialModule.packageAccess,
arguments: []
)
}

Expand Down
6 changes: 3 additions & 3 deletions Sources/PackageModel/Manifest/Manifest.swift
Original file line number Diff line number Diff line change
Expand Up @@ -237,7 +237,7 @@ public final class Manifest: Sendable {

let plugins: [String] = target.pluginUsages?.compactMap { pluginUsage in
switch pluginUsage {
case .plugin(name: let name, package: nil):
case .plugin(name: let name, package: nil, _):
if targetsByName.keys.contains(name) {
return name
} else if let targetName = productsByName[name]?.targets.first {
Expand Down Expand Up @@ -334,7 +334,7 @@ public final class Manifest: Sendable {
referencedBy pluginUsage: TargetDescription.PluginUsage
) -> PackageDependency? {
switch pluginUsage {
case .plugin(_, .some(let package)):
case .plugin(_, .some(let package), _):
return self.packageDependency(referencedBy: package)
default:
return nil
Expand Down Expand Up @@ -433,7 +433,7 @@ public final class Manifest: Sendable {
availablePackages: Set<PackageIdentity>
) {
switch requiredPlugIn {
case .plugin(let name, let package):
case .plugin(let name, let package, _):
if let package {
if !self.register(
product: name,
Expand Down
8 changes: 5 additions & 3 deletions Sources/PackageModel/Manifest/TargetDescription.swift
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,7 @@ public struct TargetDescription: Hashable, Encodable, Sendable {

/// Represents a target's usage of a plugin target or product.
public enum PluginUsage: Hashable, Sendable {
case plugin(name: String, package: String?)
case plugin(name: String, package: String?, arguments: [String]?)
}

public init(
Expand Down Expand Up @@ -357,10 +357,11 @@ extension TargetDescription.PluginUsage: Codable {
public func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
switch self {
case let .plugin(name, package):
case let .plugin(name, package, arguments):
var unkeyedContainer = container.nestedUnkeyedContainer(forKey: .plugin)
try unkeyedContainer.encode(name)
try unkeyedContainer.encode(package)
try unkeyedContainer.encode(arguments)
}
}

Expand All @@ -374,7 +375,8 @@ extension TargetDescription.PluginUsage: Codable {
var unkeyedValues = try values.nestedUnkeyedContainer(forKey: key)
let name = try unkeyedValues.decode(String.self)
let package = try unkeyedValues.decodeIfPresent(String.self)
self = .plugin(name: name, package: package)
let arguments = try? unkeyedValues.decodeIfPresent([String].self)
self = .plugin(name: name, package: package, arguments: arguments)
}
}
}
Expand Down
9 changes: 8 additions & 1 deletion Sources/PackageModel/Target/PluginTarget.swift
Original file line number Diff line number Diff line change
Expand Up @@ -18,16 +18,20 @@ public final class PluginTarget: Target {
/// API version to use for PackagePlugin API availability.
public let apiVersion: ToolsVersion

public var arguments: [String]

public init(
name: String,
sources: Sources,
apiVersion: ToolsVersion,
pluginCapability: PluginCapability,
dependencies: [Target.Dependency] = [],
packageAccess: Bool
packageAccess: Bool,
arguments: [String]
) {
self.capability = pluginCapability
self.apiVersion = apiVersion
self.arguments = arguments
super.init(
name: name,
type: .plugin,
Expand All @@ -45,19 +49,22 @@ public final class PluginTarget: Target {
private enum CodingKeys: String, CodingKey {
case capability
case apiVersion
case arguments
}

public override func encode(to encoder: Encoder) throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.capability, forKey: .capability)
try container.encode(self.apiVersion, forKey: .apiVersion)
try container.encode(self.arguments, forKey: .arguments)
try super.encode(to: encoder)
}

required public init(from decoder: Decoder) throws {
let container = try decoder.container(keyedBy: CodingKeys.self)
self.capability = try container.decode(PluginCapability.self, forKey: .capability)
self.apiVersion = try container.decode(ToolsVersion.self, forKey: .apiVersion)
self.arguments = try container.decode([String].self, forKey: .arguments)
try super.init(from: decoder)
}
}
Expand Down
4 changes: 2 additions & 2 deletions Sources/PackagePlugin/Plugin.swift
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ extension Plugin {
fileprivate static func handleMessage(_ message: HostToPluginMessage) async throws {
switch message {

case .createBuildToolCommands(let wireInput, let rootPackageId, let targetId, let generatedSources, let generatedResources):
case .createBuildToolCommands(let wireInput, let rootPackageId, let targetId, let generatedSources, let generatedResources, let arguments):
// Deserialize the context from the wire input structures. The root
// package is the one we'll set the context's `package` property to.
let context: PluginContext
Expand Down Expand Up @@ -195,7 +195,7 @@ extension Plugin {
}

// Invoke the plugin to create build commands for the target.
let generatedCommands = try await plugin.createBuildCommands(context: context, target: target)
let generatedCommands = try await plugin.createBuildCommands(context: context, target: target, arguments: arguments)

// Send each of the generated commands to the host.
for command in generatedCommands {
Expand Down
3 changes: 2 additions & 1 deletion Sources/PackagePlugin/PluginMessages.swift
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ enum HostToPluginMessage: Codable {
rootPackageId: InputContext.Package.Id,
targetId: InputContext.Target.Id,
pluginGeneratedSources: [InputContext.URL.Id],
pluginGeneratedResources: [InputContext.URL.Id]
pluginGeneratedResources: [InputContext.URL.Id],
arguments: [String]
)

/// The host requests that the plugin perform a user command (corresponding to a `.command` capability) on a package in the graph.
Expand Down
3 changes: 2 additions & 1 deletion Sources/PackagePlugin/Protocols.swift
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ public protocol BuildToolPlugin: Plugin {
/// that it does not directly run those commands.
func createBuildCommands(
context: PluginContext,
target: Target
target: Target,
arguments: [String]
) async throws -> [Command]
}

Expand Down
14 changes: 9 additions & 5 deletions Sources/SPMBuildCore/Plugins/PluginInvocation.swift
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ public enum PluginAction {
package: ResolvedPackage,
target: ResolvedModule,
pluginGeneratedSources: [AbsolutePath],
pluginGeneratedResources: [AbsolutePath]
pluginGeneratedResources: [AbsolutePath],
arguments: [String]
)
case performCommand(package: ResolvedPackage, arguments: [String])
}
Expand All @@ -46,7 +47,8 @@ extension PluginTarget {
modulesGraph: ModulesGraph,
observabilityScope: ObservabilityScope,
callbackQueue: DispatchQueue,
delegate: PluginInvocationDelegate
delegate: PluginInvocationDelegate,
arguments: [String]
) async throws -> Bool {
try await safe_async {
self.invoke(
Expand Down Expand Up @@ -142,7 +144,7 @@ extension PluginTarget {
let actionMessage: HostToPluginMessage
switch action {

case .createBuildToolCommands(let package, let target, let pluginGeneratedSources, let pluginGeneratedResources):
case .createBuildToolCommands(let package, let target, let pluginGeneratedSources, let pluginGeneratedResources, let arguments):
let rootPackageId = try serializer.serialize(package: package)
guard let targetId = try serializer.serialize(target: target) else {
throw StringError("unexpectedly was unable to serialize target \(target)")
Expand All @@ -162,7 +164,8 @@ extension PluginTarget {
rootPackageId: rootPackageId,
targetId: targetId,
pluginGeneratedSources: generatedSources,
pluginGeneratedResources: generatedResources
pluginGeneratedResources: generatedResources,
arguments: arguments
)
case .performCommand(let package, let arguments):
let rootPackageId = try serializer.serialize(package: package)
Expand Down Expand Up @@ -561,7 +564,8 @@ extension ModulesGraph {
package: package,
target: target,
pluginGeneratedSources: pluginDerivedSources.paths,
pluginGeneratedResources: pluginDerivedResources.map { $0.path }
pluginGeneratedResources: pluginDerivedResources.map { $0.path },
arguments: pluginTarget.arguments
),
buildEnvironment: buildParameters.buildEnvironment,
scriptRunner: pluginScriptRunner,
Expand Down
3 changes: 2 additions & 1 deletion Tests/FunctionalTests/PluginTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -831,7 +831,8 @@ final class PluginTests: XCTestCase {
modulesGraph: packageGraph,
observabilityScope: observability.topScope,
callbackQueue: delegateQueue,
delegate: delegate
delegate: delegate,
arguments: []
)
} onCancel: {
do {
Expand Down
2 changes: 1 addition & 1 deletion Tests/SPMBuildCoreTests/PluginInvocationTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ final class PluginInvocationTests: XCTestCase {
TargetDescription(
name: "Foo",
type: .regular,
pluginUsages: [.plugin(name: "FooPlugin", package: nil)]
pluginUsages: [.plugin(name: "FooPlugin", package: nil, arguments: ["123", "321"])]
),
TargetDescription(
name: "FooPlugin",
Expand Down

0 comments on commit 41083ef

Please sign in to comment.