從頭開始開發一個 Gradle 外掛

weixin_34249678發表於2017-06-01

Android 開發離不開 Gradle 構建工具,有時為了在構建過程中完成一些額外的工作,我們必須額外新增寫一些程式碼片段,比如說生成 doc,對構建物進行改名等。當需要寫的程式碼比較多時每次重寫就得不償失了,此時使用 Gradle 外掛就是一個更好的選擇。本文接下來就從頭編寫一個最簡單的 Gradle 外掛開始說起。

開發步驟

以下例項鎖使用的開發環境為 IDEA,開發語言為 Groovy,儘管也可以用 Java 來開發 Gradle 外掛,但是開發時配置繁瑣且效率低,並不推薦使用。

建立工程

使用 IDEA 建立一個基於 Gradle 構建的工程 sample-plugin,並建立子工程 plugin

修改 build.gradle 檔案

注意修改的是子專案的 build.gradle 檔案,而不是根目錄的

apply plugin: 'groovy'

buildscript {
    repositories {
        mavenCentral()
    }
}

repositories {
    mavenCentral()
    mavenLocal()
}

dependencies {
    compile gradleApi()
    compile localGroovy()
    compile 'org.codehaus.groovy:groovy-all:2.3.11'
}

編寫 Plugin 程式碼

在 plugin 工程下新建包含外掛程式碼的 gradle 檔案: greeting.gradle

apply plugin: GreetingPlugin

greeting {
    message = 'Hi'
    greeter = 'Gradle'
}

class GreetingPlugin implements Plugin<Project> {
    void apply(Project project) {
        // Add the 'greeting' extension object
        project.extensions.create("greeting", GreetingPluginExtension)

        // Add a task that uses the configuration
        project.task('hello') << {
            println "${project.greeting.message} from ${project.greeting.greeter}"
        }
    }
}

class GreetingPluginExtension {
    String message
    String greeter
}

以上程式碼建立了一個名為 GreetingPlugin 的外掛,該外掛包含一個名為 hello 的 task。此 Task 負責輸出工程的 greeting 物件下 greeting.messagegreeting.greeter

繼續修改 build.gradle,匯入以上編寫的程式碼

apply from: "greeting.gradle"

執行程式碼

在 plugin 工程下執行以下語句

gradle tasks

可以看到控制檯有輸出語句

Other tasks
-----------
hello

這就是剛才建立的 Gradle Task。接著執行以下語句執行該 Task:

gradle -q hello

成功的話控制檯會輸出 "Hi from Gradle"。至此一個簡單的外掛已經開發完畢,接下來為了在其它工程中使用我們可以先將外掛釋出到本地。

釋出外掛

編寫 Groovy 檔案

上節的 greeting.gradle 檔案只是用於快速開發時使用,正式開發或釋出時我們需要編寫單獨的 Groovy 檔案。

如果需要將上述的程式碼轉換為單獨的 Groovy 檔案只需要執行以下操作:

新建一個名為 GreetingPlugin.groovy 的檔案,將之前的 greeting.build 中的除了 applygreeting() 之外的程式碼都拷貝到該檔案即可。

指定 Short Plugin Id

使用外掛時我們需要指定外掛的 id,如 apply plugin: "Java",這表示使用一個名為 Java 的 Gradle 外掛。預設的 Gradle 外掛 ID 的值為 Plugin 所在的 包名+類名,很顯然這個太長了,所以 Gradle 允許我們通過指定一個 Short ID 來作為別名。

建立 Short ID 的步驟如下

在 plugin 工程的 resources 目錄下建立 META-INF/gradle-plugins 資料夾,在其中建立名為 <shortId>.properties 的檔案

例:

greeting.properties

implementation-class=com.bookislife.example.GreetingPlugin

implementation-class 是外掛真正的實現類,該檔名則為對應的 Short ID

釋出外掛到本地

修改 plugin 下的 build.gradle 檔案,追加以下程式碼

group "com.test"
version "1.0-SNAPSHOT"

以上指定了外掛釋出的 groupversion,而外掛的 name 則預設為模組名,即 plugin,繼續修改 build.gradle 追加 maven 釋出外掛

apply plugin: 'maven'

uploadArchives {
    repositories {
        mavenDeployer {
            repository(url: uri('../repo'))
        }
    }
}

執行

gradle -q upload

此時編寫好的外掛就會被髮布到工程根目錄下的 repo 資料夾下。

使用外掛

在父工程的根目錄下建立新的基於 Gradle 的工程 "test",這個工程用於測試剛才建立的外掛是否能正常工作。

修改該工程下的 build.gradle 檔案

buildscript {
    repositories {
        maven {
            url uri('../repo')
        }
        mavenCentral()
    }
    dependencies {
        classpath 'com.test:plugin:1.0-SNAPSHOT'
    }
}

apply plugin: 'greeting'

greeting {
    message = 'Hello'
    greeter = 'a test module'
}

接著定位到 test 工程下,在控制檯執行以下語句

gradle -q hello

成功的話可以看到控制檯輸出 Hello from a test module

Log 系統

在開發 Gradle 外掛時可以使用 Gradle 自身的日誌系統來方便除錯

使用時只需呼叫 project.logger.error(msg) 即可,其中 error() 方法指定 Log 級別為 error,除了 error 之外還有以下幾個級別,每個級別都可以通過對應名稱的方法進行呼叫:

Log 級別

  • quiet
  • error
  • warn
  • lifecycle
  • info
  • debug
  • trace

在執行 Gradle 命令時可以通過加上級別或其縮寫來控制只輸出某個級別以上的日誌

gradle -q build

gradle --quiet build

以上兩句表面只有 quiet 級別以上的 Log 日誌才可以被輸出。

如果嫌使用 Log 麻煩的話也可以直接使用內建的 println() 方法進行輸出,Gradle 內部會將其重定向為 quiet 級別的日誌。

Debug

開發外掛不可避免需要進行 Debug,此時只需執行以下幾個步驟即可:

  1. 在對應的程式碼處打上斷點
  2. 執行需要 Debug 的 task
    gradle -Dorg.gradle.debug=true hello
    
  3. 選擇 IDEA 的 Run Configurations -> 建立 Remote,建立完後點選 Debug 按鈕,程式就會在斷點處中斷執行了,然後就可以愉快的 Debug 了。

本節完整的 Gradle Plugin 示例可以參見 https://github.com/SidneyXu/templates/tree/master/hello-gradle

相關文章