Gradle не распознает задачи плагина из примененного дочернего скрипта - PullRequest
0 голосов
/ 12 декабря 2018

Мне бы очень хотелось, чтобы мой скрипт был разделен на несколько частей (тест, стандарт, документация и Android).Но у меня возникают проблемы, когда я пытаюсь применить дочерние сценарии к родительскому сценарию ...

Это мой дочерний сценарий (в данный момент среда IDE не жалуется)

import io.gitlab.arturbosch.detekt.Detekt


task("hello").doLast {
    println("Hello World from plugins! :D")
}


tasks {
    val detekt by existing(Detekt::class) {
        reports {
            html {
                val destination = "$buildDir/detekt"
            }
        }
    }
}

Но когда я пытаюсьчтобы применить этот сценарий к основному сценарию:

apply(from = "tdd.gradle.kts")

Я получаю следующую ошибку:

    Script compilation errors:

  Line 01: import io.gitlab.arturbosch.detekt.Detekt
                  ^ Unresolved reference: io

  Line 10:  val detekt by existing(Detekt::class) {
                                   ^ Unresolved reference: Detekt

  Line 11:      reports {
             ^ Unresolved reference: reports

  Line 12:          html {
              ^ Unresolved reference: html

Как мне решить эту проблему, чтобы я мог применить, например, плагин Detekt в дочернем сценарии иприменить его к скрипту parrent?

Ответы [ 2 ]

0 голосов
/ 21 февраля 2019

Я пытался взломать это многими способами.Короче говоря, в Kotlin DSL это невозможно.

UNTESTED: метод, который я бы попробовал (bc, это единственная вещь, которую я еще не пробовал), это сделать оба применения плагина (в старом стиле) и конфигурации все в вашем подключаемом скрипте в качестве явной кросс-проектной конфигурации таким образом, что не требует использования блоков allProjects или subProjects в прикладном скрипте.

Вы должны обратиться к текущей документации Gradle для проектов, но обычно она имеет вид:

project(":foo") {
    // Some configuration here
    apply(plugin = "plugin.id.here.sample-plugin")
    // Then use configuration techniques in the Kotlin DSL guide for configuring when you don't have access to type-safe accessors, small example below
    configure<SamplePluginExtension> {
        // Plugin extension configuration...
    }
}

Это связано с тем, что в Kotlin DSL allProjects и subProjects блоки по-прежнему не работают так, как если бынадеюсь / ожидаю (насколько мне известно), когда оно определено в плагинах прикладных скриптов.

Хотя мои требования не позволили мне протестировать полную технику плагинов для кросс-проекта / применения, описанную выше, я все же обошел allProjects и subProjects не ведут себя ожидаемо (и нуждаются в правильном использовании withPlugin<PluginClass> в этих блоках, поскольку это, похоже, плохо работает с проблемой плагинов above либо) путем объявления дополнительных лямб в моих прикладных сценариях и последующего вызова их из целевого сценария внутри блоков конфигурации allProjects или subProjects, для которых они были актуальны.

Например:

apply.build.gradle.kts

val allProjectsConfiguration by extra { p: Project ->
    // Some project configuration here...
}

build.gradle.kts

//Boilerplate build script dependencies, repositories, and buildscript block as necessary...
val allProjectsConfiguration: (Project) -> Unit by extra
allProjects {
    allProjectsConfiguration(this)
// where `this` is not the host script's project, not the applied script's project (of course), but one of the given projects in *all* of the projects.

Некоторые общие советы по безопасности для этих видовиз лямбда-выражений:

  • с использованием p для экземпляра Project гарантирует, что разработчикам, использующим его, не нужно будет думать о том, какой экземпляр проекта в данный момент находится в области действия (в применяемом сценарии или где он находитсяназывается).Это также означает, что project, предоставляемый ограждающей областью на месте вызова, все еще может использоваться.
  • в значительной степени рассмотрите возможность возврата Unit для обеспечения использования без побочных эффектов.Некоторые плагины имеют расширения, которые будут автоматически конфигурировать различные элементы контейнера, просто регистрируя все экземпляры, найденные в блоке config из них.Самым безопасным вариантом является неявная поддержка цепочки, за исключением случаев, когда это абсолютно необходимо.
  • Имейте в виду, что во многих контекстах нельзя полагаться на число Котлина T.apply { } в стандартной библиотеке, потому что оно разрешается в apply Грэдлатак что, если вы хотите легко сделать это (или вернуться к Unit) через несколько лямбд-конфигураций, лучше создать небольшую вспомогательную функцию, которая в основном выполняет то же, что применяется в Kotlin, или, как я сделал, создать помощник, который запускает блок.он задан и всегда возвращает Unit (или некоторый обобщенный тип).

@ ToYonos - предложение gradle не будет работать для Kotlin DSL.Я получил плохие результаты с этим (я использовал конкретно classpath зависимость), потому что gradle сообщит, что плагин никогда не применялся, и в том же сообщении об ошибке он показывает, что расширение применено.Я полагаю, что это связано с байтовым кодом и / или наличием отдельных загрузчиков классов для прикладных скриптов.(извините, я бы добавил это в комментарии к вашему ответу, но мне не хватает представителя)

0 голосов
/ 12 декабря 2018

От разработчика ядра Gradle (ситуация довольно похожа на вашу):

Плагины сценариев не имеют доступа к основному пути к классам buildscript.

Вы можете добавить зависимость от mycompany.plugin в tests.gradle, используя синтаксис buildscript {}

Так что в основном используйте старый синтаксис buildscript, и ваш импорт должен работать

...