Refactor the spring-beans build
This commit merges back the "spring-beans-groovy" module into the main "spring-beans" one. The build is configured so: * Java and Groovy sources are jointly compiled * Kotlin sources are compiled after With this change, the `MergePlugin` is not used anymore in the project build and therefore is removed. The `DetectSplitPackagesPlugin` wasn't applied so it's been removed as well. Issue: SPR-15885
This commit is contained in:
parent
0c178ff762
commit
41cbc4670f
60
build.gradle
60
build.gradle
|
@ -184,7 +184,6 @@ configure(allprojects) { project ->
|
|||
}
|
||||
|
||||
configure(subprojects - project(":spring-build-src")) { subproject ->
|
||||
apply plugin: "merge"
|
||||
apply from: "${gradleScriptDir}/publish-maven.gradle"
|
||||
apply plugin: "io.spring.dependency-management"
|
||||
|
||||
|
@ -379,47 +378,6 @@ project("spring-core") {
|
|||
}
|
||||
}
|
||||
|
||||
project("spring-beans") {
|
||||
description = "Spring Beans"
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-core"))
|
||||
compile(files(project(":spring-core").cglibRepackJar))
|
||||
optional("javax.inject:javax.inject:1")
|
||||
optional("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
|
||||
optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
|
||||
optional("org.yaml:snakeyaml:1.18")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-beans-groovy") {
|
||||
description "Groovy Bean Definitions"
|
||||
|
||||
merge.into = project(":spring-beans")
|
||||
apply plugin: "groovy"
|
||||
|
||||
dependencies {
|
||||
compile(project(":spring-core"))
|
||||
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
|
||||
}
|
||||
|
||||
// This module's Java and Groovy sources need to be compiled together.
|
||||
compileJava.enabled = false
|
||||
sourceSets {
|
||||
main {
|
||||
groovy {
|
||||
srcDir "src/main/java"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
compileGroovy {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
}
|
||||
|
||||
project("spring-aop") {
|
||||
description = "Spring AOP"
|
||||
|
||||
|
@ -1110,23 +1068,6 @@ project("spring-framework-bom") {
|
|||
repositories.mavenInstaller {
|
||||
pom.whenConfigured {
|
||||
packaging = "pom"
|
||||
withXml {
|
||||
asNode().children().last() + {
|
||||
delegate.dependencyManagement {
|
||||
delegate.dependencies {
|
||||
parent.subprojects.sort { "$it.name" }.each { p ->
|
||||
if (p.hasProperty("merge") && p.merge.into == null && p != project) {
|
||||
delegate.dependency {
|
||||
delegate.groupId(p.group)
|
||||
delegate.artifactId(p.name)
|
||||
delegate.version(p.version)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1151,7 +1092,6 @@ configure(rootProject) {
|
|||
|
||||
apply plugin: "groovy"
|
||||
apply plugin: "io.spring.dependency-management"
|
||||
// apply plugin: "detect-split-packages"
|
||||
apply from: "${gradleScriptDir}/jdiff.gradle"
|
||||
apply from: "${gradleScriptDir}/docs.gradle"
|
||||
|
||||
|
|
|
@ -1,158 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2013 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.build.gradle
|
||||
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.GradleException
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.Task
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
|
||||
|
||||
/**
|
||||
* Gradle plugin that detects identically named, non-empty packages split across multiple
|
||||
* subprojects, e.g. "org.springframework.context.annotation" existing in both spring-core
|
||||
* and spring-aspects. Adds a 'detectSplitPackages' task to the current project's task
|
||||
* collection. If the project already contains a 'check' task (i.e. is a typical Gradle
|
||||
* project with the "java" plugin applied), the 'check' task will be updated to depend on
|
||||
* the execution of 'detectSplitPackages'.
|
||||
*
|
||||
* By default, all subprojects will be scanned. Use the 'projectsToScan' task property to
|
||||
* modify this value. Example usage:
|
||||
*
|
||||
* apply plugin: 'detect-split-packages // typically applied to root project
|
||||
*
|
||||
* detectSplitPackages {
|
||||
* packagesToScan -= project(":spring-xyz") // scan every project but spring-xyz
|
||||
* }
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Glyn Normington
|
||||
* @author Chris Beams
|
||||
*/
|
||||
public class DetectSplitPackagesPlugin implements Plugin<Project> {
|
||||
public void apply(Project project) {
|
||||
def tasks = project.tasks
|
||||
Task detectSplitPackages = tasks.create("detectSplitPackages", DetectSplitPackagesTask.class)
|
||||
if (tasks.asMap.containsKey("check")) {
|
||||
tasks.getByName("check").dependsOn detectSplitPackages
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public class DetectSplitPackagesTask extends DefaultTask {
|
||||
|
||||
private static final String JAVA_FILE_SUFFIX = ".java"
|
||||
private static final String PACKAGE_SEPARATOR = "."
|
||||
private static final String HIDDEN_DIRECTORY_PREFIX = "."
|
||||
|
||||
@Input
|
||||
Set<Project> projectsToScan = project.subprojects
|
||||
|
||||
public DetectSplitPackagesTask() {
|
||||
this.group = "Verification"
|
||||
this.description = "Detects packages split across two or more subprojects."
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
public void detectSplitPackages() {
|
||||
def splitPackages = doDetectSplitPackages()
|
||||
if (!splitPackages.isEmpty()) {
|
||||
def message = "The following split package(s) have been detected:\n"
|
||||
splitPackages.each { pkg, mod ->
|
||||
message += " - ${pkg} (split across ${mod[0].name} and ${mod[1].name})\n"
|
||||
}
|
||||
throw new GradleException(message)
|
||||
}
|
||||
}
|
||||
|
||||
private Map<String, List<Project>> doDetectSplitPackages() {
|
||||
def splitPackages = [:]
|
||||
def mergedProjects = findMergedProjects()
|
||||
def packagesByProject = mapPackagesByProject()
|
||||
|
||||
def projects = packagesByProject.keySet().toArray()
|
||||
def nProjects = projects.length
|
||||
|
||||
for (int i = 0; i < nProjects - 1; i++) {
|
||||
for (int j = i + 1; j < nProjects - 1; j++) {
|
||||
def prj_i = projects[i]
|
||||
def prj_j = projects[j]
|
||||
|
||||
def pkgs_i = new HashSet(packagesByProject.get(prj_i))
|
||||
def pkgs_j = packagesByProject.get(prj_j)
|
||||
pkgs_i.retainAll(pkgs_j)
|
||||
|
||||
if (!pkgs_i.isEmpty()
|
||||
&& mergedProjects.get(prj_i) != prj_j
|
||||
&& mergedProjects.get(prj_j) != prj_i) {
|
||||
pkgs_i.each { pkg ->
|
||||
def readablePkg = pkg.substring(1).replaceAll(File.separator, PACKAGE_SEPARATOR)
|
||||
splitPackages[readablePkg] = [prj_i, prj_j]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return splitPackages;
|
||||
}
|
||||
|
||||
private Map<Project, Set<String>> mapPackagesByProject() {
|
||||
def packagesByProject = [:]
|
||||
this.projectsToScan.each { Project p ->
|
||||
def packages = new HashSet<String>()
|
||||
p.sourceSets.main.java.srcDirs.each { File dir ->
|
||||
findPackages(packages, dir, "")
|
||||
}
|
||||
if (!packages.isEmpty()) {
|
||||
packagesByProject.put(p, packages)
|
||||
}
|
||||
}
|
||||
return packagesByProject;
|
||||
}
|
||||
|
||||
private Map<Project, Project> findMergedProjects() {
|
||||
def mergedProjects = [:]
|
||||
this.projectsToScan.findAll { p ->
|
||||
p.plugins.findPlugin(MergePlugin)
|
||||
}.findAll { p ->
|
||||
p.merge.into
|
||||
}.each { p ->
|
||||
mergedProjects.put(p, p.merge.into)
|
||||
}
|
||||
return mergedProjects
|
||||
}
|
||||
|
||||
private static void findPackages(Set<String> packages, File dir, String packagePath) {
|
||||
def scanDir = new File(dir, packagePath)
|
||||
def File[] javaFiles = scanDir.listFiles({ file ->
|
||||
!file.isDirectory() && file.name.endsWith(JAVA_FILE_SUFFIX)
|
||||
} as FileFilter)
|
||||
|
||||
if (javaFiles != null && javaFiles.length != 0) {
|
||||
packages.add(packagePath)
|
||||
}
|
||||
|
||||
scanDir.listFiles({ File file ->
|
||||
file.isDirectory() && !file.name.startsWith(HIDDEN_DIRECTORY_PREFIX)
|
||||
} as FileFilter).each { File subDir ->
|
||||
findPackages(packages, dir, packagePath + File.separator + subDir.name)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1,177 +0,0 @@
|
|||
/*
|
||||
* Copyright 2002-2015 the original author or authors.
|
||||
*
|
||||
* Licensed 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.springframework.build.gradle
|
||||
|
||||
import org.gradle.api.*
|
||||
import org.gradle.api.artifacts.Configuration
|
||||
import org.gradle.api.artifacts.ProjectDependency;
|
||||
import org.gradle.api.artifacts.maven.Conf2ScopeMapping
|
||||
import org.gradle.api.plugins.MavenPlugin
|
||||
import org.gradle.plugins.ide.eclipse.EclipsePlugin
|
||||
import org.gradle.plugins.ide.idea.IdeaPlugin
|
||||
import org.gradle.api.invocation.*
|
||||
|
||||
/**
|
||||
* Gradle plugin that allows projects to merged together. Primarily developed to
|
||||
* allow Spring to support multiple incompatible versions of third-party
|
||||
* dependencies (for example Hibernate v3 and v4).
|
||||
* <p>
|
||||
* The 'merge' extension should be used to define how projects are merged, for example:
|
||||
* <pre class="code">
|
||||
* configure(subprojects) {
|
||||
* apply plugin: MergePlugin
|
||||
* }
|
||||
*
|
||||
* project("myproject") {
|
||||
* }
|
||||
*
|
||||
* project("myproject-extra") {
|
||||
* merge.into = project("myproject")
|
||||
* }
|
||||
* </pre>
|
||||
* <p>
|
||||
* This plugin adds two new configurations:
|
||||
* <ul>
|
||||
* <li>merging - Contains the projects being merged into this project<li>
|
||||
* <li>runtimeMerge - Contains all dependencies that are merge projects. These are used
|
||||
* to allow an IDE to reference merge projects.</li>
|
||||
* <ul>
|
||||
*
|
||||
* @author Rob Winch
|
||||
* @author Phillip Webb
|
||||
*/
|
||||
class MergePlugin implements Plugin<Project> {
|
||||
|
||||
private static boolean attachedProjectsEvaluated;
|
||||
|
||||
public void apply(Project project) {
|
||||
project.plugins.apply(MavenPlugin)
|
||||
project.plugins.apply(EclipsePlugin)
|
||||
project.plugins.apply(IdeaPlugin)
|
||||
|
||||
MergeModel model = project.extensions.create("merge", MergeModel)
|
||||
model.project = project
|
||||
project.configurations.create("merging")
|
||||
Configuration runtimeMerge = project.configurations.create("runtimeMerge")
|
||||
|
||||
// Ensure the IDE can reference merged projects
|
||||
project.eclipse.classpath.plusConfigurations += [ runtimeMerge ]
|
||||
project.idea.module.scopes.PROVIDED.plus += [ runtimeMerge ]
|
||||
|
||||
// Hook to perform the actual merge logic
|
||||
project.afterEvaluate{
|
||||
if (it.merge.into != null) {
|
||||
setup(it)
|
||||
}
|
||||
setupIdeDependencies(it)
|
||||
}
|
||||
|
||||
// Hook to build runtimeMerge dependencies
|
||||
if (!attachedProjectsEvaluated) {
|
||||
project.gradle.projectsEvaluated{
|
||||
postProcessProjects(it)
|
||||
}
|
||||
attachedProjectsEvaluated = true;
|
||||
}
|
||||
}
|
||||
|
||||
private void setup(Project project) {
|
||||
project.merge.into.dependencies.add("merging", project)
|
||||
project.dependencies.add("provided", project.merge.into.sourceSets.main.output)
|
||||
project.dependencies.add("runtimeMerge", project.merge.into)
|
||||
setupTaskDependencies(project)
|
||||
setupMaven(project)
|
||||
}
|
||||
|
||||
private void setupTaskDependencies(Project project) {
|
||||
// invoking a task will invoke the task with the same name on 'into' project
|
||||
["sourcesJar", "jar", "javadocJar", "javadoc", "install", "artifactoryPublish"].each {
|
||||
def task = project.tasks.findByPath(it)
|
||||
if (task) {
|
||||
task.enabled = false
|
||||
task.dependsOn(project.merge.into.tasks.findByPath(it))
|
||||
}
|
||||
}
|
||||
|
||||
// update 'into' project artifacts to contain the source artifact contents
|
||||
project.merge.into.sourcesJar.from(project.sourcesJar.source)
|
||||
project.merge.into.jar.from(project.sourceSets.main.output)
|
||||
project.merge.into.javadoc {
|
||||
source += project.javadoc.source
|
||||
classpath += project.javadoc.classpath
|
||||
}
|
||||
}
|
||||
|
||||
private void setupIdeDependencies(Project project) {
|
||||
project.configurations.each { c ->
|
||||
c.dependencies.findAll( { it instanceof org.gradle.api.artifacts.ProjectDependency } ).each { d ->
|
||||
d.dependencyProject.merge.from.each { from ->
|
||||
project.dependencies.add("runtimeMerge", from)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setupMaven(Project project) {
|
||||
project.configurations.each { configuration ->
|
||||
Conf2ScopeMapping mapping = project.conf2ScopeMappings.getMapping([configuration])
|
||||
if (mapping.scope) {
|
||||
Configuration intoConfiguration = project.merge.into.configurations.create(
|
||||
project.name + "-" + configuration.name)
|
||||
configuration.excludeRules.each {
|
||||
configuration.exclude([
|
||||
(ExcludeRule.GROUP_KEY) : it.group,
|
||||
(ExcludeRule.MODULE_KEY) : it.module])
|
||||
}
|
||||
configuration.dependencies.each {
|
||||
def intoCompile = project.merge.into.configurations.getByName("compile")
|
||||
// Protect against changing a compile scope dependency (SPR-10218)
|
||||
if (!intoCompile.dependencies.contains(it)) {
|
||||
intoConfiguration.dependencies.add(it)
|
||||
}
|
||||
}
|
||||
def index = project.parent.childProjects.findIndexOf {p -> p.getValue() == project}
|
||||
project.merge.into.install.repositories.mavenInstaller.pom.scopeMappings.addMapping(
|
||||
mapping.priority + 100 + index, intoConfiguration, mapping.scope)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private postProcessProjects(Gradle gradle) {
|
||||
gradle.allprojects(new Action<Project>() {
|
||||
public void execute(Project project) {
|
||||
project.configurations.getByName("runtime").allDependencies.withType(ProjectDependency).each{
|
||||
Configuration dependsOnMergedFrom = it.dependencyProject.configurations.getByName("merging");
|
||||
dependsOnMergedFrom.dependencies.each{ dep ->
|
||||
project.dependencies.add("runtimeMerge", dep.dependencyProject)
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
class MergeModel {
|
||||
Project project;
|
||||
Project into;
|
||||
List<Project> from = [];
|
||||
|
||||
public void setInto(Project into) {
|
||||
this.into = into;
|
||||
into.merge.from.add(project);
|
||||
}
|
||||
}
|
|
@ -1 +0,0 @@
|
|||
implementation-class=org.springframework.build.gradle.DetectSplitPackagesPlugin
|
|
@ -1 +0,0 @@
|
|||
implementation-class=org.springframework.build.gradle.MergePlugin
|
|
@ -12,7 +12,6 @@ pluginManagement {
|
|||
include "spring-aop"
|
||||
include "spring-aspects"
|
||||
include "spring-beans"
|
||||
include "spring-beans-groovy"
|
||||
include "spring-context"
|
||||
include "spring-context-support"
|
||||
include "spring-context-indexer"
|
||||
|
|
|
@ -0,0 +1,33 @@
|
|||
description = "Spring Beans"
|
||||
|
||||
apply plugin: "groovy"
|
||||
|
||||
dependencies {
|
||||
compile(project(':spring-core'))
|
||||
optional("javax.inject:javax.inject:1")
|
||||
optional("org.jetbrains.kotlin:kotlin-reflect:${kotlinVersion}")
|
||||
optional("org.jetbrains.kotlin:kotlin-stdlib:${kotlinVersion}")
|
||||
optional("org.yaml:snakeyaml:1.18")
|
||||
optional("org.codehaus.groovy:groovy-all:${groovyVersion}")
|
||||
testCompile("org.apache.tomcat.embed:tomcat-embed-core:${tomcatVersion}")
|
||||
}
|
||||
|
||||
// This modules does joint compilation for Java and Groovy code,
|
||||
// with the compileGroovy task.
|
||||
sourceSets {
|
||||
main.groovy.srcDirs += "src/main/java"
|
||||
main.java.srcDirs = []
|
||||
}
|
||||
|
||||
compileGroovy {
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
}
|
||||
|
||||
// This module also builds Kotlin code and the compileKotlin task
|
||||
// naturally depends on compileJava.
|
||||
// We need to redefine dependencies to break task cycles.
|
||||
compileGroovy.dependsOn = compileGroovy.taskDependencies.values - 'compileJava'
|
||||
compileKotlin.dependsOn(compileGroovy)
|
||||
compileKotlin.classpath += files(compileGroovy.destinationDir)
|
||||
|
Loading…
Reference in New Issue