This message was deleted.
# plugin-development
s
This message was deleted.
v
It is possible, but I personally dislike it. You are not Gradle so imho you should not put things in the
org.gradle
namespace. But as long as Gradle does not run on the module path where split packages are disallowed, it should work. Instead I would suggest you do not provide Kotlin extension functions, but create a Gradle extension on those containers and have the methods in that extension. Then it also works without import and even works the same for Groovy DSL and Kotlin DSL consumers.
Don't get trapped by
RepositoryHandler
not formally declaring it is
ExtensionAware
. Practically any Gradle model class and also all classes you let Gradle create from any other plugin is dynamically decorated to be
ExtensionAware
. Just use
(repositories as ExtensionAware).
and you can still add extensions and for both of these containers you also get type-safe accessors generated for Kotlin DSL:
j
I’m also concerned about using
org.gradle
This looks promising, so I could go with:
Copy code
repositories {
    intellijPlatform.intellij()
    mavenCentral()
    intellijPlatform.intellijSnapshots()
}
Note that order matters here.
👍 1
Especially when it comes to dependencies.
p
Please upvote so we can prioritize this eventually
v
Yes, of course. Order of repositories matters unless you also have repository content rules that define which dependencies should be taken from what repository
j
My minimal Gradle I’ll require for IntelliJ Platform Gradle Plugin 2.0 is 8.0, but still… I need something for now. 😞
v
You could even do
Copy code
repositories {
    intellijPlatform {
        intellij()
        mavenCentral()
        intellijSnapshots()
    }
}
I think. The
mavenCentral()
should automatically be called on the outer scope
but still… I need something for now.
So? What I described should work on older versions too I think.
j
I was referring to issue from Paul. 🙂
v
Maybe typesafe accessors for one of the containers was added later, but then you could still do
Copy code
repositories {
    the<IntellijPlatformRepoExtension>().intellij()
    mavenCentral()
    the<IntellijPlatformRepoExtension>().intellijSnapshots()
}
if someone needs to use an older version and Kotlin DSL
Would need an import again though, but that's ok imho
I was referring to issue from Paul
Ah, ok, yeah. Imho an extension is anyway better than a default import for the cases you described as it then works for Groovy and Kotlin alike
👍 1
For other situations, for example containers where no type-safe accessor is generated it would be handy though
j
I’m pretty afraid of having too many extensions in the game, like:
Copy code
repositories {
    intellijPlatform.intellij()
}

dependencies {
    intellijPlatform.intellijIdeaCommunity("2023.2.2")
}

intellijPlatform {
    pluginConfiguration {
        id = properties("pluginId")
        name = properties("pluginName")
        ...
    }

    // ... other options TBD
}
OTOH it’s pretty descriptive. 🙂
v
Yeah, what is your concern with the amount of extensions?
j
Just readability.
Sometimes, some of extension functions need an access to the project.
So I need to have double context provided.
Because of that.
v
Well, when creating the extension, you can give it the reference to the
repositories
container or
project
as constructor argument for example. But anyway it imho is very questionable to add repositories unasked and non-optional. That will fail with
repositoriesMode.set(RepositoriesMode.FAIL_ON_PROJECT_REPOS)
and make it harder to fulfill guidelines like "only use in-house maven repository mirrors".
j
Basically this is what I run away from. In 1.x all repositories and dependencies were added under the hood. Now everything goes in a proper way, through helpers, but eventually regular dependencies are created. What you see here is an Ivy repository used just for the purpose of attaching local IDE instance or local JBR.
v
But it would still fail with
FAIL_ON_PROJECT_REPOS
, wouldn't it?
We still miss an exposed "detached repositories" like you have "detached configuration".
j
It will fail but you add this on purpose in rather a border case.
v
Ah, so this helper is not usually used, I see
👌
So yeah, just add a reference to the
repositories
container or
project
to the constructor args when you let Gradle create your extension and it should probably work
j
On CI this shouldn't be even used. Local IDE dependency helper can be used to point to IDE installed with JetBrains Toolbox
FTR, I made it possible to use repository helpers in the settings.gradle.kts
So you still can use them to avoid defining repositories on project level.
v
That was a dependency helper though, that implicitly adds a repository. 😄 But yeah, having the helpers on the settings script is great. Just that you will not get typesafe accessors there iirc, so there you will need to use the
the<IJPExtension>().addRepo()
syntax I mentioned above when using the extension route and Kotlin DSL.
Or you provide an according accessor of course, but either way consumer will have an import or you have to abuse the
org.gradle
namespace. I personally don't have problems with imports from Plugins I use.
j
😬
Copy code
dependencyResolutionManagement {
    repositories {
        (this as ExtensionAware).the<IntelliJPlatformRepositoriesExtension>().releases()
    }
}
Otherwise,
the
refers to object other than
RepositoryHandler
v
Oh, yeah, right,
RepositoryHandler
does not officially declare
ExtensionAware
😞 So at least for the settings script a custom accessor probably makes sense.
One more thing that came to my mind. If you have a custom extension for usage in settings script, that your register with name
intellijPlatform
, we said in Groovy DSL you can just do
Copy code
intellijPlatform {
    // ...
}
but with Kotlin DSL you do not get typesafe accessors created, so you would need to use something like
Copy code
import org.jetbrains.IntelliJPlatformSettingsExtension

configure<IntelliJPlatformSettingsExtension) {
    // ...
}
Or with manually provided accessor outside
org.gradle
namespace like
Copy code
package org.jetbrains

val Settings.intellijPlatform: IntelliJPlatformSettingsExtension
    get() = extensions.getByName("intellijPlatform") as IntelliJPlatformSettingsExtension

fun Settings.intellijPlatform(configuration: Action<IntelliJPlatformSettingsExtension>): Unit =
    extensions.configure("intellijPlatform", configuration)
you could have
Copy code
import org.jetbrains.intellijPlatform

intellijPlatform {
    // ...
}
That's what we had so far. But if the
import
is what bugs you most, you can also simply tell the users to use fully-qualified:
Copy code
org.jetbrains.intellijPlatform {
    // ...
}
j
Thanks! For settings I’ve already created
Copy code
fun RepositoryHandler.intellijPlatform(configure: Action<IntelliJPlatformRepositoriesExtension>) =
    (this as ExtensionAware).the<IntelliJPlatformRepositoriesExtension>().apply(configure::execute)
and this is fine to have single import for this particular case. What I wanted to avoid is a bloated import section in a daily-basis work for regular users.
v
Ok, just something that came to my mind. But I would suggest using
Copy code
fun RepositoryHandler.intellijPlatform(configure: Action<IntelliJPlatformRepositoriesExtension>) =
    (this as ExtensionAware).extensions.configure("intellijPlatform", configure)
the
is more meant to get the extension, not to configure it. And with the
extensions.configure
you also configure by type and name to be sure you are configuring the intended extension. Otherwise if someone would have the strange idea to register a second extension of that type, it would fail iirc.
j
Makes sense, thanks for highlighting that!
👌 1