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

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

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

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

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

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

subprojects {
   apply java...
   ...

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

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

Спасибо!


person Sason Ohanian    schedule 17.07.2013    source источник


Ответы (5)


Я искал то же самое. Немного просмотрев документы 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, знание которого значительно упрощает использование плагина дистрибутива :)

Ознакомьтесь с собственным файлом subprojects/distributions/distributions.gradle Gradle, чтобы найти отличные примеры использования CopySpec.

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

  • Вычитание состоит в том, чтобы удалить дублированные банки.
  • Строки «.jar» должны добавить банку этого проекта, так как файл configurations.runtime, похоже, содержит только зависимости.

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

person pvdissel    schedule 21.09.2013

Я нашел решение, которое хорошо работает для меня. Суть в том, что вы добавляете отдельный подпроект для создания дистрибутива. Этот подпроект является родственным по отношению к другим подпроектам. То есть не пытайтесь заскриптовать дистрибутив в файле 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 из main заставляет плагин следовать всем транзитивным зависимостям всех main наборов исходников всех родственных проектов.

Далее файл 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, который вы хотите: родственный проект JARs и их транзитивные зависимости.

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

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

person sparc_spread    schedule 16.05.2014

На самом деле я заставил его работать, объединив подходы pvdisssel и 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.

person Michel Krämer    schedule 25.07.2014

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

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 содержит фактические файлы jar, src содержит файлы jar с исходниками и doc содержит, как вы уже догадались, файлы Javadoc).

person Czyzby    schedule 30.04.2016

Просто как тот.

distributions {
    main {
        contents {
            into('lib') {
                from subprojects*.jar
                from subprojects*.configurations.runtimeClasspath
            }
            into('doc') {
                from subprojects*.javadocJar
            }
        }
    }
}
person themeasure43    schedule 30.01.2021