How to properly distribute my plugin in my case?

I’ve been developing my plugin for some time now and while testing it I’ve encountered funny
issue. My project uses some dependencies which aren’t available on mavenCentral and therefore use 3rd party repositories. Whenever I attempt to apply my plugin to a testing project, gradle build fails saying: dependency was not found in following repositories:. This issue is solvable pretty easily, by specifying the repositories in the testing project, but my plugin uses like 5 different 3rd party repositories, which would make applying the plugin pretty confusing. I’d like to know how is this solvable, and which possible solution should I approach to make this work without specifying any external repository in the testing project

That’s exactly the idiomatic way.
A project that applies a plugin is responsible to define all repositories that are necessary to resolve the plugin and all its transitive dependencies.

Think for example about a corporate environment where there is a rule to only use in-house repository mirrors, which makes sense for several reasons like avoiding supply-chain attacks, increasing reliability, and so on. A project in such an environment only wants their internal mirrors be used in their projects and on the mirror side make sure to have the necessary dependencies included.

What you could maybe do, if what you develop is a project plugin, to make it easier for your consumers - but only do this as an optional opt-in option, not in any way mandatory or automatic - is to publish an additional settings plugin that declares the repositories you need as plugin repositories. So if a consumer willingly decides to just use the configuration you suggest, they can apply your settings plugin and be done.

Another option would be to convince those library authors to publish their libraries on MavenCentral, which would also good for the whole ecosystem.

Hmm I see what you mean, but isn’t there a way to declare the missing repositoriers for the project directly in the plugin? something like you have project.afterEvaluate, and you could just specify the repositories there, without making the consumer touch anything else than actually applying the plugin

Actually I was thinking of adding this block of code before any code evaluation, but that doesn’t seem to work either:

target.gradle.settingsEvaluated { settings ->
            settings.pluginManagement { spec ->
                spec.repositories { repo ->
                    repo.maven {
                        it.url = target.uri("project url")
                    }
                }
            }
        }

(target is Project)

but isn’t there a way to declare the missing repositoriers for the project directly in the plugin?

No

something like you have project.afterEvaluate

afterEvaluate anyway is almost always an error. It usually only does symptom treatment, shifting the actual problem to a later, harder to reproduce, harder to debug, and harder to solve point in time. The main effect of using afterEvaluate is to introduce ordering problems, timing problems, and race conditions.

without making the consumer touch anything else than actually applying the plugin

This is not even possible conceptually.
To apply a plugin you have to have its dependencies in the classpath.
So to resolve the classpath you would need to apply the plugin, but to apply the plugin you would already need the classpath.
Kind of a hen-and-egg problem.
Besides, that it would be extremely bad practice.
It is even extremely bad practice to unconditionally declare production repositories in a plugin due to the points described above.

but that doesn’t seem to work either

No, it cannot, due to what I just explained. hen-end-egg, you know.

Alright this makes sense for me, so ideal setup for this would be to have some sort of bootstrap plugin which would apply the real plugin as well with all the dependencies?

No, as I said, I would make the real plugin and additionally a settings plugin that only declares those repositories and then let the consumer decide where the real plugin needs to be applied and whether he wants to apply the settings plugin or not.

Thanks for the tip, I started working on it and found out that I can’t specify version of the plugin when I want to apply it in my settings plugin using project.plugins.apply(name). How should I be applying it?

I said you should not :slight_smile: