Как поддерживать несколько проектов на нескольких языках (Java и Scala) в Gradle?

Я пытаюсь преобразовать нашу устаревшую сборку Ant в Gradle. Проект содержит около 50 подпроектов Java и 10 подпроектов Scala. Проекты Java содержат только Java, а проекты Scala — только Scala. Каждый проект создается на Java, а затем на Scala, что значительно замедляет нашу сборку.

Я хочу разместить как можно больше общей логики в корневом файле build.gradle, который выглядит так:

subprojects {
    apply plugin: 'java'
    apply plugin: 'scala'

    sourceCompatibility=1.7
    targetCompatibility=1.7

    sourceSets {
        main {
            scala {
                srcDir 'src'
            }
            java {
                srcDir 'src'
            }
        }
        test {
            scala {
                srcDir 'test'
            }
            java {
                srcDir 'test'
            }
        }
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        scalaTools "org.scala-lang:scala-compiler:2.9.3"
        compile "org.scala-lang:scala-library:2.9.3"
    }

    // Use the sbt compiler (not scalac ant task)
    tasks.withType(ScalaCompile) {
        scalaCompileOptions.useAnt = false
    }

    task showCompileClasspath << {
       sourceSets.main.compileClasspath.each { println it }
    }

    test {
        systemProperty "user.dir", projectDir
    }
}

Когда я запускаю свою сборку, я получаю следующий вывод: обратите внимание, что :esb-server:compileJava и :esb-server:compileScala содержат одни и те же предупреждения, поэтому классы создаются дважды. Также обратите внимание, что каждый второй проект содержит compileJava и compileScala.

:common:assemble
:esb-server:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:esb-server:compileScala
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
:esb-server:processResources UP-TO-DATE
:esb-server:classes
:esb-server:jar
:esb-server:assemble
:plugins:compileJava UP-TO-DATE
:plugins:compileScala UP-TO-DATE
:plugins:processResources UP-TO-DATE
:plugins:classes UP-TO-DATE
:plugins:jar
:plugins:assemble
:raas-transform:assemble
:saxonee-helper:assemble
:scala-common:compileJava UP-TO-DATE
:scala-common:compileScala
/Users/iain.hull/code/trunk/ccdev/scala-common/src/com/workday/esb/assembly/audit/TreeAudit.scala:138: method first in trait IterableLike is deprecated: use `head' instead
    override def getLast():Option[AuditNode] = if (children.isEmpty) None else children.first.getLast
                                                                                        ^
one warning found
:scala-common:processResources UP-TO-DATE
:scala-common:classess
:scala-common:jar
:scala-common:assemble
:plugins:hibernatepersistence:compileJava
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
:plugins:hibernatepersistence:compileScala
Note: Some input files use or override a deprecated API.
Note: Recompile with -Xlint:deprecation for details.
Note: Some input files use unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
:plugins:hibernatepersistence:processResources
:plugins:hibernatepersistence:classes
:plugins:hibernatepersistence:jar
:plugins:hibernatepersistence:assemble

Я знаю, что две строки apply plugin вверху моего корня build.gradle вызывают такое поведение. Однако, если я применяю только правильный плагин к каждому подпроекту, я не могу реорганизовать общую конфигурацию в свой корневой build.gradle. Другой подход — просто использовать плагин Scala для всего, но лучший ли это способ?

Могу ли я использовать подключаемый модуль Java для компиляции проектов Java и подключаемый модуль Scala для компиляции проектов Scala и при этом выполнять рефакторинг общей конфигурации сборки для всех моих проектов в корневой каталог build.gradle? Каков наилучший способ поддержки нескольких языков в Gradle?


person iain    schedule 05.04.2013    source источник
comment
Как говорится в документе Gradle о плагине scala — The Scala plugin extends the Java plugin to add support for Scala projects. И compileScala на самом деле зависит от compileJava, поэтому вы видите, что они оба выполняются для каждого проекта.   -  person denis.solonenko    schedule 05.04.2013
comment
Спасибо за ваш вклад, но да, я знаю это. Однако как лучше всего поддерживать проекты как с java, так и с scala? Нужно ли просто рассматривать все как scala, поскольку оно включает java? Что произойдет, если мы решим добавить заводной проект в будущем? Должен ли он иметь скальную и заводную природу? Должен ли я стандартизировать структуру исходного кода, прежде чем беспокоиться об этом?   -  person iain    schedule 05.04.2013


Ответы (1)


Как насчет такого:

configure(subprojects.findAll {project  ->
    file('src/main/java').exists()
}) {
    apply plugin: 'java'
}

configure(subprojects.findAll {project  ->
    file('src/main/scala').exists()
}) {
    apply plugin: 'scala'
}

Because your source directory is src, some other discriminator mechanism inside the closures is needed.

person Ori Dar    schedule 05.04.2013
comment
Это не сработает, внимательно посмотрите на его определение исходников. Нет ни src/main/java, ни src/main/scala, только src. - person Pascal Gélinas; 05.04.2013
comment
Правда, именно поэтому я упомянул или использовать любой другой дискриминатор внутри замыканий. Это просто серверы в качестве примера условного применения плагина. Спасибо - person Ori Dar; 05.04.2013
comment
Спасибо за ваш ответ, я не знал о функции configure, возможно, я смогу использовать ее немного по-другому. Поместите операторы apply plugin в соответствующие подпроекты, затем используйте configure, чтобы найти подпроекты с природой Java и настроить их, а также для проектов scala. Хотя меня волнует порядок исполнения. - person iain; 05.04.2013
comment
Я бы очень хотел использовать наборы исходников maven/gradle по умолчанию. Это то, что я планирую посмотреть, как только я запущу Gradle. На данный момент я должен поддерживать сборку ant и не хочу вносить в нее такие изменения. - person iain; 05.04.2013