Плагин Gradle — зависимость от модуля Java, также используемого в основном проекте

Я хочу, чтобы мой плагин 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")
Gradle за прокси-сервером
Gradle за прокси-сервером
Создайте проект Gradle под сетевым прокси.
"DevOps: Jenkins & AWS Series, часть 5: Установка Gradle на Ubuntu 22.04
"DevOps: Jenkins & AWS Series, часть 5: Установка Gradle на Ubuntu 22.04
В этой статье блога мы проведем вас через процесс установки Gradle на Ubuntu 22.04, интеграции его с Jenkins и создания задания Gradle. Мы...
0
0
74
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Используйте включенную сборку

Вам нужна включенная сборка для совместного использования кода плагина и кода приложения проекта.

Мне не ясно, где вы пишете код своего плагина, но логичным местом его размещения является подпроект включенной сборки, который я опишу ниже. Вот несколько пошаговых инструкций.

Настройка включенной сборки
  1. Настройте включенный проект сборки в новую папку в основной папке проекта. Позвоните, скажем, myIncludedBuild.

  2. Дайте включенной сборке собственный settings.gradle.kts файл в этой папке. Я предлагаю вам написать свой плагин и общую библиотеку в этом проекте, поэтому, помня об этом, включите их оба в многопроектный проект, написав в этом файле следующее:

    include("myPlugin", "myLibrary")
    
Настройка плагина
  1. Создайте папку для своего плагина по адресу myIncludedBuild/myPlugin. Дайте ему файл build.gradle.kts и, предполагая, что вы пишете плагин на Kotlin, примените плагин kotlin-dsl1.
    plugins {
       `kotlin-dsl`
    }
    
  2. Продолжите этот build.gradle.kts файл, чтобы указать детали вашего плагина в синтаксисе Java Gradle Plugin. Это дает этому плагину информацию, необходимую для упаковки вашего плагина предписанным способом, чтобы другие проекты могли его найти.
    gradlePlugin {
       plugins {
           create("myPlugin") {
               id = "myPluginId"
               implementationClass = "package.MyPlugin"
           }
       }
    }
    
  3. Поместите код вашего плагина в файл myIncludedBuild/myPlugin/src/kotlin/package/MyPlugin.kt (или любой другой пакет, который вам подходит, отразив его в файле сборки) в классе MyPlugin, реализующем Plugin<Project>.
Настройка библиотеки
  1. Для библиотеки создайте папку myIncludedBuild/myLibrary и добавьте в нее файл build.gradle.kts. Там примените плагин библиотеки Java и присвойте проекту группу.

    plugins {
       `java-library`
    }
    
    group = "myIncludedBuildGroup"
    
  2. Напишите свой общий код в myIncludedBuild/myLibrary/src/main/java

Включите библиотеку в плагин
  1. Чтобы включить код библиотеки в код плагина, добавьте следующее в build.gradle.kts плагина, импортировав его как родственный проект:
    dependencies {
        implementation(project(":myLibrary"))
    }
    
Настройка основного проекта
  1. Перейдя к основному проекту, включите сборку в основной settings.gradle.kts:
    includeBuild("myIncludedBuild")
    
  2. Теперь плагин будет доступен для применения в файлах сборки основного проекта:
    plugins {
        id("myPluginId")
    }
    
  3. Кроме того, библиотека будет доступна как зависимость от любого проекта в вашей основной сборке, используя ее координаты Maven:
    dependencies {
        implementation("myIncludedBuildGroup:myLibrary")
    }
    

1Плагин Kotlin DSL включает плагин Kotlin JVM и плагин Java Gradle; он помещает DSL Kotlin Gradle в путь к классам; и он обеспечивает удобное изменение синтаксиса Kotlin, чтобы сделать обычный код Kotlin похожим на написание сценария сборки Kotlin DSL, поскольку параметры Gradle Action обрабатываются вместе со своим субъектом как получатели.

ваш ответ помог мне решить мою проблему - однако вы удалили самую полезную часть. Чтобы мой плагин Gradle мог использовать общую библиотеку Java, мне нужна была зависимость от пути к классу — с помощью этой подсказки я мог бы решить свою проблему.

prom85 16.04.2024 09:58

Одна вещь, которую я не мог решить, - это переместить мой плагин Gradle и общий проект в подпапку, потому что я не мог заставить путь к классам работать с подпапкой - есть какие-нибудь намеки на это? Даже установка имени includeBuild и попытка использовать его в пути к классам не сработали...

prom85 16.04.2024 10:04

Я все время сомневался, где находится код вашего плагина (и до сих пор не уверен). Я думаю, что лучшее место для этого — это часть вашей включенной сборки, и я описал, как это сделать, в дальнейшем редактировании.

Simon Jacobs 16.04.2024 13:22

Я ценю вашу помощь. Я добавил в свой вопрос полную настройку и добавил комментарий в "1" - то, что вы пишете как implementation(project(":myLibrary")), у меня не работает. Он работает в «обычных» проектах, но я не могу включить общий Java-модуль в свой модуль плагина Gradle без использования includeBuild или classpath, как вы изначально предлагали. Вы видите проблему в моем примере?

prom85 16.04.2024 17:40

Вам необходимо следовать всем инструкциям. Я знаю, что это много, но почти все это необходимо, чтобы все заработало. И плагин, и библиотека должны быть частью включенной сборки. Вам нужен новый файл настроек, структура папок, которую я описал, и т. д. и т. п.

Simon Jacobs 16.04.2024 17:45

это была моя вина, верно. Небольшие изменения в вашем предложении, и теперь оно работает как положено. Я просто перепутал, что myIncludedBuild — это подпапка, в которой находится общая библиотека и плагин. Большое спасибо.

prom85 16.04.2024 20:11

есть ли у вас подсказка, почему плагин gradle не публикуется через maven? Независимо от того, публикуется ли плагин gradle автоматически или я публикую его вручную — он не публикуется задачей root publishToMavenLocal, ​​и я бы хотел опубликовать его в jitpack. Похоже, проблема здесь в includeBuild и может потребоваться дополнительная настройка?

prom85 17.04.2024 08:13

Описанный выше подход не предполагает публикацию. Он автономен и автоматически реагирует на любые изменения в коде плагина или библиотеки без выполнения каких-либо отдельных задач публикации. Вы могли бы связать проекты посредством простой публикации, но при каждом изменении вам пришлось бы переиздавать публикацию. Вы, конечно, можете продолжить и опубликовать любой или все модули, обычно с помощью плагина maven-publish. Прилагаемая ссылка на сборку не помешает вам сделать это.

Simon Jacobs 17.04.2024 09:05

Проблема в том, что publishToMavenLocal из моего корневого проекта не публикует библиотеки, включенные через includeBuild. Вызов publishToMavenLocal из самого плагина работает, задача есть и работает, но почему-то задача root проектов об этом не знает... Вызов publishToMavenLocal из корневого проекта останавливается после вызова задачи jar для моего плагина и не вызывает задачи, связанные с maven.

prom85 17.04.2024 10:53

Да, это ожидаемое поведение. Если вам нужно что-то другое, потребуется дополнительная настройка.

Simon Jacobs 17.04.2024 11:01

Это связано с тем, что включенные сборки представляют собой отдельные сборки, поэтому они не имеют такой степени взаимосвязи, как многопроектные проекты.

Simon Jacobs 17.04.2024 11:09

Поскольку на этот вопрос дан ответ, я создал новый вопрос для настройки, совместимой с Mavon, я также буду признателен за вашу помощь, если у вас еще есть время помочь мне, спасибо. stackoverflow.com/questions/78345653/…

prom85 18.04.2024 09:36

Другие вопросы по теме