Расширь границы возможного вместе с
Gradle
1
@tolkv
2
@aatarasoff
3
Что будет
1. Немного о том как люди проекты собирали/собирают
2. Несколько жизненных примеров
3. Микросервисный подход к сборке проекта, детка)
a. Дизайн того, что мы хотим
b. Попробуем наивный императивный подход
c. Уменьшим количество боли. Напишем плагин
4. А что там с тестами
5. Немного о том как люди будут собирать проекты на Gradle
6. Резюме
7. Q&A
4
Где мы сейчас?
1. Немного о том как люди проекты собирали/собирают
2. Несколько жизненных примеров
3. Микросервисный подход к сборке проекта детка
a. Дизайн того, что мы хотим
b. Попробуем наивный императивный подход
c. Уменьшим количество боли. Напишем плагин
4. А что там с тестами
5. Немного о том как люди проекты будут собирать
6. Резюме
7. Q&A
5
Что значит “собрать проект” ?
6
Что значит “собрать проект” ?
7
Процесс
1. Исходные данные
a. Исходники ПО
2. Дополнительные ресурсы
a. картинки
b. настройки
3. Метадата
a. конфигурация IDE
4. Что то очень странное и
специфичное
Нечто
8
Процесс
1. Исходные данные
a. Исходники ПО
2. Дополнительные ресурсы
a. картинки
b. настройки
3. Метадата
a. конфигурация IDE
4. Что то очень странное и
специфичное
Нечто, что можно использовать
9
javac
javac -classpath 
/examples/examples/greetings/Hi.java
jar
jar cvf mySuperProject.jar *
Usage: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C
dir] files ...
Options:
-c create new archive
-t
…………
10
javac
javac -classpath 
/examples/examples/greetings/Hi.java
jar
jar cvf mySuperProject.jar *
Usage: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C
dir] files ...
Options:
-c create new archive
-t
…………
Compile
11
Apache Ant
<project name="MyProject" default="dist" basedir=".">
<property name="src" location="src"/>
<property name="build" location="build"/>
<property name="dist" location="dist"/>
<target name="init">
</target>
<target name="compile" depends="init">
<javac srcdir="${src}" destdir="${build}"/>
</target>
<target name="dist" depends="compile">
<mkdir dir="${dist}/lib"/>
<jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/>
</target>
</project>
12
Apache Ant
Compile Distr
13
Maven
<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/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>one.util</groupId>
<artifactId>streamex</artifactId>
<version>0.6.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>StreamEx</name>
<description>Enhancing Java 8 Streams</description>
<url>https://github.com/amaembo/streamex</url>
<licenses>
<license>
<name>Apache License, Version 2.0</name>
<url>https://www.apache.org/licenses/LICENSE-2.0</url>
<distribution>repo</distribution>
</license>
</licenses>
<distributionManagement>
<snapshotRepository>
<id>ossrh</id>
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
</snapshotRepository>
</distributionManagement>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
14
Maven
Compile Distr
Management
15
Gradle
Compile Distr
Management
Automation
Framework
16
17
Где мы сейчас?
1. Немного о том как люди проекты собирали/собирают
2. Несколько жизненных примеров
3. Микросервисный подход к сборке проекта детка
a. Дизайн того, что мы хотим
b. Попробуем наивный императивный подход
c. Уменьшим количество боли. Напишем плагин
4. А что там с тестами
5. Немного о том как люди проекты будут собирать
6. Резюме
7. Q&A
18
Как бывает в жизни
1. ant
2. maven
3. gradle
4.
19
Keep calm and make MAR (not WAR)
task mar(type: Zip) {
archiveName = 'AutoGeneratedMar.mar'
destinationDir = project.libsDir
from "resourcebundles" // ← WTF?
from ('Portal/public_html') { // ← WTF?
include 'oracle/**/*.*' // ← WTF?
}
}
20
Epic Story “one mile XML”
21
Just another epic story
apply plugin: “idea”
// joke apply plugin: “JDeveloper”
task createJpr() << {
…………. I love JDeveloper !
}
22
Всем понятно
JDeveloper сложно, но нужно. Напишем плагин?
23
Всем понятно
JDeveloper сложно, но нужно. Напишем плагин?
24
Времена JDeveloper-a прошли
25
Подход к
документированию
микросервисов, должен
быть микросервисным
26
Где мы сейчас?
1. Немного о том как люди проекты собирали/собирают
2. Несколько жизненных примеров
3. Микросервисный подход к сборке проекта детка
a. Дизайн того, что мы хотим
b. Попробуем наивный императивный подход
c. Уменьшим количество боли. Напишем плагин
4. А что там с тестами
5. Немного о том как люди проекты будут собирать
6. Резюме
7. Q&A
27
Документация + Asciidoctor = ❤
1. Все любят AsciiDoctor
2. Все могут писать документацию с помощью AsciiDoctor
3. Позволяет комбинировать документы
4. Внешние документы
28
Как это выглядит
= Самая главная документация
В этом документе описано как быть самым главным и важным документом в мире
разнообразных документов
include::https://raw.github.com/asciidoctor/asciidoctor/master/Gemfile[]
include::../other.adoc[]
include::/home/tolkv/git/docs-0/superdoc.adoc[]
29
Волшебные инклуды
= Самая главная документация
В этом документе описано как быть самым главным и важным документом в мире
разнообразных документов
include::https://raw.github.com/asciidoctor/asciidoctor/master/Gemfile[]
include::../other.adoc[]
include::/home/tolkv/git/docs-0/superdoc.adoc[]
30
А как хотим? Ещё более волшебные
= Самая главная документация
В этом документе описано как быть самым главным и важным документом в мире
разнообразных документов
include::https://raw.github.com/asciidoctor/asciidoctor/master/Gemfile[]
include::gradle://gradle-advanced:service-with-deps:1.0/deps.adoc[]
include::gradle://:service/doc.adoc[]
31
Где мы сейчас?
1. Немного о том как люди проекты собирали/собирают
2. Несколько жизненных примеров
3. Микросервисный подход к сборке проекта детка
a. Дизайн того, что мы хотим
b. Попробуем наивный императивный подход
c. Уменьшим количество боли. Напишем плагин
4. А что там с тестами
5. Немного о том как люди проекты будут собирать
6. Резюме
7. Q&A
32
DEMO
33
Где мы сейчас?
1. Немного о том как люди проекты собирали/собирают
2. Несколько жизненных примеров
3. Микросервисный подход к сборке проекта детка
a. Дизайн того, что мы хотим
b. Попробуем наивный императивный подход
c. Уменьшим количество боли. Напишем плагин
4. А что там с тестами
5. Немного о том как люди проекты будут собирать
6. Резюме
7. Q&A
34
Кто нам поможет?
1. apply plugin: 'java-gradle-plugin'
2. 'org.asciidoctor:asciidoctorj:1.5.4'
'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3'
3. org.gradle.api.Plugin
35
DEMO
36
Где мы сейчас?
1. Немного о том как люди проекты собирали/собирают
2. Несколько жизненных примеров
3. Микросервисный подход к сборке проекта детка
a. Дизайн того, что мы хотим
b. Попробуем наивный императивный подход
c. Уменьшим количество боли. Напишем плагин
4. А что там с тестами
5. Немного о том как люди проекты будут собирать
6. Резюме
7. Q&A
37
Самое главное - тесты. Gradle TestKit
1. testCompile gradleTestKit()
2. testCompile 'org.spockframework:spock-core:1.0-groovy-2.4'
testCompile 'junit:junit:4.12'
3. Кодим
38
class BuildLogicFunctionalTest extends Specification {
@Rule final TemporaryFolder testProjectDir = new TemporaryFolder()
File buildFile
def setup() {
buildFile = testProjectDir.newFile('build.gradle')
}
def "can execute hello world task with Gradle version #gradleVersion"() {
given:
buildFile << """
task helloWorld {
doLast {
logger.quiet 'Hello world!'
}
}
"""
when:
def result = GradleRunner.create()
.withGradleVersion(gradleVersion)
.withProjectDir(testProjectDir.root)
.withArguments('helloWorld')
.build()
then:
result.output.contains('Hello world!')
result.task(":helloWorld").outcome == SUCCESS
where:
gradleVersion << ['2.6', '2.7']
}
}
39
DEMO
40
Не всё так радужно и с тестами
Feature Minimum
Version
Description
Inspecting executed tasks 2.5 Inspecting the executed tasks, using BuildResult.getTasks() and similar methods.
Plugin classpath injection 2.8 Injecting the code under test via GradleRunner.withPluginClasspath().
Inspecting build output in debug mode 2.9 Inspecting the build's text output when run in debug mode, using BuildResult.
getOutput().
41
Не всё так радужно и с тестами
Feature Minimum
Version
Description
Inspecting executed tasks 2.5 Inspecting the executed tasks, using BuildResult.getTasks() and similar methods.
Plugin classpath injection 2.8 Injecting the code under test via GradleRunner.withPluginClasspath().
Inspecting build output in debug mode 2.9 Inspecting the build's text output when run in debug mode, using BuildResult.
getOutput().
42
DEMO
43
И что же делать?
1. Извращаться
https://github.com/bmuschko/gradle-docker-plugin
2. Nebula-test
https://github.com/nebula-plugins/nebula-test
3. Заниматься продвинутым юнит тестированием https://github.com/spring-
gradle-plugins/dependency-management-plugin
44
Где мы сейчас?
1. Немного о том как люди проекты собирали/собирают
2. Несколько жизненных примеров
3. Микросервисный подход к сборке проекта детка
a. Дизайн того, что мы хотим
b. Попробуем наивный императивный подход
c. Уменьшим количество боли. Напишем плагин
4. А что там с тестами
5. Немного о том как люди проекты будут собирать
6. Резюме
7. Q&A
45
46
Как это будет выглядеть в build.gradle
Объявление по типу:
model {
html(Document) {
name ‘mydoc.html’
}
txt(Document) {
name ‘mydoc.txt
}
}
Объявление по имени:
model {
document {
name ‘mydoc.doc’
}
}
47
@Managed Mystery
@Managed
interface Document {
String getName
void setName(String name)
}
48
@Managed Explanation
@Managed
interface Document {
String getName
void setName(String name)
}
Immutability
49
@Managed Explanation
@Managed
interface Document {
String getName
void setName(String name)
}
Immutability
Autogenerated
50
@Managed Explanation
@Managed
interface Document {
String getName
void setName(String name)
}
Immutability
Autogenerated
Behaviour-less
51
Поведение - это правила
class DocumentationModelPlugin extends RuleSource {
@Model
void document(Document document) { }
@Defaults
void setDefaults(Document document) { }
@Mutate
void createTasks(ModelMap<Task> tasks, Document document) { }
@Finalize
void calculateHash(Document document) { }
@Validate
void validateHashIsNotEmpty(Document document) { }
} 52
Flow of Rules
@Defaults
53
Flow of Rules
@Defaults
@Model @Mutate
54
Flow of Rules
@Defaults
@Model @Mutate
@Finalize
55
Flow of Rules
@Defaults
@Model @Mutate
@Finalize
@Validate
56
57
Где мы сейчас?
1. Немного о том как люди проекты собирали/собирают
2. Несколько жизненных примеров
3. Микросервисный подход к сборке проекта детка
a. Дизайн того, что мы хотим
b. Попробуем наивный императивный подход
c. Уменьшим количество боли. Напишем плагин
4. А что там с тестами
5. Немного о том как люди проекты будут собирать
6. Резюме
7. Q&A
58
Выводы
● Императивный подход хорошо когда проект единичный
● Когда проектов много - надо писать плагины
● Декомпозируй, переиспользуй плагины
● Тестируй правильно:
○ сейчас Nebula или юнит-тесты
○ ждём допиленный GradleTestKit
● RuleBased-модель - будущее, которое пока можно только пощупать
59
Ссылки
Весь код находится здесь:
https://github.com/lavcraft/jpoint2016-gradle
Тут только плагин с тестами:
https://github.com/aatarasoff/documentation-plugin-demo
Статья про сравнение способов тестирования:
http://bit.ly/217tZEx
60
Спасибо! Готовы ответить на ваши вопросы
@tolkv
@aatarasoff
61

Расширь границы возможного вместе с Gradle

  • 1.
  • 2.
  • 3.
  • 4.
    Что будет 1. Немногоо том как люди проекты собирали/собирают 2. Несколько жизненных примеров 3. Микросервисный подход к сборке проекта, детка) a. Дизайн того, что мы хотим b. Попробуем наивный императивный подход c. Уменьшим количество боли. Напишем плагин 4. А что там с тестами 5. Немного о том как люди будут собирать проекты на Gradle 6. Резюме 7. Q&A 4
  • 5.
    Где мы сейчас? 1.Немного о том как люди проекты собирали/собирают 2. Несколько жизненных примеров 3. Микросервисный подход к сборке проекта детка a. Дизайн того, что мы хотим b. Попробуем наивный императивный подход c. Уменьшим количество боли. Напишем плагин 4. А что там с тестами 5. Немного о том как люди проекты будут собирать 6. Резюме 7. Q&A 5
  • 6.
  • 7.
  • 8.
    Процесс 1. Исходные данные a.Исходники ПО 2. Дополнительные ресурсы a. картинки b. настройки 3. Метадата a. конфигурация IDE 4. Что то очень странное и специфичное Нечто 8
  • 9.
    Процесс 1. Исходные данные a.Исходники ПО 2. Дополнительные ресурсы a. картинки b. настройки 3. Метадата a. конфигурация IDE 4. Что то очень странное и специфичное Нечто, что можно использовать 9
  • 10.
    javac javac -classpath /examples/examples/greetings/Hi.java jar jarcvf mySuperProject.jar * Usage: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ... Options: -c create new archive -t ………… 10
  • 11.
    javac javac -classpath /examples/examples/greetings/Hi.java jar jarcvf mySuperProject.jar * Usage: jar {ctxui}[vfmn0PMe] [jar-file] [manifest-file] [entry-point] [-C dir] files ... Options: -c create new archive -t ………… Compile 11
  • 12.
    Apache Ant <project name="MyProject"default="dist" basedir="."> <property name="src" location="src"/> <property name="build" location="build"/> <property name="dist" location="dist"/> <target name="init"> </target> <target name="compile" depends="init"> <javac srcdir="${src}" destdir="${build}"/> </target> <target name="dist" depends="compile"> <mkdir dir="${dist}/lib"/> <jar jarfile="${dist}/lib/MyProject-${DSTAMP}.jar" basedir="${build}"/> </target> </project> 12
  • 13.
  • 14.
    Maven <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.0http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>one.util</groupId> <artifactId>streamex</artifactId> <version>0.6.1-SNAPSHOT</version> <packaging>jar</packaging> <name>StreamEx</name> <description>Enhancing Java 8 Streams</description> <url>https://github.com/amaembo/streamex</url> <licenses> <license> <name>Apache License, Version 2.0</name> <url>https://www.apache.org/licenses/LICENSE-2.0</url> <distribution>repo</distribution> </license> </licenses> <distributionManagement> <snapshotRepository> <id>ossrh</id> <url>https://oss.sonatype.org/content/repositories/snapshots</url> </snapshotRepository> </distributionManagement> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> 14
  • 15.
  • 16.
  • 17.
  • 18.
    Где мы сейчас? 1.Немного о том как люди проекты собирали/собирают 2. Несколько жизненных примеров 3. Микросервисный подход к сборке проекта детка a. Дизайн того, что мы хотим b. Попробуем наивный императивный подход c. Уменьшим количество боли. Напишем плагин 4. А что там с тестами 5. Немного о том как люди проекты будут собирать 6. Резюме 7. Q&A 18
  • 19.
    Как бывает вжизни 1. ant 2. maven 3. gradle 4. 19
  • 20.
    Keep calm andmake MAR (not WAR) task mar(type: Zip) { archiveName = 'AutoGeneratedMar.mar' destinationDir = project.libsDir from "resourcebundles" // ← WTF? from ('Portal/public_html') { // ← WTF? include 'oracle/**/*.*' // ← WTF? } } 20
  • 21.
    Epic Story “onemile XML” 21
  • 22.
    Just another epicstory apply plugin: “idea” // joke apply plugin: “JDeveloper” task createJpr() << { …………. I love JDeveloper ! } 22
  • 23.
    Всем понятно JDeveloper сложно,но нужно. Напишем плагин? 23
  • 24.
    Всем понятно JDeveloper сложно,но нужно. Напишем плагин? 24
  • 25.
  • 26.
  • 27.
    Где мы сейчас? 1.Немного о том как люди проекты собирали/собирают 2. Несколько жизненных примеров 3. Микросервисный подход к сборке проекта детка a. Дизайн того, что мы хотим b. Попробуем наивный императивный подход c. Уменьшим количество боли. Напишем плагин 4. А что там с тестами 5. Немного о том как люди проекты будут собирать 6. Резюме 7. Q&A 27
  • 28.
    Документация + Asciidoctor= ❤ 1. Все любят AsciiDoctor 2. Все могут писать документацию с помощью AsciiDoctor 3. Позволяет комбинировать документы 4. Внешние документы 28
  • 29.
    Как это выглядит =Самая главная документация В этом документе описано как быть самым главным и важным документом в мире разнообразных документов include::https://raw.github.com/asciidoctor/asciidoctor/master/Gemfile[] include::../other.adoc[] include::/home/tolkv/git/docs-0/superdoc.adoc[] 29
  • 30.
    Волшебные инклуды = Самаяглавная документация В этом документе описано как быть самым главным и важным документом в мире разнообразных документов include::https://raw.github.com/asciidoctor/asciidoctor/master/Gemfile[] include::../other.adoc[] include::/home/tolkv/git/docs-0/superdoc.adoc[] 30
  • 31.
    А как хотим?Ещё более волшебные = Самая главная документация В этом документе описано как быть самым главным и важным документом в мире разнообразных документов include::https://raw.github.com/asciidoctor/asciidoctor/master/Gemfile[] include::gradle://gradle-advanced:service-with-deps:1.0/deps.adoc[] include::gradle://:service/doc.adoc[] 31
  • 32.
    Где мы сейчас? 1.Немного о том как люди проекты собирали/собирают 2. Несколько жизненных примеров 3. Микросервисный подход к сборке проекта детка a. Дизайн того, что мы хотим b. Попробуем наивный императивный подход c. Уменьшим количество боли. Напишем плагин 4. А что там с тестами 5. Немного о том как люди проекты будут собирать 6. Резюме 7. Q&A 32
  • 33.
  • 34.
    Где мы сейчас? 1.Немного о том как люди проекты собирали/собирают 2. Несколько жизненных примеров 3. Микросервисный подход к сборке проекта детка a. Дизайн того, что мы хотим b. Попробуем наивный императивный подход c. Уменьшим количество боли. Напишем плагин 4. А что там с тестами 5. Немного о том как люди проекты будут собирать 6. Резюме 7. Q&A 34
  • 35.
    Кто нам поможет? 1.apply plugin: 'java-gradle-plugin' 2. 'org.asciidoctor:asciidoctorj:1.5.4' 'org.asciidoctor:asciidoctor-gradle-plugin:1.5.3' 3. org.gradle.api.Plugin 35
  • 36.
  • 37.
    Где мы сейчас? 1.Немного о том как люди проекты собирали/собирают 2. Несколько жизненных примеров 3. Микросервисный подход к сборке проекта детка a. Дизайн того, что мы хотим b. Попробуем наивный императивный подход c. Уменьшим количество боли. Напишем плагин 4. А что там с тестами 5. Немного о том как люди проекты будут собирать 6. Резюме 7. Q&A 37
  • 38.
    Самое главное -тесты. Gradle TestKit 1. testCompile gradleTestKit() 2. testCompile 'org.spockframework:spock-core:1.0-groovy-2.4' testCompile 'junit:junit:4.12' 3. Кодим 38
  • 39.
    class BuildLogicFunctionalTest extendsSpecification { @Rule final TemporaryFolder testProjectDir = new TemporaryFolder() File buildFile def setup() { buildFile = testProjectDir.newFile('build.gradle') } def "can execute hello world task with Gradle version #gradleVersion"() { given: buildFile << """ task helloWorld { doLast { logger.quiet 'Hello world!' } } """ when: def result = GradleRunner.create() .withGradleVersion(gradleVersion) .withProjectDir(testProjectDir.root) .withArguments('helloWorld') .build() then: result.output.contains('Hello world!') result.task(":helloWorld").outcome == SUCCESS where: gradleVersion << ['2.6', '2.7'] } } 39
  • 40.
  • 41.
    Не всё такрадужно и с тестами Feature Minimum Version Description Inspecting executed tasks 2.5 Inspecting the executed tasks, using BuildResult.getTasks() and similar methods. Plugin classpath injection 2.8 Injecting the code under test via GradleRunner.withPluginClasspath(). Inspecting build output in debug mode 2.9 Inspecting the build's text output when run in debug mode, using BuildResult. getOutput(). 41
  • 42.
    Не всё такрадужно и с тестами Feature Minimum Version Description Inspecting executed tasks 2.5 Inspecting the executed tasks, using BuildResult.getTasks() and similar methods. Plugin classpath injection 2.8 Injecting the code under test via GradleRunner.withPluginClasspath(). Inspecting build output in debug mode 2.9 Inspecting the build's text output when run in debug mode, using BuildResult. getOutput(). 42
  • 43.
  • 44.
    И что жеделать? 1. Извращаться https://github.com/bmuschko/gradle-docker-plugin 2. Nebula-test https://github.com/nebula-plugins/nebula-test 3. Заниматься продвинутым юнит тестированием https://github.com/spring- gradle-plugins/dependency-management-plugin 44
  • 45.
    Где мы сейчас? 1.Немного о том как люди проекты собирали/собирают 2. Несколько жизненных примеров 3. Микросервисный подход к сборке проекта детка a. Дизайн того, что мы хотим b. Попробуем наивный императивный подход c. Уменьшим количество боли. Напишем плагин 4. А что там с тестами 5. Немного о том как люди проекты будут собирать 6. Резюме 7. Q&A 45
  • 46.
  • 47.
    Как это будетвыглядеть в build.gradle Объявление по типу: model { html(Document) { name ‘mydoc.html’ } txt(Document) { name ‘mydoc.txt } } Объявление по имени: model { document { name ‘mydoc.doc’ } } 47
  • 48.
    @Managed Mystery @Managed interface Document{ String getName void setName(String name) } 48
  • 49.
    @Managed Explanation @Managed interface Document{ String getName void setName(String name) } Immutability 49
  • 50.
    @Managed Explanation @Managed interface Document{ String getName void setName(String name) } Immutability Autogenerated 50
  • 51.
    @Managed Explanation @Managed interface Document{ String getName void setName(String name) } Immutability Autogenerated Behaviour-less 51
  • 52.
    Поведение - этоправила class DocumentationModelPlugin extends RuleSource { @Model void document(Document document) { } @Defaults void setDefaults(Document document) { } @Mutate void createTasks(ModelMap<Task> tasks, Document document) { } @Finalize void calculateHash(Document document) { } @Validate void validateHashIsNotEmpty(Document document) { } } 52
  • 53.
  • 54.
  • 55.
    Flow of Rules @Defaults @Model@Mutate @Finalize 55
  • 56.
    Flow of Rules @Defaults @Model@Mutate @Finalize @Validate 56
  • 57.
  • 58.
    Где мы сейчас? 1.Немного о том как люди проекты собирали/собирают 2. Несколько жизненных примеров 3. Микросервисный подход к сборке проекта детка a. Дизайн того, что мы хотим b. Попробуем наивный императивный подход c. Уменьшим количество боли. Напишем плагин 4. А что там с тестами 5. Немного о том как люди проекты будут собирать 6. Резюме 7. Q&A 58
  • 59.
    Выводы ● Императивный подходхорошо когда проект единичный ● Когда проектов много - надо писать плагины ● Декомпозируй, переиспользуй плагины ● Тестируй правильно: ○ сейчас Nebula или юнит-тесты ○ ждём допиленный GradleTestKit ● RuleBased-модель - будущее, которое пока можно только пощупать 59
  • 60.
    Ссылки Весь код находитсяздесь: https://github.com/lavcraft/jpoint2016-gradle Тут только плагин с тестами: https://github.com/aatarasoff/documentation-plugin-demo Статья про сравнение способов тестирования: http://bit.ly/217tZEx 60
  • 61.
    Спасибо! Готовы ответитьна ваши вопросы @tolkv @aatarasoff 61