Gradle实战1-微信Tinker项目中的maven-publish封装

引言

前面咱们学习了Groovy语言,Gradle相关知识(如:生命周期/project/task等)java

了解到了Gradle是一个很好用的构建工具,具体细节能够自行回顾往期文章:git

1)【Gradle系列】初识Gradlegithub

2)【Gradle系列】Groovy语法之变量定义编程

3)【Gradle系列】Groovy基础编程知识1数组

4)【Gradle系列】Groovy基础编程知识2微信

5)【Gradle系列】Gradle的生命周期markdown

6)【Gradle系列】Gradle 之Project详解(一)闭包

7)【Gradle系列】Gradle之Project详解(二)app

8)【Gradle系列】Gradle之 Project详解(三)maven

9)【Gradle系列】Gradle之Task

10)【Gradle系列】Gradle在Android上的拓展

接下来,咱们将用前面学习的理论,逐步用到实战中去

背景

平常开发中,咱们若是开发了一个基础组件,都会经过maven来发布到远程或者本地,来提供给业务开发的同窗使用;

若是基础组件比较多的时候,那么上传脚本的通用性就必需要考虑了,由于不可能再每个基础组件的项目中,都重复写上传的脚本;

因此接下来,咱们将利用前面学过的知识(如:gradle属性拓展/生命周期等)来实现maven上传的通用脚本;

另外,基于方案的科学性/实用性方面考虑,本章将经过研究微信Tinker项目中的maven-publish封装来开展

实现的效果

1)根工程的gradle

1.png

在上传maven的时候,通常要指定上传的地点/组件的版本号/组件名称等信息

这些是输入信息,会根据不一样开发者/企业等的不一样而改变,属于配置信息

全部须要抽到指定的地方(如:根工程的gradle文件/单独的配置文件等),这里咱们 放在了根工程的gradle中

上图能够看出咱们配置了的信息有:

VERSION_NAME = '1.0.666'
GROUP = 'com.davi.mavenPlu'
// 会在项目根目录生成文件夹
POM_URL = 'file:daviRepoMaven666'
复制代码

其中,咱们上传到本地仓库(即特定的文件夹中)

2)组件工程的gradle

1.png

这里咱们是一个java的组件(java工程模块),在输出jar后上传到本地仓库;

这里是使用《maven-publish封装》的地方,能够看出咱们引入了通用封装好的脚本:

apply from: rootProject.file('daviGradle/DaviPublish.gradle')
复制代码

使用的时候,比较简单:

1)daviPublish,自定义的拓展标示,表明发布maven

2)pom,自定义的拓展,表明要发布的内容

3)publishToMaven,自定义的拓展,表明要发布的地址

3)通用封装好的脚本

在第2点中,封装好的脚本位置以下:

3.png 细节先不在这里展开

4)运行效果

经过前面的3步以后,执行task就能够实现java组件的上传,具体效果以下:

4.png

除此以外,不管下次是任何java组件须要上传,只须要简单的配置便可(也就是第1和第2点) 而后引用下第3点这个封装好的《maven-publish封装》便可,好比微信Tinker项目中的复用效果:

2.png

《maven-publish封装》具体实现

// Register extension
extensions.create('daviPublish', JavaLibraryPublishExtension.class, project)
//ext.artifactId = name

/** * * 基于《maven-publish》方式的上传java工程的jar * * */
class JavaLibraryPublishExtension {

    private final Project project

    protected final ArrayList<Closure> pomClosures = []

    private final ArrayList<Closure> mavenPublishClosures = []

    JavaLibraryPublishExtension(Project p) {
        project = p

        //执行阶段 publish
        p.afterEvaluate {
            this.publish()
        }
    }

    protected void publish() {
        //强校验
        //由于这个功能是基于'maven-publish'的通用设计
        if (!project.plugins.hasPlugin('maven-publish')) {
            project.plugins.apply('maven-publish')
        }

        emitPublicationDSL(project)

        emitRepositoryDSL(project)
    }

    /** * 要发布的内容准备(如:java源码/javaDoc等) * */
    protected void emitPublicationDSL(Project project) {
        /*** * 获取源码的task * */
        def sourcesJarTask = project.task('sourcesJar', type: Jar) {
            classifier = 'sources'
            //project.sourceSets.main 中的代码的位置目录保存起来,输出到 srcDirs = []
            def srcDirs = []
            def sources = project.sourceSets.main
            ['java', 'groovy', 'scala', 'kotlin'].each {
                if (sources.hasProperty(it)) {
                    println "获取源码的task : project.sourceSets.main has ${it}"
                    srcDirs << sources[it].srcDirs
                }
            }
            from srcDirs
        }


        /*** * maven 要发布的内容(可配置多个) * * 发布:sourcesJarTask的源码 * */
        project.publishing.publications {
            //${publicationName},称为发布组件Component,用于配置一项要发布的内容
            //只是一个命名,并没有特殊含义(也能够将其更换为别的名称,但不能与其它发布组件名称重复)
            "${publicationName}"(MavenPublication) {
                from project.components.java
                groupId this.groupId
                version this.version
                //将 sourcesJarTask 看做 artifact,交给 archives 管理
                //artifact sourcesJarTask
            }
        }

        /** * maven 要发布的内容(可配置多个) * 外部传进来的pom * */
        pomClosures.each { cl ->
            //要发布的内容(可配置多个)
            project.publishing.publications {
                "${publicationName}"(MavenPublication) {
                    // 闭包存到 pomClosures数组
                    pom cl
                }
            }
        }
    }

    /** * 要发布的地点 * */
    private void emitRepositoryDSL(Project project) {
        mavenPublishClosures.each { cl ->
            project.publishing.repositories {
                maven {
                    cl.delegate = delegate
                    cl()
                }
            }
        }
    }

    String getGroupId() {
        return project.group
    }

    String getVersion() {
        return project.version
    }

    final protected String getPublicationName() {
        return project.name
    }

    /*** * 自定义拓展属性 pom * */
    void pom(Closure cl) {
        if (cl != null)
            pomClosures << cl
    }

    /*** * 自定义拓展属性 publishToMaven * */
    void publishToMaven(Closure cl) {
        if (cl != null)
            mavenPublishClosures << cl
    }

}
复制代码

源码地址

github.com/zgxzgxzg/Da…

结尾

哈哈,该篇就写到这里(一块儿体系化学习,一块儿成长)

相关文章
相关标签/搜索