Relocate projects to spring-boot-project
Move projects to better reflect the way that Spring Boot is released. The following projects are under `spring-boot-project`: - `spring-boot` - `spring-boot-autoconfigure` - `spring-boot-tools` - `spring-boot-starters` - `spring-boot-actuator` - `spring-boot-actuator-autoconfigure` - `spring-boot-test` - `spring-boot-test-autoconfigure` - `spring-boot-devtools` - `spring-boot-cli` - `spring-boot-docs` See gh-9316
This commit is contained in:
@@ -0,0 +1,41 @@
|
||||
def processModule(File moduleDir, File generatedResourcesDir) {
|
||||
def moduleName = moduleDir.name
|
||||
def factoriesFile = new File(moduleDir, 'META-INF/spring.factories')
|
||||
new File(generatedResourcesDir, "auto-configuration-classes-${moduleName}.adoc")
|
||||
.withPrintWriter {
|
||||
generateAutoConfigurationClassTable(moduleName, factoriesFile, it)
|
||||
}
|
||||
}
|
||||
|
||||
def generateAutoConfigurationClassTable(String module, File factories, PrintWriter writer) {
|
||||
writer.println '[cols="4,1"]'
|
||||
writer.println '|==='
|
||||
writer.println '| Configuration Class | Links'
|
||||
|
||||
getAutoConfigurationClasses(factories).each {
|
||||
writer.println ''
|
||||
writer.println "| {github-code}/$module/src/main/java/$it.path.{sc-ext}[`$it.name`]"
|
||||
writer.println "| {dc-root}/$it.path.{dc-ext}[javadoc]"
|
||||
}
|
||||
|
||||
writer.println '|==='
|
||||
}
|
||||
|
||||
def getAutoConfigurationClasses(File factories) {
|
||||
factories.withInputStream {
|
||||
def properties = new Properties()
|
||||
properties.load(it)
|
||||
properties.get('org.springframework.boot.autoconfigure.EnableAutoConfiguration')
|
||||
.split(',')
|
||||
.collect {
|
||||
def path = it.replace('.', '/')
|
||||
def name = it.substring(it.lastIndexOf('.') + 1)
|
||||
[ 'path': path, 'name': name]
|
||||
}
|
||||
.sort {a, b -> a.name.compareTo(b.name)}
|
||||
}
|
||||
}
|
||||
|
||||
def autoConfigDir = new File(project.build.directory, 'auto-config')
|
||||
def generatedResourcesDir = new File(project.build.directory, 'generated-resources')
|
||||
autoConfigDir.eachDir { processModule(it, generatedResourcesDir) }
|
||||
@@ -0,0 +1,76 @@
|
||||
import groovy.util.XmlSlurper
|
||||
|
||||
def getStarters(File dir) {
|
||||
def starters = []
|
||||
new File(project.build.directory, 'external-resources/starter-poms').eachDir { starterDir ->
|
||||
def pom = new XmlSlurper().parse(new File(starterDir, 'pom.xml'))
|
||||
def dependencies = getDependencies(pom)
|
||||
if (isStarter(dependencies)) {
|
||||
def name = pom.artifactId.text()
|
||||
starters << [
|
||||
'name': name,
|
||||
'description': postProcessDescription(pom.description.text()),
|
||||
'dependencies': dependencies,
|
||||
'pomUrl': "{github-code}/spring-boot-starters/$name/pom.xml"
|
||||
]
|
||||
}
|
||||
}
|
||||
return starters.sort { it.name }
|
||||
}
|
||||
|
||||
boolean isApplicationStarter(def starter) {
|
||||
!isTechnicalStarter(starter) && !isProductionStarter(starter)
|
||||
}
|
||||
|
||||
boolean isTechnicalStarter(def starter) {
|
||||
starter.name != 'spring-boot-starter-test' && !isProductionStarter(starter) &&
|
||||
starter.dependencies.find {
|
||||
it.startsWith('org.springframework.boot:spring-boot-starter') } == null
|
||||
}
|
||||
|
||||
boolean isProductionStarter(def starter) {
|
||||
starter.name in ['spring-boot-starter-actuator']
|
||||
}
|
||||
|
||||
boolean isStarter(def dependencies) {
|
||||
!dependencies.empty
|
||||
}
|
||||
|
||||
def postProcessDescription(String description) {
|
||||
addStarterCrossLinks(removeExtraWhitespace(description))
|
||||
}
|
||||
|
||||
def removeExtraWhitespace(String input) {
|
||||
input.replaceAll('\\s+', ' ')
|
||||
}
|
||||
|
||||
def addStarterCrossLinks(String input) {
|
||||
input.replaceAll('(spring-boot-starter[A-Za-z-]*)', '<<$1,`$1`>>')
|
||||
}
|
||||
|
||||
def getDependencies(def pom) {
|
||||
dependencies = []
|
||||
pom.dependencies.dependency.each { dependency ->
|
||||
dependencies << "${dependency.groupId.text()}:${dependency.artifactId.text()}"
|
||||
}
|
||||
dependencies
|
||||
}
|
||||
|
||||
def writeTable(String name, def starters) {
|
||||
new File(project.build.directory, "generated-resources/${name}.adoc").withPrintWriter { writer ->
|
||||
writer.println '|==='
|
||||
writer.println '| Name | Description | Pom'
|
||||
starters.each { starter ->
|
||||
writer.println ''
|
||||
writer.println "| [[${starter.name}]]`${starter.name}`"
|
||||
writer.println "| ${starter.description}"
|
||||
writer.println "| ${starter.pomUrl}[Pom]"
|
||||
}
|
||||
writer.println '|==='
|
||||
}
|
||||
}
|
||||
|
||||
def starters = getStarters(new File(project.build.directory, 'external-resources/starter-poms'))
|
||||
writeTable('application-starters', starters.findAll { isApplicationStarter(it) })
|
||||
writeTable('production-starters', starters.findAll { isProductionStarter(it) })
|
||||
writeTable('technical-starters', starters.findAll { isTechnicalStarter(it) })
|
||||
@@ -0,0 +1,117 @@
|
||||
import groovy.io.FileType
|
||||
|
||||
import java.util.Properties
|
||||
|
||||
import org.springframework.core.io.InputStreamResource
|
||||
import org.springframework.core.type.AnnotationMetadata
|
||||
import org.springframework.core.type.ClassMetadata
|
||||
import org.springframework.core.type.classreading.MetadataReader
|
||||
import org.springframework.core.type.classreading.MetadataReaderFactory
|
||||
import org.springframework.core.type.classreading.SimpleMetadataReaderFactory
|
||||
import org.springframework.util.ClassUtils
|
||||
import org.springframework.util.StringUtils
|
||||
|
||||
class Project {
|
||||
|
||||
final List<File> classFiles
|
||||
|
||||
final Properties springFactories
|
||||
|
||||
Project(File rootDirectory) {
|
||||
this.springFactories = loadSpringFactories(rootDirectory)
|
||||
this.classFiles = []
|
||||
rootDirectory.eachFileRecurse (FileType.FILES) { file ->
|
||||
if (file.name.endsWith('.class')) {
|
||||
classFiles << file
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static Properties loadSpringFactories(File rootDirectory) {
|
||||
Properties springFactories = new Properties()
|
||||
new File(rootDirectory, 'META-INF/spring.factories').withInputStream { inputStream ->
|
||||
springFactories.load(inputStream)
|
||||
}
|
||||
return springFactories
|
||||
}
|
||||
}
|
||||
|
||||
class TestSlice {
|
||||
|
||||
final String name
|
||||
|
||||
final SortedSet<String> importedAutoConfiguration
|
||||
|
||||
TestSlice(String annotationName, Collection<String> importedAutoConfiguration) {
|
||||
this.name = ClassUtils.getShortName(annotationName)
|
||||
this.importedAutoConfiguration = new TreeSet<String>(importedAutoConfiguration)
|
||||
}
|
||||
}
|
||||
|
||||
List<TestSlice> createTestSlices(Project project) {
|
||||
MetadataReaderFactory metadataReaderFactory = new SimpleMetadataReaderFactory()
|
||||
project.classFiles
|
||||
.findAll { classFile ->
|
||||
classFile.name.endsWith('Test.class')
|
||||
}.collect { classFile ->
|
||||
createMetadataReader(metadataReaderFactory, classFile)
|
||||
}.findAll { metadataReader ->
|
||||
metadataReader.classMetadata.annotation
|
||||
}.collect { metadataReader ->
|
||||
createTestSlice(project.springFactories, metadataReader.classMetadata, metadataReader.annotationMetadata)
|
||||
}.sort {
|
||||
a, b -> a.name.compareTo b.name
|
||||
}
|
||||
}
|
||||
|
||||
MetadataReader createMetadataReader(MetadataReaderFactory factory, File classFile) {
|
||||
classFile.withInputStream { inputStream ->
|
||||
factory.getMetadataReader(new InputStreamResource(inputStream))
|
||||
}
|
||||
}
|
||||
|
||||
TestSlice createTestSlice(Properties springFactories, ClassMetadata classMetadata, AnnotationMetadata annotationMetadata) {
|
||||
new TestSlice(classMetadata.className, getImportedAutoConfiguration(springFactories, annotationMetadata))
|
||||
}
|
||||
|
||||
Set<String> getImportedAutoConfiguration(Properties springFactories, AnnotationMetadata annotationMetadata) {
|
||||
Set<String> importers = findMetaImporters(annotationMetadata)
|
||||
if (annotationMetadata.isAnnotated('org.springframework.boot.autoconfigure.ImportAutoConfiguration')) {
|
||||
importers.add(annotationMetadata.className)
|
||||
}
|
||||
importers
|
||||
.collect { autoConfigurationImporter ->
|
||||
StringUtils.commaDelimitedListToSet(springFactories.get(autoConfigurationImporter))
|
||||
}.flatten()
|
||||
}
|
||||
|
||||
Set<String> findMetaImporters(AnnotationMetadata annotationMetadata) {
|
||||
annotationMetadata.annotationTypes
|
||||
.findAll { annotationType ->
|
||||
isAutoConfigurationImporter(annotationType, annotationMetadata)
|
||||
}
|
||||
}
|
||||
|
||||
boolean isAutoConfigurationImporter(String annotationType, AnnotationMetadata metadata) {
|
||||
metadata.getMetaAnnotationTypes(annotationType).contains('org.springframework.boot.autoconfigure.ImportAutoConfiguration')
|
||||
}
|
||||
|
||||
void writeTestSlicesTable(List<TestSlice> testSlices) {
|
||||
new File(project.build.directory, "generated-resources/test-slice-auto-configuration.adoc").withPrintWriter { writer ->
|
||||
writer.println '[cols="d,a"]'
|
||||
writer.println '|==='
|
||||
writer.println '| Test slice | Imported auto-configuration'
|
||||
testSlices.each { testSlice ->
|
||||
writer.println ''
|
||||
writer.println "| `@${testSlice.name}`"
|
||||
writer.print '| '
|
||||
testSlice.importedAutoConfiguration.each {
|
||||
writer.println "`${it}`"
|
||||
}
|
||||
}
|
||||
writer.println '|==='
|
||||
}
|
||||
}
|
||||
|
||||
List<TestSlice> testSlices = createTestSlices(new Project(new File(project.build.directory, 'test-auto-config')))
|
||||
writeTestSlicesTable(testSlices)
|
||||
Reference in New Issue
Block a user