Run a plugin again when a resource of the called tool changes?

I am making a SPM plugin for code parsing and generation (a toy Sourcery clone to parse Swift files, render a stencil template and output a Swift file).

This is made in two parts: the first part is the generation tool itself, depending on SwiftSyntax and Stencil. The second part is the build tool plugin that makes a build command for every Swift file of the target to run the tool on.

The stencil files are declared as resources inside the generation tool. I can read them from the bundle without any problem.

However I have a problem: the plugin isn't run again by SPM when the stencil file changes. After all why would it? The build command only has a Swift file as an input. The result is that I need to clean the project every time I change the templates, which is unpractical.

How could I fix this? Is there any way for me to get the path to the stencil file from the plugin (stencil file which belongs to an entirely different target)?

I thought about making the tool executable an input of the build command too, but it doesn't work because the tool isn't actually rebuilt, the resource is copied to the bundle again and it stops there (as it should).

Thanks in advance o7

This is a bug. Report it. The executable itself is an implicit input, but the separate resource bundle is falling through the cracks. For SwiftPM to fix it, either changed resources need to touch the executable so the dependencies cascade into the rest of the build system, or else the resource bundle needs to be added as an implicit input the same way the executable itself is. Not sure which strategy the team would prefer.

As a workaround, you can manually add the stencil file as an input. The argument to executable is a Path. The tool may not actually be there yet, but SwiftPM is telling you where it plans to put it once built. You can inspect that path and derive the resulting resource bundle location. It will be fragile, but should enable your plug‐in to function for now. (While the resource bundle location is stable across build invocations—sufficient for your needs—, it may differ across platforms and is an implementation detail not guaranteed to remain stable across different versions of Swift—either of which you can clumsily use #if to sidestep.)

1 Like

Thanks for the reply, I made an issue: Changes to an executable's resources don't trigger build commands depending on the executable itself ¡ Issue #5982 ¡ apple/swift-package-manager ¡ GitHub

Adding the stencil file manually while this gets resolved is a good idea, I'll do that.