前面咱們學習了Groovy語言,Gradle相關知識(如:生命週期/project/task等)java
瞭解到了Gradle是一個很好用的構建工具,具體細節能夠自行回顧往期文章:git
1)【Gradle系列】初識Gradlegithub
5)【Gradle系列】Gradle的生命週期markdown
6)【Gradle系列】Gradle 之Project詳解(一)閉包
7)【Gradle系列】Gradle之Project詳解(二)app
8)【Gradle系列】Gradle之 Project詳解(三)maven
10)【Gradle系列】Gradle在Android上的拓展
接下來,咱們將用前面學習的理論,逐步用到實戰中去
平常開發中,咱們若是開發了一個基礎組件,都會經過maven來發布到遠程或者本地,來提供給業務開發的同窗使用;
若是基礎組件比較多的時候,那麼上傳腳本的通用性就必需要考慮了,由於不可能再每個基礎組件的項目中,都重複寫上傳的腳本;
因此接下來,咱們將利用前面學過的知識(如:gradle屬性拓展/生命週期等)來實現maven上傳的通用腳本;
另外,基於方案的科學性/實用性方面考慮,本章將經過研究微信Tinker項目中的maven-publish封裝來開展
在上傳maven的時候,通常要指定上傳的地點/組件的版本號/組件名稱等信息
這些是輸入信息,會根據不一樣開發者/企業等的不一樣而改變,屬於配置信息
全部須要抽到指定的地方(如:根工程的gradle文件/單獨的配置文件等),這裏咱們 放在了根工程的gradle中
上圖能夠看出咱們配置了的信息有:
VERSION_NAME = '1.0.666'
GROUP = 'com.davi.mavenPlu'
// 會在項目根目錄生成文件夾
POM_URL = 'file:daviRepoMaven666'
複製代碼
其中,咱們上傳到本地倉庫(即特定的文件夾中)
這裏咱們是一個java的組件(java工程模塊),在輸出jar後上傳到本地倉庫;
這裏是使用《maven-publish封裝》的地方,能夠看出咱們引入了通用封裝好的腳本:
apply from: rootProject.file('daviGradle/DaviPublish.gradle')
複製代碼
使用的時候,比較簡單:
1)daviPublish,自定義的拓展標示,表明發佈maven
2)pom,自定義的拓展,表明要發佈的內容
3)publishToMaven,自定義的拓展,表明要發佈的地址
在第2點中,封裝好的腳本位置以下:
細節先不在這裏展開
經過前面的3步以後,執行task就能夠實現java組件的上傳,具體效果以下:
除此以外,不管下次是任何java組件須要上傳,只須要簡單的配置便可(也就是第1和第2點) 而後引用下第3點這個封裝好的《maven-publish封裝》便可,好比微信Tinker項目中的複用效果:
// 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
}
}
複製代碼
哈哈,該篇就寫到這裏(一塊兒體系化學習,一塊兒成長)