Share
Embed
Transcript
44 slides
-
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 *.JAVA class GreeterPlugin implements Plugin<Project> { @Override public void
apply(Project project) { System.out.println("Hello Java!"); } } class GreeterPlugin implements Plugin<Project> { @Override public void 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 -
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 -
SayHelloTask ENTER FILENAME/LANG import 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/LANG import 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/LANG import 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/LANG class 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/plugin/rxviper-gradle-plugi n 3) Books: https://gradle.org/books/