SlideShare uma empresa Scribd logo
1 de 44
Baixar para ler offline
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

Mais conteúdo relacionado

Mais procurados

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
 

Mais procurados (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
 

Semelhante a 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
 

Semelhante a 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
 

Último

Block diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptBlock diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptNANDHAKUMARA10
 
Rums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdfRums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdfsmsksolar
 
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills KuwaitKuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwaitjaanualu31
 
Computer Lecture 01.pptxIntroduction to Computers
Computer Lecture 01.pptxIntroduction to ComputersComputer Lecture 01.pptxIntroduction to Computers
Computer Lecture 01.pptxIntroduction to ComputersMairaAshraf6
 
Computer Networks Basics of Network Devices
Computer Networks  Basics of Network DevicesComputer Networks  Basics of Network Devices
Computer Networks Basics of Network DevicesChandrakantDivate1
 
Design For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startDesign For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startQuintin Balsdon
 
Generative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTGenerative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTbhaskargani46
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Servicemeghakumariji156
 
Bridge Jacking Design Sample Calculation.pptx
Bridge Jacking Design Sample Calculation.pptxBridge Jacking Design Sample Calculation.pptx
Bridge Jacking Design Sample Calculation.pptxnuruddin69
 
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptxS1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptxSCMS School of Architecture
 
Minimum and Maximum Modes of microprocessor 8086
Minimum and Maximum Modes of microprocessor 8086Minimum and Maximum Modes of microprocessor 8086
Minimum and Maximum Modes of microprocessor 8086anil_gaur
 
Air Compressor reciprocating single stage
Air Compressor reciprocating single stageAir Compressor reciprocating single stage
Air Compressor reciprocating single stageAbc194748
 
A Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna MunicipalityA Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna MunicipalityMorshed Ahmed Rahath
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfJiananWang21
 
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments""Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"mphochane1998
 
Learn the concepts of Thermodynamics on Magic Marks
Learn the concepts of Thermodynamics on Magic MarksLearn the concepts of Thermodynamics on Magic Marks
Learn the concepts of Thermodynamics on Magic MarksMagic Marks
 
notes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.pptnotes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.pptMsecMca
 
kiln thermal load.pptx kiln tgermal load
kiln thermal load.pptx kiln tgermal loadkiln thermal load.pptx kiln tgermal load
kiln thermal load.pptx kiln tgermal loadhamedmustafa094
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.Kamal Acharya
 
DeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesDeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesMayuraD1
 

Último (20)

Block diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.pptBlock diagram reduction techniques in control systems.ppt
Block diagram reduction techniques in control systems.ppt
 
Rums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdfRums floating Omkareshwar FSPV IM_16112021.pdf
Rums floating Omkareshwar FSPV IM_16112021.pdf
 
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills KuwaitKuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
Kuwait City MTP kit ((+919101817206)) Buy Abortion Pills Kuwait
 
Computer Lecture 01.pptxIntroduction to Computers
Computer Lecture 01.pptxIntroduction to ComputersComputer Lecture 01.pptxIntroduction to Computers
Computer Lecture 01.pptxIntroduction to Computers
 
Computer Networks Basics of Network Devices
Computer Networks  Basics of Network DevicesComputer Networks  Basics of Network Devices
Computer Networks Basics of Network Devices
 
Design For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the startDesign For Accessibility: Getting it right from the start
Design For Accessibility: Getting it right from the start
 
Generative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPTGenerative AI or GenAI technology based PPT
Generative AI or GenAI technology based PPT
 
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best ServiceTamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
Tamil Call Girls Bhayandar WhatsApp +91-9930687706, Best Service
 
Bridge Jacking Design Sample Calculation.pptx
Bridge Jacking Design Sample Calculation.pptxBridge Jacking Design Sample Calculation.pptx
Bridge Jacking Design Sample Calculation.pptx
 
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptxS1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
S1S2 B.Arch MGU - HOA1&2 Module 3 -Temple Architecture of Kerala.pptx
 
Minimum and Maximum Modes of microprocessor 8086
Minimum and Maximum Modes of microprocessor 8086Minimum and Maximum Modes of microprocessor 8086
Minimum and Maximum Modes of microprocessor 8086
 
Air Compressor reciprocating single stage
Air Compressor reciprocating single stageAir Compressor reciprocating single stage
Air Compressor reciprocating single stage
 
A Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna MunicipalityA Study of Urban Area Plan for Pabna Municipality
A Study of Urban Area Plan for Pabna Municipality
 
data_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdfdata_management_and _data_science_cheat_sheet.pdf
data_management_and _data_science_cheat_sheet.pdf
 
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments""Lesotho Leaps Forward: A Chronicle of Transformative Developments"
"Lesotho Leaps Forward: A Chronicle of Transformative Developments"
 
Learn the concepts of Thermodynamics on Magic Marks
Learn the concepts of Thermodynamics on Magic MarksLearn the concepts of Thermodynamics on Magic Marks
Learn the concepts of Thermodynamics on Magic Marks
 
notes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.pptnotes on Evolution Of Analytic Scalability.ppt
notes on Evolution Of Analytic Scalability.ppt
 
kiln thermal load.pptx kiln tgermal load
kiln thermal load.pptx kiln tgermal loadkiln thermal load.pptx kiln tgermal load
kiln thermal load.pptx kiln tgermal load
 
Employee leave management system project.
Employee leave management system project.Employee leave management system project.
Employee leave management system project.
 
DeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakesDeepFakes presentation : brief idea of DeepFakes
DeepFakes presentation : brief idea of DeepFakes
 

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