Я хочу, чтобы мой плагин Gradle зависел от некоторого общего кода, который можно использовать внутри плагина Gradle, а также внутри библиотеки Android.
Есть ли способ поделиться простым кодом Java/Kotlin между плагином Gradle и библиотекой Android?
Когда я пытаюсь добавить модуль в плагин gradle, я получаю сообщение об ошибке «не удалось найти в проекте». Я пробовал разные комбинации includeBuild
и include
, но они не решают проблему. .
Пример:
Плагин Градла:
plugins {
`kotlin-dsl`
`java-gradle-plugin`
`maven-publish`
}
dependencies {
// fails
implementation(project(":Library:Plugin:Shared"))
//implementation(project(":library:plugin:shared"))
}
Библиотечный модуль:
plugins {
id("com.android.library")
id("kotlin-android")
id("kotlin-parcelize")
id("maven-publish")
}
android {
// ...
}
dependencies {
api(project(":Library:Plugin:Shared"))
}
Общий модуль:
repositories {
mavenCentral()
}
plugins {
id("org.jetbrains.kotlin.jvm")
`java-library`
`maven-publish`
}
dependencies {
}
настройки.gradle.kts:
pluginManagement {
includeBuild(File("library/plugin/gradle"))
}
include(":Library:Plugin:Shared")
project(":Library:Plugin:Shared").projectDir = file("library/plugin/shared")
include(":Library:Plugin:Gradle")
project(":Library:Plugin:Gradle").projectDir = file("library/plugin/gradle")
ПРИМЕР НАСТРОЙКИ
1) корень/gradle-plugin/build.gradle.kts
repositories {
mavenCentral()
}
plugins {
`kotlin-dsl-base`
`java-gradle-plugin`
`maven-publish`
}
dependencies {
//implementation(":gradle-shared")
// following does not work inside a gradle plugin module...
// it works in other modules though
implementation(project(":Library:Plugin:Shared"))
}
gradlePlugin {
plugins {
create("changelog-utils") {
id = "changelog-utils"
implementationClass = "<path>.ClassLoaderPlugin"
}
}
}
2) корень/gradle-shared/build.gradle.kts
repositories {
mavenCentral()
}
plugins {
`kotlin-dsl-base`
`java-library`
//`maven-publish`
}
3) корень/settings.gradle.kts
// --------------
// Gradle Plugin
// --------------
includeBuild("gradle-plugin")
// --------------
// Shared Code (Plugin + Library)
// --------------
include(":MyLibrary:Plugin:Shared")
project(":MyLibrary:Plugin:Shared").projectDir = file("gradle-shared")
Вам нужна включенная сборка для совместного использования кода плагина и кода приложения проекта.
Мне не ясно, где вы пишете код своего плагина, но логичным местом его размещения является подпроект включенной сборки, который я опишу ниже. Вот несколько пошаговых инструкций.
Настройте включенный проект сборки в новую папку в основной папке проекта. Позвоните, скажем, myIncludedBuild
.
Дайте включенной сборке собственный settings.gradle.kts
файл в этой папке. Я предлагаю вам написать свой плагин и общую библиотеку в этом проекте, поэтому, помня об этом, включите их оба в многопроектный проект, написав в этом файле следующее:
include("myPlugin", "myLibrary")
myIncludedBuild/myPlugin
. Дайте ему файл build.gradle.kts
и, предполагая, что вы пишете плагин на Kotlin, примените плагин kotlin-dsl
1.
plugins {
`kotlin-dsl`
}
build.gradle.kts
файл, чтобы указать детали вашего плагина в синтаксисе Java Gradle Plugin. Это дает этому плагину информацию, необходимую для упаковки вашего плагина предписанным способом, чтобы другие проекты могли его найти.
gradlePlugin {
plugins {
create("myPlugin") {
id = "myPluginId"
implementationClass = "package.MyPlugin"
}
}
}
myIncludedBuild/myPlugin/src/kotlin/package/MyPlugin.kt
(или любой другой пакет, который вам подходит, отразив его в файле сборки) в классе MyPlugin
, реализующем Plugin<Project>
.Для библиотеки создайте папку myIncludedBuild/myLibrary
и добавьте в нее файл build.gradle.kts
. Там примените плагин библиотеки Java и присвойте проекту группу.
plugins {
`java-library`
}
group = "myIncludedBuildGroup"
Напишите свой общий код в myIncludedBuild/myLibrary/src/main/java
build.gradle.kts
плагина, импортировав его как родственный проект:
dependencies {
implementation(project(":myLibrary"))
}
settings.gradle.kts
:
includeBuild("myIncludedBuild")
plugins {
id("myPluginId")
}
dependencies {
implementation("myIncludedBuildGroup:myLibrary")
}
1Плагин Kotlin DSL включает плагин Kotlin JVM и плагин Java Gradle; он помещает DSL Kotlin Gradle в путь к классам; и он обеспечивает удобное изменение синтаксиса Kotlin, чтобы сделать обычный код Kotlin похожим на написание сценария сборки Kotlin DSL, поскольку параметры Gradle Action
обрабатываются вместе со своим субъектом как получатели.
Одна вещь, которую я не мог решить, - это переместить мой плагин Gradle и общий проект в подпапку, потому что я не мог заставить путь к классам работать с подпапкой - есть какие-нибудь намеки на это? Даже установка имени includeBuild и попытка использовать его в пути к классам не сработали...
Я все время сомневался, где находится код вашего плагина (и до сих пор не уверен). Я думаю, что лучшее место для этого — это часть вашей включенной сборки, и я описал, как это сделать, в дальнейшем редактировании.
Я ценю вашу помощь. Я добавил в свой вопрос полную настройку и добавил комментарий в "1" - то, что вы пишете как implementation(project(":myLibrary"))
, у меня не работает. Он работает в «обычных» проектах, но я не могу включить общий Java-модуль в свой модуль плагина Gradle без использования includeBuild
или classpath
, как вы изначально предлагали. Вы видите проблему в моем примере?
Вам необходимо следовать всем инструкциям. Я знаю, что это много, но почти все это необходимо, чтобы все заработало. И плагин, и библиотека должны быть частью включенной сборки. Вам нужен новый файл настроек, структура папок, которую я описал, и т. д. и т. п.
это была моя вина, верно. Небольшие изменения в вашем предложении, и теперь оно работает как положено. Я просто перепутал, что myIncludedBuild
— это подпапка, в которой находится общая библиотека и плагин. Большое спасибо.
есть ли у вас подсказка, почему плагин gradle не публикуется через maven? Независимо от того, публикуется ли плагин gradle автоматически или я публикую его вручную — он не публикуется задачей root publishToMavenLocal
, и я бы хотел опубликовать его в jitpack. Похоже, проблема здесь в includeBuild
и может потребоваться дополнительная настройка?
Описанный выше подход не предполагает публикацию. Он автономен и автоматически реагирует на любые изменения в коде плагина или библиотеки без выполнения каких-либо отдельных задач публикации. Вы могли бы связать проекты посредством простой публикации, но при каждом изменении вам пришлось бы переиздавать публикацию. Вы, конечно, можете продолжить и опубликовать любой или все модули, обычно с помощью плагина maven-publish
. Прилагаемая ссылка на сборку не помешает вам сделать это.
Проблема в том, что publishToMavenLocal
из моего корневого проекта не публикует библиотеки, включенные через includeBuild
. Вызов publishToMavenLocal
из самого плагина работает, задача есть и работает, но почему-то задача root проектов об этом не знает... Вызов publishToMavenLocal
из корневого проекта останавливается после вызова задачи jar
для моего плагина и не вызывает задачи, связанные с maven.
Да, это ожидаемое поведение. Если вам нужно что-то другое, потребуется дополнительная настройка.
Это связано с тем, что включенные сборки представляют собой отдельные сборки, поэтому они не имеют такой степени взаимосвязи, как многопроектные проекты.
Поскольку на этот вопрос дан ответ, я создал новый вопрос для настройки, совместимой с Mavon, я также буду признателен за вашу помощь, если у вас еще есть время помочь мне, спасибо. stackoverflow.com/questions/78345653/…
ваш ответ помог мне решить мою проблему - однако вы удалили самую полезную часть. Чтобы мой плагин Gradle мог использовать общую библиотеку Java, мне нужна была зависимость от пути к классу — с помощью этой подсказки я мог бы решить свою проблему.