Move publishing configuration to a separate plugin (#56727)
This is another part of the breakup of the massive BuildPlugin. This PR moves the code for configuring publications to a separate plugin. Most of the time these publications are jar files, but this also supports the zip publication we have for integ tests.
This commit is contained in:
parent
5e90ff32f7
commit
9fb80d3827
|
@ -157,7 +157,7 @@ if (project == rootProject) {
|
|||
// to enforce precommit checks like forbidden apis, as well as setup publishing
|
||||
if (project != rootProject) {
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
allprojects {
|
||||
targetCompatibility = 10
|
||||
|
|
|
@ -111,8 +111,7 @@ class BuildPlugin implements Plugin<Project> {
|
|||
)
|
||||
}
|
||||
project.pluginManager.apply('elasticsearch.java')
|
||||
configureJars(project)
|
||||
configureJarManifest(project)
|
||||
project.pluginManager.apply('elasticsearch.publish')
|
||||
|
||||
// apply global test task failure listener
|
||||
project.rootProject.pluginManager.apply(TestFailureReportingPlugin)
|
||||
|
@ -121,9 +120,6 @@ class BuildPlugin implements Plugin<Project> {
|
|||
|
||||
configureRepositories(project)
|
||||
project.extensions.getByType(ExtraPropertiesExtension).set('versions', VersionProperties.versions)
|
||||
configureJavadoc(project)
|
||||
configureSourcesJar(project)
|
||||
configurePomGeneration(project)
|
||||
configurePrecommit(project)
|
||||
configureDependenciesInfo(project)
|
||||
configureFips140(project)
|
||||
|
@ -305,206 +301,6 @@ class BuildPlugin implements Plugin<Project> {
|
|||
}
|
||||
}
|
||||
|
||||
/**Configuration generation of maven poms. */
|
||||
static void configurePomGeneration(Project project) {
|
||||
// have to defer this until archivesBaseName is set
|
||||
project.afterEvaluate {
|
||||
project.pluginManager.withPlugin('maven-publish') {
|
||||
PublishingExtension publishing = project.extensions.getByType(PublishingExtension)
|
||||
publishing.publications.withType(MavenPublication) { MavenPublication publication ->
|
||||
publication.artifactId = project.convention.getPlugin(BasePluginConvention).archivesBaseName
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project.plugins.withType(MavenPublishPlugin).whenPluginAdded {
|
||||
TaskProvider generatePomTask = project.tasks.register("generatePom") { Task task ->
|
||||
task.dependsOn 'generatePomFileForNebulaPublication'
|
||||
}
|
||||
|
||||
maybeConfigure(project.tasks, LifecycleBasePlugin.ASSEMBLE_TASK_NAME) { assemble ->
|
||||
assemble.dependsOn(generatePomTask)
|
||||
}
|
||||
|
||||
project.tasks.withType(GenerateMavenPom).configureEach({ GenerateMavenPom pomTask ->
|
||||
pomTask.destination = { "${project.buildDir}/distributions/${project.convention.getPlugin(BasePluginConvention).archivesBaseName}-${project.version}.pom" }
|
||||
} as Action<GenerateMavenPom>)
|
||||
|
||||
PublishingExtension publishing = project.extensions.getByType(PublishingExtension)
|
||||
|
||||
project.pluginManager.withPlugin('com.github.johnrengelman.shadow') {
|
||||
MavenPublication publication = publishing.publications.maybeCreate('shadow', MavenPublication)
|
||||
ShadowExtension shadow = project.extensions.getByType(ShadowExtension)
|
||||
shadow.component(publication)
|
||||
// Workaround for https://github.com/johnrengelman/shadow/issues/334
|
||||
// Here we manually add any project dependencies in the "shadow" configuration to our generated POM
|
||||
publication.pom.withXml(this.&addScmInfo)
|
||||
publication.pom.withXml { xml ->
|
||||
Node root = xml.asNode()
|
||||
root.appendNode('name', project.name)
|
||||
root.appendNode('description', project.description)
|
||||
Node dependenciesNode = (root.get('dependencies') as NodeList).get(0) as Node
|
||||
project.configurations.getByName(ShadowBasePlugin.CONFIGURATION_NAME).allDependencies.each { dependency ->
|
||||
if (dependency instanceof ProjectDependency) {
|
||||
def dependencyNode = dependenciesNode.appendNode('dependency')
|
||||
dependencyNode.appendNode('groupId', dependency.group)
|
||||
dependencyNode.appendNode('artifactId', dependency.getDependencyProject().convention.getPlugin(BasePluginConvention).archivesBaseName)
|
||||
dependencyNode.appendNode('version', dependency.version)
|
||||
dependencyNode.appendNode('scope', 'compile')
|
||||
}
|
||||
}
|
||||
}
|
||||
generatePomTask.configure({ Task t -> t.dependsOn = ['generatePomFileForShadowPublication'] } as Action<Task>)
|
||||
}
|
||||
}
|
||||
|
||||
// Add git origin info to generated POM files
|
||||
project.pluginManager.withPlugin('nebula.maven-base-publish') {
|
||||
PublishingExtension publishing = project.extensions.getByType(PublishingExtension)
|
||||
MavenPublication nebulaPublication = (MavenPublication) publishing.publications.getByName('nebula')
|
||||
nebulaPublication.pom.withXml(this.&addScmInfo)
|
||||
}
|
||||
}
|
||||
|
||||
private static void addScmInfo(XmlProvider xml) {
|
||||
Node root = xml.asNode()
|
||||
root.appendNode('url', PluginBuildPlugin.urlFromOrigin(BuildParams.gitOrigin))
|
||||
Node scmNode = root.appendNode('scm')
|
||||
scmNode.appendNode('url', BuildParams.gitOrigin)
|
||||
}
|
||||
|
||||
static void configureJavadoc(Project project) {
|
||||
// remove compiled classes from the Javadoc classpath: http://mail.openjdk.java.net/pipermail/javadoc-dev/2018-January/000400.html
|
||||
final List<File> classes = new ArrayList<>()
|
||||
project.tasks.withType(JavaCompile).configureEach { JavaCompile javaCompile ->
|
||||
classes.add(javaCompile.destinationDir)
|
||||
}
|
||||
project.tasks.withType(Javadoc).configureEach { Javadoc javadoc ->
|
||||
// only explicitly set javadoc executable if compiler JDK is different from Gradle
|
||||
// this ensures better cacheability as setting ths input to an absolute path breaks portability
|
||||
if (Files.isSameFile(BuildParams.compilerJavaHome.toPath(), Jvm.current().getJavaHome().toPath()) == false) {
|
||||
javadoc.executable = new File(BuildParams.compilerJavaHome, 'bin/javadoc')
|
||||
}
|
||||
javadoc.classpath = javadoc.getClasspath().filter { f ->
|
||||
return classes.contains(f) == false
|
||||
}
|
||||
/*
|
||||
* Generate docs using html5 to suppress a warning from `javadoc`
|
||||
* that the default will change to html5 in the future.
|
||||
*/
|
||||
(javadoc.options as CoreJavadocOptions).addBooleanOption('html5', true)
|
||||
}
|
||||
// ensure javadoc task is run with 'check'
|
||||
project.pluginManager.withPlugin('lifecycle-base') {
|
||||
project.tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME).configure { it.dependsOn(project.tasks.withType(Javadoc)) }
|
||||
}
|
||||
configureJavadocJar(project)
|
||||
}
|
||||
|
||||
/** Adds a javadocJar task to generate a jar containing javadocs. */
|
||||
static void configureJavadocJar(Project project) {
|
||||
TaskProvider<Jar> javadocJarTask = project.tasks.register('javadocJar', Jar, { Jar jar ->
|
||||
jar.archiveClassifier.set('javadoc')
|
||||
jar.group = 'build'
|
||||
jar.description = 'Assembles a jar containing javadocs.'
|
||||
jar.from(project.tasks.named(JavaPlugin.JAVADOC_TASK_NAME))
|
||||
} as Action<Jar>)
|
||||
maybeConfigure(project.tasks, BasePlugin.ASSEMBLE_TASK_NAME) { Task t ->
|
||||
t.dependsOn(javadocJarTask)
|
||||
}
|
||||
}
|
||||
|
||||
static void configureSourcesJar(Project project) {
|
||||
TaskProvider<Jar> sourcesJarTask = project.tasks.register('sourcesJar', Jar, { Jar jar ->
|
||||
jar.archiveClassifier.set('sources')
|
||||
jar.group = 'build'
|
||||
jar.description = 'Assembles a jar containing source files.'
|
||||
jar.from(project.extensions.getByType(SourceSetContainer).getByName(SourceSet.MAIN_SOURCE_SET_NAME).allSource)
|
||||
} as Action<Jar>)
|
||||
maybeConfigure(project.tasks, BasePlugin.ASSEMBLE_TASK_NAME) { Task t ->
|
||||
t.dependsOn(sourcesJarTask)
|
||||
}
|
||||
}
|
||||
|
||||
/** Adds additional manifest info to jars */
|
||||
static void configureJars(Project project) {
|
||||
ExtraPropertiesExtension ext = project.extensions.getByType(ExtraPropertiesExtension)
|
||||
ext.set('licenseFile', null)
|
||||
ext.set('noticeFile', null)
|
||||
project.tasks.withType(Jar).configureEach { Jar jarTask ->
|
||||
// we put all our distributable files under distributions
|
||||
jarTask.destinationDirectory.set(new File(project.buildDir, 'distributions'))
|
||||
// fixup the jar manifest
|
||||
jarTask.doFirst {
|
||||
// this doFirst is added before the info plugin, therefore it will run
|
||||
// after the doFirst added by the info plugin, and we can override attributes
|
||||
JavaVersion compilerJavaVersion = BuildParams.compilerJavaVersion
|
||||
jarTask.manifest.attributes(
|
||||
'Build-Date': BuildParams.buildDate,
|
||||
'Build-Java-Version': BuildParams.compilerJavaVersion)
|
||||
}
|
||||
}
|
||||
// add license/notice files
|
||||
project.afterEvaluate {
|
||||
project.tasks.withType(Jar).configureEach { Jar jarTask ->
|
||||
if (ext.has('licenseFile') == false || ext.get('licenseFile') == null || ext.has('noticeFile') == false || ext.get('noticeFile') == null) {
|
||||
throw new GradleException("Must specify license and notice file for project ${project.path}")
|
||||
}
|
||||
|
||||
File licenseFile = ext.get('licenseFile') as File
|
||||
File noticeFile = ext.get('noticeFile') as File
|
||||
|
||||
jarTask.metaInf { CopySpec spec ->
|
||||
spec.from(licenseFile.parent) { CopySpec from ->
|
||||
from.include licenseFile.name
|
||||
from.rename { 'LICENSE.txt' }
|
||||
}
|
||||
spec.from(noticeFile.parent) { CopySpec from ->
|
||||
from.include noticeFile.name
|
||||
from.rename { 'NOTICE.txt' }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
project.pluginManager.withPlugin('com.github.johnrengelman.shadow') {
|
||||
project.tasks.getByName(ShadowJavaPlugin.SHADOW_JAR_TASK_NAME).configure { ShadowJar shadowJar ->
|
||||
/*
|
||||
* Replace the default "-all" classifier with null
|
||||
* which will leave the classifier off of the file name.
|
||||
*/
|
||||
shadowJar.archiveClassifier.set((String) null)
|
||||
/*
|
||||
* Not all cases need service files merged but it is
|
||||
* better to be safe
|
||||
*/
|
||||
shadowJar.mergeServiceFiles()
|
||||
}
|
||||
// Add "original" classifier to the non-shadowed JAR to distinguish it from the shadow JAR
|
||||
project.tasks.getByName(JavaPlugin.JAR_TASK_NAME).configure { Jar jar ->
|
||||
jar.archiveClassifier.set('original')
|
||||
}
|
||||
// Make sure we assemble the shadow jar
|
||||
project.tasks.named(BasePlugin.ASSEMBLE_TASK_NAME).configure { Task task ->
|
||||
task.dependsOn 'shadowJar'
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void configureJarManifest(Project project) {
|
||||
project.pluginManager.apply('nebula.info-broker')
|
||||
project.pluginManager.apply('nebula.info-basic')
|
||||
project.pluginManager.apply('nebula.info-java')
|
||||
project.pluginManager.apply('nebula.info-jar')
|
||||
|
||||
project.plugins.withId('nebula.info-broker') { InfoBrokerPlugin manifestPlugin ->
|
||||
manifestPlugin.add('Module-Origin') { BuildParams.gitOrigin }
|
||||
manifestPlugin.add('Change') { BuildParams.gitRevision }
|
||||
manifestPlugin.add('X-Compile-Elasticsearch-Version') { VersionProperties.elasticsearch }
|
||||
manifestPlugin.add('X-Compile-Lucene-Version') { VersionProperties.lucene }
|
||||
manifestPlugin.add('X-Compile-Elasticsearch-Snapshot') { VersionProperties.isElasticsearchSnapshot() }
|
||||
}
|
||||
}
|
||||
|
||||
private static configurePrecommit(Project project) {
|
||||
TaskProvider precommit = PrecommitTasks.create(project, true)
|
||||
project.tasks.named(LifecycleBasePlugin.CHECK_TASK_NAME).configure { it.dependsOn(precommit) }
|
||||
|
|
|
@ -241,28 +241,7 @@ class PluginBuildPlugin implements Plugin<Project> {
|
|||
project.artifacts.add('zip', bundle)
|
||||
}
|
||||
|
||||
/** Adds a task to move jar and associated files to a "-client" name. */
|
||||
|
||||
static final Pattern GIT_PATTERN = Pattern.compile(/git@([^:]+):([^\.]+)\.git/)
|
||||
|
||||
/** Find the reponame. */
|
||||
static String urlFromOrigin(String origin) {
|
||||
if (origin == null) {
|
||||
return null // best effort, the url doesnt really matter, it is just required by maven central
|
||||
}
|
||||
if (origin.startsWith('https')) {
|
||||
return origin
|
||||
}
|
||||
Matcher matcher = GIT_PATTERN.matcher(origin)
|
||||
if (matcher.matches()) {
|
||||
return "https://${matcher.group(1)}/${matcher.group(2)}"
|
||||
} else {
|
||||
return origin // best effort, the url doesnt really matter, it is just required by maven central
|
||||
}
|
||||
}
|
||||
|
||||
/** Configure the pom for the main jar of this plugin */
|
||||
|
||||
protected static void addNoticeGeneration(Project project, PluginPropertiesExtension extension) {
|
||||
File licenseFile = extension.licenseFile
|
||||
if (licenseFile != null) {
|
||||
|
|
|
@ -20,6 +20,8 @@
|
|||
package org.elasticsearch.gradle;
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin;
|
||||
import com.github.jengelman.gradle.plugins.shadow.tasks.ShadowJar;
|
||||
import nebula.plugin.info.InfoBrokerPlugin;
|
||||
import org.elasticsearch.gradle.info.BuildParams;
|
||||
import org.elasticsearch.gradle.info.GlobalBuildInfoPlugin;
|
||||
import org.elasticsearch.gradle.test.ErrorReportingTestListener;
|
||||
|
@ -35,24 +37,34 @@ import org.gradle.api.artifacts.ModuleDependency;
|
|||
import org.gradle.api.artifacts.ProjectDependency;
|
||||
import org.gradle.api.artifacts.ResolutionStrategy;
|
||||
import org.gradle.api.file.FileCollection;
|
||||
import org.gradle.api.plugins.BasePlugin;
|
||||
import org.gradle.api.plugins.ExtraPropertiesExtension;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.plugins.JavaPluginExtension;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.SourceSetContainer;
|
||||
import org.gradle.api.tasks.bundling.Jar;
|
||||
import org.gradle.api.tasks.compile.CompileOptions;
|
||||
import org.gradle.api.tasks.compile.GroovyCompile;
|
||||
import org.gradle.api.tasks.compile.JavaCompile;
|
||||
import org.gradle.api.tasks.javadoc.Javadoc;
|
||||
import org.gradle.api.tasks.testing.Test;
|
||||
import org.gradle.external.javadoc.CoreJavadocOptions;
|
||||
import org.gradle.internal.jvm.Jvm;
|
||||
import org.gradle.language.base.plugins.LifecycleBasePlugin;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.io.UncheckedIOException;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import java.util.function.Function;
|
||||
|
||||
import static org.elasticsearch.gradle.util.GradleUtils.maybeConfigure;
|
||||
import static org.elasticsearch.gradle.util.Util.toStringable;
|
||||
|
||||
/**
|
||||
* A wrapper around Gradle's Java plugin that applies our common configuration.
|
||||
|
@ -68,6 +80,9 @@ public class ElasticsearchJavaPlugin implements Plugin<Project> {
|
|||
configureCompile(project);
|
||||
configureInputNormalization(project);
|
||||
configureTestTasks(project);
|
||||
configureJars(project);
|
||||
configureJarManifest(project);
|
||||
configureJavadoc(project);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -382,4 +397,124 @@ public class ElasticsearchJavaPlugin implements Plugin<Project> {
|
|||
});
|
||||
});
|
||||
}
|
||||
|
||||
/** Adds additional manifest info to jars */
|
||||
static void configureJars(Project project) {
|
||||
ExtraPropertiesExtension ext = project.getExtensions().getExtraProperties();
|
||||
ext.set("licenseFile", null);
|
||||
ext.set("noticeFile", null);
|
||||
project.getTasks()
|
||||
.withType(Jar.class)
|
||||
.configureEach(
|
||||
jarTask -> {
|
||||
// we put all our distributable files under distributions
|
||||
jarTask.getDestinationDirectory().set(new File(project.getBuildDir(), "distributions"));
|
||||
// fixup the jar manifest
|
||||
jarTask.doFirst(
|
||||
t -> {
|
||||
// this doFirst is added before the info plugin, therefore it will run
|
||||
// after the doFirst added by the info plugin, and we can override attributes
|
||||
jarTask.getManifest()
|
||||
.attributes(
|
||||
Map.of(
|
||||
"Build-Date",
|
||||
BuildParams.getBuildDate(),
|
||||
"Build-Java-Version",
|
||||
BuildParams.getCompilerJavaVersion()
|
||||
)
|
||||
);
|
||||
}
|
||||
);
|
||||
}
|
||||
);
|
||||
// add license/notice files
|
||||
project.afterEvaluate(p -> project.getTasks().withType(Jar.class).configureEach(jarTask -> {
|
||||
File licenseFile = (File) ext.get("licenseFile");
|
||||
File noticeFile = (File) ext.get("noticeFile");
|
||||
if (licenseFile == null || noticeFile == null) {
|
||||
throw new GradleException("Must specify license and notice file for project");
|
||||
}
|
||||
|
||||
jarTask.metaInf(spec -> {
|
||||
spec.from(licenseFile.getParent(), from -> {
|
||||
from.include(licenseFile.getName());
|
||||
from.rename(s -> "LICENSE.txt");
|
||||
});
|
||||
spec.from(noticeFile.getParent(), from -> {
|
||||
from.include(noticeFile.getName());
|
||||
from.rename(s -> "NOTICE.txt");
|
||||
});
|
||||
});
|
||||
}));
|
||||
project.getPluginManager().withPlugin("com.github.johnrengelman.shadow", p -> {
|
||||
project.getTasks()
|
||||
.withType(ShadowJar.class)
|
||||
.configureEach(
|
||||
shadowJar -> {
|
||||
/*
|
||||
* Replace the default "-all" classifier with null
|
||||
* which will leave the classifier off of the file name.
|
||||
*/
|
||||
shadowJar.getArchiveClassifier().set((String) null);
|
||||
/*
|
||||
* Not all cases need service files merged but it is
|
||||
* better to be safe
|
||||
*/
|
||||
shadowJar.mergeServiceFiles();
|
||||
}
|
||||
);
|
||||
// Add "original" classifier to the non-shadowed JAR to distinguish it from the shadow JAR
|
||||
project.getTasks().named(JavaPlugin.JAR_TASK_NAME, Jar.class).configure(jar -> jar.getArchiveClassifier().set("original"));
|
||||
// Make sure we assemble the shadow jar
|
||||
project.getTasks().named(BasePlugin.ASSEMBLE_TASK_NAME).configure(task -> task.dependsOn("shadowJar"));
|
||||
});
|
||||
}
|
||||
|
||||
private static void configureJarManifest(Project project) {
|
||||
project.getPlugins().withType(InfoBrokerPlugin.class).whenPluginAdded(manifestPlugin -> {
|
||||
manifestPlugin.add("Module-Origin", toStringable(BuildParams::getGitOrigin));
|
||||
manifestPlugin.add("Change", toStringable(BuildParams::getGitRevision));
|
||||
manifestPlugin.add("X-Compile-Elasticsearch-Version", toStringable(VersionProperties::getElasticsearch));
|
||||
manifestPlugin.add("X-Compile-Lucene-Version", toStringable(VersionProperties::getLucene));
|
||||
manifestPlugin.add(
|
||||
"X-Compile-Elasticsearch-Snapshot",
|
||||
toStringable(() -> Boolean.toString(VersionProperties.isElasticsearchSnapshot()))
|
||||
);
|
||||
});
|
||||
|
||||
project.getPluginManager().apply("nebula.info-broker");
|
||||
project.getPluginManager().apply("nebula.info-basic");
|
||||
project.getPluginManager().apply("nebula.info-java");
|
||||
project.getPluginManager().apply("nebula.info-jar");
|
||||
}
|
||||
|
||||
private static void configureJavadoc(Project project) {
|
||||
project.getTasks().withType(Javadoc.class).configureEach(javadoc -> {
|
||||
// only explicitly set javadoc executable if compiler JDK is different from Gradle
|
||||
// this ensures better cacheability as setting ths input to an absolute path breaks portability
|
||||
Path compilerJvm = BuildParams.getCompilerJavaHome().toPath();
|
||||
Path gradleJvm = Jvm.current().getJavaHome().toPath();
|
||||
try {
|
||||
if (Files.isSameFile(compilerJvm, gradleJvm) == false) {
|
||||
javadoc.setExecutable(compilerJvm.resolve("bin/javadoc").toString());
|
||||
}
|
||||
} catch (IOException e) {
|
||||
throw new UncheckedIOException(e);
|
||||
}
|
||||
|
||||
// remove compiled classes from the Javadoc classpath:
|
||||
// http://mail.openjdk.java.net/pipermail/javadoc-dev/2018-January/000400.html
|
||||
javadoc.setClasspath(Util.getJavaMainSourceSet(project).get().getCompileClasspath());
|
||||
/*
|
||||
* Generate docs using html5 to suppress a warning from `javadoc`
|
||||
* that the default will change to html5 in the future.
|
||||
*/
|
||||
CoreJavadocOptions javadocOptions = (CoreJavadocOptions) javadoc.getOptions();
|
||||
javadocOptions.addBooleanOption("html5", true);
|
||||
});
|
||||
// ensure javadoc task is run with 'check'
|
||||
project.getTasks()
|
||||
.named(LifecycleBasePlugin.CHECK_TASK_NAME)
|
||||
.configure(t -> t.dependsOn(project.getTasks().withType(Javadoc.class)));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* Licensed to Elasticsearch under one or more contributor
|
||||
* license agreements. See the NOTICE file distributed with
|
||||
* this work for additional information regarding copyright
|
||||
* ownership. Elasticsearch licenses this file to you under
|
||||
* the Apache License, Version 2.0 (the "License"); you may
|
||||
* not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing,
|
||||
* software distributed under the License is distributed on an
|
||||
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
|
||||
* KIND, either express or implied. See the License for the
|
||||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
|
||||
package org.elasticsearch.gradle;
|
||||
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowBasePlugin;
|
||||
import com.github.jengelman.gradle.plugins.shadow.ShadowExtension;
|
||||
import groovy.util.Node;
|
||||
import groovy.util.NodeList;
|
||||
import org.elasticsearch.gradle.info.BuildParams;
|
||||
import org.elasticsearch.gradle.util.Util;
|
||||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.Task;
|
||||
import org.gradle.api.XmlProvider;
|
||||
import org.gradle.api.artifacts.ProjectDependency;
|
||||
import org.gradle.api.plugins.BasePlugin;
|
||||
import org.gradle.api.plugins.BasePluginConvention;
|
||||
import org.gradle.api.plugins.JavaPlugin;
|
||||
import org.gradle.api.publish.PublishingExtension;
|
||||
import org.gradle.api.publish.maven.MavenPublication;
|
||||
import org.gradle.api.publish.maven.tasks.GenerateMavenPom;
|
||||
import org.gradle.api.tasks.SourceSet;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
import org.gradle.api.tasks.bundling.Jar;
|
||||
import org.gradle.language.base.plugins.LifecycleBasePlugin;
|
||||
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
import static org.elasticsearch.gradle.util.GradleUtils.maybeConfigure;
|
||||
|
||||
public class PublishPlugin implements Plugin<Project> {
|
||||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
project.getPluginManager().apply("nebula.maven-base-publish");
|
||||
|
||||
configureJavadocJar(project);
|
||||
configureSourcesJar(project);
|
||||
configurePomGeneration(project);
|
||||
}
|
||||
|
||||
private static String getArchivesBaseName(Project project) {
|
||||
return project.getConvention().getPlugin(BasePluginConvention.class).getArchivesBaseName();
|
||||
}
|
||||
|
||||
/**Configuration generation of maven poms. */
|
||||
private static void configurePomGeneration(Project project) {
|
||||
|
||||
TaskProvider<Task> generatePomTask = project.getTasks().register("generatePom");
|
||||
|
||||
maybeConfigure(project.getTasks(), LifecycleBasePlugin.ASSEMBLE_TASK_NAME, assemble -> assemble.dependsOn(generatePomTask));
|
||||
|
||||
project.getTasks().withType(GenerateMavenPom.class).configureEach(pomTask -> pomTask.setDestination(new Callable<String>() {
|
||||
@Override
|
||||
public String call() throws Exception {
|
||||
return String.format(
|
||||
"%s/distributions/%s-%s.pom",
|
||||
project.getBuildDir(),
|
||||
getArchivesBaseName(project),
|
||||
project.getVersion()
|
||||
);
|
||||
}
|
||||
}));
|
||||
|
||||
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
|
||||
|
||||
project.getPluginManager().withPlugin("com.github.johnrengelman.shadow", plugin -> {
|
||||
MavenPublication publication = publishing.getPublications().maybeCreate("shadow", MavenPublication.class);
|
||||
ShadowExtension shadow = project.getExtensions().getByType(ShadowExtension.class);
|
||||
shadow.component(publication);
|
||||
// Workaround for https://github.com/johnrengelman/shadow/issues/334
|
||||
// Here we manually add any project dependencies in the "shadow" configuration to our generated POM
|
||||
publication.getPom().withXml(xml -> {
|
||||
Node root = xml.asNode();
|
||||
root.appendNode("name", project.getName());
|
||||
root.appendNode("description", project.getDescription());
|
||||
Node dependenciesNode = (Node) ((NodeList) root.get("dependencies")).get(0);
|
||||
project.getConfigurations().getByName(ShadowBasePlugin.getCONFIGURATION_NAME()).getAllDependencies().all(dependency -> {
|
||||
if (dependency instanceof ProjectDependency) {
|
||||
Node dependencyNode = dependenciesNode.appendNode("dependency");
|
||||
dependencyNode.appendNode("groupId", dependency.getGroup());
|
||||
ProjectDependency projectDependency = (ProjectDependency) dependency;
|
||||
String artifactId = getArchivesBaseName(projectDependency.getDependencyProject());
|
||||
dependencyNode.appendNode("artifactId", artifactId);
|
||||
dependencyNode.appendNode("version", dependency.getVersion());
|
||||
dependencyNode.appendNode("scope", "compile");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Add git origin info to generated POM files
|
||||
publishing.getPublications().withType(MavenPublication.class, publication -> {
|
||||
publication.getPom().withXml(PublishPlugin::addScmInfo);
|
||||
|
||||
// have to defer this until archivesBaseName is set
|
||||
project.afterEvaluate(p -> publication.setArtifactId(getArchivesBaseName(project)));
|
||||
|
||||
generatePomTask.configure(
|
||||
t -> t.dependsOn(String.format("generatePomFileFor%sPublication", Util.capitalize(publication.getName())))
|
||||
);
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
private static void addScmInfo(XmlProvider xml) {
|
||||
Node root = xml.asNode();
|
||||
root.appendNode("url", Util.urlFromOrigin(BuildParams.getGitOrigin()));
|
||||
Node scmNode = root.appendNode("scm");
|
||||
scmNode.appendNode("url", BuildParams.getGitOrigin());
|
||||
}
|
||||
|
||||
/** Adds a javadocJar task to generate a jar containing javadocs. */
|
||||
private static void configureJavadocJar(Project project) {
|
||||
project.getPlugins().withId("elasticsearch.java", p -> {
|
||||
TaskProvider<Jar> javadocJarTask = project.getTasks().register("javadocJar", Jar.class);
|
||||
javadocJarTask.configure(jar -> {
|
||||
jar.getArchiveClassifier().set("javadoc");
|
||||
jar.setGroup("build");
|
||||
jar.setDescription("Assembles a jar containing javadocs.");
|
||||
jar.from(project.getTasks().named(JavaPlugin.JAVADOC_TASK_NAME));
|
||||
});
|
||||
maybeConfigure(project.getTasks(), BasePlugin.ASSEMBLE_TASK_NAME, t -> t.dependsOn(javadocJarTask));
|
||||
});
|
||||
}
|
||||
|
||||
static void configureSourcesJar(Project project) {
|
||||
project.getPlugins().withId("elasticsearch.java", p -> {
|
||||
TaskProvider<Jar> sourcesJarTask = project.getTasks().register("sourcesJar", Jar.class);
|
||||
sourcesJarTask.configure(jar -> {
|
||||
jar.getArchiveClassifier().set("sources");
|
||||
jar.setGroup("build");
|
||||
jar.setDescription("Assembles a jar containing source files.");
|
||||
SourceSet mainSourceSet = Util.getJavaMainSourceSet(project).get();
|
||||
jar.from(mainSourceSet.getAllSource());
|
||||
});
|
||||
maybeConfigure(project.getTasks(), BasePlugin.ASSEMBLE_TASK_NAME, t -> t.dependsOn(sourcesJarTask));
|
||||
});
|
||||
}
|
||||
}
|
|
@ -23,7 +23,6 @@ import org.elasticsearch.gradle.util.Util;
|
|||
import org.gradle.api.Plugin;
|
||||
import org.gradle.api.Project;
|
||||
import org.gradle.api.publish.PublishingExtension;
|
||||
import org.gradle.api.publish.maven.plugins.MavenPublishPlugin;
|
||||
import org.gradle.api.publish.maven.tasks.GenerateMavenPom;
|
||||
import org.gradle.api.tasks.TaskProvider;
|
||||
|
||||
|
@ -34,7 +33,7 @@ public class PomValidationPlugin implements Plugin<Project> {
|
|||
|
||||
@Override
|
||||
public void apply(Project project) {
|
||||
project.getPlugins().withType(MavenPublishPlugin.class).whenPluginAdded(p -> {
|
||||
project.getPluginManager().withPlugin("maven-publish", p -> {
|
||||
PublishingExtension publishing = project.getExtensions().getByType(PublishingExtension.class);
|
||||
publishing.getPublications().all(publication -> {
|
||||
String publicationName = Util.capitalize(publication.getName());
|
||||
|
|
|
@ -37,6 +37,9 @@ import java.net.URI;
|
|||
import java.net.URISyntaxException;
|
||||
import java.util.Locale;
|
||||
import java.util.Optional;
|
||||
import java.util.function.Supplier;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
public class Util {
|
||||
|
||||
|
@ -144,4 +147,31 @@ public class Util {
|
|||
? Optional.empty()
|
||||
: Optional.ofNullable(GradleUtils.getJavaSourceSets(project).findByName(SourceSet.MAIN_SOURCE_SET_NAME));
|
||||
}
|
||||
|
||||
static final Pattern GIT_PATTERN = Pattern.compile("git@([^:]+):([^\\.]+)\\.git");
|
||||
|
||||
/** Find the reponame. */
|
||||
public static String urlFromOrigin(String origin) {
|
||||
if (origin == null) {
|
||||
return null; // best effort, the url doesnt really matter, it is just required by maven central
|
||||
}
|
||||
if (origin.startsWith("https")) {
|
||||
return origin;
|
||||
}
|
||||
Matcher matcher = GIT_PATTERN.matcher(origin);
|
||||
if (matcher.matches()) {
|
||||
return String.format("https://%s/%s", matcher.group(1), matcher.group(2));
|
||||
} else {
|
||||
return origin; // best effort, the url doesnt really matter, it is just required by maven central
|
||||
}
|
||||
}
|
||||
|
||||
public static Object toStringable(Supplier<String> getter) {
|
||||
return new Object() {
|
||||
@Override
|
||||
public String toString() {
|
||||
return getter.get();
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
implementation-class=org.elasticsearch.gradle.PublishPlugin
|
|
@ -27,6 +27,9 @@ thirdPartyAudit.enabled = false
|
|||
// This requires an additional Jar not part of build-tools
|
||||
loggerUsageCheck.enabled = false
|
||||
|
||||
// TODO: shouldn't be part of BuildPlugin, should be tested separately
|
||||
validateNebulaPom.enabled = false
|
||||
|
||||
task hello {
|
||||
doFirst {
|
||||
println "build plugin can be applied"
|
||||
|
|
|
@ -22,7 +22,7 @@ import org.elasticsearch.gradle.info.BuildParams
|
|||
apply plugin: 'elasticsearch.testclusters'
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'elasticsearch.rest-test'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
apply plugin: 'elasticsearch.rest-resources'
|
||||
|
||||
group = 'org.elasticsearch.client'
|
||||
|
|
|
@ -19,7 +19,7 @@ import de.thetaphi.forbiddenapis.gradle.CheckForbiddenApis
|
|||
* under the License.
|
||||
*/
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* under the License.
|
||||
*/
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
|
|
|
@ -353,10 +353,8 @@ configure(subprojects.findAll { it.name == 'integ-test-zip' }) {
|
|||
MavenFilteringHack.filter(it, project(':distribution').restTestExpansions)
|
||||
}
|
||||
|
||||
|
||||
// The integ-test-distribution is published to maven
|
||||
BuildPlugin.configurePomGeneration(project)
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
// make the pom file name use elasticsearch instead of the project name
|
||||
archivesBaseName = "elasticsearch${it.name.contains('oss') ? '-oss' : ''}"
|
||||
|
@ -364,37 +362,9 @@ configure(subprojects.findAll { it.name == 'integ-test-zip' }) {
|
|||
publishing {
|
||||
publications {
|
||||
nebula {
|
||||
artifactId archivesBaseName
|
||||
pom.packaging = 'zip'
|
||||
artifact(buildDist.flatMap { it.archiveFile })
|
||||
}
|
||||
/*
|
||||
* HUGE HACK: the underlying maven publication library refuses to
|
||||
* deploy any attached artifacts when the packaging type is set to
|
||||
* 'pom'. But Sonatype's OSS repositories require source files for
|
||||
* artifacts that are of type 'zip'. We already publish the source
|
||||
* and javadoc for Elasticsearch under the various other subprojects.
|
||||
* So here we create another publication using the same name that
|
||||
* has the "real" pom, and rely on the fact that gradle will execute
|
||||
* the publish tasks in alphabetical order. This lets us publish the
|
||||
* zip file and even though the pom says the type is 'pom' instead of
|
||||
* 'zip'. We cannot setup a dependency between the tasks because the
|
||||
* publishing tasks are created *extremely* late in the configuration
|
||||
* phase, so that we cannot get ahold of the actual task. Furthermore,
|
||||
* this entire hack only exists so we can make publishing to maven
|
||||
* local work, since we publish to maven central externally.
|
||||
*/
|
||||
nebulaRealPom(MavenPublication) {
|
||||
artifactId archivesBaseName
|
||||
pom.packaging = 'pom'
|
||||
pom.withXml { XmlProvider xml ->
|
||||
Node root = xml.asNode()
|
||||
root.appendNode('name', 'Elasticsearch')
|
||||
root.appendNode('description', 'A Distributed RESTful Search Engine')
|
||||
root.appendNode('url', PluginBuildPlugin.urlFromOrigin(BuildParams.gitOrigin))
|
||||
Node scmNode = root.appendNode('scm')
|
||||
scmNode.appendNode('url', BuildParams.gitOrigin)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.optional-base'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
dependencies {
|
||||
compile 'net.sf.jopt-simple:jopt-simple:5.0.2'
|
||||
|
|
|
@ -20,7 +20,7 @@ import org.elasticsearch.gradle.info.BuildParams
|
|||
*/
|
||||
|
||||
apply plugin: 'nebula.optional-base'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
archivesBaseName = 'elasticsearch-core'
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
dependencies {
|
||||
testCompile(project(":test:framework")) {
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
dependencies {
|
||||
compile project(':libs:elasticsearch-core')
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
dependencies {
|
||||
// do not add non-test compile dependencies to secure-sm without a good reason to do so
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
apply plugin: "nebula.maven-base-publish"
|
||||
apply plugin: "elasticsearch.publish"
|
||||
|
||||
dependencies {
|
||||
compile project(':libs:elasticsearch-core')
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
dependencies {
|
||||
compile project(':libs:elasticsearch-core')
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
group = 'org.elasticsearch.plugin'
|
||||
archivesBaseName = 'elasticsearch-scripting-painless-spi'
|
||||
|
|
|
@ -18,7 +18,7 @@ import org.elasticsearch.gradle.info.BuildParams
|
|||
* specific language governing permissions and limitations
|
||||
* under the License.
|
||||
*/
|
||||
apply plugin: "nebula.maven-base-publish"
|
||||
apply plugin: "elasticsearch.publish"
|
||||
|
||||
esplugin {
|
||||
description 'The nio transport.'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
apply plugin: 'elasticsearch.rest-resources'
|
||||
apply plugin: 'elasticsearch.validate-rest-spec'
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ import org.elasticsearch.gradle.info.BuildParams
|
|||
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.optional-base'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
apply plugin: 'elasticsearch.internal-cluster-test'
|
||||
|
||||
publishing {
|
||||
|
|
|
@ -23,7 +23,7 @@ subprojects {
|
|||
|
||||
group = 'org.elasticsearch.test'
|
||||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
|
||||
// TODO: should we have licenses for our test deps?
|
||||
dependencyLicenses.enabled = false
|
||||
|
|
|
@ -5,7 +5,7 @@ import java.nio.file.Files
|
|||
import java.nio.file.Paths
|
||||
|
||||
apply plugin: 'elasticsearch.esplugin'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
apply plugin: 'elasticsearch.internal-cluster-test'
|
||||
|
||||
archivesBaseName = 'x-pack-core'
|
||||
|
|
|
@ -3,7 +3,7 @@ import org.elasticsearch.gradle.info.BuildParams
|
|||
evaluationDependsOn(xpackModule('core'))
|
||||
|
||||
apply plugin: 'elasticsearch.esplugin'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
esplugin {
|
||||
name 'x-pack-identity-provider'
|
||||
description 'Elasticsearch Expanded Pack Plugin - Identity Provider'
|
||||
|
|
|
@ -3,7 +3,7 @@ import org.elasticsearch.gradle.info.BuildParams
|
|||
evaluationDependsOn(xpackModule('core'))
|
||||
|
||||
apply plugin: 'elasticsearch.esplugin'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
esplugin {
|
||||
name 'x-pack-security'
|
||||
description 'Elasticsearch Expanded Pack Plugin - Security'
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
apply plugin: 'elasticsearch.build'
|
||||
apply plugin: 'nebula.maven-base-publish'
|
||||
apply plugin: 'elasticsearch.publish'
|
||||
apply plugin: 'com.github.johnrengelman.shadow'
|
||||
|
||||
description = 'JDBC driver for Elasticsearch'
|
||||
|
|
Loading…
Reference in New Issue