Gradle plugin, take control of the build

128
@YourTwitterHandle #YourSessionHashtag Plugin Gradle, prenez le contrôle du build !

Transcript of Gradle plugin, take control of the build

Page 1: Gradle plugin, take control of the build

@YourTwitterHandle#YourSessionHashtag

Plugin Gradle, prenez le contrôle du build !

Page 2: Gradle plugin, take control of the build

Eyal LEZMYhttp://eyal.fr

Cedric CHAMPEAU @CedricChampeau

Page 4: Gradle plugin, take control of the build

DEFINITIONS01

Page 5: Gradle plugin, take control of the build

A dependency management engine

A dependency based execution system

A plugin system

A set of plugins

DEFINITIONS

What is Gradle?

by Luke Daley, Gradle core developer

Page 6: Gradle plugin, take control of the build

Build scriptsYour build.gradle file

Script pluginsThe customization you start writing

Binary pluginsThe code I want you to write

DEFINITIONS

Gradle Plugins Types

Page 7: Gradle plugin, take control of the build

Is a piece of work for a buildCompiling a class, generating javadoc, ...

Can be manipulateddoFirst, doLast

Can inherit from anothertype

Can depend on another taskdependsOn, finalizedBy

DEFINITIONS

The Gradle Task

Page 8: Gradle plugin, take control of the build

LET’S GET STARTED!02

Page 9: Gradle plugin, take control of the build

Your unit tests results, you have to

version

THE SUBJECT

Page 10: Gradle plugin, take control of the build

THE JOB

Copy and version this folder

Page 11: Gradle plugin, take control of the build

task archiveTests (type: Copy) { from "$reportsDir/reports" into "$projectDir/reports/report-${currentTimeMillis()}"}

tasks.test.finalizedBy archiveTests

THE CODE

End of build.gradle

Page 12: Gradle plugin, take control of the build

task archiveTests (type: Copy) { from "$reportsDir/reports" into "$projectDir/reports/report-${currentTimeMillis()}"}

tasks.test.finalizedBy archiveTests

THE CODE

We create the task

End of build.gradle

Page 13: Gradle plugin, take control of the build

task archiveTests (type: Copy) { from "$reportsDir/reports" into "$projectDir/reports/report-${currentTimeMillis()}"}

tasks.test.finalizedBy archiveTests

THE CODE

It inherits from Copy taskEnd of build.gradle

Page 14: Gradle plugin, take control of the build

task archiveTests (type: Copy) { from "$reportsDir/reports" into "$projectDir/reports/report-${currentTimeMillis()}"}

tasks.test.finalizedBy archiveTests

THE CODE

We define the copy parameters

End of build.gradle

Page 15: Gradle plugin, take control of the build

task archiveTests (type: Copy) { from "$reportsDir/reports" into "$projectDir/reports/report-${currentTimeMillis()}"}

tasks.test.finalizedBy archiveTests

THE CODE

We define the copy parameters

This is the versioningEnd of build.gradle

Page 16: Gradle plugin, take control of the build

task archiveTests (type: Copy) { from "$reportsDir/reports" into "$projectDir/reports/report-${currentTimeMillis()}"}

tasks.test.finalizedBy archiveTests

THE CODE

We ask to run it after test task

End of build.gradle

Page 17: Gradle plugin, take control of the build

BUILD A PLUGIN03

… for real

Page 18: Gradle plugin, take control of the build

A PLUGIN?

Use it on different projects

Share it with others

Keep your build script clean

Keep your build script focused

Cause’ it’s so easy!

Why a plugin?

Page 19: Gradle plugin, take control of the build

Is a Gradle projectBasically, a Groovy project

It containsA build.gradleA plugin classA descriptorOne or several tasksAn extension

ExamplesJava, Groovy, Maven, Android plugin

A PLUGIN?

The Binary Plugin

Page 20: Gradle plugin, take control of the build

THE ARCHITECTURE

Page 21: Gradle plugin, take control of the build

THE ARCHITECTURE

The plugin class

Page 22: Gradle plugin, take control of the build

THE ARCHITECTURE

The plugin class

A task

Page 23: Gradle plugin, take control of the build

THE ARCHITECTURE

The plugin class

A task

The extension

Page 24: Gradle plugin, take control of the build

THE ARCHITECTURE

The plugin class

A task

The extension

The descriptor

Page 25: Gradle plugin, take control of the build

THE ARCHITECTURE

The plugin class

A task

The extension

The descriptor

The build.gradle

Page 26: Gradle plugin, take control of the build

class ArchiveTestsPlugin implements Plugin<Project> {

void apply(Project project) {

//TODO create the extension//TODO create the tasks//TODO link the tasks to the build chain

}}

THE CODE

The Plugin class

Page 27: Gradle plugin, take control of the build

class ArchiveTestsPlugin implements Plugin<Project> {

void apply(Project project) {

//TODO create the extension//TODO create the tasks//TODO link the tasks to the build chain

}}

THE CODE

The Plugin class

Page 28: Gradle plugin, take control of the build

class ArchiveTestsPlugin implements Plugin<Project> {

void apply(Project project) {

//TODO create the extension//TODO create the tasks//TODO link the tasks to the build chain

}}

THE CODE

The Plugin class

Page 29: Gradle plugin, take control of the build

class ArchiveTestsPlugin implements Plugin<Project> {

void apply(Project project) {

//TODO create the extension//TODO create the tasks//TODO link the tasks to the build chain

}}

THE CODE

The Plugin class

Page 30: Gradle plugin, take control of the build

class ArchiveTestsPlugin implements Plugin<Project> {

void apply(Project project) {

//create the extensionproject.extensions.create(“achivetest”,ArchiveTestPluginExtension,

project)//create the tasks

project.task(name:“achivetest”, type:ArchiveTask){}

//link the tasks to the build chain Task task = project.tasks.getByName(project.archivetest.task) task.finalizedBy “achivetest”

}}

THE CODE

The Plugin class

Page 31: Gradle plugin, take control of the build

class ArchiveTask extends Copy {

ArchiveTask(){ from project.archivetest.from into project.archivetest.into }

@TaskAction def exec() { println "Reports copied into ${project.archivetest.into}" }}

THE CODE

The Task class

Page 32: Gradle plugin, take control of the build

class ArchiveTask extends Copy {

ArchiveTask(){ from project.archivetest.from into project.archivetest.into }

@TaskAction def exec() { println "Reports copied into ${project.archivetest.into}" }}

THE CODE

The Task class

Page 33: Gradle plugin, take control of the build

class ArchiveTask extends Copy {

ArchiveTask(){ from project.archivetest.from into project.archivetest.into }

@TaskAction def exec() { println "Reports copied into ${project.archivetest.into}" }}

THE CODE

We want a Copy task.Use DefaultTask to implement your ownThe Task class

Page 34: Gradle plugin, take control of the build

class ArchiveTask extends Copy {

ArchiveTask(){ from project.archivetest.from into project.archivetest.into }

@TaskAction def exec() { println "Reports copied into ${project.archivetest.into}" }}

THE CODE

The Task class

Page 35: Gradle plugin, take control of the build

class ArchiveTask extends Copy {

ArchiveTask(){ from project.archivetest.from into project.archivetest.into }

@TaskAction def exec() { println "Reports copied into ${project.archivetest.into}" }}

THE CODE

The Task class

Page 36: Gradle plugin, take control of the build

class ArchiveTask extends Copy {

ArchiveTask(){ from project.archivetest.from into project.archivetest.into }

@TaskAction def exec() { println "Reports copied into ${project.archivetest.into}" }}

THE CODE

The Task class

Here we use the extension’s content

Page 37: Gradle plugin, take control of the build

archivetest {

from "origin/folder" into "destination/folder" task "taskToLaunchCopy"

}

THE CODE

The Extension: the syntax expected

Page 38: Gradle plugin, take control of the build

archivetest {

from "origin/folder" into "destination/folder" task "taskToLaunchCopy"

}

THE CODE

The Extension: the syntax expected

Page 39: Gradle plugin, take control of the build

THE CODE

The Extension classclass ArchiveTestPluginExtension {

def from def into def task

ArchiveTestPluginExtension(Project project) { from = project. reportsDir into = project.projectDir+"/reports/report-${currentTimeMillis()}"

task = "test" }}

Page 40: Gradle plugin, take control of the build

THE CODE

The Extension classclass ArchiveTestPluginExtension {

def from def into def task

ArchiveTestPluginExtension(Project project) { from = project. reportsDir into = project.projectDir+"/reports/report-${currentTimeMillis()}"

task = "test" }}

This is a simple POGO

Page 41: Gradle plugin, take control of the build

THE CODE

The Extension classclass ArchiveTestPluginExtension {

def from def into def task

ArchiveTestPluginExtension(Project project) { from = project.reportsDir into = project.projectDir+"/reports/report-${currentTimeMillis()}"

task = "test" }}

Page 42: Gradle plugin, take control of the build

implementation-class= main.groovy.fr.eyal.ArchiveTestPlugin

THE CODE

The Descriptor: achivetest.properties

Page 43: Gradle plugin, take control of the build

implementation-class=main.groovy.fr.eyal.ArchiveTestPlugin

THE CODE

The name of this file impliesapply plugin: “archivetest”

The Descriptor: achivetest.properties

Page 44: Gradle plugin, take control of the build

apply plugin: 'groovy'

dependencies { compile gradleApi() compile localGroovy()}

...

THE CODE

The build.gradle (1/2)

Page 45: Gradle plugin, take control of the build

apply plugin: 'groovy'

dependencies { compile gradleApi() compile localGroovy()}

...

THE CODE

The build.gradle (1/2) A plugin is a groovy project

Page 46: Gradle plugin, take control of the build

apply plugin: 'groovy'

dependencies { compile gradleApi() compile localGroovy()}

...

THE CODE

The build.gradle (1/2)

Add a gradle API dependency corresponding to the gradle version used to compile the project

Page 47: Gradle plugin, take control of the build

apply plugin: 'groovy'

dependencies { compile gradleApi() compile localGroovy()}

...

THE CODE

The build.gradle (1/2)

Add a groovy dependency corresponding to the gradle version used

Page 48: Gradle plugin, take control of the build

...

apply plugin: 'maven-publish'

group = 'fr.eyal'version = '0.1'

publishing { publications { mavenJava(MavenPublication) { from components.java } }}

THE CODE

The build.gradle (2/2)

Page 49: Gradle plugin, take control of the build

...

apply plugin: 'maven-publish'

group = 'fr.eyal'version = '0.1'

publishing { publications { mavenJava(MavenPublication) { from components.java } }}

THE CODE

The build.gradle (2/2)

Page 50: Gradle plugin, take control of the build

...

apply plugin: 'maven-publish'

group = 'fr.eyal'version = '0.1'

publishing { publications { mavenJava(MavenPublication) { from components.java } }}

THE CODE

The build.gradle (2/2)

Page 51: Gradle plugin, take control of the build

USE THE PLUGIN04

Page 52: Gradle plugin, take control of the build

USE THE PLUGIN

Add the repository

Add dependency

Apply the plugin

Configure the plugin if needed

How to use our plugin?

Page 53: Gradle plugin, take control of the build

buildscript { repositories { mavenLocal() } dependencies { classpath 'fr.eyal:archivetest:0.1' }}

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task “connectedAndroidTest”

}

THE CODE

The user’s build.gradle

Page 54: Gradle plugin, take control of the build

buildscript { repositories { mavenLocal() } dependencies { classpath 'fr.eyal:archivetest:0.1' }}

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task “connectedAndroidTest”

}

THE CODE

The user’s build.gradle

Page 55: Gradle plugin, take control of the build

buildscript { repositories { mavenLocal() } dependencies { classpath 'fr.eyal:archivetest:0.1' }}

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task “connectedAndroidTest”

}

THE CODE

The user’s build.gradle The local repository folder

Page 56: Gradle plugin, take control of the build

buildscript { repositories { mavenLocal() } dependencies { classpath ' fr.eyal:archivetest:0.1' }}

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task “connectedAndroidTest”

}

THE CODE

The user’s build.gradle

pom.group pom.artifactId pom.version

Page 57: Gradle plugin, take control of the build

buildscript { repositories { mavenLocal() } dependencies { classpath 'fr.eyal:archivetest:0.1' }}

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task “connectedAndroidTest”

}

THE CODE

The user’s build.gradle

archivetest.properties

Page 58: Gradle plugin, take control of the build

buildscript { repositories { mavenLocal() } dependencies { classpath 'fr.eyal:archivetest:0.1' }}

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task “connectedAndroidTest”

}

THE CODE

The user’s build.gradle

Our extension

Page 59: Gradle plugin, take control of the build

RUN IT05

Page 60: Gradle plugin, take control of the build

archivetest {from "build/report"into "/tmp/archives"

}

RUN IT

$ gradle test

Page 61: Gradle plugin, take control of the build

archivetest {from "build/report"into "/tmp/archives"

}

RUN IT

$ gradle test

...

Reports copied into /home/user/project/reports/report-1422480068261

...

BUILD SUCCESSFUL

Page 62: Gradle plugin, take control of the build

archivetest {from "build/report"into "/tmp/archives"

}

RUN IT

$ gradle test

...

Reports copied into /home/user/project/reports/report-1422480068261

...

BUILD SUCCESSFUL

Yay!

Page 63: Gradle plugin, take control of the build

RUN IT

archivetest {from "build/report"into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

Page 64: Gradle plugin, take control of the build

RUN IT

archivetest {from "build/report"into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

Copy after the hello task

Page 65: Gradle plugin, take control of the build

RUN IT

archivetest {from "build/report"into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

Copy after the hello task

Create the hello task

Page 66: Gradle plugin, take control of the build

$ gradle hello

archivetest {from "build/report"into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

RUN IT

Page 67: Gradle plugin, take control of the build

RUN IT

$ gradle hello

...

BUILD SUCCESSFUL

archivetest {from "build/report"into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

No copy

Page 68: Gradle plugin, take control of the build

RUN IT

$ gradle hello

...

BUILD SUCCESSFUL

archivetest {from "build/report"into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

Oh no...

Page 69: Gradle plugin, take control of the build

To figure out you have to

Page 70: Gradle plugin, take control of the build

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

DEBUG IT

The user’s build.gradle

Page 71: Gradle plugin, take control of the build

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

DEBUG IT

The user’s build.gradleCall apply() on ArchiveTestPlugin

Page 72: Gradle plugin, take control of the build

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

DEBUG IT

The user’s build.gradleCall apply() on ArchiveTestPlugin- Create the extension - archivetest.task = "test"- Create the copy task- Finalize archivetest.task by achivetest task

Page 73: Gradle plugin, take control of the build

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

DEBUG IT

The user’s build.gradle

Modify the extension content- archivetest.task = "hello"

Call apply() on ArchiveTestPlugin- Create the extension - archivetest.task = "test"- Create the copy task- Finalize archivetest.task by achivetest task

Page 74: Gradle plugin, take control of the build

apply plugin: 'archivetest'

archivetest { from "build/report"

into "/tmp/archives"task "hello"

}

task hello << {println "Sample task"

}

DEBUG IT

The user’s build.gradleCall apply() on ArchiveTestPlugin

Create the hello task

- Create the extension - archivetest.task = "test"- Create the copy task- Finalize archivetest.task by achivetest task

Modify the extension content- archivetest.task = "hello"

Page 75: Gradle plugin, take control of the build

THE TASK GRAPH

Page 76: Gradle plugin, take control of the build

THE TASK GRAPH

Created by Java/Groovy plugin

test

Page 77: Gradle plugin, take control of the build

THE TASK GRAPH

Created by archivetest plugin

test test

archivetest

Page 78: Gradle plugin, take control of the build

THE TASK GRAPH

‘test’ finalized by ‘archivetest’

test test

archivetest

Page 79: Gradle plugin, take control of the build

THE TASK GRAPH

test test

archivetest

test

archivetest

Created by build.gradlehello

Page 80: Gradle plugin, take control of the build

THE TASK GRAPH

test

archivetest

hello Launch hello

Page 81: Gradle plugin, take control of the build

THE TASK GRAPH

test

archivetest

hello Launch hello

Page 82: Gradle plugin, take control of the build

THE TASK GRAPH

test

archivetest

hello Launch hello

Page 83: Gradle plugin, take control of the build

THE TASK GRAPH

test

archivetest

hello Launch hello

No link to our copy task

Page 84: Gradle plugin, take control of the build

class ArchiveTestsPlugin implements Plugin<Project> {

void apply(Project project) {

//create the extensionproject.extensions.create(“achivetest”,ArchiveTestPluginExtension,

project)//create the tasks

project.task(name:“achivetest”, type:ArchiveTask){}

//link the tasks to the build chain Task task = project.tasks.getByName(project.archivetest.task) task.finalizedBy “achivetest”

}}

DEBUG IT

The Plugin class

Page 85: Gradle plugin, take control of the build

class ArchiveTestsPlugin implements Plugin<Project> {

void apply(Project project) {

//create the extensionproject.extensions.create(“achivetest”,ArchiveTestPluginExtension,

project)//create the tasks

project.task(name:“achivetest”, type:ArchiveTask){}

//link the tasks to the build chain Task task = project.tasks.getByName(project.archivetest.task) task.finalizedBy “achivetest”

}}

DEBUG IT

The Plugin class

Executed too early

Page 86: Gradle plugin, take control of the build

DEBUG IT

InitializationChoose project(s) to build

ConfigurationExecute build.gradleBuild task graph

ExecutionExecute tasks chain

Gradle build

lifecylcle

Page 87: Gradle plugin, take control of the build

DEBUG IT

Project evaluationbeforeEvaluateafterEvaluate

Task GraphwhenTaskAddedwhenReadybeforeTaskafterTask

The lifecycleevents

Page 88: Gradle plugin, take control of the build

class ArchiveTestsPlugin implements Plugin<Project> {

void apply(Project project) {

...

//link the tasks to the build chain Task task = project.tasks.getByName(project.archivetest.task) task.finalizedBy “achivetest”

}}

DEBUG IT

The Plugin class

Page 89: Gradle plugin, take control of the build

class ArchiveTestsPlugin implements Plugin<Project> {

void apply(Project project) {

...

//link the tasks to the build chainproject.afterEvaluate {

Task task = project.tasks.getByName(project.archivetest.task) task.finalizedBy “achivetest”

}}

}

DEBUG IT

The Plugin class

We add the task after the evaluation

Page 90: Gradle plugin, take control of the build

THE TASK GRAPH

test

archivetest

hello

Page 91: Gradle plugin, take control of the build

THE TASK GRAPH

test

archivetest

hello

Yay!

Page 92: Gradle plugin, take control of the build

TEST IT06

Page 93: Gradle plugin, take control of the build

Very simpleAs simple as Groovy is

Groovy is your best friendA language very easy to mock

Junit & coAs anybody knows

TEST IT

Gradle project testing

Page 94: Gradle plugin, take control of the build

ProjectBuilderTo create a mock project

EvaluateTo execute your mocked build script

A few specificities

TEST IT

Page 95: Gradle plugin, take control of the build

TEST IT

Page 96: Gradle plugin, take control of the build

TEST IT

Adding a test class

Page 97: Gradle plugin, take control of the build

TEST IT

Adding a test class

Adding junit dependency

Page 98: Gradle plugin, take control of the build

TEST IT

Our buid.gradle

...

repositories { jcenter()}

dependencies { testCompile 'junit:junit:4.11'}

...

Page 99: Gradle plugin, take control of the build

TEST IT

Our buid.gradle

...

repositories { jcenter()}

dependencies { testCompile 'junit:junit:4.11'}

...

Adding maven central repository

Page 100: Gradle plugin, take control of the build

TEST IT

Our buid.gradle

...

repositories { jcenter()}

dependencies { testCompile 'junit:junit:4.11'}

...

Adding junit as testing dependency

Page 101: Gradle plugin, take control of the build

Now, test the extension

Page 102: Gradle plugin, take control of the build

TEST IT

Your first test!

class ArchiveTestPluginTest {

@Test public void canAddArchiveTestExtension() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'java' project.apply plugin: 'archivetest'

assert project.archivetest instanceof ArchiveTestPluginExtension }}

Page 103: Gradle plugin, take control of the build

TEST IT

Your first test!

class ArchiveTestPluginTest {

@Test public void canAddArchiveTestExtension() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'java' project.apply plugin: 'archivetest'

assert project.archivetest instanceof ArchiveTestPluginExtension }}

Mock a Gradle project

Page 104: Gradle plugin, take control of the build

TEST IT

Your first test!

class ArchiveTestPluginTest {

@Test public void canAddArchiveTestExtension() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'java' project.apply plugin: 'archivetest'

assert project.archivetest instanceof ArchiveTestPluginExtension }}

Apply Java pluginTo create ‘test’ task

Page 105: Gradle plugin, take control of the build

TEST IT

Your first test!

class ArchiveTestPluginTest {

@Test public void canAddArchiveTestExtension() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'java' project.apply plugin: 'archivetest'

assert project.archivetest instanceof ArchiveTestPluginExtension }}

Apply our plugin

Page 106: Gradle plugin, take control of the build

TEST IT

Your first test!

class ArchiveTestPluginTest {

@Test public void canAddArchiveTestExtension() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'java' project.apply plugin: 'archivetest'

assert project.archivetest instanceof ArchiveTestPluginExtension }}

Test our extension exists

Page 107: Gradle plugin, take control of the build

Now, test the task

Page 108: Gradle plugin, take control of the build

TEST IT

Your second test!

class ArchiveTestPluginTest {

@Test public void canAddArchiveTask() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'java' project.apply plugin: 'archivetest'

assert project.tasks.archivetest instanceof ArchiveTask }}

We initialize our project

Page 109: Gradle plugin, take control of the build

TEST IT

Your second test!

class ArchiveTestPluginTest {

@Test public void canAddArchiveTask() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'java' project.apply plugin: 'archivetest'

assert project.tasks.archivetest instanceof ArchiveTask }}

We test the task

Page 110: Gradle plugin, take control of the build

TEST IT

Run your second test$ gradle test --stacktrace --debug

Page 111: Gradle plugin, take control of the build

TEST IT

Run your second test$ gradle test --stacktrace --debug

...

test.groovy.fr.eyal.ArchiveTestPluginTest > canAddArchiveTask FAILEDMissingPropertyException: Could not find property 'archivetest' on task set

...

BUILD FAILED

Page 112: Gradle plugin, take control of the build

TEST IT

Run your second test$ gradle test --stacktrace --debug

...

test.groovy.fr.eyal.ArchiveTestPluginTest > canAddArchiveTask FAILEDMissingPropertyException: Could not find property 'archivetest' on task set

...

BUILD FAILED

Our task is not created

Page 113: Gradle plugin, take control of the build

class ArchiveTestsPlugin implements Plugin<Project> {

void apply(Project project) {

...

project.afterEvaluate {//create the tasks

project.task(name:“achivetest”, type:ArchiveTask){}

//inject the task Task task = project.tasks.getByName(project.archivetest.task) task.finalizedBy “achivetest”

}}

}

TEST IT

The Plugin class

Tasks are often created after project.evaluate()

Page 114: Gradle plugin, take control of the build

So, evaluate.

Page 115: Gradle plugin, take control of the build

TEST IT

Your first test!

class ArchiveTestPluginTest {

@Test void canAddArchiveTask() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'java' project.apply plugin: 'archivetest' project.evaluate()

assert project.tasks.archivetest instanceof ArchiveTask }} We launch evaluate() on the project

Page 116: Gradle plugin, take control of the build

TEST IT

Run your second test$ gradle test --stacktrace --debug

Page 117: Gradle plugin, take control of the build

TEST IT

Run your second test$ gradle test --stacktrace --debug

...

BUILD SUCCESSFUL

Page 118: Gradle plugin, take control of the build

TEST IT

Run your second test$ gradle test --stacktrace --debug

...

BUILD SUCCESSFUL Yay!

Page 119: Gradle plugin, take control of the build

TEST IT

LUKE DALEYGradleware Principal Engineer

GRADLE FORUM

You don't see this in the API docs for Project because it is an internal method and is therefore potentially subject to change in future releases.

There will be a supported mechanism for doing this kind of thing in the near future.

Page 120: Gradle plugin, take control of the build

TEST IT

LUKE DALEYGradleware Principal Engineer

GRADLE FORUM

You don't see this in the API docs for Project because it is an internal method and is therefore potentially subject to change in future releases.

There will be a supported mechanism for doing this kind of thing in the near future.

June 2011

Page 121: Gradle plugin, take control of the build

IMPROVE IT07

Page 122: Gradle plugin, take control of the build

Plugin Base Javavs. Plugin Java

Defines what is a test tasktasks.withType(Test)

IMPROVE IT

Convention over

Configuration

Page 123: Gradle plugin, take control of the build

Avoid running useless tasksUP-TO-DATE

Declare Inputs@Input, @InputFile, @InputFiles, @InputDirectory

Declare outputs@OutputFile, @OutputDirectory

IMPROVE IT

Incremental builds

Page 124: Gradle plugin, take control of the build

More flexibility of annotations@InputFile String filePath@InputDirectory String directoryPath...

IMPROVE IT

Coming soon

Page 125: Gradle plugin, take control of the build

OnlyIfConditional task execution

IMPROVE IT

Tweaking Execution

Graph

Page 126: Gradle plugin, take control of the build

ArchiveTask() { onlyIf { !parent.state.skipped }}

IMPROVE IT

Page 127: Gradle plugin, take control of the build

Gradle Plugin documentationhttps://gradle.org/documentation

References

Page 128: Gradle plugin, take control of the build

SLIDES http://bit.ly/gradle-plugin-devoxx

Thank you!