This proposal is great and I'm very excited about it!
- The shape and number of exposed information to the plugins sounds about right.
[from the proposal] One key tension in this proposal is between providing rich functionality for plugins to use while still presenting that functionality in a way that's general enough to be implemented in both the SwiftPM CLI and in any IDE that supports packages. To that end, this proposal provides a minimal initial API, with the intention of adding more functionality in future proposals.
- Realistically as long as an IDE can get a list of "command + description" they'll all be happy. This will work well with either CLion or Visual Studio Code I believe; they all generally simply expose "the commands" that they have discovered in some way as a list like this:
And for VS Code we're trying to get together and work on improving existing plugin or making a new one in the SSWG, so we'll figure it out. CLion has a good history supporting build tool commands, and I'm not worried about them as long as there's some way to "dump" what commands are available.
Question: So, how are external tools going to find commands they can invoke? Is there some swift plugin list --type=command
or similar?
- Great that a plugin can invoke build or test using the provided
PackageManager
, this is great. The name of that type is fine too, I think we had some worries about it at some point, but it seems fine to me 
- I would really really love re-visit is allowing commands to be "top level".
I.e.: swift doc
rather than swift package doc
, most notably because I'd love to offer "more fancy" ways to test that do things like "only this file changed, only re-run tests affected by it" which is something sbt can do and is called
I really would love to have "deployment" and documentation tasks available as top-level...
One can imagine that swift docc
(to be honest I'd argue for swift doc
but let's bikeshed that once that's on the table...) it much more what people will expect from other ecosystems:
mvn javadoc
-- java's maven does not know about javadoc at all, it's a plugin; in our world we want to document the entire package of course
sbt test
, sbt jmh
, sbt testQuick
I think most notably, we should look at go that while does not have plugins, it does have the "CLI tool" share the name with the language (as does our swift
command), and there are plenty "not really package task" involved here as well:
go doc
go vet
(linting, in our world this would be swift lint
which again is an external tool today).
go generate
(generate sources) etc.
I think it really matters for discoverability and making swift feel simple if such tasks are possible to invoke just as swift
. I was recently dreaming of swift deploy staging
where staging is an environment name you want to deploy to (and have configured the plugin to do so). All those become rather tedious if we had to say "swift package deploy staging
" IMHO...
We could say that if ambiguous (or the top level name is used up by something provided by Swift already) you have to invoke the "long form" of swift package <command>
but in general I'd love commands to just be available on top level.
The PluginCommandIntent
sounds good to me, but I wonder -- shouldn't this be a collection of static properties rather than an enum?
I can imagine browsing plugins by "intent" and looking for a good source code formatter etc, but why should specific names be blocked on major swift versions, as I understand we could not add new enum cases within minor swift releases?
Minor: Should we qualify as MyPlugin:doc
rather than MyPlugin.doc
? I guess the dot seems weird to me personally... Swift doesn't really have namespacing so we don't have much to lean on here...
The permissions affect the ways in which the command plugin can access external resources such as the file system or network. By default, command plugins have only read-only access to the file system (except for temporary-files locations) and cannot access the network.
We should clarify that this is only currently supported on apple platforms via sandboxing, as I understand we don't have this implemented on Linux yet...?
Feedback on the implementation of:
Many command plugins will invoke other tools to do the actual work. A plugin can use Foundation’s Process API to invoke executables, using the PluginContext.tool(named:) API to obtain the full path of the command line tool in the local file system (even if it originally came from a binary target or is provided by the Swift toolchain, etc).
When writing plugins I found it hard to understand what name I'm expected to pass there.
It would be nice if the error when crashing with an unknown name provided the available tools and where they came from.
It seems we want to call this:
var packageManager: PackageManagerServiceProvider { get }
just PackageManager
instead? it seems so in the listing below where we discuss struct PackageManager
.
I love the ways to interact with it -- great that it's an async function to build or test. This would allow me to implement a "quick test" (only run tests which failed the last time) thing that other package managers offer, very excited for this.
The TestResult
seems to be missing information that I'd like to see in the proposal?
public struct TestResult {
/// Path of the code coverage JSON file, if code coverage was requested.
public var codeCoveragePath: Path?
/// This should also contain information about the tests that were run
/// and whether each succeeded/failed.
}
So if TestResult
is "all the tests" how will be the individual tests reported? let tests: [????TestResult]
? where each has a failed / succeeded / skipped? Would those also be able to have the time it took them to execute?
I love the way running tests is exposed, it is nice to be able to pass the filterest list there.
Overall design comment:
So this is a pretty simple plugin infrastructure; we can't have plugins produce outputs that other plugins take as inputs and have it be type-safe etc. That's fine I suppose, though every time I read these I'm left longing for a very powerful system like that (and that I'm used to from a prior life). I understand though this would be very hard to implement in compatible ways with existing build systems, so I'll drop the ball on that -- this should be good enough for all the needs we have today 
I'm positive on the pitch! I'm excited to be able to write a few types of plugins I'm missing in Swift today: building docs, deployments, "test quick", and "special weird tests (that create multiple clustered nodes)" etc.
Thank you for the work on this, it's really promising!