creating gradle plugins - gr8conf us

70
Gradle Plugin Goodness

Upload: annyce-davis

Post on 21-Jan-2018

308 views

Category:

Software


0 download

TRANSCRIPT

Page 1: Creating Gradle Plugins - GR8Conf US

Gradle Plugin Goodness

Page 2: Creating Gradle Plugins - GR8Conf US

@BRWNGRLDEV

Page 3: Creating Gradle Plugins - GR8Conf US

@BRWNGRLDEV

Page 4: Creating Gradle Plugins - GR8Conf US

apply plugin: 'checkstyle'apply plugin: 'findbugs'apply plugin: 'pmd'task checkstyle(type: Checkstyle) { description 'Checks if the code is somewhat acceptable' group 'verification' configFile file('./qa-check/checkstyle.xml') source 'src' include '**/*.java' exclude '**/gen/**' classpath = files() ignoreFailures = false}task findbugs(type: FindBugs) { description 'Run findbugs'

Page 5: Creating Gradle Plugins - GR8Conf US

apply plugin: 'checkstyle'apply plugin: 'findbugs'apply plugin: 'pmd'task checkstyle(type: Checkstyle) { description 'Checks if the code is somewhat acceptable' group 'verification' configFile file('./qa-check/checkstyle.xml') source 'src' include '**/*.java' exclude '**/gen/**' classpath = files() ignoreFailures = false}task findbugs(type: FindBugs) { description 'Run findbugs' group 'verification' classes = files("$project.buildDir/intermediates/classes") source 'src' classpath = files() effort 'max' excludeFilter file('./qa-check/findbugs-exclude.xml') reports { xml.enabled = true html.enabled = false } ignoreFailures = true}task pmd(type: Pmd) { description 'Run PMD' group 'verification' ruleSetFiles = files("./qa-check/pmd-ruleset.xml") ruleSets = [] source 'src' include '**/*.java' exclude '**/gen/**' reports { xml.enabled = false html.enabled = true } ignoreFailures = true}

apply plugin: 'info.adavis.qualitychecks'

Page 6: Creating Gradle Plugins - GR8Conf US

OVERVIEW

▸Plugin Skeleton

▸Dependencies

▸Plugin.groovy

▸CustomTask.groovy

▸Publishing

@BRWNGRLDEV

Page 7: Creating Gradle Plugins - GR8Conf US

PLUGIN SKELETON@BRWNGRLDEV

Page 8: Creating Gradle Plugins - GR8Conf US

PLUGIN SKELETON

@BRWNGRLDEV

Page 9: Creating Gradle Plugins - GR8Conf US

PLUGIN SKELETON

@BRWNGRLDEV

Page 10: Creating Gradle Plugins - GR8Conf US

PLUGIN SKELETON

How Gradle finds the Plugin Implementation

@BRWNGRLDEV

Page 11: Creating Gradle Plugins - GR8Conf US

PLUGIN SKELETON

implementation-class=info.adavis.qualitychecks.QualityChecksPlugin

@BRWNGRLDEV

Page 12: Creating Gradle Plugins - GR8Conf US

DEPENDENCIES@BRWNGRLDEV

Page 13: Creating Gradle Plugins - GR8Conf US

DEPENDENCIES

apply plugin: ‘groovy'

dependencies {

compile gradleApi()

compile localGroovy()

}

@BRWNGRLDEV

Page 14: Creating Gradle Plugins - GR8Conf US

DEPENDENCIES

dependencies {

testCompile 'junit:junit:4.12' testCompile ('org.spockframework:spock-core:1.0-groovy-2.4') { exclude module: 'groovy-all' }

}

@BRWNGRLDEV

Page 15: Creating Gradle Plugins - GR8Conf US

THE CODE@BRWNGRLDEV

Page 16: Creating Gradle Plugins - GR8Conf US

BUT FIRST…@BRWNGRLDEV

Page 17: Creating Gradle Plugins - GR8Conf US

GRADLE BUILD

@BRWNGRLDEV

PROJECT

TASK TASK TASK

BUILD

Page 18: Creating Gradle Plugins - GR8Conf US

GRADLE BUILD

@BRWNGRLDEV

PROJECT

TASK TASK TASK

BUILD

PROJECT

TASK TASK TASK

Page 19: Creating Gradle Plugins - GR8Conf US

PLUGIN.GROOVY

class CustomPlugin implements Plugin<Project> {

}

@BRWNGRLDEV

Page 20: Creating Gradle Plugins - GR8Conf US

PLUGIN.GROOVY

class CustomPlugin implements Plugin<Project> {

@Override

void apply(Project project) {

}

}

@BRWNGRLDEV

Page 21: Creating Gradle Plugins - GR8Conf US

QUALITYCHECKSPLUGIN.GROOVY

@BRWNGRLDEV

Page 22: Creating Gradle Plugins - GR8Conf US

APPLY METHOD

@BRWNGRLDEV

void apply(Project project) { this.project = project

}

Page 23: Creating Gradle Plugins - GR8Conf US

APPLY METHOD

@BRWNGRLDEV

void apply(Project project) { this.project = project project.extensions.create('qualityChecks', QualityChecksExtension)

}

Page 24: Creating Gradle Plugins - GR8Conf US

APPLY METHOD

@BRWNGRLDEV

void apply(Project project) { this.project = project project.extensions.create('qualityChecks', QualityChecksExtension) createConfigFilesIfNeeded() createConfigFileTasks() createQualityChecksTasks()}

Page 25: Creating Gradle Plugins - GR8Conf US

PROJECT EXTENSION

@BRWNGRLDEV

class QualityChecksExtension { String pmdConfigFile = 'quality-checks/pmd-ruleset.xml' String checkstyleConfigFile = 'quality-checks/checkstyle.xml' String findBugsExclusionFile = 'quality-checks/findbugs-exclude.xml'}

Page 26: Creating Gradle Plugins - GR8Conf US

PROJECT EXTENSION

@BRWNGRLDEV

class QualityChecksExtension { String pmdConfigFile = 'quality-checks/pmd-ruleset.xml' String checkstyleConfigFile = 'quality-checks/checkstyle.xml' String findBugsExclusionFile = 'quality-checks/findbugs-exclude.xml'}

Page 27: Creating Gradle Plugins - GR8Conf US

PROJECT EXTENSION

Back in the application’s build.gradle file…

@BRWNGRLDEV

qualityChecks { pmdConfigFile = ‘checks/pmd.xml’

checkstyleConfigFile = ‘checks/checkstyle.xml’ }

Page 28: Creating Gradle Plugins - GR8Conf US

PROJECT EXTENSION

Back in the application’s build.gradle file…

@BRWNGRLDEV

qualityChecks { pmdConfigFile = ‘checks/pmd.xml’

checkstyleConfigFile = ‘checks/checkstyle.xml’ }

Page 29: Creating Gradle Plugins - GR8Conf US

TASKS@BRWNGRLDEV

Page 30: Creating Gradle Plugins - GR8Conf US

CREATING TASKS

Give it a name and a type

@BRWNGRLDEV

Page 31: Creating Gradle Plugins - GR8Conf US

CREATING TASKS

@BRWNGRLDEV

▸Build on existing task

▸Extend the DefaultTask

Page 32: Creating Gradle Plugins - GR8Conf US

BUILD ON EXISTING TASK

@BRWNGRLDEV

Page 33: Creating Gradle Plugins - GR8Conf US

BUILD ON EXISTING

@BRWNGRLDEV

Page 34: Creating Gradle Plugins - GR8Conf US

EXTEND DEFAULT TASK

@BRWNGRLDEV

Page 35: Creating Gradle Plugins - GR8Conf US

CUSTOMTASK.GROOVY

class CustomTask extends DefaultTask {

CustomTask() { group: ‘verification’

}

}

@BRWNGRLDEV

Page 36: Creating Gradle Plugins - GR8Conf US

CUSTOMTASK.GROOVY

class CustomTask extends DefaultTask {

CustomTask() { group: ‘verification’

}

}

@BRWNGRLDEV

Page 37: Creating Gradle Plugins - GR8Conf US

CUSTOMTASK.GROOVY

CustomTask() { group: ‘verification’

onlyIf { // skip under certain conditions }

}

@BRWNGRLDEV

Page 38: Creating Gradle Plugins - GR8Conf US

CUSTOMTASK.GROOVY

@TaskAction def defaultAction() {

description: ‘What my task does’

}

@BRWNGRLDEV

Page 39: Creating Gradle Plugins - GR8Conf US

CUSTOMTASK.GROOVY

@BRWNGRLDEV

@TaskAction def defaultAction() {

description: ‘What my task does’

<do your cool stuff here> }

Page 40: Creating Gradle Plugins - GR8Conf US

GRADLE TASK DOCUMENTATION

@BRWNGRLDEV

Page 41: Creating Gradle Plugins - GR8Conf US

SO FAR…

▸Plugin Skeleton

▸Dependencies

▸Plugin.groovy

▸CustomTask.groovy

@BRWNGRLDEV

Page 42: Creating Gradle Plugins - GR8Conf US

PUBLISHING@BRWNGRLDEV

Page 43: Creating Gradle Plugins - GR8Conf US

PUBLISHING

@BRWNGRLDEV

Page 44: Creating Gradle Plugins - GR8Conf US

PUBLISHING

buildscript { …

dependencies { classpath "com.gradle.publish:plugin-publish-plugin:0.9.4" } }

apply plugin: 'com.gradle.plugin-publish'

@BRWNGRLDEV

Page 45: Creating Gradle Plugins - GR8Conf US

PUBLISHING

version = "0.1.3" group = "info.adavis"

@BRWNGRLDEV

Page 46: Creating Gradle Plugins - GR8Conf US

PUBLISHING

pluginBundle { website = 'https://github.com/adavis/quality-checks' vcsUrl = 'https://github.com/adavis/quality-checks.git' description = 'Gradle Plugin for…’ tags = ['Checkstyle', 'FindBugs', 'PMD']

}

@BRWNGRLDEV

Page 47: Creating Gradle Plugins - GR8Conf US

PUBLISHING

pluginBundle { …

plugins { qualityChecksPlugin { id = 'info.adavis.qualitychecks' displayName = 'Quality Checks Plugin' } }

@BRWNGRLDEV

Page 48: Creating Gradle Plugins - GR8Conf US

@BRWNGRLDEV

Page 49: Creating Gradle Plugins - GR8Conf US

@BRWNGRLDEV

Page 50: Creating Gradle Plugins - GR8Conf US

WE’RE DONE…

WRONG!@BRWNGRLDEV

Page 51: Creating Gradle Plugins - GR8Conf US

WE’RE DONE…

TESTS@BRWNGRLDEV

Page 52: Creating Gradle Plugins - GR8Conf US

TESTING - WITH JUNIT

@Beforevoid setUp() { projectDir = temporaryFolder.root projectDir.mkdirs()

}

@BRWNGRLDEV

Page 53: Creating Gradle Plugins - GR8Conf US

TESTING - WITH JUNIT

@Beforevoid setUp() { projectDir = temporaryFolder.root projectDir.mkdirs() project = ProjectBuilder.builder().withProjectDir(projectDir).build() task = project.tasks.create('writeConfigFile', WriteConfigFileTask)}

@BRWNGRLDEV

Page 54: Creating Gradle Plugins - GR8Conf US

TESTING - WITH JUNIT

@Test void shouldBeAbleToCreateTask() { assertTrue(task instanceof WriteConfigFileTask) }

@BRWNGRLDEV

Page 55: Creating Gradle Plugins - GR8Conf US

TESTING - WITH JUNIT

@Test void pluginShouldBeApplied() { project.apply(plugin: QualityChecksPlugin)

assertNotNull(project.tasks.findByName(‘mytask’)) }

@BRWNGRLDEV

Page 56: Creating Gradle Plugins - GR8Conf US

SPOCK@BRWNGRLDEV

Page 57: Creating Gradle Plugins - GR8Conf US

TESTING - WITH SPOCK

def createCheckstyleTask() { given: "we have a project" def project = ProjectBuilder.builder().build()

}

Page 58: Creating Gradle Plugins - GR8Conf US

TESTING - WITH SPOCKdef createCheckstyleTask() { and: "we apply the extension" project.extensions.create('qualityChecks', QualityChecksExtension) and: "we supply an existing checkstyle config file" project.qualityChecks.checkstyleConfigFile = File.createTempFile('temp', '.xml').path

}

Page 59: Creating Gradle Plugins - GR8Conf US

TESTING - WITH SPOCK

def createCheckstyleTask() {

when: "we create a checkstyle task" def checkstyleTask = project.tasks.create('checkstyle', CheckstyleTask)

}

Page 60: Creating Gradle Plugins - GR8Conf US

TESTING - WITH SPOCKdef createCheckstyleTask() {

then: "it should not replace our previous file" checkstyleTask.configFile.name.startsWith('temp')}

Page 61: Creating Gradle Plugins - GR8Conf US

TESTING - WITH SPOCK

@BRWNGRLDEV

Page 62: Creating Gradle Plugins - GR8Conf US

TESTING - REPORT

@BRWNGRLDEV

Page 63: Creating Gradle Plugins - GR8Conf US

TESTING - SPOCK-REPORT

dependencies {

testCompile( 'com.athaydes:spock-reports:1.2.12' ) { transitive = false }

}

@BRWNGRLDEV

Page 64: Creating Gradle Plugins - GR8Conf US

TESTING - SPOCK-REPORT

@BRWNGRLDEV

Page 65: Creating Gradle Plugins - GR8Conf US

@BRWNGRLDEV

Page 66: Creating Gradle Plugins - GR8Conf US

BONUS: README

@BRWNGRLDEV

Page 67: Creating Gradle Plugins - GR8Conf US

BONUS: README

@BRWNGRLDEV

Page 68: Creating Gradle Plugins - GR8Conf US

BONUS: README

@BRWNGRLDEV

Page 69: Creating Gradle Plugins - GR8Conf US

SUMMARY

▸Helps avoid copy/paste horror

▸Simple project structure

▸Extending DefaultTask

▸Testing techniques

▸Easy to publish

@BRWNGRLDEV

Page 70: Creating Gradle Plugins - GR8Conf US

THANKS!

@brwngrldev

+AnnyceDavis

www.adavis.info

@BRWNGRLDEV