Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Guide to build Gradle Plugin for efficient deve...

Guide to build Gradle Plugin for efficient development

Video: https://www.youtube.com/watch?v=Lo326kQt7L8

[Slides in Japanese] This deck will be presented in DroidKaigi 2018, Day 2 6:30-7:00 pm at Room 3.

Yuki Fujisaki

February 09, 2018
Tweet

More Decks by Yuki Fujisaki

Other Decks in Programming

Transcript

  1. Α͘ॻ͘΍ͭ • gitͷϋογϡຒΊࠐΜͩΓ def hash = 'git rev-parse --short HEAD'.

    execute([], project.rootDir).in.text.trim() versionNameSuffix "-$hash"
  2. Hello World!ϓϥάΠϯ class MyPlugin implements Plugin<Project> { @Override void apply(Project

    project) { println "Hello ${project.name}!" } } apply plugin: MyPlugin ✅ ͍͖ͳΓ build.gradle ʹ௚ʹॻ͍ͯOK
  3. Plugin interface public interface Plugin<T> { void apply(T target); }

    • apply plugin: ͨ͠ͱ͖ʹݺͼग़͞ΕΔ • ͢΂ͯΛ͜͜Ͱఆٛ͢Δ • ઃఆΛ௥Ճ͢Δ, ৽͍͠λεΫΛ࡞Δ, ίʔϧόοΫΛઃఆ͢Δ, etc.
  4. classఆٛ + Project#with{}Ͱғͬͯ͋͛Δ ͜͏͡Ό class AutoDebugSuffixPlugin implements Plugin<Project> { void

    apply(Project target) { target.with { android { buildTypes { debug { applicationIdSuffix '.debug' versionNameSuffix '-DEBUG' } } } } } }
  5. Extensionͷ࣮૷ class AutoDebugSuffixExtension { boolean updateVersionName = true // σϑΥϧτtrue

    } • GroovyͳΒ͜Ε͚ͩͰgetter/setter͕ੜ͑Δ • Ϋϥε໊͸ಛʹ੍໿͸ͳ͍ • Extension ͰऴΘΔͷ͕௨ྫ
  6. ProjectʹExtensionΛ௥Ճ void apply(Project target) { def extension = target.extensions.create( "autoDebugSuffix",

    AutoDebuguffixExtension ) } • build.gradle ಺Ͱ autoDebugSuffix {} Λ ఆٛՄೳʹ • if (extension.updateVersionName) Ͱ ධՁ͢Ε͹͍͍…ʁ
  7. class AutoDebugSuffixPlugin implements Plugin<Project> { void apply(Project target) { //

    [2] Projectʹ `autoDebugSuffix {}` ͕ੜ͑Δ def extension = target.extensions.create( "autoDebugSuffix", AutoDebuguffixExtension) // [3] if (extension.updateVersionName) ͯ͠΋ // ·ͩԼͷઃఆ͕ධՁ͞Ε͍ͯͳ͍ } } // [1] ͜͜Ͱ AutoDebugSuffixPlugin#apply() ͕ݺ͹ΕΔ apply plugin: AutoDebugSuffixPlugin // [4] apply ͔Β໭͖ͬͯͯɺҎԼ͕ධՁ͞ΕΔ autoDebugSuffix { updateDisplayVersion false }
  8. [3] ͷ࣌఺Ͱ͸ಈ͔ͳ͍ android { buildTypes { debug { applicationIdSuffix '.debug'

    // ҎԼͷΑ͏ʹॻ͖׵͑ͯ΋ظ଴௨Γʹ͸ಈ͔ͳ͍ if (extension.updateVersionName) { versionNameSuffix '-DEBUG' } } } }
  9. void apply(Project target) { def extension = target.extensions.create( "autoDebugSuffix", AutoDebugSuffixExtension)

    // build.gradleͷධՁ͕ऴΘͬͨޙͰ࣮ߦ͞ΕΔ target.afterEvaluate { project -> project.android { buildTypes { debug { applicationIdSuffix '.debug' // ධՁޙͳͷͰઃఆ஋͕൓ө͞Ε͍ͯΔ if (extension.updateVersionName) { versionNameSuffix '-DEBUG' } } } } } }
  10. λεΫ͸ಈతʹੜ੒Մೳ ྫ: buildTypes ΍ productFlavors buildTypes { debug {}; release

    {} } productFlavors { development {}; production {} } ↓ assembleDevelopmentDebug, assembleDevelopmentRelease, assembleProductionDebug, assembleProductionRelease
  11. ࠓճ࢖͏΋ͷ • AppExtension#applicationVariants • ͢΂ͯͷ ApplicationVariant Λ஌ͬͯΔ • developmentDebug, productionRelease

    ͳͲ • ApplicationVariant: Ϗϧυʹඞཁͳ৘ใ ✅ assemble λεΫʹΞΫηεͰ͖Δ ✅ outputs ͔Βग़ྗϑΝΠϧʹΞΫηεͰ͖Δ
  12. assemble ʹॲཧΛ௥Ճ • applicationVariants.all Ͱྻڍˍ௥Ճ͢Δ void apply(Project target) { target.android.applicationVariants.all

    { v -> v.assemble.doLast { println "${v.outputs.first().outputFile}" } } } • ApplicationVariant#outputs 㱺ग़ྗϑΝΠϧ৘ใ • obb෼ׂ͞ΕΔ࣌͸ෳ਺͋Δ(Ұ൪ઌ಄͕APK)
  13. locateλεΫΛ௥Ճ void apply(Project target) { target.android.applicationVariants.all { v -> target.task("locate${v.name.capitalize()}").doLast

    { ["open", "-R", variant.outputs.first().outputFile]. execute() } } } • ϑΝΠϧͷ৔ॴΛ։͘ʹ͸ Mac: open -R, Windows: explorer • List ʹ execute() ͕ੜ͑ͯΔ
  14. Ϗϧυ׬ྃ࣌ʹFinderΛ։͘ assembleAndLocate* ͱ͍͏λεΫΛ࡞Δ • dependsOn Ͱґଘ͢ΔλεΫΛࢦఆ void apply(Project target) {

    target.android.applicationVariants.all { v -> target.task( "assembleAndLocate${v.name.capitalize()}", dependsOn: v.assemble).doLast { ["open", "-R", v.outputs.first().outputFile]. execute() } } }
  15. ࣮૷ϑΝΠϧ • ͖ͬ͞·Ͱbuild.gradleͷ࡞ͬͯͨ΍ͭΛίϐϖ! class AutoDebugSuffixPlugin implements Plugin<Project> { void apply(Project

    target) { def extension = target.extensions.create( "autoDebugSuffix", AutoDebugSuffixExtension) target.afterEvaluate { project -> project.android.buildTypes.debug { applicationIdSuffix '.debug' if (extension.updateVersionName) versionNameSuffix '-DEBUG' } } } }
  16. Android StudioͰ։͘ • build.gradle ͕Ͱ͖ͨΒ Android Studio Ͱ։͚Δ • ෆ଍͍ͯ͠Δ

    package ΍ import Λิ׬͢Δ • build.gradle ͷதͰ͸େମ import ͞Εͯͯෆཁ
  17. ϩʔΧϧͰ࢖ͬͯΈΑ͏ • mavenϓϥάΠϯͰϩʔΧϧΠϯετʔϧ͢Δ apply plugin: 'maven' group = 'sh.nothing' archivesBaseName

    = 'auto-debug-suffix' version = '0.1.0' • install λεΫ͕࢖͑ΔΑ͏ʹͳΔ ࣮ߦ͢Δͱ $HOME/.m2/repository ͷԼʹ഑ஔ
  18. ࢖ͬͯΈΔ ϩʔΧϧʹଞͷϓϩδΣΫτͷ build.gradle Ͱ buildscript { repositories { mavenLocal() //

    ϩʔΧϧͷϦϙδτϦΛ࢖͑ΔΑ͏ʹ͢Δ } dependencies { classpath 'sh.nothing:auto-debug-suffix:0.1.0' } } ͱॻ͍ͯɺ apply plugin: 'sh.nothing.auto-debug-suffix'
  19. ެ։खॱ 4/5 ެ։ʹඞཁͳઃఆΛॻ͘ pluginBundle { website = 'https://github.com/tnj/auto-debug-suffix' vcsUrl =

    'https://github.com/tnj/auto-debug-suffix' description = 'Automatically add DEBUG suffix...' tags = ['android'] plugins { // ೚ҙͷ໊લͰෳ਺ఆٛՄೳ autoDebugSuffix { id = 'sh.nothing.auto-debug-suffix' displayName = 'Auto Debug Suffix Plugin' } } }
  20. ެ։ͨ͠ϓϥάΠϯͷ࢖͍ํ • ৽͍͠ plugins DSL͕࢖͑Δ dependencies ΍ apply plugin ͕ඞཁͳ͍

    • ࢖͍͍ͨϓϩδΣΫτͷ build.gradle ͷઌ಄ʹ plugins { id "sh.nothing.auto-debug-suffix" version "0.1.0" } ͱॻ͚͹ґଘղܾͱ apply ͕ಉ࣌ʹ׬ྃʂ
  21. plugins DSLʹ͍ͭͯ The feature is technically still incubating, but it

    works well, and should be used by most users. • ʮ΄ͱΜͲͷϢʔβʔʹ͸͕͓ͬͪ͜קΊʯ • ·੍ͩ໿͋Γ • version ʹม਺͕࢖͑ͳ͍ • ଞͷ apply plugin ͱͷ૊Έ߹Θͤ →࣍
  22. ࣮ࡍެ։͠·ͨ͠ ࢖͍ํ plugins { id "sh.nothing.auto-debug-suffix" version "0.1.0" id "sh.nothing.locate-apk"

    version "0.1.0" apply false } apply plugin: 'com.android.application' apply plugin: 'sh.nothing.locate-apk'