This message was deleted.
# plugin-development
s
This message was deleted.
e
gradleApi()
is treated specially, I believe (ditto other internal dependencies like
gradleTestKit()
and
localGroovy()
)
at least at a quick glance here, they seem to disappear from the published POM/GMM, but still resolve to the relevant files in the local distribution when used
👀 2
1
m
I just got into an issue because it was pulled transitively from another module
(not using publishing so it might still be removed from the POM/GMM but looks like it's still in the outgoing variant or so?)
Besides the usual "it broke my workflow" for users relying on this being in api(), what would be the downside of making it a compileOnly dependency?
e
api()
is the right thing if you're publicly exposing anything based on that dependency's types, which I think a plugin is expected to do?
🤔 1
m
Mmmm fair point. Although in that case, removing it from the POM sounds counterintuitive...
e
I guess it's just because what Gradle wants can't be expressed in POM, but IDK why it doesn't seem to have some representation in GMM either (unless I'm missing it)
g
nah, gradle api is implicit dependency, it isn't present in apiElements not runtimeElements in module metadata
👀 1
if you use Nokee redistributed gradle api jars (
dev.gradleplugins:gradle-api
artifacts) you still have to add them to `compileOnly`/`compileOnlyApi`
e
redistributed API aside, doesn't that mean a library using a plugin as a dependency would have different behavior depending on whether it's a source or binary dependency? there's probably not that many cases where you're doing that aside from building another plugin, but it still seems… odd
g
I'm not sure, never used source deps (if you mean this https://blog.gradle.org/introducing-source-dependencies) In case of the second plugin depending on the first one I have
gradleApi()
in both (implicitly via `kotlin-dsl`/`java-gradle-plugin` usually), so for more or less standard workflow you wouldn't see a difference
e
I meant depending on a sibling project within the same build (where the outgoing variant seems to contain
gradleApi()
) versus depending on a binary artifact (where the GMM doesn't have any remnant of
gradleApi()
)
in most cases, yeah I expect the consumer would also have
gradleApi()
so it doesn't make a difference, but that still seems inconsistent
m
I'm doing something like this:
Copy code
:module1

plugins {
  id("java-gradle-plugin")
}

:module2

val testConfig = configurations.create("testConfig")
dependencies {
  add("testConfig", project(":module1"))
}
testConfig.files.forEach { println(it.name) }
And I'm getting this in the output:
Copy code
/Users/mbonnin/.gradle/caches/7.3.1/generated-gradle-jars/gradle-api-7.3.1.jar
Which somehow would indicate that
gradleApi()
made it to my module2. It's annoying in my case because I want to shadow these dependencies so I end up shadowing
gradleApi()
, which I don't want
I can workaround but was mainly curious how this worked
And also is there a use case where
gradleApi()
is not injected in the classpath by Gradle itself?
g
They are handled in some special way (gradleApi, gradleKotlinDsl, localGroovy and gradleTestKit use special
ClassPathNotation
).
gradleApi
is added to
api
configuration by
java-gradle-plugin
unconditionally and should be visible to the projects in the same build. I don't see where is it excluded from gmm/pom though,
pluginMaven
publication just use
publication.from(components["java"])
internally.
If you just want a library with plugin implementation you could just try using
java-library
and explicit
compileOnly(gradleApi())
to avoid polluting dependent project and/or source configuration for shadow plugin with gradleApi artifact
m
I don't see where is it excluded from gmm/pom though
Just made a test and it's not in the
"dependencies"
section of the module file🤷
g
I'm not sure if gradleApi is exposed in the case of included build
it's certainly some kind of dark magic xD
1
t
Check this lines how it could be removed
👍 3
j
This change was actually done once but reverted shortly after: • https://github.com/gradle/gradle/pull/14240 (make it compileOnlyApi) • https://github.com/gradle/gradle/pull/14374 (turn that back) I don’t fully remember why it was changed back. There were conversations with other folks and unfortunately nothing was documented in the PRs. I think the argument was that conceptually the API is needed at runtime. So this is not really what compileOnly stands for. So conceptually this would be more like what providedCompile is in the war plugin (I think). But (for me) it’s a question of perspective and I think it could be made compileOnlyApi.
👀 1
Maybe looking at what code was touched in these PRs helps to understand how this dark magic works (if you really wanna know 🙂 )
m
Oooh nice find, thanks for all the context 🤗 !