Skip to content

Commit 73087f3

Browse files
committed
Merge branch '3.5.x'
Closes gh-48071
2 parents 4096b73 + 52951ed commit 73087f3

File tree

13 files changed

+615
-182
lines changed

13 files changed

+615
-182
lines changed

buildSrc/build.gradle

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,10 @@ gradlePlugin {
114114
id = "org.springframework.boot.bom"
115115
implementationClass = "org.springframework.boot.build.bom.BomPlugin"
116116
}
117+
configurationMetadataPlugin {
118+
id = "org.springframework.boot.configuration-metadata"
119+
implementationClass = "org.springframework.boot.build.context.properties.ConfigurationMetadataPlugin"
120+
}
117121
configurationPropertiesPlugin {
118122
id = "org.springframework.boot.configuration-properties"
119123
implementationClass = "org.springframework.boot.build.context.properties.ConfigurationPropertiesPlugin"

buildSrc/src/main/java/org/springframework/boot/build/context/properties/CheckAdditionalSpringConfigurationMetadata.java

Lines changed: 6 additions & 98 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,6 @@
1818

1919
import java.io.File;
2020
import java.io.IOException;
21-
import java.nio.file.Files;
22-
import java.nio.file.Path;
23-
import java.nio.file.StandardOpenOption;
24-
import java.util.ArrayList;
25-
import java.util.Collection;
26-
import java.util.Collections;
27-
import java.util.Iterator;
28-
import java.util.List;
29-
import java.util.Map;
3021

3122
import org.gradle.api.file.FileTree;
3223
import org.gradle.api.file.RegularFileProperty;
@@ -37,8 +28,8 @@
3728
import org.gradle.api.tasks.SourceTask;
3829
import org.gradle.api.tasks.TaskAction;
3930
import org.gradle.api.tasks.VerificationException;
40-
import tools.jackson.core.StreamReadFeature;
41-
import tools.jackson.databind.json.JsonMapper;
31+
32+
import org.springframework.boot.build.context.properties.ConfigurationPropertiesAnalyzer.Report;
4233

4334
/**
4435
* {@link SourceTask} that checks additional Spring configuration metadata files.
@@ -65,98 +56,15 @@ public FileTree getSource() {
6556

6657
@TaskAction
6758
void check() throws IOException {
68-
Report report = createReport();
59+
ConfigurationPropertiesAnalyzer analyzer = new ConfigurationPropertiesAnalyzer(getSource().getFiles());
60+
Report report = new Report(this.projectDir);
61+
analyzer.analyzeSort(report);
6962
File reportFile = getReportLocation().get().getAsFile();
70-
Files.write(reportFile.toPath(), report, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
63+
report.write(reportFile);
7164
if (report.hasProblems()) {
7265
throw new VerificationException(
7366
"Problems found in additional Spring configuration metadata. See " + reportFile + " for details.");
7467
}
7568
}
7669

77-
@SuppressWarnings("unchecked")
78-
private Report createReport() {
79-
JsonMapper jsonMapper = JsonMapper.builder().enable(StreamReadFeature.INCLUDE_SOURCE_IN_LOCATION).build();
80-
Report report = new Report();
81-
for (File file : getSource().getFiles()) {
82-
Analysis analysis = report.analysis(this.projectDir.toPath().relativize(file.toPath()));
83-
Map<String, Object> json = jsonMapper.readValue(file, Map.class);
84-
check("groups", json, analysis);
85-
check("properties", json, analysis);
86-
check("hints", json, analysis);
87-
}
88-
return report;
89-
}
90-
91-
@SuppressWarnings("unchecked")
92-
private void check(String key, Map<String, Object> json, Analysis analysis) {
93-
List<Map<String, Object>> groups = (List<Map<String, Object>>) json.getOrDefault(key, Collections.emptyList());
94-
List<String> names = groups.stream().map((group) -> (String) group.get("name")).toList();
95-
List<String> sortedNames = sortedCopy(names);
96-
for (int i = 0; i < names.size(); i++) {
97-
String actual = names.get(i);
98-
String expected = sortedNames.get(i);
99-
if (!actual.equals(expected)) {
100-
analysis.problems.add("Wrong order at $." + key + "[" + i + "].name - expected '" + expected
101-
+ "' but found '" + actual + "'");
102-
}
103-
}
104-
}
105-
106-
private List<String> sortedCopy(Collection<String> original) {
107-
List<String> copy = new ArrayList<>(original);
108-
Collections.sort(copy);
109-
return copy;
110-
}
111-
112-
private static final class Report implements Iterable<String> {
113-
114-
private final List<Analysis> analyses = new ArrayList<>();
115-
116-
private Analysis analysis(Path path) {
117-
Analysis analysis = new Analysis(path);
118-
this.analyses.add(analysis);
119-
return analysis;
120-
}
121-
122-
private boolean hasProblems() {
123-
for (Analysis analysis : this.analyses) {
124-
if (!analysis.problems.isEmpty()) {
125-
return true;
126-
}
127-
}
128-
return false;
129-
}
130-
131-
@Override
132-
public Iterator<String> iterator() {
133-
List<String> lines = new ArrayList<>();
134-
for (Analysis analysis : this.analyses) {
135-
lines.add(analysis.source.toString());
136-
lines.add("");
137-
if (analysis.problems.isEmpty()) {
138-
lines.add("No problems found.");
139-
}
140-
else {
141-
lines.addAll(analysis.problems);
142-
}
143-
lines.add("");
144-
}
145-
return lines.iterator();
146-
}
147-
148-
}
149-
150-
private static final class Analysis {
151-
152-
private final List<String> problems = new ArrayList<>();
153-
154-
private final Path source;
155-
156-
private Analysis(Path source) {
157-
this.source = source;
158-
}
159-
160-
}
161-
16270
}
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
/*
2+
* Copyright 2012-present the original author or authors.
3+
*
4+
* Licensed under the Apache License, Version 2.0 (the "License");
5+
* you may not use this file except in compliance with the License.
6+
* You may obtain a copy of the License at
7+
*
8+
* https://www.apache.org/licenses/LICENSE-2.0
9+
*
10+
* Unless required by applicable law or agreed to in writing, software
11+
* distributed under the License is distributed on an "AS IS" BASIS,
12+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
* See the License for the specific language governing permissions and
14+
* limitations under the License.
15+
*/
16+
17+
package org.springframework.boot.build.context.properties;
18+
19+
import java.io.File;
20+
import java.io.IOException;
21+
import java.util.List;
22+
23+
import org.gradle.api.DefaultTask;
24+
import org.gradle.api.file.RegularFileProperty;
25+
import org.gradle.api.provider.ListProperty;
26+
import org.gradle.api.provider.Property;
27+
import org.gradle.api.tasks.Input;
28+
import org.gradle.api.tasks.InputFile;
29+
import org.gradle.api.tasks.OutputFile;
30+
import org.gradle.api.tasks.PathSensitive;
31+
import org.gradle.api.tasks.PathSensitivity;
32+
import org.gradle.api.tasks.SourceTask;
33+
import org.gradle.api.tasks.TaskAction;
34+
import org.gradle.api.tasks.VerificationException;
35+
36+
import org.springframework.boot.build.context.properties.ConfigurationPropertiesAnalyzer.Report;
37+
38+
/**
39+
* {@link SourceTask} that checks manual Spring configuration metadata files.
40+
*
41+
* @author Andy Wilkinson
42+
* @author Stephane Nicoll
43+
*/
44+
public abstract class CheckManualSpringConfigurationMetadata extends DefaultTask {
45+
46+
private final File projectDir;
47+
48+
public CheckManualSpringConfigurationMetadata() {
49+
this.projectDir = getProject().getProjectDir();
50+
}
51+
52+
@OutputFile
53+
public abstract RegularFileProperty getReportLocation();
54+
55+
@InputFile
56+
@PathSensitive(PathSensitivity.RELATIVE)
57+
public abstract Property<File> getMetadataLocation();
58+
59+
@Input
60+
public abstract ListProperty<String> getExclusions();
61+
62+
@TaskAction
63+
void check() throws IOException {
64+
ConfigurationPropertiesAnalyzer analyzer = new ConfigurationPropertiesAnalyzer(
65+
List.of(getMetadataLocation().get()));
66+
Report report = new Report(this.projectDir);
67+
analyzer.analyzeSort(report);
68+
analyzer.analyzePropertyDescription(report, getExclusions().get());
69+
File reportFile = getReportLocation().get().getAsFile();
70+
report.write(reportFile);
71+
if (report.hasProblems()) {
72+
throw new VerificationException(
73+
"Problems found in manual Spring configuration metadata. See " + reportFile + " for details.");
74+
}
75+
}
76+
77+
}

buildSrc/src/main/java/org/springframework/boot/build/context/properties/CheckSpringConfigurationMetadata.java

Lines changed: 9 additions & 84 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,7 @@
1818

1919
import java.io.File;
2020
import java.io.IOException;
21-
import java.nio.file.Files;
22-
import java.nio.file.Path;
23-
import java.nio.file.StandardOpenOption;
24-
import java.util.ArrayList;
25-
import java.util.Iterator;
2621
import java.util.List;
27-
import java.util.Map;
2822

2923
import org.gradle.api.DefaultTask;
3024
import org.gradle.api.file.RegularFileProperty;
@@ -37,7 +31,8 @@
3731
import org.gradle.api.tasks.SourceTask;
3832
import org.gradle.api.tasks.TaskAction;
3933
import org.gradle.api.tasks.VerificationException;
40-
import tools.jackson.databind.json.JsonMapper;
34+
35+
import org.springframework.boot.build.context.properties.ConfigurationPropertiesAnalyzer.Report;
4136

4237
/**
4338
* {@link SourceTask} that checks {@code spring-configuration-metadata.json} files.
@@ -46,10 +41,10 @@
4641
*/
4742
public abstract class CheckSpringConfigurationMetadata extends DefaultTask {
4843

49-
private final Path projectRoot;
44+
private final File projectRoot;
5045

5146
public CheckSpringConfigurationMetadata() {
52-
this.projectRoot = getProject().getProjectDir().toPath();
47+
this.projectRoot = getProject().getProjectDir();
5348
}
5449

5550
@OutputFile
@@ -64,86 +59,16 @@ public CheckSpringConfigurationMetadata() {
6459

6560
@TaskAction
6661
void check() throws IOException {
67-
Report report = createReport();
62+
Report report = new Report(this.projectRoot);
63+
ConfigurationPropertiesAnalyzer analyzer = new ConfigurationPropertiesAnalyzer(
64+
List.of(getMetadataLocation().get().getAsFile()));
65+
analyzer.analyzePropertyDescription(report, getExclusions().get());
6866
File reportFile = getReportLocation().get().getAsFile();
69-
Files.write(reportFile.toPath(), report, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING);
67+
report.write(reportFile);
7068
if (report.hasProblems()) {
7169
throw new VerificationException(
7270
"Problems found in Spring configuration metadata. See " + reportFile + " for details.");
7371
}
7472
}
7573

76-
@SuppressWarnings("unchecked")
77-
private Report createReport() {
78-
JsonMapper jsonMapper = new JsonMapper();
79-
File file = getMetadataLocation().get().getAsFile();
80-
Report report = new Report(this.projectRoot.relativize(file.toPath()));
81-
Map<String, Object> json = jsonMapper.readValue(file, Map.class);
82-
List<Map<String, Object>> properties = (List<Map<String, Object>>) json.get("properties");
83-
for (Map<String, Object> property : properties) {
84-
String name = (String) property.get("name");
85-
if (!isDeprecated(property) && !isDescribed(property) && !isExcluded(name)) {
86-
report.propertiesWithNoDescription.add(name);
87-
}
88-
}
89-
return report;
90-
}
91-
92-
private boolean isExcluded(String propertyName) {
93-
for (String exclusion : getExclusions().get()) {
94-
if (propertyName.equals(exclusion)) {
95-
return true;
96-
}
97-
if (exclusion.endsWith(".*")) {
98-
if (propertyName.startsWith(exclusion.substring(0, exclusion.length() - 2))) {
99-
return true;
100-
}
101-
}
102-
}
103-
return false;
104-
}
105-
106-
@SuppressWarnings("unchecked")
107-
private boolean isDeprecated(Map<String, Object> property) {
108-
return (Map<String, Object>) property.get("deprecation") != null;
109-
}
110-
111-
private boolean isDescribed(Map<String, Object> property) {
112-
return property.get("description") != null;
113-
}
114-
115-
private static final class Report implements Iterable<String> {
116-
117-
private final List<String> propertiesWithNoDescription = new ArrayList<>();
118-
119-
private final Path source;
120-
121-
private Report(Path source) {
122-
this.source = source;
123-
}
124-
125-
private boolean hasProblems() {
126-
return !this.propertiesWithNoDescription.isEmpty();
127-
}
128-
129-
@Override
130-
public Iterator<String> iterator() {
131-
List<String> lines = new ArrayList<>();
132-
lines.add(this.source.toString());
133-
lines.add("");
134-
if (this.propertiesWithNoDescription.isEmpty()) {
135-
lines.add("No problems found.");
136-
}
137-
else {
138-
lines.add("The following properties have no description:");
139-
lines.add("");
140-
lines.addAll(this.propertiesWithNoDescription.stream().map((line) -> "\t" + line).toList());
141-
}
142-
lines.add("");
143-
return lines.iterator();
144-
145-
}
146-
147-
}
148-
14974
}

0 commit comments

Comments
 (0)