SlideShare a Scribd company logo
Anatomy of a Gradle plugin
Dmytro Zaitsev
Mobile Team Leader @ Lóhika
#dfua
Build script buildSrc project Standalone project
Script plugins Binary plugin
Build script
Not visible outside the build script
Can’t reuse the plugin outside the build script it’s defined in
Easy to add
Automatically compiled and included in the classpath
buildSrc project
Not visible outside the build
Can’t reuse the plugin outside the build it’s defined in
Has dedicated directory
Automatically compiled and included in the classpath
Visible to every build script used by the build
|____rootProjectDir
| |____buildSrc
| | |____src
| | | |____main
| | | | |____groovy
Standalone project
Can be used in multiple builds
Requires a separate project
Can be published and shared with others
Packaged JAR may include many plugins
Requires an ID (e.g. ‘java’, `com.android.application` etc)
Standalone project
apply plugin: 'groovy'
dependencies {
compile gradleApi()
compile localGroovy()
}
implementation-class=GreeterPlugin
src/main/resources/META-INF/gradle-plugins/greeter.properties
Language
Language
*.JAVA
class GreeterPlugin implements Plugin<Project> {
@Override
public void apply(Project project) {
System.out.println("Hello Java!");
}
}
class GreeterPlugin implements Plugin<Project> {
@Override
def apply(Project project) {
println(‘Hello Groovy!’)
}
}
*.GROOVY
class GreeterPlugin : Plugin<Project> {
override fun apply(project: Project) {
println("Hello Kotlin!")
}
}
*.KOTLIN
class GreeterPlugin extends Plugin[Project] {
override def apply(project: Project) {
println("Hello Scala!")
}
}
*.SCALA
Language
But Groovy is your best
friend here!
GreeterPlugin
ENTER FILENAME/LANG
import org.gradle.api.Plugin
import org.gradle.api.Project
class GreeterPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
println 'Hello World!'
}
}
GreeterPlugin
ENTER FILENAME/LANG
import org.gradle.api.Plugin
import org.gradle.api.Project
class GreeterPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
println 'Hello World!'
}
} Represents an extension to
Gradle
This interface is the main API
you use to interact with Gradle
GreeterPlugin
ENTER FILENAME/LANG
import org.gradle.api.Plugin
import org.gradle.api.Project
class GreeterPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
println 'Hello World!'
}
}
GreeterPlugin
ENTER FILENAME/LANG
class GreeterPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.tasks.create('sayHello') {
group 'greeter'
description 'Says hello'
doLast {
println 'Hello World!'
}
}
}
}
TaskContainer
Task name
Task action
$ gradle tasks -q
ENTER FILENAME/LANG
------------------------------------------------------------
All tasks runnable from root project
------------------------------------------------------------
Build Setup tasks
-----------------
init - Initializes a new Gradle build.
wrapper - Generates Gradle wrapper files.
Greeter tasks
-------------
sayHello - Says hello
Help tasks
----------
Our task with specified
group and description
$ gradle -q sayHello
ENTER FILENAME/LANG
$ gradle sayHello -q
Hello World!
$
SayHelloTask
ENTER FILENAME/LANGimport org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
class SayHelloTask extends DefaultTask {
@TaskAction
void sayHello() {
println 'Hello World!'
}
}
the standard Task
implementation. You can
extend this to implement
your own task types.
Marks a method as the
action to run when the task
is executed.
GreeterPlugin
ENTER FILENAME/LANG
import org.gradle.api.Plugin
import org.gradle.api.Project
class GreeterPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.tasks.create('sayHello', SayHelloTask) {
group 'greeter'
description 'Says hello'
}
}
}
GreeterPlugin
ENTER FILENAME/LANG
import org.gradle.api.Plugin
import org.gradle.api.Project
class GreeterPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.tasks.create('sayHello', SayHelloTask) {
group 'greeter'
description 'Says hello'
}
}
}
Create the Task of specific type
build.gradle
ENTER FILENAME/LANG
apply plugin: GreeterPlugin
// or apply plugin: `greeter`
greeter {
speaker 'Dmytro Zaitsev'
}
build.gradle
build.gradle
ENTER FILENAME/LANG
apply plugin: GreeterPlugin
greeter {
speaker 'Dmytro Zaitsev'
}
build.gradle
Project extension we need to register
in our plugin
GreeterExtension
ENTER FILENAME/LANG
class GreeterExtension {
@Optional
String speaker = ‘Dmytro Zaitsev`
}
build.gradle
So, we create a class...
GreeterPlugin
ENTER FILENAME/LANG
class GreeterPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
project.extensions.create('greeter', GreeterExtension)
/* … */
}
}
… and register new Project property
ExtensionContainer
SayHelloTask
ENTER FILENAME/LANGimport org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
class SayHelloTask extends DefaultTask {
@TaskAction
void sayHello() {
println "Hello ${project.greeter.speaker}!"
}
}
$ gradle -q sayHello
ENTER FILENAME/LANG
$ gradle sayHello -q
Hello Dmytro Zaitsev!
$
Create a DSL
ENTER FILENAME/LANG
apply plugin: GreeterPlugin
greeter {
addSpeaker('Dmytro Zaitsev', 'Kiev', 'Lohika')
addSpeaker('Jake Wharton', 'San Francisco', 'Square')
addSpeaker('Mateusz Herych', 'Kraków', 'IGcom')
}
build.gradle
UGLY!
Create readable DSL!
ENTER FILENAME/LANG
apply plugin: GreeterPlugin
greeter {
speakers {
‘Dmytro Zaitsev’ {
city 'Kyiv'
company 'Lóhika'
}
‘Jake Wharton’ {
city 'San Francisco'
company 'Square'
}
‘Mateusz Herych’ {
city 'Kraków'
company 'IGcom'
}
}
}
build.gradle
NamedDomainObjectContainer
Domain objects
Speaker domain object
ENTER FILENAME/LANG
class Speaker {
String name
String city
String company
Speaker(String name) {
this.name = name
}
def city(String city) {
this.city = city
}
def company(String company) {
this.company = company
}
}
We need a name property
so the object can be created
by Gradle using a DSL.
GreeterExtension
ENTER FILENAME/LANG
import org.gradle.api. NamedDomainObjectContainer
class GreeterExtension {
NamedDomainObjectContainer <Speaker> speakers
GreeterExtension (NamedDomainObjectContainer <Speaker> speakers) {
this.speakers = speakers
}
def speakers(Closure<NamedDomainObjectContainer <Speaker>> closure) {
this.speakers.configure (closure)
}
}
GreeterExtension.groovy
GreeterExtension
ENTER FILENAME/LANG
import org.gradle.api.NamedDomainObjectContainer
class GreeterExtension {
NamedDomainObjectContainer <Speaker> speakers
GreeterExtension(NamedDomainObjectContainer <Speaker> speakers) {
this.speakers = speakers
}
def speakers(Closure<NamedDomainObjectContainer<Speaker>> closure) {
this.speakers.configure(closure)
}
}
GreeterExtension.groovy
SayHelloTask
ENTER FILENAME/LANGimport org.gradle.api.DefaultTask
import org.gradle.api.tasks.TaskAction
class SayHelloTask extends DefaultTask {
@TaskAction
void sayHello() {
project.greeter.speakers.all {
println "Hello ${it.name}!"
}
}
}
GreeterPlugin
ENTER FILENAME/LANGclass GreeterPlugin implements Plugin<Project> {
@Override
void apply(Project project) {
// add extensions
project.extensions.create ('greeter',
GreeterExtension , project.container(Speaker))
// add tasks
project.tasks.create('sayHello', SayHelloTask) {
group 'greeter'
description 'Says hello'
}
}
}
$ gradle -q sayHello
ENTER FILENAME/LANG
$ gradle sayHello -q
Hello Dmytro Zaitsev!
Hello Jake Wharton!
Hello Mateusz Herych!
$
Extension test
ENTER FILENAME/LANG
class GreeterPluginTest {
@Test
public void canAddGreeterExtension() {
Project project = ProjectBuilder.builder().build()
project.apply plugin: 'greeter'
assert project.greeter instanceof GreeterExtension
}
}
Extension test
ENTER FILENAME/LANG
class GreeterPluginTest {
@Test
public void canAddGreeterExtension() {
Project project = ProjectBuilder.builder().build()
project.apply plugin: 'greeter'
assert project.greeter instanceof GreeterExtension
}
}
Stub a Project
Extension test
ENTER FILENAME/LANG
class GreeterPluginTest {
@Test
public void canAddGreeterExtension() {
Project project = ProjectBuilder.builder().build()
project.apply plugin: 'greeter'
assert project.greeter instanceof GreeterExtension
}
}
Apply the plugin
Extension test
ENTER FILENAME/LANG
class GreeterPluginTest {
@Test
public void canAddGreeterExtension() {
Project project = ProjectBuilder.builder().build()
project.apply plugin: 'greeter'
assert project.greeter instanceof GreeterExtension
}
}
Check that extension exists
Task test
ENTER FILENAME/LANG
class GreeterPluginTest {
@Test
public void canAddSayHelloTask() {
Project project = ProjectBuilder.builder().build()
project.apply plugin: 'greeter'
assert project.tasks.sayHello instanceof SayHelloTask
}
}
Links
1) Official Gradle documentation:
https://docs.gradle.org/current/userguide/custom_plugins.html
2) Example of plugin written in Kotlin:
https://github.com/RxViper/RxViper/tree/1.x/rxviper-gradle-plugin
3) Books:
https://gradle.org/books/
#dfua
Thank you!
Questions?Questions?
@DmitriyZaitsev

More Related Content

What's hot

C++ for Java Developers (SwedenCpp Meetup 2017)
C++ for Java Developers (SwedenCpp Meetup 2017)C++ for Java Developers (SwedenCpp Meetup 2017)
C++ for Java Developers (SwedenCpp Meetup 2017)Patricia Aas
 
Discovering functional treasure in idiomatic Groovy
Discovering functional treasure in idiomatic GroovyDiscovering functional treasure in idiomatic Groovy
Discovering functional treasure in idiomatic GroovyNaresha K
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJosé Paumard
 
Scripting Oracle Develop 2007
Scripting Oracle Develop 2007Scripting Oracle Develop 2007
Scripting Oracle Develop 2007Tugdual Grall
 
Trying to build an Open Source browser in 2020
Trying to build an Open Source browser in 2020Trying to build an Open Source browser in 2020
Trying to build an Open Source browser in 2020Patricia Aas
 
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Ontico
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivitynklmish
 
Kubernetes Scheduler deep dive
Kubernetes Scheduler deep diveKubernetes Scheduler deep dive
Kubernetes Scheduler deep diveDONGJIN KIM
 
What's new in c# 10
What's new in c# 10What's new in c# 10
What's new in c# 10Moaid Hathot
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveepamspb
 
Using Spinnaker to Create a Development Workflow on Kubernetes - Paul Czarkowski
Using Spinnaker to Create a Development Workflow on Kubernetes - Paul CzarkowskiUsing Spinnaker to Create a Development Workflow on Kubernetes - Paul Czarkowski
Using Spinnaker to Create a Development Workflow on Kubernetes - Paul CzarkowskiVMware Tanzu
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)James Titcumb
 
Building High Performance Web Applications and Sites
Building High Performance Web Applications and SitesBuilding High Performance Web Applications and Sites
Building High Performance Web Applications and Sitesgoodfriday
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyDavid Gómez García
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorBartosz Kosarzycki
 
HTTP Middlewares in PHP by Eugene Dounar
HTTP Middlewares in PHP by Eugene DounarHTTP Middlewares in PHP by Eugene Dounar
HTTP Middlewares in PHP by Eugene DounarMinsk PHP User Group
 

What's hot (20)

C++ for Java Developers (SwedenCpp Meetup 2017)
C++ for Java Developers (SwedenCpp Meetup 2017)C++ for Java Developers (SwedenCpp Meetup 2017)
C++ for Java Developers (SwedenCpp Meetup 2017)
 
Java objects on steroids
Java objects on steroidsJava objects on steroids
Java objects on steroids
 
Discovering functional treasure in idiomatic Groovy
Discovering functional treasure in idiomatic GroovyDiscovering functional treasure in idiomatic Groovy
Discovering functional treasure in idiomatic Groovy
 
JAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) BridgeJAX-RS and CDI Bike the (Reactive) Bridge
JAX-RS and CDI Bike the (Reactive) Bridge
 
Scripting Oracle Develop 2007
Scripting Oracle Develop 2007Scripting Oracle Develop 2007
Scripting Oracle Develop 2007
 
Trying to build an Open Source browser in 2020
Trying to build an Open Source browser in 2020Trying to build an Open Source browser in 2020
Trying to build an Open Source browser in 2020
 
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
Паразитируем на React-экосистеме (Angular 4+) / Алексей Охрименко (IPONWEB)
 
Kotlin boost yourproductivity
Kotlin boost yourproductivityKotlin boost yourproductivity
Kotlin boost yourproductivity
 
Kubernetes
KubernetesKubernetes
Kubernetes
 
Kubernetes Scheduler deep dive
Kubernetes Scheduler deep diveKubernetes Scheduler deep dive
Kubernetes Scheduler deep dive
 
What's new in c# 10
What's new in c# 10What's new in c# 10
What's new in c# 10
 
Mobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast diveMobile Open Day: React Native: Crossplatform fast dive
Mobile Open Day: React Native: Crossplatform fast dive
 
C# Is The Future
C# Is The FutureC# Is The Future
C# Is The Future
 
Using Spinnaker to Create a Development Workflow on Kubernetes - Paul Czarkowski
Using Spinnaker to Create a Development Workflow on Kubernetes - Paul CzarkowskiUsing Spinnaker to Create a Development Workflow on Kubernetes - Paul Czarkowski
Using Spinnaker to Create a Development Workflow on Kubernetes - Paul Czarkowski
 
XML-Motor
XML-MotorXML-Motor
XML-Motor
 
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
Kicking off with Zend Expressive and Doctrine ORM (PHP Srbija 2017)
 
Building High Performance Web Applications and Sites
Building High Performance Web Applications and SitesBuilding High Performance Web Applications and Sites
Building High Performance Web Applications and Sites
 
Leveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results AsynchrhonouslyLeveraging Completable Futures to handle your query results Asynchrhonously
Leveraging Completable Futures to handle your query results Asynchrhonously
 
Daggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processorDaggerate your code - Write your own annotation processor
Daggerate your code - Write your own annotation processor
 
HTTP Middlewares in PHP by Eugene Dounar
HTTP Middlewares in PHP by Eugene DounarHTTP Middlewares in PHP by Eugene Dounar
HTTP Middlewares in PHP by Eugene Dounar
 

Similar to Anatomy of a Gradle plugin

Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingSchalk Cronjé
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingSchalk Cronjé
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionSchalk Cronjé
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingSchalk Cronjé
 
Basic Gradle Plugin Writing
Basic Gradle Plugin WritingBasic Gradle Plugin Writing
Basic Gradle Plugin WritingSchalk Cronjé
 
Idiomatic gradle plugin writing
Idiomatic gradle plugin writingIdiomatic gradle plugin writing
Idiomatic gradle plugin writingSchalk Cronjé
 
Gradle in a Polyglot World
Gradle in a Polyglot WorldGradle in a Polyglot World
Gradle in a Polyglot WorldSchalk Cronjé
 
[DEPRECATED]Gradle the android
[DEPRECATED]Gradle the android[DEPRECATED]Gradle the android
[DEPRECATED]Gradle the androidJun Liu
 
Lightweight Developer Provisioning with Gradle
Lightweight Developer Provisioning with GradleLightweight Developer Provisioning with Gradle
Lightweight Developer Provisioning with GradleQAware GmbH
 
Lightweight Developer Provisioning with Gradle and SEU-as-code
Lightweight Developer Provisioning with Gradle and SEU-as-codeLightweight Developer Provisioning with Gradle and SEU-as-code
Lightweight Developer Provisioning with Gradle and SEU-as-codeMario-Leander Reimer
 
Gradle plugin, take control of the build
Gradle plugin, take control of the buildGradle plugin, take control of the build
Gradle plugin, take control of the buildEyal Lezmy
 
Making the Most of Your Gradle Build
Making the Most of Your Gradle BuildMaking the Most of Your Gradle Build
Making the Most of Your Gradle BuildAndres Almiray
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with GradleRyan Cuprak
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with GradleRyan Cuprak
 
Gradle - small introduction
Gradle - small introductionGradle - small introduction
Gradle - small introductionIgor Popov
 
Making the Most of Your Gradle Build
Making the Most of Your Gradle BuildMaking the Most of Your Gradle Build
Making the Most of Your Gradle BuildAndres Almiray
 

Similar to Anatomy of a Gradle plugin (20)

Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Gradle in 45min
Gradle in 45minGradle in 45min
Gradle in 45min
 
Enter the gradle
Enter the gradleEnter the gradle
Enter the gradle
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Gradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 versionGradle in 45min - JBCN2-16 version
Gradle in 45min - JBCN2-16 version
 
GradleFX
GradleFXGradleFX
GradleFX
 
Idiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin WritingIdiomatic Gradle Plugin Writing
Idiomatic Gradle Plugin Writing
 
Basic Gradle Plugin Writing
Basic Gradle Plugin WritingBasic Gradle Plugin Writing
Basic Gradle Plugin Writing
 
Idiomatic gradle plugin writing
Idiomatic gradle plugin writingIdiomatic gradle plugin writing
Idiomatic gradle plugin writing
 
Gradle in a Polyglot World
Gradle in a Polyglot WorldGradle in a Polyglot World
Gradle in a Polyglot World
 
[DEPRECATED]Gradle the android
[DEPRECATED]Gradle the android[DEPRECATED]Gradle the android
[DEPRECATED]Gradle the android
 
Lightweight Developer Provisioning with Gradle
Lightweight Developer Provisioning with GradleLightweight Developer Provisioning with Gradle
Lightweight Developer Provisioning with Gradle
 
Lightweight Developer Provisioning with Gradle and SEU-as-code
Lightweight Developer Provisioning with Gradle and SEU-as-codeLightweight Developer Provisioning with Gradle and SEU-as-code
Lightweight Developer Provisioning with Gradle and SEU-as-code
 
Gradle plugin, take control of the build
Gradle plugin, take control of the buildGradle plugin, take control of the build
Gradle plugin, take control of the build
 
Making the Most of Your Gradle Build
Making the Most of Your Gradle BuildMaking the Most of Your Gradle Build
Making the Most of Your Gradle Build
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with Gradle
 
Faster Java EE Builds with Gradle
Faster Java EE Builds with GradleFaster Java EE Builds with Gradle
Faster Java EE Builds with Gradle
 
Dart Workshop
Dart WorkshopDart Workshop
Dart Workshop
 
Gradle - small introduction
Gradle - small introductionGradle - small introduction
Gradle - small introduction
 
Making the Most of Your Gradle Build
Making the Most of Your Gradle BuildMaking the Most of Your Gradle Build
Making the Most of Your Gradle Build
 

Recently uploaded

shape functions of 1D and 2 D rectangular elements.pptx
shape functions of 1D and 2 D rectangular elements.pptxshape functions of 1D and 2 D rectangular elements.pptx
shape functions of 1D and 2 D rectangular elements.pptxVishalDeshpande27
 
İTÜ CAD and Reverse Engineering Workshop
İTÜ CAD and Reverse Engineering WorkshopİTÜ CAD and Reverse Engineering Workshop
İTÜ CAD and Reverse Engineering WorkshopEmre Günaydın
 
Quality defects in TMT Bars, Possible causes and Potential Solutions.
Quality defects in TMT Bars, Possible causes and Potential Solutions.Quality defects in TMT Bars, Possible causes and Potential Solutions.
Quality defects in TMT Bars, Possible causes and Potential Solutions.PrashantGoswami42
 
A CASE STUDY ON ONLINE TICKET BOOKING SYSTEM PROJECT.pdf
A CASE STUDY ON ONLINE TICKET BOOKING SYSTEM PROJECT.pdfA CASE STUDY ON ONLINE TICKET BOOKING SYSTEM PROJECT.pdf
A CASE STUDY ON ONLINE TICKET BOOKING SYSTEM PROJECT.pdfKamal Acharya
 
Construction method of steel structure space frame .pptx
Construction method of steel structure space frame .pptxConstruction method of steel structure space frame .pptx
Construction method of steel structure space frame .pptxwendy cai
 
Cloud-Computing_CSE311_Computer-Networking CSE GUB BD - Shahidul.pptx
Cloud-Computing_CSE311_Computer-Networking CSE GUB BD - Shahidul.pptxCloud-Computing_CSE311_Computer-Networking CSE GUB BD - Shahidul.pptx
Cloud-Computing_CSE311_Computer-Networking CSE GUB BD - Shahidul.pptxMd. Shahidul Islam Prodhan
 
CFD Simulation of By-pass Flow in a HRSG module by R&R Consult.pptx
CFD Simulation of By-pass Flow in a HRSG module by R&R Consult.pptxCFD Simulation of By-pass Flow in a HRSG module by R&R Consult.pptx
CFD Simulation of By-pass Flow in a HRSG module by R&R Consult.pptxR&R Consult
 
Halogenation process of chemical process industries
Halogenation process of chemical process industriesHalogenation process of chemical process industries
Halogenation process of chemical process industriesMuhammadTufail242431
 
RS Khurmi Machine Design Clutch and Brake Exercise Numerical Solutions
RS Khurmi Machine Design Clutch and Brake Exercise Numerical SolutionsRS Khurmi Machine Design Clutch and Brake Exercise Numerical Solutions
RS Khurmi Machine Design Clutch and Brake Exercise Numerical SolutionsAtif Razi
 
Electrostatic field in a coaxial transmission line
Electrostatic field in a coaxial transmission lineElectrostatic field in a coaxial transmission line
Electrostatic field in a coaxial transmission lineJulioCesarSalazarHer1
 
2024 DevOps Pro Europe - Growing at the edge
2024 DevOps Pro Europe - Growing at the edge2024 DevOps Pro Europe - Growing at the edge
2024 DevOps Pro Europe - Growing at the edgePaco Orozco
 
Democratizing Fuzzing at Scale by Abhishek Arya
Democratizing Fuzzing at Scale by Abhishek AryaDemocratizing Fuzzing at Scale by Abhishek Arya
Democratizing Fuzzing at Scale by Abhishek Aryaabh.arya
 
School management system project report.pdf
School management system project report.pdfSchool management system project report.pdf
School management system project report.pdfKamal Acharya
 
Courier management system project report.pdf
Courier management system project report.pdfCourier management system project report.pdf
Courier management system project report.pdfKamal Acharya
 
ONLINE VEHICLE RENTAL SYSTEM PROJECT REPORT.pdf
ONLINE VEHICLE RENTAL SYSTEM PROJECT REPORT.pdfONLINE VEHICLE RENTAL SYSTEM PROJECT REPORT.pdf
ONLINE VEHICLE RENTAL SYSTEM PROJECT REPORT.pdfKamal Acharya
 
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdf
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdfONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdf
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdfKamal Acharya
 
Digital Signal Processing Lecture notes n.pdf
Digital Signal Processing Lecture notes n.pdfDigital Signal Processing Lecture notes n.pdf
Digital Signal Processing Lecture notes n.pdfAbrahamGadissa
 
The Benefits and Techniques of Trenchless Pipe Repair.pdf
The Benefits and Techniques of Trenchless Pipe Repair.pdfThe Benefits and Techniques of Trenchless Pipe Repair.pdf
The Benefits and Techniques of Trenchless Pipe Repair.pdfPipe Restoration Solutions
 
NO1 Pandit Amil Baba In Bahawalpur, Sargodha, Sialkot, Sheikhupura, Rahim Yar...
NO1 Pandit Amil Baba In Bahawalpur, Sargodha, Sialkot, Sheikhupura, Rahim Yar...NO1 Pandit Amil Baba In Bahawalpur, Sargodha, Sialkot, Sheikhupura, Rahim Yar...
NO1 Pandit Amil Baba In Bahawalpur, Sargodha, Sialkot, Sheikhupura, Rahim Yar...Amil baba
 

Recently uploaded (20)

shape functions of 1D and 2 D rectangular elements.pptx
shape functions of 1D and 2 D rectangular elements.pptxshape functions of 1D and 2 D rectangular elements.pptx
shape functions of 1D and 2 D rectangular elements.pptx
 
İTÜ CAD and Reverse Engineering Workshop
İTÜ CAD and Reverse Engineering WorkshopİTÜ CAD and Reverse Engineering Workshop
İTÜ CAD and Reverse Engineering Workshop
 
Quality defects in TMT Bars, Possible causes and Potential Solutions.
Quality defects in TMT Bars, Possible causes and Potential Solutions.Quality defects in TMT Bars, Possible causes and Potential Solutions.
Quality defects in TMT Bars, Possible causes and Potential Solutions.
 
A CASE STUDY ON ONLINE TICKET BOOKING SYSTEM PROJECT.pdf
A CASE STUDY ON ONLINE TICKET BOOKING SYSTEM PROJECT.pdfA CASE STUDY ON ONLINE TICKET BOOKING SYSTEM PROJECT.pdf
A CASE STUDY ON ONLINE TICKET BOOKING SYSTEM PROJECT.pdf
 
Construction method of steel structure space frame .pptx
Construction method of steel structure space frame .pptxConstruction method of steel structure space frame .pptx
Construction method of steel structure space frame .pptx
 
Cloud-Computing_CSE311_Computer-Networking CSE GUB BD - Shahidul.pptx
Cloud-Computing_CSE311_Computer-Networking CSE GUB BD - Shahidul.pptxCloud-Computing_CSE311_Computer-Networking CSE GUB BD - Shahidul.pptx
Cloud-Computing_CSE311_Computer-Networking CSE GUB BD - Shahidul.pptx
 
CFD Simulation of By-pass Flow in a HRSG module by R&R Consult.pptx
CFD Simulation of By-pass Flow in a HRSG module by R&R Consult.pptxCFD Simulation of By-pass Flow in a HRSG module by R&R Consult.pptx
CFD Simulation of By-pass Flow in a HRSG module by R&R Consult.pptx
 
Halogenation process of chemical process industries
Halogenation process of chemical process industriesHalogenation process of chemical process industries
Halogenation process of chemical process industries
 
Standard Reomte Control Interface - Neometrix
Standard Reomte Control Interface - NeometrixStandard Reomte Control Interface - Neometrix
Standard Reomte Control Interface - Neometrix
 
RS Khurmi Machine Design Clutch and Brake Exercise Numerical Solutions
RS Khurmi Machine Design Clutch and Brake Exercise Numerical SolutionsRS Khurmi Machine Design Clutch and Brake Exercise Numerical Solutions
RS Khurmi Machine Design Clutch and Brake Exercise Numerical Solutions
 
Electrostatic field in a coaxial transmission line
Electrostatic field in a coaxial transmission lineElectrostatic field in a coaxial transmission line
Electrostatic field in a coaxial transmission line
 
2024 DevOps Pro Europe - Growing at the edge
2024 DevOps Pro Europe - Growing at the edge2024 DevOps Pro Europe - Growing at the edge
2024 DevOps Pro Europe - Growing at the edge
 
Democratizing Fuzzing at Scale by Abhishek Arya
Democratizing Fuzzing at Scale by Abhishek AryaDemocratizing Fuzzing at Scale by Abhishek Arya
Democratizing Fuzzing at Scale by Abhishek Arya
 
School management system project report.pdf
School management system project report.pdfSchool management system project report.pdf
School management system project report.pdf
 
Courier management system project report.pdf
Courier management system project report.pdfCourier management system project report.pdf
Courier management system project report.pdf
 
ONLINE VEHICLE RENTAL SYSTEM PROJECT REPORT.pdf
ONLINE VEHICLE RENTAL SYSTEM PROJECT REPORT.pdfONLINE VEHICLE RENTAL SYSTEM PROJECT REPORT.pdf
ONLINE VEHICLE RENTAL SYSTEM PROJECT REPORT.pdf
 
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdf
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdfONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdf
ONLINE CAR SERVICING SYSTEM PROJECT REPORT.pdf
 
Digital Signal Processing Lecture notes n.pdf
Digital Signal Processing Lecture notes n.pdfDigital Signal Processing Lecture notes n.pdf
Digital Signal Processing Lecture notes n.pdf
 
The Benefits and Techniques of Trenchless Pipe Repair.pdf
The Benefits and Techniques of Trenchless Pipe Repair.pdfThe Benefits and Techniques of Trenchless Pipe Repair.pdf
The Benefits and Techniques of Trenchless Pipe Repair.pdf
 
NO1 Pandit Amil Baba In Bahawalpur, Sargodha, Sialkot, Sheikhupura, Rahim Yar...
NO1 Pandit Amil Baba In Bahawalpur, Sargodha, Sialkot, Sheikhupura, Rahim Yar...NO1 Pandit Amil Baba In Bahawalpur, Sargodha, Sialkot, Sheikhupura, Rahim Yar...
NO1 Pandit Amil Baba In Bahawalpur, Sargodha, Sialkot, Sheikhupura, Rahim Yar...
 

Anatomy of a Gradle plugin

  • 1. Anatomy of a Gradle plugin Dmytro Zaitsev Mobile Team Leader @ Lóhika
  • 3. Build script buildSrc project Standalone project Script plugins Binary plugin
  • 4. Build script Not visible outside the build script Can’t reuse the plugin outside the build script it’s defined in Easy to add Automatically compiled and included in the classpath
  • 5. buildSrc project Not visible outside the build Can’t reuse the plugin outside the build it’s defined in Has dedicated directory Automatically compiled and included in the classpath Visible to every build script used by the build |____rootProjectDir | |____buildSrc | | |____src | | | |____main | | | | |____groovy
  • 6. Standalone project Can be used in multiple builds Requires a separate project Can be published and shared with others Packaged JAR may include many plugins Requires an ID (e.g. ‘java’, `com.android.application` etc)
  • 7. Standalone project apply plugin: 'groovy' dependencies { compile gradleApi() compile localGroovy() } implementation-class=GreeterPlugin src/main/resources/META-INF/gradle-plugins/greeter.properties
  • 9. Language *.JAVA class GreeterPlugin implements Plugin<Project> { @Override public void apply(Project project) { System.out.println("Hello Java!"); } } class GreeterPlugin implements Plugin<Project> { @Override def apply(Project project) { println(‘Hello Groovy!’) } } *.GROOVY class GreeterPlugin : Plugin<Project> { override fun apply(project: Project) { println("Hello Kotlin!") } } *.KOTLIN class GreeterPlugin extends Plugin[Project] { override def apply(project: Project) { println("Hello Scala!") } } *.SCALA
  • 10. Language But Groovy is your best friend here!
  • 11.
  • 12. GreeterPlugin ENTER FILENAME/LANG import org.gradle.api.Plugin import org.gradle.api.Project class GreeterPlugin implements Plugin<Project> { @Override void apply(Project project) { println 'Hello World!' } }
  • 13. GreeterPlugin ENTER FILENAME/LANG import org.gradle.api.Plugin import org.gradle.api.Project class GreeterPlugin implements Plugin<Project> { @Override void apply(Project project) { println 'Hello World!' } } Represents an extension to Gradle This interface is the main API you use to interact with Gradle
  • 14. GreeterPlugin ENTER FILENAME/LANG import org.gradle.api.Plugin import org.gradle.api.Project class GreeterPlugin implements Plugin<Project> { @Override void apply(Project project) { println 'Hello World!' } }
  • 15. GreeterPlugin ENTER FILENAME/LANG class GreeterPlugin implements Plugin<Project> { @Override void apply(Project project) { project.tasks.create('sayHello') { group 'greeter' description 'Says hello' doLast { println 'Hello World!' } } } } TaskContainer Task name Task action
  • 16. $ gradle tasks -q ENTER FILENAME/LANG ------------------------------------------------------------ All tasks runnable from root project ------------------------------------------------------------ Build Setup tasks ----------------- init - Initializes a new Gradle build. wrapper - Generates Gradle wrapper files. Greeter tasks ------------- sayHello - Says hello Help tasks ---------- Our task with specified group and description
  • 17. $ gradle -q sayHello ENTER FILENAME/LANG $ gradle sayHello -q Hello World! $
  • 18. SayHelloTask ENTER FILENAME/LANGimport org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction class SayHelloTask extends DefaultTask { @TaskAction void sayHello() { println 'Hello World!' } } the standard Task implementation. You can extend this to implement your own task types. Marks a method as the action to run when the task is executed.
  • 19. GreeterPlugin ENTER FILENAME/LANG import org.gradle.api.Plugin import org.gradle.api.Project class GreeterPlugin implements Plugin<Project> { @Override void apply(Project project) { project.tasks.create('sayHello', SayHelloTask) { group 'greeter' description 'Says hello' } } }
  • 20. GreeterPlugin ENTER FILENAME/LANG import org.gradle.api.Plugin import org.gradle.api.Project class GreeterPlugin implements Plugin<Project> { @Override void apply(Project project) { project.tasks.create('sayHello', SayHelloTask) { group 'greeter' description 'Says hello' } } } Create the Task of specific type
  • 21. build.gradle ENTER FILENAME/LANG apply plugin: GreeterPlugin // or apply plugin: `greeter` greeter { speaker 'Dmytro Zaitsev' } build.gradle
  • 22. build.gradle ENTER FILENAME/LANG apply plugin: GreeterPlugin greeter { speaker 'Dmytro Zaitsev' } build.gradle Project extension we need to register in our plugin
  • 23. GreeterExtension ENTER FILENAME/LANG class GreeterExtension { @Optional String speaker = ‘Dmytro Zaitsev` } build.gradle So, we create a class...
  • 24. GreeterPlugin ENTER FILENAME/LANG class GreeterPlugin implements Plugin<Project> { @Override void apply(Project project) { project.extensions.create('greeter', GreeterExtension) /* … */ } } … and register new Project property ExtensionContainer
  • 25. SayHelloTask ENTER FILENAME/LANGimport org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction class SayHelloTask extends DefaultTask { @TaskAction void sayHello() { println "Hello ${project.greeter.speaker}!" } }
  • 26. $ gradle -q sayHello ENTER FILENAME/LANG $ gradle sayHello -q Hello Dmytro Zaitsev! $
  • 27.
  • 28. Create a DSL ENTER FILENAME/LANG apply plugin: GreeterPlugin greeter { addSpeaker('Dmytro Zaitsev', 'Kiev', 'Lohika') addSpeaker('Jake Wharton', 'San Francisco', 'Square') addSpeaker('Mateusz Herych', 'Kraków', 'IGcom') } build.gradle UGLY!
  • 29. Create readable DSL! ENTER FILENAME/LANG apply plugin: GreeterPlugin greeter { speakers { ‘Dmytro Zaitsev’ { city 'Kyiv' company 'Lóhika' } ‘Jake Wharton’ { city 'San Francisco' company 'Square' } ‘Mateusz Herych’ { city 'Kraków' company 'IGcom' } } } build.gradle NamedDomainObjectContainer Domain objects
  • 30. Speaker domain object ENTER FILENAME/LANG class Speaker { String name String city String company Speaker(String name) { this.name = name } def city(String city) { this.city = city } def company(String company) { this.company = company } } We need a name property so the object can be created by Gradle using a DSL.
  • 31. GreeterExtension ENTER FILENAME/LANG import org.gradle.api. NamedDomainObjectContainer class GreeterExtension { NamedDomainObjectContainer <Speaker> speakers GreeterExtension (NamedDomainObjectContainer <Speaker> speakers) { this.speakers = speakers } def speakers(Closure<NamedDomainObjectContainer <Speaker>> closure) { this.speakers.configure (closure) } } GreeterExtension.groovy
  • 32. GreeterExtension ENTER FILENAME/LANG import org.gradle.api.NamedDomainObjectContainer class GreeterExtension { NamedDomainObjectContainer <Speaker> speakers GreeterExtension(NamedDomainObjectContainer <Speaker> speakers) { this.speakers = speakers } def speakers(Closure<NamedDomainObjectContainer<Speaker>> closure) { this.speakers.configure(closure) } } GreeterExtension.groovy
  • 33. SayHelloTask ENTER FILENAME/LANGimport org.gradle.api.DefaultTask import org.gradle.api.tasks.TaskAction class SayHelloTask extends DefaultTask { @TaskAction void sayHello() { project.greeter.speakers.all { println "Hello ${it.name}!" } } }
  • 34. GreeterPlugin ENTER FILENAME/LANGclass GreeterPlugin implements Plugin<Project> { @Override void apply(Project project) { // add extensions project.extensions.create ('greeter', GreeterExtension , project.container(Speaker)) // add tasks project.tasks.create('sayHello', SayHelloTask) { group 'greeter' description 'Says hello' } } }
  • 35. $ gradle -q sayHello ENTER FILENAME/LANG $ gradle sayHello -q Hello Dmytro Zaitsev! Hello Jake Wharton! Hello Mateusz Herych! $
  • 36.
  • 37. Extension test ENTER FILENAME/LANG class GreeterPluginTest { @Test public void canAddGreeterExtension() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'greeter' assert project.greeter instanceof GreeterExtension } }
  • 38. Extension test ENTER FILENAME/LANG class GreeterPluginTest { @Test public void canAddGreeterExtension() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'greeter' assert project.greeter instanceof GreeterExtension } } Stub a Project
  • 39. Extension test ENTER FILENAME/LANG class GreeterPluginTest { @Test public void canAddGreeterExtension() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'greeter' assert project.greeter instanceof GreeterExtension } } Apply the plugin
  • 40. Extension test ENTER FILENAME/LANG class GreeterPluginTest { @Test public void canAddGreeterExtension() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'greeter' assert project.greeter instanceof GreeterExtension } } Check that extension exists
  • 41. Task test ENTER FILENAME/LANG class GreeterPluginTest { @Test public void canAddSayHelloTask() { Project project = ProjectBuilder.builder().build() project.apply plugin: 'greeter' assert project.tasks.sayHello instanceof SayHelloTask } }
  • 42. Links 1) Official Gradle documentation: https://docs.gradle.org/current/userguide/custom_plugins.html 2) Example of plugin written in Kotlin: https://github.com/RxViper/RxViper/tree/1.x/rxviper-gradle-plugin 3) Books: https://gradle.org/books/
  • 43. #dfua