itevent gradle. Еволюція систем автоматичної збірки....
DESCRIPTION
Gradle - нова система збірки та інтеграційний засіб нового покоління. У доповіді ми ознайомимося з можливостями цього інструменту, порівняємо його з Ant та Maven, а також розглянемо випадки, у яких мінімальними зусиллями можна перетворити складний і незрозумілий процес складання великого проекту - на просту і прозору процедуру. Святослав БабичTRANSCRIPT
Еволюція систем автоматичної збірки.
Порівняння із Ant’ом та Maven’ом
Зміст1.Що таке Gradle ? Основні можливості .2.Основи скриптової мови (Groovy)3.Управління залежностями та зв’язками4.Збираємо багато проектів одночасно5.Плагіни
1.Java2.War, Ear3.Eclipse, Eclipse-wtp
6.Робота із система безперервної інтеграції (continuous integration – Jenkins, Hudson)
Що таке Gradle ? Основні можливості.• Гнучкий інструмент для автоматичної збірки (build tool) назразок Ant’у
• Поставляється разом із build description language (DSL) на основі Groovy
• Як і Maven побудований на принципі - build-by-convention
• Дуже гнучкий та легко розширюваний.• Містить вбудовані плагіни для Java,
Eclipse, Scala, Groovi, Web, OSGi • Потужна підтримка для збірки
багатьох проектів одночасно (multi-project builds)
• Керування залежностями (dependency management) побудована на основі Apache Ivy
• Повністю інтегрований із Ant, Maven та Ivy. Підтримує їх структуру репозиторіїв.
• Безкоштовний та з відкритим кодом• Паралельне виконання юніт тестів• Підтримка послідовних збірок
(incremental builds)• Динамічні таски та правила для тасків
+ гнучкість + залежність
тасків + контроль над
процесом + різні таски на
кожну задачу - важкі build.xml - тяжко підтримувати
+ керування залежностями
+ плагіни + збірка багатьох
модулів проекту + угода по конфігурації
(convention over configuration)
- важкі pom.xml - тяжко
перевизначити поведінку по замовчуванні
+ DSL , замість XML легкість кастомізації
Основи скриптової мови (Groovy)
task hello << { println 'Hello world!'}
D:\@gradle\hello.world>gradle hello:helloHello world!BUILD SUCCESSFUL
Дві основні концепції: проекти та таски.Gradle task == Ant target
task intro(dependsOn: hello) << { println "I'm Gradle"}
1. Hello World
2. Залежності між таскамиD:\@gradle\hello.world>gradle intro:introHello world!I'm GradleBUILD SUCCESSFUL
4.times { counter -> task "task$counter" << { println "I'm task number $counter" }}
D:\@gradle\hello.world>gradle task1:task1I'm task number 1 BUILD SUCCESSFUL
task0.dependsOn task2, task3
3. Динамічні таски
4. Маніпулювання таскамиD:\@gradle\hello.world>gradle task0:task0I'm task number 2 I'm task number 3 I'm task number 0 BUILD SUCCESSFUL
task0.doFirst { println ‘before task hook'}task0.doLast { println ‘after task hook'}
D:\@gradle\hello.world>gradle task0:task0before task hook I'm task number 0 after task hook BUILD SUCCESSFUL
taskGraph
Управління залежностями та зв’язками
apply plugin: 'java' repositories { mavenCentral()} dependencies { compile group: 'org.hibernate', name: 'hibernate-core', version: '3.6.7.Final' testCompile group: 'junit', name: 'junit', version: '4.+'}
compile Залежності необхідні на етапі компіляції проекту з сорсів
runtime Залежності необхідні для зкомпільованих класів в рантаймі. Також включають в себе compile залежності
testCompile
Залежності необхідні для компіляції тест сорсів. Також включають в себе compile залежності та зкомпільовані класи
testRuntime
Залежності необхідні для запуску тестів. Включає compile, compiled classes, testCompile
Репозиторії:• основний Maven, • віддалені Maven / Ivy, • локальні Maven / Ivy
repositories { ivy { url "../local-repo" } maven { url "http://repo.company.com/maven2" }}
Збираємо багато проектів одночасно• Необхідно створити settings.gradle файл у якому вказати які проекти включати.
• Можна задати дефолтні налаштування для всіх підпроектів за допомогою subprojects {}
• Можна задати залежності між проектами. Таким чином можна регулювати порядок білдання підпроектів.
include "shared", "api", "services:webservice", "services:shared"
dependencies { compile project(':shared') }
subprojects { apply plugin: 'java‘ apply plugin: 'eclipse-wtp' repositories { mavenCentral() } dependencies { testCompile 'junit:junit:4.11' }}
Плагіни• Додають таски до проекту• Налаштовують додані таски значеннями по-замовчуванню
• Додають налаштування залежностей • Додають нові властивості та методи до існуючого типу через розширенняjava announce war checkst
yleproject-report
groovy
application java-library-distribution
codenarc
signing
scala build-announcements
ivy-publish eclipse sonar
antlr ear maven-publish eclipse-wtp
cpp jetty maven2Gradle findbugs
cpp-exe
maven build-dashboard
idea
cpp-liv
osgi pmd jdepend
Java ПлагінcompileJa
va processRe
sources clean
classes javadoc
compileTestJava
processTestResources jar
testClasses
test uploadArchives
check assemble
build
<project name="simple" default="dist" basedir="."> <property name="src" location="src/main/java" /> <property name="srcTest" location="src/test/java" /> <property name="build" location="build" /> <property name="dist" location="${build}/lib" /> <path id="classpath.test"> <pathelement location="libs/junit-4.8.1.jar" /> <pathelement location="${srcTest}" /> <pathelement location="${build}/classes" /> <pathelement location="${build}/test-classes" /> </path>
<target name="init"> <mkdir dir="${build}/classes" /> <mkdir dir="${build}/test-classes" /> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}/classes" /> </target> <target name="testCompile" depends="init"> <javac srcdir="${srcTest}" destdir="${build}/test-classes"> <classpath refid="classpath.test" /> </javac> </target> <target name="test" depends="testCompile"> <junit fork="yes" haltonfailure="yes"> <batchtest fork="yes"> <fileset dir="${srcTest}"> <include name="**/*Test.java" /> <include name="**/Test*.java" />
</fileset> </batchtest> <classpath refid="classpath.test" /> <formatter type="plain"/> </junit> </target> <target name="dist" depends="compile"> <mkdir dir="${dist}" /> <jar jarfile="${dist}/simple.jar" basedir="${build}/classes" /> </target> <target name="clean">
<delete dir="${build}" /> </target></project>
<?xml version="1.0" encoding="UTF-8"?><project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion><groupId>pl.gradle</groupId><artifactId>simple</artifactId><packaging>jar</packaging><version>1.0-SNAPSHOT</version><dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId><version>4.8.1</
version><scope>test</
scope></dependency>
</dependencies><build> <plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-
plugin</artifactId> <configuration>
<source>1.5</source>
<target>1.5</target>
</configuration></plugin>
</plugins></build>
</project>
apply plugin: 'java'
version = '1.0-SNAPSHOT'
repositories { mavenCentral()}
dependencies { testCompile 'junit:junit:4.8.1'}
javaProject
War, Earclasses assemble war. ear
Структура проекту:
apply plugin: 'java' version = '1.0'jar { manifest { attributes 'Implementation-Title': 'Java Project', 'Implementation-Version': version }} repositories { mavenCentral()} dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2' testCompile group: 'junit', name: 'junit', version: '4.+'} test { systemProperties 'property': 'value'} uploadArchives { repositories { flatDir { dirs 'repos' } }}
earWithWar
Eclipse, Eclipse-wtpeclipseProject генерує .project файл
eclipseClasspath
генерує .classpath файл
eclipseJdt генерує .settings/org.eclipse.jdt.core.prefs файл
eclipseWtpComponent
генерує .settings/org.eclipse.wst.common.component файл
eclipseWtpFacet
генерує .settings/org.eclipse.wst.common.project.facet.core.xml файл
eclipse генерує всі конфігураційні файл
clean, clean… видаляє відповідні файли
Кожен із згенерованих файлів можна модифікувати за допомогою хуків.
Процес генерації файлів виглядає наступним чином: 1. Читається відповідний файл, або якщо
такого файлу не існує то використовується дефолтовий передбачений Gradle’ом.
2. Виконується beforeMerged хук із об’єктом, який представляє відповідний файл.
3. Поточний контент файлу об’єднується із налаштуваннями з білд скрипту або дефолтовими з Gradle’ у
4. Виконується whenMerged хук із об’єктом, який представляє вміст результуючого файлу
5. Виконується withXml хук із XML представленням результуючого файлу
6. Створюється фінальний XML файл
apply plugin: 'war'apply plugin: 'eclipse' repositories { mavenCentral()} dependencies { compile group: 'commons-collections', name: 'commons-collections', version: '3.2' testCompile group: 'junit', name: 'junit', version: '4.+'} eclipse.classpath.file { beforeMerged { classpath -> classpath.entries.removeAll { entry -> entry.kind == 'lib' || entry.kind == 'var' } } whenMerged { classpath -> classpath.entries.findAll { entry -> entry.kind == 'lib' }*.exported = false }} apply plugin: 'eclipse-wtp' eclipse.wtp.facet.file.withXml { provider -> provider.asNode().fixed.find { it.@facet == 'jst.java' }.@facet = 'jst2.java'}
eclipse
Дякую за увагу
Запитання ??