Gradle
作为编译工具,理所当然也要谈谈publish
这块。Gradle
提供了两种发布方式,分别是ivy
和maven
,这里着重说下maven
的方式好了,这也是最常用的方式。
PublishingExtension
Gradle
提供出来的publishing
闭包配置为:
publishing {
publications { ... }
repositories.maven { ... }
}
从前面的文章可知,对应的分别是两个方法:
void repositories(Action<? super RepositoryHandler> configure)
publications(Action<? super PublicationContainer> configure)
RepositoryHandler
repositories
函数用来设置具体的RepositoryHandler
实例(FlatDirectoryArtifactRepository
,IvyArtifactRepository
以及MavenArtifactRepository
)。
repositories {
maven {
credentials {
username = "user"
password = "password"
}
url "https://xxx.com"
}
}
这里对应的就是MavenArtifactRepository
,分别调用方法setUrl(Object url)
设置仓库地址以及方法credentials(Action<? super PasswordCredentials> action)
设置仓库地址进行登陆鉴权的用户名和密码。
PublicationContainer
同样,publications
用来创建PublicationContainer
实例(IvyPublication以及MavenPublication)。
publications {
myPublication(MavenPublication) {
from components.java
artifact sourceJar
pom.withXml {
asNode().appendNode('description', 'A demonstration of Maven POM customization')
}
}
}
上述闭包配置作用在于创建两个实现了MavenPublication
接口的task
。
-
publishMyPublicationToMavenLocal
发布到本地仓库 -
publishMyPublicationToMavenRepository
发布到远程仓库。
理所当然,这两个task
必须在build
后执行,因为需要拿build
后生成的jar
或者aar
包。
在前面task
章节我们了解到这里需要进行dependsOn
配置。
tasks.whenTaskAdded { task ->
if (task.name == "publishMyPublicationToMavenLocal" ||
task.name == "publishMyPublicationToMavenRepository") {
task.dependsOn build
}
}
接下来,详细了解具体的MavenPublication
的配置选项。
MavenPublication
具体类为org.gradle.api.publish.maven.MavenPublication
,详细的方法可以自行查略,这里说说其中最为关键的几个方法。
-
void setGroupId(String groupId)
设置groupID
,对应com.gradle:tools:1.0
中的com.gradle
。 -
void setArtifactId(String artifactId)
设置artifactId
,对应com.gradle:tools:1.0
中的tools
。 -
MavenArtifact artifact(Object source)
添加MavenArtifact
到publish
任务中。 -
void pom(Action<? super MavenPom> configure)
配置Pom
,对应就是用来进行递归依赖的Pom.xml
中内容。
artifact
artifact
方法是提供Object
对象,具体是什么呢?主要是三种。
-
artifact 'my-file-name.jar'
具体的文件。 -
artifact sourceJar
任务sourceJar
输出物,例如这里是对源码进行了打包的Jar
包。 -
artifact source: sourceJar, classifier: 'src', extension: 'zip'
通过source
、classifier
以及extension
构造的MavenArtifact
实例,参数分别对应源文件,名称类别(artifactId-classifier
)以及扩展名称(.jar/.zip
等)。
pom
pom
方法通过传递一个MavenPom
对象来添加对应配置内容到Pom.xml
文件中。
<dependencies>
<dependency>
<groupId>com.gradle</groupId>
<artifactId>design</artifactId>
<version>1.0</version>
<exclusions>
<exclusion>
<groupId>com.gradle</groupId>
<artifactId>support</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
org.gradle.api.artifacts.maven.MavenPom
提供的get
方法和xml中配置选项是一一对应的,例如getGroupId()
、getArtifactId()
等。
这样,当你发布出去的包被依赖的时候,所包含的Pom.xml
中的com.gradle:design:1.0
包也会依赖进来,但是这个包所依赖的com.gradle:support
却除外不再依赖进来。
那我们怎么去构造一个这样的MavenPom
对象出来呢?有很多种方法,这里提及一种最常见的方式,MavenPom withXml(Action<XmlProvider> action)
。
XmlProvider
可以通过xml
文件格式进行实现。
pom.withXml({ XmlProvider xmlProvider ->
def dependenciesNode = xmlProvider.asNode().appendNode('dependencies')
def dependencyNode = dependenciesNode.appendNode('dependency')
dependencyNode.appendNode('groupId', "com.gradle")
dependencyNode.appendNode('artifactId', "com.tools")
dependencyNode.appendNode('version', "1.0")
//excludeRules是存储org.gradle.api.artifacts.ExcludeRule对象的集合
if (excludeRules != null && excludeRules.size() > 0) {
def exclusionsNode = dependencyNode.appendNode('exclusions')
excludeRules.each { ExcludeRule rule ->
def exclusionNode = exclusionsNode.appendNode('exclusion')
exclusionNode.appendNode('groupId', rule.group)
exclusionNode.appendNode('artifactId', rule.module)
}
}
}
到此为止,已经可以完成对本地文件的发布(包含但不限于jar/aar/so
等),对应的唯一依赖标示为com.gradle:tools:1.0
。
后续
Gradle
提供的publish
不仅仅可用于常规的jar、aar、so
发布,还可以发布一些我们在进行编译的时候需要用到的脚本(python、luna等)、配置信息等,这些就需要针对编译流程进行各自的思考。