-
Notifications
You must be signed in to change notification settings - Fork 5k
First pass at adding a custom plugin portal #883
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
I'm on my way back to AU. I'll look into this on my Monday. Thanks @ethankhall! |
Awesome! Let me know what you think. If this is the path we want to take I'll add some tests for it. |
@ethankhall I think this is looking good. I've left some requests in there. The main theme is that we want to reduce the user implementable types, but add more type safety and avenues for evolution. We also need to come up with a better name for this than “custom” :\ @oehme @eljobe any ideas? |
@alkemist I didn't see any comments on the PR. |
The current implementation is probably not what you want. It uses the (otherwise unused) code path for "isolated" plugins, which means that plugins resolved from such a custom repo will be isolated and unable to see any other plugins. You'll want to use the "legacy" (misleading name) code path instead. A better name/DSL for this could be
|
Using the Isolated code path can you access plugins in the same jar / dependencies of the plugin? That would solve an issue I have with plugins using different library versions that aren't compatible nicely. Can plugins using the plugin portal configure other plugins? It sounds like not. |
Plugins using the We could make the new isolated behavior opt-in of course, by offering another method on the |
Sounds good. I'll work on making those changes. Will this api be avaliable via an Init Script / what would the api to access it look like? |
There is currently no
|
Alrighty, I'll want to add some API to configure this as part of an init script, but i'll work on the bit make the API better first. |
@oehme I've done the API changes that you requested. Let me know if that's what your thinking. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There is a lot of unnecessary code churn here, probably caused by a rename refactoring. Could you revert that and use the interface type where applicable?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This name is missing a word I think, maybe "Handler"
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let's not introduce another type, but just change/rename the existing BackedByArtifactRepository
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We don't need a new type here, let's use RepositoryHandler
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The other Gradle APIs don't define new interfaces, but instead provide a single parameter object and use an Action
. I think we should stick with that pattern to keep it consistent.
@ethankhall Let's tackle init scripts in another PR. I think the most straightforward thing would be to allow the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This should take a structured object, and return some kind of result object. Something like this …
CustomPluginResolutionResult resolvePlugin(PluginRequest plugin, CustomPluginResolutionResultFactory resultFactory)
CustomPluginResolutionResult
should be a sealed type hierarchy, with two subtypes: ResolvedCustomPluginResolutionResult
and UnresolvedCustomPluginResolutionResult
. These latter two should be final and all should have package scoped constructors.
CustomPluginResolutionResultFactory
should have methods that create instances of these two types. e.g.
interface CustomPluginResolutionResultFactory {
ResolvedCustomPluginResolutionResultFactory resolved(Object dependencyNotation)
UnresolvedCustomPluginResolutionResultFactory unresolved(@Nullable String reason)
}
ResolvedCustomPluginResolutionResultFactory
will have a Dependency getDependency()
.
The reason for all this is that we now have some communicative types, and more options for safely evolving this API if necessary.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'd prefer having a found/notFound callback instead of a factory plus return type.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we can just inline the provider method here. I don't think we need two types.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think this needs to return a repository. The RepositoryHandler
is effectively the container of repositories.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because we want to prepend instead of append repositories. The global plugin repositories should have precedence over the ones defined in the buildscript block of a project. It's an unlikely edge case, users will rarely mix the two.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This method name is a little long winded. Perhaps just rules
would be ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm quite confused by this interface. Is it the repository? It seems that it's more like a builder for a repository. What's the usage pattern here?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess I was thinking a repository is something that provides plugins. I think this kinda follows the PluginPortal way of doing things, maybe it's a Portal instead?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's the same pattern like the other plugin repository subtypes. The user configures it and it has an internal method that turns into a plugin resolver.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be Action<? super X>
@ethankhall looks like I don't know how to use GitHub code reviews. I added a bunch of comments, but it looks like they weren't saved (or whatever). They should be there now. Some of them no longer hold after the change requests from @oehme. As for the init script issue, I agree with @oehme. I'm not quite understanding how the usage patterns of the new API. I think this is indicative of it being a little convoluted. @ethankhall @oehme @eriwen the quickest way forward here is probably to meet for 30 minutes to discuss synchronously. @eriwen would you mind making this happen? |
@alkemist sounds good! I'm generally avaliable to meet. |
@alkemist The user-facing DSL is shown in one of my comments above. Adjusted for the latest changes it looks like this:
It closely follows the patterns of existing plugin repository types as well as patterns of our dependency resolution API. I'm up for a short meeting, just let me know when. |
Moving PluginId to be a public Interface, and then created an implementation called DefaultPluginId Added the first phase of interfaces (inside the class, will move out later) so that I can start working on the API under the hood.
- Moved PluginRequest to InternalPluginRequest - Created PluginRequest that InternalPluginRequest extends - Made the code compile for RuleBasedPluginRepository
Removed PluginId interface and made DefaultPluginId be a class that we share and part of the public API.
Removing extra classes added by earlier changes: - Using Actions now - Using the RepositoryHandler
Also fixing issue Luke pointed out with Action<X> should be Action<? super X>.
PluginId was pulled into an interface so that we can control the creation of those instances.
Added notFound(reason) to the API per Stefan's suggestion.
@eriwen I fixed the merge conflict on this guy. |
This was rebased and merged onto |
1) PluginResolutionServiceResolver was renamed to PluginPortalResolver, which broke tests that set the url for the portal. 2) We need to make sure to move the buildscript repositories after the plugin repositories
Closing as superseded by #1343 |
This is a first pass at adding the ability to define a custom plugin portal.
I don't like the names of most of the classes, I would appreciate some suggestions to fix it. I also put some of it in it's own package, but that was just to help keep it separate, but I am more than happy to remove the package.
This still needs tests but I wanted to open the review now to get some early feedback.