maven gradle插件如何上傳多渠道library

1、背景

對接的第三方SDK分聯調版(測試環境)跟正式版(生產環境),調試時用聯調版,上線用正式版。兩個環境對應不同的代碼、資源文件,考慮到複用問題,因此新建一個library集成這個SDK,並上傳到公共庫,之後在項目中直接依賴即可。

2、需求及實現

2.1、需求

因爲分兩個版本,且版本的代碼、資源各不相同,因此這個library應該要實現以下需求

  1. 一個library module包含多個渠道flavor
  2. 可以單獨上傳flavor,並且互不影響

2.2、一個任務上傳一個渠道

正常情況下使用maven 插件是這樣:

apply plugin: 'com.android.library'
apply plugin: 'maven'

然後用uploadArchives配置pom相關信息,和上傳路徑等:

uploadArchives {
        repositories.mavenDeployer {
            pom.groupId = GROUP
            pom.artifactId = ARTIFACT_ID
            pom.version = VERSION_NAME
            repository(url: REPOSITORY_URL) {
                authentication(userName: NEXUS_USERNAME, password: NEXUS_PASSWORD)
            }
        }
}

最後執行uploadArchives任務即可上傳成功。

但是這樣顯然不符合需求,多個渠道的情況下會有多個aar,且pom.artifactId也是不一樣的,需要針對性的配置。

2.3、一個任務同時上傳多個渠道

查了好幾天資料,都沒發現什麼有用的信息,大多都是針對單個flavor的,終於在StackOverflow上找到了一些有用信息,照葫蘆畫瓢,最後gradle如下:

import org.gradle.api.internal.artifacts.publish.DefaultPublishArtifact //導入類
...
android {
    publishNonDefault true
    productFlavors {
        //調試環境、測試環境
        dev {
        }
        //生產環境、正式環境
        production {
        }
    }
    ...
}
//配置要上傳的文件信息
artifacts {
    archives new DefaultPublishArtifact("production", "aar", "aar", null, new Date(), new File("build/outputs/aar", "lib-production-release.aar"))
    archives new DefaultPublishArtifact("dev", "aar", "aar", null, new Date(), new File("build/outputs/aar", "lib-dev-release.aar"))
}
//上傳任務配置
uploadArchives {
    repositories.mavenDeployer {
        ...
        //添加過濾器
        //正式環境
        addFilter('pro') { artifact, file ->
            artifact.name.contains("production")  //production就是artifacts裏指定的name
        }
        //測試環境
        addFilter('dev') { artifact, file ->
            artifact.name.contains("dev")
        }
        //單獨設置pom文件
        pom('pro').groupId = GROUP
        pom('pro').artifactId = PRODUCTION_MAVEN.ARTIFACT_ID
        pom('pro').version = PRODUCTION_MAVEN.VERSION_NAME
        pom('dev').groupId = GROUP
        pom('dev').artifactId = DEV_MAVEN.ARTIFACT_ID
        pom('dev').version = DEV_MAVEN.VERSION_NAME
    }
}


這樣執行uploadArchives之後,就會上傳多個渠道的aar了,這裏算完成了一半。

2.4、自定義上傳任務

要實現單個渠道上傳,只靠uploadArchives這一個任務是不行的,因此要自定義上傳任務,實現一樣的功能。本質上uploadArchives也是Upload類型的Task,即我們可以照着uploadArchives自定義Task繼承Upload:

//上傳調試版aar
task uploadDev(type: Upload, group: "upload") {
    repositories.mavenDeployer {
        repository(url: uri('../repos')) {
            
        }
        addFilter('dev') { artifact, file ->
            println("artifact " + artifact.name)
            artifact.name.contains("dev")
        }
        pom('dev').groupId = MIGU_GROUP
        pom('dev').artifactId = DEV_MAVEN.ARTIFACT_ID
        pom('dev').version = DEV_MAVEN.VERSION_NAME
    }
}

同步之後就會在upload目錄下多了一個任務:
在這裏插入圖片描述

執行之後,就會發現這個錯誤:

No value has been specified for property ‘artifacts’.

這時看uploadArchives的源碼是最好的,但是我不知道去哪裏看,所以又耗費了我一些時間查資料。最後實在沒轍,終於直面這個錯誤:既然沒指定,那就顯示的設置好了。

2.4.1 artifacts和configuration

配置上傳信息的時候用到了artifacts,但是不知道爲什麼要這樣寫,看了下源碼,artifacts和configurations都是位於project下:

//Configures the published artifacts for this project.
	 *	configurations {
     *   //declaring new configuration that will be used to associate with artifacts
     *   schema
     * }
     * task schemaJar(type: Jar) {
     *   //some imaginary task that creates a jar artifact with the schema
     * }
     * artifacts {
     *   //configuration name and the task:
     *   schema schemaJar
     * }
void artifacts(Closure configureClosure);

根據註釋的說明,應該有個默認的configuration,是這樣寫的:

configurations {
 	archives   
}

所以我們才能使用archives來配置要上傳的文件,而看了Upload的源碼後發現,artifacts並沒有直接設置的方法,而是通過Configuration獲取的:

	/**
     * Returns the artifacts which will be uploaded.
     *
     * @return the artifacts.
     */
    @InputFiles
    public FileCollection getArtifacts() {
        Configuration configuration = getConfiguration();
        return configuration == null ? null : configuration.getAllArtifacts().getFiles();
    }

也就說是要設置artifacts必須要先設置Configuration。通過打印configurations和上面的分析,archives就是我們的目標。所以手動把archives這個配置加進來:

//上傳調試版aar
task uploadDev(type: Upload, group: "upload") {
    //設置configuration
    setConfiguration(project.configurations.getByName("archives"))
    repositories.mavenDeployer {
    ...
}

到這裏已經可以了。

2.4.2 自定義artifacts和configuration

同樣地,可以自定義configuration來過濾配置文件,自定義上傳Task設置爲該configuration即可

configurations {
    dev
    pro
}
//配置要上傳的文件信息
artifacts {
    pro new DefaultPublishArtifact("production", "aar", "aar", null, new Date(), new File("build/outputs/aar", "lib-production-release.aar"))
    dev new DefaultPublishArtifact("dev", "aar", "aar", null, new Date(), new File("build/outputs/aar", "lib-dev-release.aar"))
}

//上傳調試版aar
task uploadDev(type: Upload, group: "upload") {
    //設置configuration
    setConfiguration(project.configurations.getByName("dev"))
    repositories.mavenDeployer {
    ...
}

2.4.3 最終版本

configurations {
    devArchives
    proArchives
}
//配置要上傳的文件信息
artifacts {
    proArchives new DefaultPublishArtifact("production", "aar", "aar", null, new Date(), new File("build/outputs/aar", "lib-production-release.aar"))
    devArchives new DefaultPublishArtifact("dev", "aar", "aar", null, new Date(), new File("build/outputs/aar", "lib-dev-release.aar"))
}

//上傳調試版aar
task uploadDev(type: Upload, group: "upload", dependsOn: 'assembleDevRelease') {

    setConfiguration(project.configurations.getByName("devArchives"))
    repositories.mavenDeployer {
        pom.groupId = MIGU_GROUP
        pom.artifactId = DEV_MAVEN.ARTIFACT_ID
        pom.version = DEV_MAVEN.VERSION_NAME
        repository(url: uri('../repos')) {

        }

    }
}

//上傳正式版aar
task uploadPro(type: Upload, group: "upload", dependsOn: 'assembleProRelease') {

    setConfiguration(project.configurations.getByName("proArchives"))
    repositories.mavenDeployer {
        pom.groupId = MIGU_GROUP
        pom.artifactId = PRODUCTION_MAVEN.ARTIFACT_ID
        pom.version = PRODUCTION_MAVEN.VERSION_NAME
        repository(url: uri('../repos')) {

        }

    }
}

生成的兩個任務分別用於上傳聯調版和正式版。爲了每次上傳都是最新版本,task可以依賴於assembleXXX後執行,如dependsOn: ‘assembleProRelease’
在這裏插入圖片描述

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章