Is it possible to set a flag or an option to allow plugin to write to a package directory/subdirectories?

I found a PluginPermission struct with no description.
It has factory method writeToPackageDirectory, but It is unclear how to use it.
Is there any documentation about this feature?
https://developer.apple.com/documentation/swift_packages/pluginpermission/

I'm not conversant with the API internals, but as an example the swift-docc-plugin uses this option. A quick example from swift-docc-plugin README include the following CLI invocation:

swift package --allow-writing-to-directory ./docs \
    generate-documentation --target MyFramework --output-path ./docs

So in terms of using it with a command plugin, it's an option you add on the CLI to allow the command plugin explicit permission to write into the package's source directory. I'd expect the same would be relevant for code generation tools, formatters, etc.

But how to run this plugin as a part of build process?
If I have an Xcode project with app and several local packages, how can I run a plugin inside one of these packages?

I think that depends on what kind of plugin you're using (or are creating). In the evolution proposal, there's a buildCommand and prebuildCommand, which look to be integratabtle into the build based on dependencies to inputs or outputs.

The Docc plugin I referenced is a CommandPlugin, which I don't think explicitly integrates.

In addition to examples roughed out in the proposal, @abertelrud has an examples plugin repository with some interesting (and functional!) examples that are very much worth reading through to get a sense of how to use them, but in a large respect I found the examples in the proposal itself to be most illustrative.

I'd personally love to see a complete example of a project that used, for example, a the swift protobuf generation example from the proposal. I think the core of that would show how to make it an explicit dependency and see it operating right off the bat. I haven't tried to build such a thing myself, but it would be a great example.

That's correct, and currently there is no way to give a build tool command permission to write to the package directory (it can write to a temporary directory). The writeToPackageDirectory option is for command plugins, which as you mention are invoked directly from the swift package command line but not during a build.

@lolgear, is the intent here to have a build tool that can modify the project sources while it runs? That seemed like an unsafe thing to have, but if the user approves of it somehow, I can definitely see that being useful. I think that would involve extending the plugin definition for build tool plugins to allow permissions like the ones that are currently allowed for command plugins.

Agreed, this is long overdue — something like an iOS app that has a local package that uses SwiftProtobuf in a ready-to-run way would help. I have also started writing a guide for authoring plugins and really need to make time to wrap it up — that would be in the SwiftPM repository and not be specific to any Apple technologies, and should be more approachable than the proposal itself. I realize that it's currently harder than it should be to get started with package plugins.

2 Likes

@abertelrud
I read proposal several times.
It has a section about Shell scripts but only as "unclear alternative", because all shell scripts should know information about target and build.
So, this proposal isn't considering ( or isn't mentioning ) shell scripts as "previous solution" with all their advantages and disadvantages.
Shell scripts can write to project directories ( and to many more directories ) and this is not bad if you don't control it.
It is bad if you add restrictions for them without controlling these restrictions.

I would like to have a place ( Swift file or any other file ) which contains all places where script ( plugin, yes ) can do its work.
Without this ability all these plugins are only a toy.
So, if you try to replace shell scripts ( yes, you are trying ), please, add convenient way to support every piece of their freedom ( even in your "restricted" environment ).

For example, plugins can invoke cmake and cmake may need access to other directories. So, I can provide this access only for command line plugin, but it is not what I really want. I need this plugin as a build phase.

One more "simple" example is localization.
Script gathers NSLocalizedStrings from all sources and generates Localizable.strings.
It definitely needs package readwrite permissions and it is "Build phase" plugin.

1 Like