Gradle распределение нескольких проектов

Я пытаюсь сделать часть многопроектной сборки. Корневой проект выглядит примерно так:

apply plugin: 'distribution'
version 1.0
distributions {
    main {
        baseName = 'someName'
        contents {
            from 'nodes' 
        into 'nodes'
        }
    }
}

Он просто копирует папку с некоторыми файлами на dist.

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

Я не знаю, как вводить из подпроекта корневой каталог. Должен ли я вообще что-то делать? Я имею в виду что-то вроде этого:

subprojects {
   apply java...
   ...

   // pseudocode
   jack into the root project dist plugin
   put my produced jars and dependencies in a folder with my name
   ...
}

Есть ли у кого-нибудь примеры или просто указать мне в правильном направлении?

спасибо!

Ответ 1

Я искал то же самое. С некоторыми взглядами на документы API и Gradle 'собственные файлы сборки я пришел к следующему:

apply plugin: 'distribution'

distributions {
    main {
        contents {
            into('bin') {
                from { project(':subproject1').startScripts.outputs.files }
                from { project(':subproject2').startScripts.outputs.files }
                fileMode = 0755
            }
            into('lib') {
                def libs = []
                libs << project(':subproject1').configurations.runtime - project(':runner').configurations.runtime
                libs << project(':subproject2').configurations.runtime
                from libs
                from project(':subproject1').jar
                from project(':subproject2').jar
            }
        }
    }
}

Содержимое {} закрывается CopySpec, зная, что упрощает использование плагина распространения:)

Проверьте Gradle 'собственные подпроекты/дистрибутивы/дистрибутивы .gradle для некоторых отличных примеров использования CopySpec.

Это работает.

  • Подчеркивание - удаление дублированных банок.
  • Строки ".jar" должны добавить банку этого проекта в качестве конфигураций. Время выполнения только, кажется, содержит зависимость.

К сожалению, в настоящее время я не знаю, как масштабировать это до более чем двух проектов в чистом виде. По крайней мере, мы на один шаг ближе:)

Ответ 2

Я нашел решение, которое хорошо работает для меня. Ключ в том, что вы добавляете отдельный подпроект для создания dist. Этот подпроект sibling для других подпроектов. То есть не пытайтесь script распространять в вашем файле верхнего уровня build.gradle.

Позвоните в новый подпроект dist. Первое, что нужно сделать, это добавить его в файл верхнего уровня settings.gradle в вашем многопроектном корне:

include "subproject1", "subproject2", "subproject3", ....... , "dist"

В проекте dist должен быть минимум:

  • build.gradle - подробнее ниже
  • src/main/dist/at_least_one_dummy_file.txt - для плагина распространения всегда требуется каталог src/main/$distribution.name. Наличие непустого с distribution.name of main позволяет плагину следовать всем транзитивным зависимостям всех наборов main всех проектов sibling.

Далее, файл build.gradle для проекта dist:

/* Hook in all sibling project jars and their transitive dependencies */
apply plugin: 'java'
dependencies {
    compile project(':subproject1')
    compile project(':subproject2')
    compile project(':subproject3')
    . . . 
}

/* Distribution */
apply plugin: 'java-library-distribution'
distributions {
    main {
        baseName = "your-top-level-project-name"
        contents {
            exclude "dist-${version}.jar"
            . . . 
        }
    }
}

Затем запустите gradle distZip. Файл ZIP в dist/build/distributions будет иметь подкаталог lib с каждым единственным JAR, который вы хотите: проект sibling JAR и их транзитивные зависимости.

Из-за используемого трюка плагин распространения сделает пустой JAR, называемый dist-${version}.jar. По косметическим причинам я удаляю его с помощью вызова exclude выше, но он безвреден. Вы также можете использовать второй вызов exclude для удаления at_least_one_dummy_file.txt, если в разделе src/main/dist, которое вы хотите включить, действительно нет содержимого. Если вы не хотите добавлять какие-либо артефакты и/или удалять те, что упомянуты здесь, вам вообще не нужен раздел contents.

Я также нашел способы выборочного включения различных артефактов на основе того, является ли это распределением "dev" или "prod", a la Maven. Если вы хотите, чтобы я добавил это, пожалуйста, напишите в комментариях, и я буду.

Ответ 3

Я действительно сделал это, объединив подходы как из pvdissel, так и sparc_spread.

В моем корневом проекте я создал каталог src/main/dist, где я помещаю ровно один файл с именем .gitkeep.

Файл build.gradle моего корневого проекта выглядит следующим образом:

apply plugin: 'java-library-distribution'

allprojects {
    ....
}

dependencies {
    // let root project depend on all subprojects that have the
    // application plugin enabled
    project.subprojects.each { p ->
        p.plugins.withType(ApplicationPlugin) {
            compile p
        }
    }
}

distributions {
    main {
        contents {
            // exclude unnecessary files from archive
            exclude ".gitkeep"
            exclude "cs3d-toolbox-${version}.jar"

            // add start scripts of all plugins that have the
            // application plugin enabled to the archive
            project.subprojects.each { p ->
                p.plugins.withType(ApplicationPlugin) {
                    into('bin') {
                        from { p.startScripts.outputs.files }
                        fileMode = 0755
                    }
                }
            }
        }
    }
}

Хорошо работает для меня. Протестировано с помощью Gradle 2.0.

Ответ 4

Это настройка, которую я использую в проекте с несколькими библиотеками для создания "выпуска" архива:

apply plugin: 'distribution'

distributions {
  main {
    baseName = libVersion
    contents {
      project.subprojects.each { sub ->
        into('lib') {
          from sub.jar
        }
        into('src') {
          from sub.sourcesJar
        }
        into('doc') {
          from sub.javadocJar
        }
      }
    }
  }
}

С помощью задачи distZip создается архив со всеми библиотеками, их файлы разделены на три папки (lib содержит фактические банки, src содержит банки с источниками и doc содержит - вы уже догадались - javadoc jars).