Gradle » History » Revision 8
Revision 7 (Alexey Demakov, 11/13/2015 11:43 PM) → Revision 8/9 (Alexey Demakov, 11/24/2015 05:13 PM)
h1. Gradle-based build system. h2. История Предыдущая версия системы сборки использовала Ant для управления сборкой и Ivy для управления зависимостями. Система сборки представляла собой библиотечный Ant файл, который подключался к проекту и предоставлял базовую функциональность по сборке Java проектов и управлению выпуском релизов. Gradle реализует и расширяет эту функциональность, поэтому принято решение использовать этот инструмент для сборки проектов. h2. Ресурсы http://gradle.org h2. Подключение Gradle к проекту h3. 1. Установить gradle, определить переменную окружения GRADLE_HOME. h3. 2. В каталоге проекта выполнить команду создания конфигурационных файлов для Java проекта: @> gradle init --type java-library@ Другие доступные типы проектов: https://docs.gradle.org/current/userguide/build_init_plugin.html Также будет создана обертка-запускач gradlew/gradlew.bat, которая избавляет от необходимости вручную устанавливать gradle для сборки проекта - разработчику достаточно просто выкачать рабочую копию проекта из репозитория, gradle будет установлен автоматически. Имя проекта будет записано в settings.gradle. Gradle предполагает, что имя проекта совпадает с именем каталога проекта. Если это не так, необходимо исправить имя проекта в файле settings.gradle. Дополнительная информация: https://docs.gradle.org/current/userguide/gradle_wrapper.html https://docs.gradle.org/current/userguide/wrapper_plugin.html h3. 3. Привести структуру папок в соответствие с соглашениями gradle: src/main/java - код проекта src/main/resources - ресурсы проекта src/test/java - код тестов Дополнительная информация: https://docs.gradle.org/current/userguide/java_plugin.html#N12323 h3. 4. Указать зависимости проекта в build.gradle: compile - зависимость, необходимая для сборки проекта testCompile - зависимость, необходимая для сборки тестов группа:имя:версия - формат зависимости <pre> dependencies { // The production code uses the SLF4J logging API at compile time compile ''org.slf4j:slf4j-api:1.7.12'' // Declare the dependency for your favourite test framework you want to use in your tests. // TestNG is also supported by the Gradle Test task. Just change the // testCompile dependency to testCompile ''org.testng:testng:6.8.1'' and add // ''test.useTestNG()'' to your build script. testCompile ''junit:junit:4.12'' } </pre> Дополнительная информация: https://docs.gradle.org/current/userguide/java_plugin.html#sec:java_plugin_and_dependency_management h3. 5. Указать репозитории, в которых ищутся зависимости build.gradle: <pre> repositories { // репозиторий ИСП РАН, подключается, если есть зависимости от наших проектов ivy { url = ''http://forge.ispras.ru/repo'' layout ''pattern'', { artifact ''[organization]/[ext]s/[artifact]-[revision](.[ext])'' } } // Use ''jcenter'' for resolving your dependencies. // You can declare any Maven/Ivy/file repository here. jcenter() } </pre> Дополнительная информация: https://docs.gradle.org/current/userguide/dependency_management.html#sec:repositories h3. 6. Настроить опции компиляции Java build.gradle: <pre> sourceCompatibility = JavaVersion.VERSION_1_8 targetCompatibility = JavaVersion.VERSION_1_8 compileJava { options.encoding = "UTF-8" } </pre> Команда компилцяии Java файлов: <pre> > gradlew compileJava </pre> Компиляция и прогон тестов: <pre> > gradlew test </pre> Дополнительная информация: https://docs.gradle.org/current/userguide/java_plugin.html#N1245A h3. 7. Подключить плагин для сборки дистрибутива Для приложений (дистрибутив содержит библиотеки и скрипты для запуска): build.gradle: <pre> apply plugin: ''application'' ... mainClassName = "org.gradle.sample.Main" </pre> Для библиотек (application plugin подключает это автоматически): build.gradle: <pre> apply plugin: ''distribution'' </pre> Команда сборки дистрибутива <pre> > gradlew distZip </pre> или <pre> > gradlew distTar </pre> оба сразу: <pre> assembleDist </pre> Дополнительная информация: https://docs.gradle.org/current/userguide/distribution_plugin.html https://docs.gradle.org/current/userguide/application_plugin.html h3. 8. Подключить плагин для выпуска релизов build.gradle: <pre> // в начало файла import java.text.SimpleDateFormat import java.util.regex.Matcher import org.gradle.api.Project plugins { id ''net.researchgate.release'' version ''2.3.4'' } ... // в конец файла release { failOnCommitNeeded = false versionPatterns = [ // Increments build number: "0.2.5-alpha-150428" => "0.2.6-alpha-150428" /(^\d+\.\d+\.)(\d+)(-[^-]*)(-[^-]*$)/: { Matcher m, Project p -> m.replaceAll("${ m[0][1] }${ (m[0][2] as int) + 1 }${ m[0][3] }" ) } ] } task setReleaseData << { project.version=project.version+''-''+new SimpleDateFormat("yyMMdd").format(new Date()) } confirmReleaseVersion.dependsOn setReleaseData </pre> Готовящаяся к выпуску версия (вместо текущей даты SNAPSHOT) хранится в файле gradle.properties: <pre> version=0.1.28-alpha-SNAPSHOT </pre> Команда выпуска новой версии: <pre> > gradlew release </pre> Будет предложено подтвердить или изменить номер выпускаемой версии, а затем номер следующей готовящейся версии. Дополнительная информация: https://github.com/researchgate/gradle-release Хорошо бы согласовать систему нумерации версий с "семантическим версионированием":http://semver.org/lang/ru/. Есть плагин, поддерживающий этот подход: https://plugins.gradle.org/plugin/de.gliderpilot.semantic-release h3. 9 Статический анализ кода build.gradle: <pre> plugins { id "org.sonarqube" version "1.0" } sonarqube { properties { property "sonar.host.url", "http://forge.ispras.ru:9000" property "sonar.jdbc.url", "jdbc:mysql://localhost:3306/sonar" property "sonar.jdbc.driverClassName", "com.mysql.jdbc.Driver" property "sonar.jdbc.username", "sonar" property "sonar.jdbc.password", "sonar" } } </pre> Дополнительная информация: http://docs.sonarqube.org/display/SONAR/Analyzing+with+SonarQube+Scanner+for+Gradle <pre> apply plugin: ''checkstyle'' apply plugin: ''findbugs'' apply plugin: ''pmd'' apply plugin: "jacoco" dependencies { checkstyle ''com.puppycrawl.tools:checkstyle:6.12.1'' pmd ''net.sourceforge.pmd:pmd-core:5.4.0'' pmd ''net.sourceforge.pmd:pmd-java:5.4.0'' findbugs ''com.google.code.findbugs:findbugs:3.0.1'' } checkstyle { showViolations = false ignoreFailures = true } findbugs { ignoreFailures = true } pmd { ignoreFailures = true ruleSets = [ "java-android,java-basic,java-braces,java-comments,java-clone,java-codesize,java-controversial," + "java-coupling,java-design,java-empty,java-finalizers,java-imports,java-j2ee," + "java-javabeans,java-junit,java-logging-jakarta-commons,java-logging-java," + "java-migrating,java-migrating_to_13,java-migrating_to_14,java-migrating_to_15," + "java-migrating_to_junit4,java-naming,java-optimizations,java-strictexception," + "java-strings,java-sunsecure,java-typeresolution,java-unnecessary,java-unusedcode"] } jacoco { toolVersion = "0.7.5.201505241946" } jacocoTestReport { reports { xml.enabled true csv.enabled false } } </pre> Компиляция, прогон тестов и запуск инструментов статического анализа кода: <pre> > gradlew check</pre> h3. 10. Копирование зависимостей в подкаталог ''libs'' gradle скачивает зависимости куда-то в свой кэш. Это неудобно при использовании eclipse. Мы привыкли, что библиотеки лежат рядом. Копировать их в подкаталог ''libs'' проекта можно так: build.gradle <pre> //copying all dependencies attached to ''compile'' into a specific folder task copylibs(type: Copy) { //referring to the ''compile'' configuration from configurations.compile, configurations.testCompile into ''libs'' } </pre> Запускать при изменении зависимостей: <pre> > gradlew copylibs </pre> В source code repository не класть! Альтернатива - "gradle eclipse plugin":https://docs.gradle.org/current/userguide/eclipse_plugin.html Но .classpath генерируется не переносимый, в source code repository его не положишь.