Skip to content

Commit

Permalink
Move publishing configuration to a separate plugin (#56727)
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
rjernst committed May 15, 2020
1 parent 5e90ff3 commit 9fb80d3
Show file tree
Hide file tree
Showing 29 changed files with 351 additions and 281 deletions.
2 changes: 1 addition & 1 deletion buildSrc/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
208 changes: 2 additions & 206 deletions buildSrc/src/main/groovy/org/elasticsearch/gradle/BuildPlugin.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand All @@ -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)
Expand Down Expand Up @@ -304,207 +300,7 @@ class BuildPlugin implements Plugin<Project> {
throw new GradleException(message)
}
}

/**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) }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down
Loading

0 comments on commit 9fb80d3

Please sign in to comment.