Browse Source
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-15885pull/1503/head
11 changed files with 33 additions and 398 deletions
@ -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 |
|
||||||
@ -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