Skip to content

Package Manager Conditional Plugin#10119

Open
clive819 wants to merge 3 commits into
swiftlang:mainfrom
clive819:conditional-plugin
Open

Package Manager Conditional Plugin#10119
clive819 wants to merge 3 commits into
swiftlang:mainfrom
clive819:conditional-plugin

Conversation

@clive819

Copy link
Copy Markdown

Comment thread Sources/Build/BuildPlan/BuildPlan.swift Outdated
throw InternalError("could not determine package for module \(self)")
}

let enabledTraits = package.enabledTraits ?? []

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@bripeticca is this correct? Not sure where the latest refactorings left us.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe we'd want to default to defaults here, since [] wrt traits API usage usually refers to the disabling of traits.

Also, there is an EnabledTrait model that is meant to be leveraged to make enabled trait checks easier. Might be good to continue the usage for that here; there is a map (EnabledTraitsMap) that is populated on the Workspace and passed through to the ModulesGraph.load(...) method; we could either add this as a property to the ModulesGraph itself since it's consumed by the BuildPlan, or it could just be passed as a parameter to the BuildPlan init. Note that model may or may not need some updates in order to handle plugins.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9a0a6b1

Comment on lines +128 to +130
public let traits: Set<String>?

public init(hostPlatforms: [Platform] = [], targetPlatforms: [Platform] = [], traits: Set<String>? = nil) {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think traits should not be optional to align with the other APIs and default to [.defaults]

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 9a0a6b1


for plugin in module.pluginDependencies(satisfying: buildParameters.buildEnvironment) {
let enabledTraits = package.enabledTraits ?? []
for plugin in module.pluginDependencies(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using the host build parameters here should be ok as the host is fixed, but using target build parameters here will not necessarily be correct if e.g. an iOS app embeds a watchOS app which links a package target. In that case the top level "target" would be iOS, but we'd want to evaluate platform conditions in the context of watchOS. Target platform plugin conditions may need to be represented in the PIF itself to model that correctly

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks, that makes sense. This part is a bit tricky, took me a while. I’m not very familiar with the build system, so please correct me if I’m wrong.

Based on my understanding, SwiftPM currently invokes build tool plugins while generating the PIF, using the top-level target build parameters. The actual configured-target context is only available later in SwiftBuild. If we want to follow the proposal semantics, where non-matching plugins are not invoked, then fully supporting targetPlatforms seems to require deferring plugin invocation into SwiftBuild’s configured-target context.

I’m not sure whether that is the right direction, since it would mean SwiftBuild no longer merely consumes plugin results from SwiftPM, but starts participating in SwiftPM plugin planning.

Looking for guidance on what we should do here in a way that aligns with the vision for SwiftPM and SwiftBuild 🙏

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

then fully supporting targetPlatforms seems to require deferring plugin invocation into SwiftBuild’s configured-target context.

yeah, I think this will be required in some form to properly support destination-platform conditions. It'll likely require new API for inspecting the build graph post-dependency resolution and injecting new CustomTasks before we go to construct the task graph. I'm not entirely sure what that should look like at the moment.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the issue with using platform filters for this is that the plugin script still runs even if the resulting tasks are filtered out, which might be a surprise to plugin authors. Ideally I think we'd fully interleave build planning and plugin execution to avoid that, although maybe there's a way to make incremental progress towards that without immediately needing to refactor everything

@dschaefer2 dschaefer2 Jun 3, 2026

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The plugins are supposed to be an extension of the package manifest. It makes sense the plugins run every time (well every time the script changes).

I'd prefer we add the platform conditions to the Commands the plugin returns an extension to the Plugin API, not on the application of the plugin itself. And this is where the platform filter on the CustomTasks created for the Commands would come into play.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what the exact process is, but this feels like a good segue to kick off the review discussion - the remaining points seem more like implementation details that would benefit from broader input.

I don't have strong opinion on the approach as either would met the proposal intent from plugin consumer's perspective. Haven't wrote any plugin myself to understand the downside of invoking plugin "unnecessarily." The filter approach seems like a good compromise to avoid a big refactor, and is somewhat similar to SE-0273 where unused dependencies are still resolved.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Build tool plugins are supposed to be super fast. All they do is build up a list of Commands.

My point is that since the Commands turn into CustomTasks, it's the commands that should have platform filters, not the plugins. That would allow you to add different commands for different platforms which I find would be more useful.

clive819 added 3 commits June 1, 2026 22:24
Companion change: swiftlang/swift-build#1439

# Conflicts:
#	Sources/SwiftBuildSupport/PIFBuilder.swift
#	Tests/SwiftBuildSupportTests/PIFBuilderTests.swift
@clive819
clive819 force-pushed the conditional-plugin branch from 1ee5075 to 7ab6e1b Compare June 2, 2026 02:57
@clive819
clive819 requested a review from FranzBusch June 17, 2026 22:11
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants