SF JUG - Gradle Lint

  • View
    107

  • Download
    0

Embed Size (px)

Transcript

  • Netflix = freedom and responsibility

    (The assignment operator is intentional)

  • What can Gradle Lint do?

    4 Remove cruft

    4 Bar practices that are universally bad

    4 Sanitize dependencies

    4 Keep Gradle version up-to-date

    4 Auto-fix violations!

  • Gradle Lint in action

    Apply it:allprojects { apply plugin: 'nebula.lint' gradleLint.rules = ['dependency-parentheses', 'dependency-tuple', ...]}

    Run it:./gradlew lintGradle./gradlew build

  • Unused dependencies4 Remove unused first-order dependencies

    4 Add transitive dependencies with compile time references as first-order dependencies

    4 Align fixed first-order dependency versions with transitives when conflict resolved

    4 Shuffle first-order dependencies to the correct configurations (e.g. junit to testCompile)

  • Creating a simple lint rule

    "All wars should be published to our binary repository"

  • 1: Apply immediately after the war plugin

    class AllWarsShouldBePublishedRule extends GradleLintRule {

    @Override void visitApplyPlugin(MethodCallExpression call, String plugin) { if(plugin == 'war') { addLintViolation('WARs must be published') .insertAfter(call, "apply plugin: 'netflix.war-publish'") } }}

  • 2: Apply only if it isn't already applied

    class AllWarsShouldBePublishedRule extends GradleLintRule {

    @Override void visitApplyPlugin(MethodCallExpression call, String plugin) { if(plugin == 'war') bookmark('applyWar', call) else if(plugin == 'netflix.war-publish') bookmark('applyWarPublish', call) }

    @Override protected void visitClassComplete(ClassNode node) { if(bookmark('applyWar') && !bookmark('applyWarPublish')) { addLintViolation('WARs must be published') .insertAfter(bookmark('applyWar'), "apply plugin: 'netflix.war-publish'") }}

  • 3: Replace the war plugin entirely

    class AllWarsShouldBePublishedRule extends GradleLintRule {

    @Override void visitApplyPlugin(MethodCallExpression call, String plugin) { if(plugin == 'war') bookmark('applyWar', call) else if(plugin == 'netflix.war-publish') bookmark('applyWarPublish', call) }

    @Override protected void visitClassComplete(ClassNode node) { if(bookmark('applyWar') && !bookmark('applyWarPublish')) { addLintViolation('WARs must be published') .replaceWith(bookmark('applyWar'), "apply plugin: 'netflix.war-publish'") }}

  • 4: Become Gradle model awareclass AllWarsShouldBePublishedRule extends GradleLintRule implements GradleModelAware {

    @Override void visitApplyPlugin(MethodCallExpression call, String plugin) { bookmark('lastApplyPlugin', call) }

    @Override protected void visitClassComplete(ClassNode node) { if(project.plugins.hasPlugin(WarPlugin) && !project.plugins.hasPlugin('netflix.war-publish')) { addLintViolation('WARs must be published') .insertAfter(bookmark('lastApplyPlugin'), "apply plugin: 'netflix.war-publish'") } }}

  • Resources

    "How We Build Code at Netflix" -- Netflix techblog

    github.com/nebula-plugins/gradle-lint-plugin

    https://github.com/nebula-plugins/gradle-lint-plugin