0%

MavenPublish插件解析

使用

添加plugin

1
2
3
plugins {
id 'maven-publish'
}

添加extension

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
publishing {
publications {

maven(MavenPublication) { // MavenPublication
groupId 'com.miniapp.tools'
artifactId 'sample'
version '0.0.1'

from components.java //SoftwareComponent 主要作用是pom中写入依赖项目

pom {
// MavenPom 手动给pom中添加一些信息(依赖,描述,licenses,组织,开发者,团队,scm等)
}

artifact { // 工件
// 仓库中上传的资源,可以是jar,source等
// miniapp_apt_debug.zip
// classifier 'debug' // 名称后缀
// extension 'zip' // 文件类型
}

versionMapping {
// pom 中 替换版本
}
}
// 这种写法很诡异,它其实调用了 <U extends T> U create(String name, Class<U> type);
// 下面的写法同publishing.publications.create("myMaven",MavenPlblication.class);
myMaven(MavenPublication) {
}
}

repositories {
mavenLocal() // mavenLocal仓库
maven { // remote仓库
name 'remote'
url mvn_repo
credentials {
username = mvn_username
password = mvn_password
}
}
}

}

原理

初始化

publishing tasks

1
./gradlew :amap_miniapp_compiler:tasks
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// metadata
generateMetadataFileForMavenPublication - Generates the Gradle metadata file for publication 'maven'.
// 生成pom
generatePomFileForMavenPublication - Generates the Maven POM file for publication 'maven'.
// 发布所有
publish - Publishes all publications produced by this project.
// 发布所有的 Publications
publishAllPublicationsToMavenLocalRepository - Publishes all Maven publications produced by this project to the MavenLocal repository.
// 发布所有的 Publications
publishAllPublicationsToRemoteRepository - Publishes all Maven publications produced by this project to the remote repository.
// 内置mavenlocal
publishMavenPublicationToMavenLocal - Publishes Maven publication 'maven' to the local Maven repository.
// 发布到自定义本地仓库
publishMavenPublicationToMavenLocalRepository - Publishes Maven publication 'maven' to Maven repository 'MavenLocal'.
//发布到自定义的源端仓库
publishMavenPublicationToRemoteRepository - Publishes Maven publication 'maven' to Maven repository 'remote'.
// plugin内置的一个 publish
publishToMavenLocal - Publishes all Maven publications produced by this project to the local Maven cache.

MavenPublishPlugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
public class MavenPublishPlugin implements Plugin<Project> {
@Override
public void apply(final Project project) {
//执行 PublishingPlugin apply
project.getPluginManager().apply(PublishingPlugin.class);

final TaskContainer tasks = project.getTasks();
//注册task publishToMavenLocal
tasks.register(PUBLISH_LOCAL_LIFECYCLE_TASK_NAME, publish -> {
publish.setDescription("Publishes all Maven publications produced by this project to the local Maven cache.");
publish.setGroup(PublishingPlugin.PUBLISH_TASK_GROUP);
});

project.getExtensions().configure(PublishingExtension.class, extension -> {
//注册 MavenPublicationFactory,它可以帮我们通过myMaven构建一个 MavenPublication
extension.getPublications().registerFactory(MavenPublication.class, new MavenPublicationFactory(
dependencyMetaDataProvider,
instantiatorFactory.decorateLenient(),
fileResolver,
project.getPluginManager(),
project.getExtensions()));
// 注册task
realizePublishingTasksLater(project, extension);
});
}

private void realizePublishingTasksLater(final Project project, final PublishingExtension extension) {

// 获取publications中的列表
final NamedDomainObjectSet<MavenPublicationInternal> mavenPublications = extension.getPublications().withType(MavenPublicationInternal.class);
final TaskContainer tasks = project.getTasks();
final DirectoryProperty buildDirectory = project.getLayout().getBuildDirectory();

// 通过name 获取 publish 的TaskProvider,这个task在PublishingPlugin进行了注册
final TaskProvider<Task> publishLifecycleTask = tasks.named(PublishingPlugin.PUBLISH_LIFECYCLE_TASK_NAME);

// 获取 publishToMavenLocal 上面进行过注册
final TaskProvider<Task> publishLocalLifecycleTask = tasks.named(PUBLISH_LOCAL_LIFECYCLE_TASK_NAME);

// 获取 repositories中的列表
final NamedDomainObjectList<MavenArtifactRepository> repositories = extension.getRepositories().withType(MavenArtifactRepository.class);

// 注册 publishAllPublicationsToMavenLocalRepository和 publishAllPublicationsToRemoteRepository
repositories.all(repository -> tasks.register(publishAllToSingleRepoTaskName(repository), publish -> {
publish.setDescription("Publishes all Maven publications produced by this project to the " + repository.getName() + " repository.");
publish.setGroup(PublishingPlugin.PUBLISH_TASK_GROUP);
}));
//遍历MavenPublication 创建task
mavenPublications.all(publication -> {

// generateMetadataFileForMavenPublication
createGenerateMetadataTask(tasks, publication, mavenPublications, buildDirectory);

// generatePomFileForMavenPublication
createGeneratePomTask(tasks, publication, buildDirectory, project);

// publishMavenPublicationToMavenLocal
createLocalInstallTask(tasks, publishLocalLifecycleTask, publication);

// 我们自定义的上传maven task
createPublishTasksForEachMavenRepo(tasks, publishLifecycleTask, publication, repositories);
});
}

private String publishAllToSingleRepoTaskName(MavenArtifactRepository repository) {
return "publishAllPublicationsTo" + capitalize(repository.getName()) + "Repository";
}

}

上面的代码主要是解析 publishing (PublishingExtension),并且根据我们设置的publications和repositories 构建task,构建的task类型,我们在上一部分中已经列出。

开头发现在apply方法中调用了PublishingPlugin的apply方法,我们继续查看PublishingPlugin

PublishingPlugin

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class PublishingPlugin implements Plugin<Project> {
@Override
public void apply(final Project project) {
RepositoryHandler repositories = publicationServices.createRepositoryHandler();
PublicationContainer publications = instantiator.newInstance(DefaultPublicationContainer.class, instantiator, collectionCallbackActionDecorator);

PublishingExtension extension = project.getExtensions().create(PublishingExtension.class, PublishingExtension.NAME, DefaultPublishingExtension.class, repositories, publications);

//注册publish task
project.getTasks().register(PUBLISH_LIFECYCLE_TASK_NAME, task -> {
task.setDescription("Publishes all publications produced by this project.");
task.setGroup(PUBLISH_TASK_GROUP);
});
extension.getPublications().all(publication -> {
PublicationInternal<?> internalPublication = Cast.uncheckedNonnullCast(publication);
ProjectInternal projectInternal = (ProjectInternal) project;
projectPublicationRegistry.registerPublication(projectInternal, internalPublication);
});
bridgeToSoftwareModelIfNeeded((ProjectInternal) project);
validatePublishingModelWhenComplete(project, extension);
}
}

初始化完成后,每个task都可以独立执行,这里分析publishMavenPublicationToMavenLocalRepository和publishMavenPublicationToRemoteRepository;构建task过程如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
private void createPublishTasksForEachMavenRepo(final TaskContainer tasks, final TaskProvider<Task> publishLifecycleTask, final MavenPublicationInternal publication, final NamedDomainObjectList<MavenArtifactRepository> repositories) {
final String publicationName = publication.getName();
repositories.all(repository -> {
final String repositoryName = repository.getName();
final String publishTaskName = "publish" + capitalize(publicationName) + "PublicationTo" + capitalize(repositoryName) + "Repository";
tasks.register(publishTaskName, PublishToMavenRepository.class, publishTask -> {
publishTask.setPublication(publication);
publishTask.setRepository(repository);
publishTask.setGroup(PublishingPlugin.PUBLISH_TASK_GROUP);
publishTask.setDescription("Publishes Maven publication '" + publicationName + "' to Maven repository '" + repositoryName + "'.");
});
publishLifecycleTask.configure(task -> task.dependsOn(publishTaskName));
tasks.named(publishAllToSingleRepoTaskName(repository), publish -> publish.dependsOn(publishTaskName));
});
}

这里的代码是帮助构建task,并且让publish和publishAllxxxxxx 依赖这个task

Task执行

PublishToMavenRepository (publishMavenPublicationToMavenLocalRepository)

  • 命令
1
./gradlew :amap_miniapp_compiler:publishMavenPublicationToMavenLocalRepository
  • publication
  • 流程图
  • 核心上传代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
abstract class AbstractMavenPublisher implements MavenPublisher {

protected void publish(MavenNormalizedPublication publication, ExternalResourceRepository repository, URI rootUri, boolean localRepo) {
String groupId = publication.getGroupId();
String artifactId = publication.getArtifactId();
String version = publication.getVersion();

ModuleArtifactPublisher artifactPublisher = new ModuleArtifactPublisher(repository, localRepo, rootUri, groupId, artifactId, version);
// snapshot
if (isSnapshot(version)) {
...
}
// 上传mainArtifact
if (publication.getMainArtifact() != null) {
artifactPublisher.publish(null, publication.getMainArtifact().getExtension(), publication.getMainArtifact().getFile());
}
// 上传pom
artifactPublisher.publish(null, "pom", publication.getPomArtifact().getFile());
for (MavenArtifact artifact : publication.getAdditionalArtifacts()) {
//其他额外的 artifact
artifactPublisher.publish(artifact.getClassifier(), artifact.getExtension(), artifact.getFile());
}

ExternalResourceName externalResource = artifactPublisher.getMetadataLocation();
Metadata metadata = createMetadata(groupId, artifactId, version, repository, externalResource);
// 上传 metadata
artifactPublisher.publish(externalResource, writeMetadataToTmpFile(metadata, "module-maven-metadata.xml"));
}
}