Skip to content

tool: generate configuration properties reference - #2145

Draft
cstamas wants to merge 2 commits into
eclipse-openvsx:mainfrom
cstamas:config-doco
Draft

tool: generate configuration properties reference#2145
cstamas wants to merge 2 commits into
eclipse-openvsx:mainfrom
cstamas:config-doco

Conversation

@cstamas

@cstamas cstamas commented Sep 3, 2026

Copy link
Copy Markdown
Member

Adds a JBang script that scans src/main/java for @Value("${...}") and @ConfigurationProperties(...) usages and generates a Markdown reference of every configuration property the server reads — key, default value, source location, and any @ConfigurationProperties prefix with its bound fields.

There's no spring-boot-configuration-processor wired into this project, and even if there would be, it generates incomplete list, so there's currently no generated list of config properties to reference; this fills that gap without adding a build-time dependency.

  • server/scripts/src/ConfigPropertiesReport.java — Java 25 JBang script (pure JDK, no external dependencies), following the existing convention in scripts/src/ (see DependencyOverrideCheck.java as example)
  • server/scripts/config-properties-report.sh — thin wrapper, mirrors dependency-override-check.sh

Regex-based source scanning (no AST parser) that correctly handles the real edge cases present in this codebase: nested ${outer:${inner:default}} defaults, SpEL-wrapped @Value expressions, string-concatenated @Value args resolved against same-file constants, @ConfigurationProperties prefixes declared via a constant reference (RateLimitProperties.PROPERTY_PREFIX), and @ConfigurationProperties on @Bean-returned collections regardless of annotation order (MirrorConfig).

Out of scope: cross-referencing application*.yml/.properties for actually-configured values, and recursing into @ConfigurationProperties nested field types beyond one level (e.g. RemoteScannerProperties's Map<String, ScannerConfig> keys are operator-chosen at runtime and aren't enumerable from source).

Example output:
https://gist.github.com/cstamas/f853eec0307f8d5977106bf69f505d29


A bit unrelated: tidy up the buildSrc sub-project to be Java 25 (as "outer build") as it now aligns the two, and IDEs like Idea are not confused about it anymore. Also JBang IDEA plugin now works just fine.

Adds a jbang script that scans src/main/java for @value("${...}") and @ConfigurationProperties(...) usages and generates a Markdown reference of every configuration property the server reads — key, default value, source location, and any @ConfigurationProperties prefix with its bound fields.

There's no spring-boot-configuration-processor wired into this project, so there's currently no generated list of config properties to reference; this fills that gap without adding a build-time dependency.

- server/scripts/src/ConfigPropertiesReport.java — jbang script (pure JDK, no external dependencies), following the existing convention in scripts/src/ (see DependencyOverrideCheck.java)
- server/scripts/config-properties-report.sh — thin wrapper, mirrors dependency-override-check.sh

Regex-based source scanning (no AST parser) that correctly handles the real edge cases present in this codebase: nested ${outer:${inner:default}} defaults, SpEL-wrapped @value expressions, string-concatenated @value args resolved against same-file constants, @ConfigurationProperties prefixes declared via a constant reference (RateLimitProperties.PROPERTY_PREFIX), and @ConfigurationProperties on @Bean-returned collections regardless of annotation order (MirrorConfig).

Out of scope: cross-referencing application*.yml/.properties for actually-configured values, and recursing into @ConfigurationProperties nested field types beyond one level (e.g. RemoteScannerProperties's Map<String, ScannerConfig> keys are operator-chosen at runtime and aren't enumerable from source).

Example output:
https://gist.github.com/cstamas/f853eec0307f8d5977106bf69f505d29
@cstamas
cstamas requested a review from netomi September 3, 2026 10:12
As right now IDEA goes lala

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

The new ConfigPropertiesReport.java has confirmed correctness/compilation issues (record component access + text-block handling + merging behavior) that will produce a broken or inaccurate report.

Once you've addressed the issues Copilot identified, you can request another Copilot review.

Pull request overview

Adds a new server-side developer script to generate a Markdown reference of Spring configuration properties by scanning @Value("${...}") and @ConfigurationProperties(...) usages, and aligns the server scripts/build tooling with Java 25.

Changes:

  • Add ConfigPropertiesReport.java (JBang) plus a config-properties-report.sh wrapper to generate a configuration properties reference from source.
  • Update existing JBang scripts to declare //JAVA 25+.
  • Bump maven-artifact used by the dependency override checker and align buildSrc compilation to Java 25.
File summaries
File Description
server/scripts/src/ImportSort.java Declares Java 25+ for the JBang script.
server/scripts/src/DependencyOverrideCheck.java Updates Maven artifact dependency and declares Java 25+.
server/scripts/src/ConfigPropertiesReport.java New JBang script that scans sources and prints a Markdown config-properties report.
server/scripts/src/ClosingBraceFix.java Declares Java 25+ for the JBang script.
server/scripts/src/AddBracesFix.java Declares Java 25+ for the JBang script.
server/scripts/config-properties-report.sh New wrapper to run the report script from the server root.
server/buildSrc/build.gradle Updates Maven artifact version and sets Java compatibility to 25.
Review details
  • Files reviewed: 7/7 changed files
  • Comments generated: 4
  • Review effort level: Lite

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Comment on lines +65 to +72
var defaultCell = entry.defaultValue == null || entry.defaultValue.isEmpty()
? "-"
: "`" + mdEscape(entry.defaultValue) + "`";
var sourceCell =
String.join(", ", entry.sources.stream().map(s -> "`" + s + "`").toList());
var noteCell = entry.note == null ? "" : mdEscape(entry.note);
System.out.println(
"| `" + entry.key + "` | " + defaultCell + " | " + sourceCell + " | " + noteCell + " |");
Comment on lines +312 to +322
void addEntry(
TreeMap<String, PropertyEntry> entries, String key, String defaultValue, String source, String note) {
var existing = entries.get(key);
if (existing == null) {
var sources = new LinkedHashSet<String>();
sources.add(source);
entries.put(key, new PropertyEntry(key, defaultValue, sources, note));
} else {
existing.sources().add(source);
}
}
Comment on lines +329 to +331
String blankStringLiterals(String source) {
return QUOTED_SEGMENT.matcher(source).replaceAll(m -> "\"" + "x".repeat(m.group(1).length()) + "\"");
}
Comment on lines +43 to +51
try (Stream<Path> paths = Files.walk(Path.of("src/main/java"))) {
for (Path path : paths.filter(p -> p.toString().endsWith(".java")).toList()) {
var raw = Files.readString(path, StandardCharsets.UTF_8);
var blanked = blankComments(blankStringLiterals(raw));
var file = path.getFileName().toString();
scanValueAnnotations(raw, blanked, file, entries);
scanConfigurationProperties(raw, blanked, file, entries, configPropsClasses);
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants