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:
Ryan Ernst 2020-05-14 18:56:59 -07:00 committed by Ryan Ernst
parent 5e90ff32f7
commit 9fb80d3827
No known key found for this signature in database
GPG Key ID: 5F7EA39E15F54DCE
29 changed files with 351 additions and 281 deletions

View File

@ -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

View File

@ -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) }

View File

@ -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) {

View File

@ -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)));
}
}

View File

@ -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));
});
}
}

View File

@ -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());

View File

@ -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();
}
};
}
}

View File

@ -0,0 +1 @@
implementation-class=org.elasticsearch.gradle.PublishPlugin

View File

@ -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"

View File

@ -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'

View File

@ -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

View File

@ -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

View File

@ -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)
}
}
}
}
}

View File

@ -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'

View File

@ -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'

View File

@ -18,7 +18,7 @@
*/
apply plugin: 'elasticsearch.build'
apply plugin: 'nebula.maven-base-publish'
apply plugin: 'elasticsearch.publish'
dependencies {
testCompile(project(":test:framework")) {

View File

@ -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')

View File

@ -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

View File

@ -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')

View File

@ -18,7 +18,7 @@
*/
apply plugin: 'elasticsearch.build'
apply plugin: 'nebula.maven-base-publish'
apply plugin: 'elasticsearch.publish'
dependencies {
compile project(':libs:elasticsearch-core')

View File

@ -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'

View File

@ -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.'

View File

@ -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'

View File

@ -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 {

View File

@ -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

View File

@ -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'

View File

@ -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'

View File

@ -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'

View File

@ -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'