From 87c097f8d0db6dd168fe538a15cf44397f5103c7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dinis=20Ferreira?= Date: Tue, 26 May 2026 10:56:58 +0200 Subject: [PATCH 01/10] feat: headless CheckDocApplication + Maven wiring for HTML docs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add an Eclipse IApplication, com.avaloq.tools.ddk.check.standalone.CheckDocApplication, that walks a source directory for .check files and emits one docs/content/.html per CheckCatalog by invoking CheckGenerator.compileDoc from a standalone CheckStandaloneSetup injector — no Eclipse workbench required. The application is registered through plugin.xml under the new id com.avaloq.tools.ddk.check.core.docApplication; the new package com.avaloq.tools.ddk.check.standalone is exported and the manifest now requires org.eclipse.equinox.app. Wire it from com.avaloq.tools.ddk.sample.helloworld via an opt-in `generateCheckDocs` Maven profile that runs tycho-eclipse-plugin:eclipse-run during generate-resources. Known PoC limitation: tycho-eclipse-plugin:eclipse-run resolves the application bundle against the target platform only, so reactor-built artifacts such as check.core are not visible during a fresh build. Documented inline in the profile; productionising needs a p2 repository aggregator or a published p2 update site for the Check bundles. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../META-INF/MANIFEST.MF | 4 +- com.avaloq.tools.ddk.check.core/plugin.xml | 8 ++ .../check/standalone/CheckDocApplication.java | 85 +++++++++++++++++++ .../pom.xml | 51 +++++++++++ 4 files changed, 147 insertions(+), 1 deletion(-) create mode 100644 com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java diff --git a/com.avaloq.tools.ddk.check.core/META-INF/MANIFEST.MF b/com.avaloq.tools.ddk.check.core/META-INF/MANIFEST.MF index bb3b31dd8b..c4caf46713 100644 --- a/com.avaloq.tools.ddk.check.core/META-INF/MANIFEST.MF +++ b/com.avaloq.tools.ddk.check.core/META-INF/MANIFEST.MF @@ -27,7 +27,8 @@ Require-Bundle: org.eclipse.xtext, com.avaloq.tools.ddk.xtext, org.apache.commons.lang3, org.apache.commons.text, - org.objectweb.asm;resolution:=optional + org.objectweb.asm;resolution:=optional, + org.eclipse.equinox.app Export-Package: com.avaloq.tools.ddk.check, com.avaloq.tools.ddk.check.check, com.avaloq.tools.ddk.check.check.impl, @@ -44,6 +45,7 @@ Export-Package: com.avaloq.tools.ddk.check, com.avaloq.tools.ddk.check.scoping, com.avaloq.tools.ddk.check.serializer, com.avaloq.tools.ddk.check.services, + com.avaloq.tools.ddk.check.standalone, com.avaloq.tools.ddk.check.typing, com.avaloq.tools.ddk.check.util, com.avaloq.tools.ddk.check.validation diff --git a/com.avaloq.tools.ddk.check.core/plugin.xml b/com.avaloq.tools.ddk.check.core/plugin.xml index 7edc2a56d3..81f2b8b7cc 100644 --- a/com.avaloq.tools.ddk.check.core/plugin.xml +++ b/com.avaloq.tools.ddk.check.core/plugin.xml @@ -11,4 +11,12 @@ + + + + + + diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java new file mode 100644 index 0000000000..2e242994ef --- /dev/null +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java @@ -0,0 +1,85 @@ +/******************************************************************************* + * Copyright (c) 2026 Avaloq Group AG and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Avaloq Group AG - initial API and implementation + *******************************************************************************/ +package com.avaloq.tools.ddk.check.standalone; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Stream; + +import org.eclipse.emf.common.util.URI; +import org.eclipse.emf.ecore.EObject; +import org.eclipse.emf.ecore.resource.Resource; +import org.eclipse.equinox.app.IApplication; +import org.eclipse.equinox.app.IApplicationContext; +import org.eclipse.xtext.resource.XtextResourceSet; + +import com.avaloq.tools.ddk.check.CheckStandaloneSetup; +import com.avaloq.tools.ddk.check.check.CheckCatalog; +import com.avaloq.tools.ddk.check.generator.CheckGenerator; +import com.google.inject.Injector; +import com.google.inject.Provider; + + +/** + * Eclipse application that emits Check documentation (HTML) for every {@code .check} + * file under a source directory, without requiring an Eclipse workbench. + * + * Arguments (positional): {@code }. + * Output: {@code /.html} per catalog. + */ +@SuppressWarnings({"nls", "PMD.SystemPrintln"}) +public class CheckDocApplication implements IApplication { + + @Override + public Object start(final IApplicationContext context) throws IOException { + String[] args = (String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS); + if (args == null || args.length < 2) { + System.err.println("Usage: -application com.avaloq.tools.ddk.check.core.docApplication "); + return Integer.valueOf(1); + } + Path sourceDir = Path.of(args[0]); + Path outputDir = Path.of(args[1]); + Files.createDirectories(outputDir); + + Injector injector = new CheckStandaloneSetup().createInjectorAndDoEMFRegistration(); + CheckGenerator generator = injector.getInstance(CheckGenerator.class); + Provider resourceSets = injector.getProvider(XtextResourceSet.class); + XtextResourceSet resourceSet = resourceSets.get(); + + List checkFiles = new ArrayList<>(); + try (Stream walk = Files.walk(sourceDir)) { + walk.filter(p -> p.toString().endsWith(".check")).forEach(checkFiles::add); + } + + int catalogs = 0; + for (Path checkFile : checkFiles) { + Resource resource = resourceSet.getResource(URI.createFileURI(checkFile.toAbsolutePath().toString()), true); + for (EObject root : resource.getContents()) { + if (root instanceof CheckCatalog catalog) { + Path target = outputDir.resolve(catalog.getName() + ".html"); + Files.writeString(target, generator.compileDoc(catalog).toString()); + System.out.println("Wrote " + target); + catalogs++; + } + } + } + System.out.println("Processed " + checkFiles.size() + " .check files (" + catalogs + " catalogs)"); + return IApplication.EXIT_OK; + } + + @Override + public void stop() { + // no-op + } +} diff --git a/com.avaloq.tools.ddk.sample.helloworld/pom.xml b/com.avaloq.tools.ddk.sample.helloworld/pom.xml index 22294deeb6..d9511fd782 100644 --- a/com.avaloq.tools.ddk.sample.helloworld/pom.xml +++ b/com.avaloq.tools.ddk.sample.helloworld/pom.xml @@ -9,4 +9,55 @@ com.avaloq.tools.ddk com.avaloq.tools.ddk.sample.helloworld eclipse-plugin + + + + + generateCheckDocs + + + + org.eclipse.tycho + tycho-eclipse-plugin + ${tycho.version} + + + generate-check-docs + generate-resources + + eclipse-run + + + JavaSE-21 + + -application + com.avaloq.tools.ddk.check.core.docApplication + ${project.basedir}/src + ${project.basedir}/docs/content + + + + com.avaloq.tools.ddk.check.core + eclipse-plugin + + + + + + + + + + From d69238cd835a48748f33096f27370a2a0f73eb75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dinis=20Ferreira?= Date: Tue, 26 May 2026 11:00:34 +0200 Subject: [PATCH 02/10] feat: emit toc.xml + contexts.xml without PDE-internal APIs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add CheckDocumentationTemplates in com.avaloq.tools.ddk.check.generator — plain Xtend templates that emit the Eclipse-Help toc.xml and contexts.xml as strings, byte-compatible with what PDE used to mutate in place (three-space indent, alphabetic ordering, ' escaping). They depend only on the Check metamodel and CheckGeneratorNaming; nothing under org.eclipse.pde.internal. CheckDocApplication now aggregates every catalog it loads in one pass and writes a single docs/toc.xml + docs/contexts.xml across the whole project, alongside the per-catalog docs/content/.html files. The Eclipse-side CheckTocGenerator / CheckContextsGenerator under com.avaloq.tools.ddk.check.ui are left in place: they still handle the incremental IDE builder path, where a single .check delta must merge into existing siblings via PDE's read-modify-write. Eventually they can call the new templates and drop the PDE-internal dependency entirely. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../CheckDocumentationTemplates.xtend | 104 ++++++++++++++++++ .../check/standalone/CheckDocApplication.java | 41 +++++-- .../pom.xml | 2 +- 3 files changed, 134 insertions(+), 13 deletions(-) create mode 100644 com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend new file mode 100644 index 0000000000..7da9cb291e --- /dev/null +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend @@ -0,0 +1,104 @@ +/******************************************************************************* + * Copyright (c) 2026 Avaloq Group AG and others. + * All rights reserved. This program and the accompanying materials + * are made available under the terms of the Eclipse Public License v1.0 + * which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v10.html + * + * Contributors: + * Avaloq Group AG - initial API and implementation + *******************************************************************************/ +package com.avaloq.tools.ddk.check.generator + +import com.avaloq.tools.ddk.check.check.CheckCatalog +import com.google.inject.Inject + +import static extension com.avaloq.tools.ddk.check.generator.CheckGeneratorNaming.* + +/** + * Emits the Eclipse-Help {@code toc.xml} and context-help {@code contexts.xml} + * files for a set of {@link CheckCatalog}s as plain XML strings, without any + * dependency on PDE-internal APIs (TocModel / CtxHelpModel et al.). Designed to + * run both inside the Xtext generator and from the headless + * {@code CheckDocApplication}. + * + * The output format is byte-compatible with the files PDE used to mutate in + * place: three-space indentation, alphabetic ordering for both catalog topics + * and context entries, and apostrophes escaped as {@code '} in attributes. + */ +class CheckDocumentationTemplates { + + static val TOC_LABEL = "Check Catalogs" + static val TOC_ANCHOR = "../com.avaloq.tools.ddk.check.runtime.ui/toc.xml#checkdocumentation" + static val DOCS_REF_PREFIX = "docs/content/" + + @Inject extension CheckGeneratorNaming naming + + /** Build the contents of {@code docs/toc.xml} aggregating every catalog in {@code catalogs}. */ + def CharSequence compileToc(Iterable catalogs) { + val sorted = catalogs.sortBy[name] + ''' + + + «FOR catalog : sorted» + + «FOR category : catalog.categories» + + «FOR check : category.checks» + + + «ENDFOR» + + «ENDFOR» + «FOR check : catalog.checks» + + + «ENDFOR» + + «ENDFOR» + + ''' + } + + /** Build the contents of {@code docs/contexts.xml} aggregating every check across {@code catalogs}. */ + def CharSequence compileContexts(Iterable catalogs) { + val entries = catalogs + .flatMap[allChecks] + .map[check | new ContextEntry(check.contextId, check.label.attrEscape, parentCatalog(check).docRef + "#" + check.contextId)] + .sortBy[id] + ''' + + + «FOR e : entries» + + + + «ENDFOR» + + ''' + } + + def private String docRef(CheckCatalog c) { + DOCS_REF_PREFIX + c.docFileName + } + + def private CheckCatalog parentCatalog(org.eclipse.emf.ecore.EObject o) { + org.eclipse.xtext.EcoreUtil2.getContainerOfType(o, CheckCatalog) + } + + /** Escape characters that have special meaning inside an XML attribute value. */ + def private String attrEscape(String s) { + s?.replace("&", "&") + ?.replace("'", "'") + ?.replace("\"", """) + ?.replace("<", "<") + ?.replace(">", ">") + } + + @org.eclipse.xtend.lib.annotations.Data + private static class ContextEntry { + String id + String label + String href + } +} diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java index 2e242994ef..7a271d2870 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java @@ -26,17 +26,22 @@ import com.avaloq.tools.ddk.check.CheckStandaloneSetup; import com.avaloq.tools.ddk.check.check.CheckCatalog; +import com.avaloq.tools.ddk.check.generator.CheckDocumentationTemplates; import com.avaloq.tools.ddk.check.generator.CheckGenerator; import com.google.inject.Injector; import com.google.inject.Provider; /** - * Eclipse application that emits Check documentation (HTML) for every {@code .check} - * file under a source directory, without requiring an Eclipse workbench. + * Eclipse application that emits the full Check documentation tree (HTML pages + * plus the Eclipse-Help {@code toc.xml} / {@code contexts.xml}) from every + * {@code .check} file under a source directory, without requiring an Eclipse + * workbench. * - * Arguments (positional): {@code }. - * Output: {@code /.html} per catalog. + * Arguments (positional): {@code } where {@code docsDir} + * is the project's {@code docs/} folder. HTML pages land in + * {@code /content/.html}; the two help-system files land + * directly in {@code /}. */ @SuppressWarnings({"nls", "PMD.SystemPrintln"}) public class CheckDocApplication implements IApplication { @@ -45,15 +50,17 @@ public class CheckDocApplication implements IApplication { public Object start(final IApplicationContext context) throws IOException { String[] args = (String[]) context.getArguments().get(IApplicationContext.APPLICATION_ARGS); if (args == null || args.length < 2) { - System.err.println("Usage: -application com.avaloq.tools.ddk.check.core.docApplication "); - return Integer.valueOf(1); + System.err.println("Usage: -application com.avaloq.tools.ddk.check.core.docApplication "); + return 1; } Path sourceDir = Path.of(args[0]); - Path outputDir = Path.of(args[1]); - Files.createDirectories(outputDir); + Path docsDir = Path.of(args[1]); + Path contentDir = docsDir.resolve("content"); + Files.createDirectories(contentDir); Injector injector = new CheckStandaloneSetup().createInjectorAndDoEMFRegistration(); CheckGenerator generator = injector.getInstance(CheckGenerator.class); + CheckDocumentationTemplates docTemplates = injector.getInstance(CheckDocumentationTemplates.class); Provider resourceSets = injector.getProvider(XtextResourceSet.class); XtextResourceSet resourceSet = resourceSets.get(); @@ -62,19 +69,29 @@ public Object start(final IApplicationContext context) throws IOException { walk.filter(p -> p.toString().endsWith(".check")).forEach(checkFiles::add); } - int catalogs = 0; + List catalogs = new ArrayList<>(); for (Path checkFile : checkFiles) { Resource resource = resourceSet.getResource(URI.createFileURI(checkFile.toAbsolutePath().toString()), true); for (EObject root : resource.getContents()) { if (root instanceof CheckCatalog catalog) { - Path target = outputDir.resolve(catalog.getName() + ".html"); + catalogs.add(catalog); + Path target = contentDir.resolve(catalog.getName() + ".html"); Files.writeString(target, generator.compileDoc(catalog).toString()); System.out.println("Wrote " + target); - catalogs++; } } } - System.out.println("Processed " + checkFiles.size() + " .check files (" + catalogs + " catalogs)"); + + if (!catalogs.isEmpty()) { + Path toc = docsDir.resolve("toc.xml"); + Files.writeString(toc, docTemplates.compileToc(catalogs).toString()); + System.out.println("Wrote " + toc); + Path contexts = docsDir.resolve("contexts.xml"); + Files.writeString(contexts, docTemplates.compileContexts(catalogs).toString()); + System.out.println("Wrote " + contexts); + } + + System.out.println("Processed " + checkFiles.size() + " .check files (" + catalogs.size() + " catalogs)"); return IApplication.EXIT_OK; } diff --git a/com.avaloq.tools.ddk.sample.helloworld/pom.xml b/com.avaloq.tools.ddk.sample.helloworld/pom.xml index d9511fd782..71f8d78d04 100644 --- a/com.avaloq.tools.ddk.sample.helloworld/pom.xml +++ b/com.avaloq.tools.ddk.sample.helloworld/pom.xml @@ -44,7 +44,7 @@ -application com.avaloq.tools.ddk.check.core.docApplication ${project.basedir}/src - ${project.basedir}/docs/content + ${project.basedir}/docs From 14b7e2f70e7a73a2b8fa31f2677a3cbb07042cc6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dinis=20Ferreira?= Date: Wed, 27 May 2026 01:43:49 +0200 Subject: [PATCH 03/10] build: wire POC profile to reactor + Eclipse p2 sites The generateCheckDocs profile now declares: - a Maven dep edge to ddk-repository so its p2 site is built before helloworld in the reactor; - a list passing both that reactor p2 (file: URL) and the Eclipse-side p2 sites (releases, EMF, xtext, MWE, Orbit) to tycho-eclipse-plugin's eclipse-run, so check.core's transitive requirements resolve. Verified end-to-end: mvn -f ddk-parent/pom.xml \ -am -pl :com.avaloq.tools.ddk.sample.helloworld,:ddk-repository \ -PgenerateCheckDocs -DskipTests clean package produces docs/toc.xml, docs/contexts.xml, and docs/content/{LibraryChecks,ExecutionEnvironment}.html. Co-Authored-By: Claude Opus 4.7 (1M context) --- .../pom.xml | 45 +++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/com.avaloq.tools.ddk.sample.helloworld/pom.xml b/com.avaloq.tools.ddk.sample.helloworld/pom.xml index 71f8d78d04..c1e936e0a4 100644 --- a/com.avaloq.tools.ddk.sample.helloworld/pom.xml +++ b/com.avaloq.tools.ddk.sample.helloworld/pom.xml @@ -25,6 +25,17 @@ --> generateCheckDocs + + + + com.avaloq.tools.ddk + ddk-repository + 17.3.0-SNAPSHOT + eclipse-repository + + @@ -46,6 +57,40 @@ ${project.basedir}/src ${project.basedir}/docs + + + + reactor-p2 + p2 + file:${project.basedir}/../ddk-repository/target/repository/ + + + + eclipse-release + p2 + https://download.eclipse.org/releases/2026-03/ + + + eclipse-emf + p2 + https://download.eclipse.org/modeling/emf/emf/builds/release/2.39.0/ + + + eclipse-xtext + p2 + https://download.eclipse.org/modeling/tmf/xtext/updates/releases/2.43.0/ + + + eclipse-mwe + p2 + https://download.eclipse.org/modeling/emft/mwe/updates/releases/2.25.0/ + + + eclipse-orbit + p2 + https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.39.0 + + com.avaloq.tools.ddk.check.core From 9f4fa57ee41fe0ba0424afb67d42e16758e0cae0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dinis=20Ferreira?= Date: Wed, 27 May 2026 10:54:03 +0200 Subject: [PATCH 04/10] feat(check): restyle generated docs as self-contained HTML The per-catalog HTML used to link a stylesheet via a PLUGINS_ROOT-prefixed URL, which only resolved inside Eclipse Help's embedded browser. Opened in Chrome/Firefox/Safari the pages rendered unstyled. Switch to a self-contained design: - HTML5 doctype, viewport meta, single inline + + +
+

Check Catalogs

+

«sorted.size» catalog«IF sorted.size != 1»s«ENDIF» documented.

+
+
+
    + «FOR catalog : sorted» +
  • +

    «catalog.name»

    + «val description = catalog.description.formatDescription» + «IF description !== null» +

    «description»

    + «ENDIF» +
  • + «ENDFOR» +
+
+ + + ''' + } + def private String docRef(CheckCatalog c) { DOCS_REF_PREFIX + c.docFileName } @@ -86,6 +260,11 @@ class CheckDocumentationTemplates { org.eclipse.xtext.EcoreUtil2.getContainerOfType(o, CheckCatalog) } + /** Path used from {@code index.html} (same directory as {@code content/}). */ + def private String indexRef(CheckCatalog c) { + "content/" + c.docFileName + } + /** Escape characters that have special meaning inside an XML attribute value. */ def private String attrEscape(String s) { s?.replace("&", "&") diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend index 083ddc9b25..f376881976 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend @@ -10,6 +10,7 @@ *******************************************************************************/ package com.avaloq.tools.ddk.check.generator +import com.avaloq.tools.ddk.check.check.Check import com.avaloq.tools.ddk.check.check.CheckCatalog import com.avaloq.tools.ddk.check.util.CheckUtil import com.google.inject.Inject @@ -59,59 +60,78 @@ class CheckGenerator extends JvmModelGenerator { } } - /* Documentation compiler, generates HTML output. */ + /* Documentation compiler, generates a self-contained HTML page per catalog. */ def compileDoc (CheckCatalog catalog)''' - «val body = bodyDoc(catalog)» - - + + - - + + «catalog.name» + - -

Check Catalog «catalog.name»

- «val formattedDescription = catalog.description.formatDescription» - «IF formattedDescription !== null» +
+

«catalog.name»

+ «val formattedDescription = catalog.description.formatDescription» + «IF formattedDescription !== null»

«formattedDescription»

- «ENDIF» - «body» + «ENDIF» + «IF !catalog.checks.empty || !catalog.categories.empty» + + «ENDIF» +
+
+ «bodyDoc(catalog)» +
- ''' def bodyDoc(CheckCatalog catalog)''' - «FOR check:catalog.checks» -

«check.label» («check.defaultSeverity.name().toLowerCase»)

- «val formattedCheckDescription = check.description.formatDescription» - «IF formattedCheckDescription !== null» - «formattedCheckDescription» - «ENDIF» -

Message: «check.message.replacePlaceholder»


+ «FOR check : catalog.checks» + «checkArticle(check)» «ENDFOR» - «FOR category:catalog.categories» -
+ «FOR category : catalog.categories» +

«category.label»

- «val formattedCateogryDescription = category.description.formatDescription» - «IF formattedCateogryDescription !== null» - «formattedCateogryDescription» + «val formattedCategoryDescription = category.description.formatDescription» + «IF formattedCategoryDescription !== null» +

«formattedCategoryDescription»

«ENDIF» - «FOR check:category.checks» -
-

«check.label» («check.defaultSeverity.name().toLowerCase»)

- «val formattedCheckDescription = check.description.formatDescription» - «IF formattedCheckDescription !== null» - «formattedCheckDescription» - «ENDIF» -

Message: «check.message.replacePlaceholder»

-
+ «FOR check : category.checks» + «checkArticle(check)» «ENDFOR» -
+ «ENDFOR» ''' + def private checkArticle(Check check)''' +
+
+

«check.label» #

+ «check.defaultSeverity.name().toLowerCase» +
+ «val formattedCheckDescription = check.description.formatDescription» + «IF formattedCheckDescription !== null» + «formattedCheckDescription» + «ENDIF» +
«check.message.replacePlaceholder»
+
+ ''' + /* * Creates an IssueCodes file for a Check Catalog. Every Check Catalog will have its own file * of issue codes. diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java index 7a271d2870..5af6b3bb34 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java @@ -89,6 +89,9 @@ public Object start(final IApplicationContext context) throws IOException { Path contexts = docsDir.resolve("contexts.xml"); Files.writeString(contexts, docTemplates.compileContexts(catalogs).toString()); System.out.println("Wrote " + contexts); + Path index = docsDir.resolve("index.html"); + Files.writeString(index, docTemplates.compileIndex(catalogs).toString()); + System.out.println("Wrote " + index); } System.out.println("Processed " + checkFiles.size() + " .check files (" + catalogs.size() + " catalogs)"); diff --git a/com.avaloq.tools.ddk.check.runtime.ui/build.properties b/com.avaloq.tools.ddk.check.runtime.ui/build.properties index 688aa65996..404b564d5f 100644 --- a/com.avaloq.tools.ddk.check.runtime.ui/build.properties +++ b/com.avaloq.tools.ddk.check.runtime.ui/build.properties @@ -2,5 +2,4 @@ source.. = src/ bin.includes = META-INF/,\ .,\ plugin.xml,\ - toc.xml,\ - css/ + toc.xml diff --git a/com.avaloq.tools.ddk.check.runtime.ui/css/check.css b/com.avaloq.tools.ddk.check.runtime.ui/css/check.css deleted file mode 100644 index dc58291782..0000000000 --- a/com.avaloq.tools.ddk.check.runtime.ui/css/check.css +++ /dev/null @@ -1,53 +0,0 @@ -body { - font-size: 11pt; - font-family: arial; - font-variant: normal; - margin-left: 1.0cm; -} - -h1 { - font-size: 18pt; - font-weight: bolder; -} - -h2 { - font-size: 14pt; - font-weight: bold; -} - -div#checklabel { - font-size: 12pt; - font-weight: bold; -} - -div.description { - margin-left: 0.5cm; - font-size: 11pt; - border-top: solid thin black; -} - -div.category { - border-top: solid 1px #000; -} - -dt { - font-weight: normal; - font-style: italic; -} - -dd { - margin-top: 2mm; -} - -dl { - margin-top: 3mm; - margin-bottom: 0mm; -} - -div#checkdescription { - margin-left: 1cm; -} - -h3 span.thin { - font-weight: normal; -} \ No newline at end of file diff --git a/com.avaloq.tools.ddk.sample.helloworld/docs/content/ExecutionEnvironment.html b/com.avaloq.tools.ddk.sample.helloworld/docs/content/ExecutionEnvironment.html new file mode 100644 index 0000000000..ea4a27aaaa --- /dev/null +++ b/com.avaloq.tools.ddk.sample.helloworld/docs/content/ExecutionEnvironment.html @@ -0,0 +1,168 @@ + + + + + + ExecutionEnvironment + + + +
+

ExecutionEnvironment

+ +
+
+
+

Test category

+

Checks the greeting name length

+
+
+

Greeting name length #

+ error +
+ Checks the greeting name length +
Greeting name ...
+
+
+
+ + diff --git a/com.avaloq.tools.ddk.sample.helloworld/docs/content/LibraryChecks.html b/com.avaloq.tools.ddk.sample.helloworld/docs/content/LibraryChecks.html new file mode 100644 index 0000000000..0989857e13 --- /dev/null +++ b/com.avaloq.tools.ddk.sample.helloworld/docs/content/LibraryChecks.html @@ -0,0 +1,197 @@ + + + + + + LibraryChecks + + + +
+

LibraryChecks

+ +
+
+
+

Checks on injections in check catalogs.

+

Warning to indicate that this catalog is active.

+
+
+

Check catalog is active #

+ warning +
+ Warning to indicate that this catalog is active. +
Catalog is active
+
+
+
+

Cache injection failed #

+ error +
+ Error if the injection didn't work. +
Cache was not injected
+
+
+
+

Cache doesn't work #

+ error +
+ Error if values cannot be read from cache. +
...
+
+
+
+

Checks on formal parameters

+

Test formal parameter access.

+
+
+

Formal Parameters #

+ error +
+ Test formal parameter access. +
...
+
+
+
+ + diff --git a/com.avaloq.tools.ddk.sample.helloworld/docs/contexts.xml b/com.avaloq.tools.ddk.sample.helloworld/docs/contexts.xml index 6d50906410..9c88fab9f7 100644 --- a/com.avaloq.tools.ddk.sample.helloworld/docs/contexts.xml +++ b/com.avaloq.tools.ddk.sample.helloworld/docs/contexts.xml @@ -1,3 +1,18 @@ - \ No newline at end of file + + + + + + + + + + + + + + + + diff --git a/com.avaloq.tools.ddk.sample.helloworld/docs/index.html b/com.avaloq.tools.ddk.sample.helloworld/docs/index.html new file mode 100644 index 0000000000..c3abef4299 --- /dev/null +++ b/com.avaloq.tools.ddk.sample.helloworld/docs/index.html @@ -0,0 +1,159 @@ + + + + + + Check Catalogs + + + +
+

Check Catalogs

+

2 catalogs documented.

+
+
+ +
+ + diff --git a/com.avaloq.tools.ddk.sample.helloworld/docs/toc.xml b/com.avaloq.tools.ddk.sample.helloworld/docs/toc.xml index 62d47779b1..8f38986abc 100644 --- a/com.avaloq.tools.ddk.sample.helloworld/docs/toc.xml +++ b/com.avaloq.tools.ddk.sample.helloworld/docs/toc.xml @@ -1,3 +1,23 @@ - - \ No newline at end of file + + + + + + + + + + + + + + + + + + + + + + From 7085b20da8529d24d9c0559ab0f3a34380362f8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dinis=20Ferreira?= Date: Wed, 27 May 2026 11:00:30 +0200 Subject: [PATCH 05/10] build(test.runtime): add generateCheckDocs profile and refresh fixtures The test.runtime bundle ships docs/{toc,contexts}.xml + docs/content/*.html under its plugin.xml as Eclipse Help registrations. The committed HTMLs had not been regenerated in 12 years and still linked the (now-removed) external check.css stylesheet. - Add the same generateCheckDocs profile already used by sample.helloworld. - Regenerate docs/{index.html, toc.xml, contexts.xml, content/*.html} from the bundle's own .check sources, producing the new browser-friendly layout with severity badges and jump-nav. Also serves as a second working example of the consumer-recipe pattern. Co-Authored-By: Claude Opus 4.7 --- .../docs/content/ExecutionEnvironment.html | 178 ++++++++++++-- .../docs/content/LibraryChecks.html | 228 +++++++++++++++--- .../docs/contexts.xml | 32 +-- .../docs/index.html | 160 ++++++++++++ .../docs/toc.xml | 28 +-- .../pom.xml | 90 ++++++- 6 files changed, 633 insertions(+), 83 deletions(-) create mode 100644 com.avaloq.tools.ddk.check.test.runtime/docs/index.html diff --git a/com.avaloq.tools.ddk.check.test.runtime/docs/content/ExecutionEnvironment.html b/com.avaloq.tools.ddk.check.test.runtime/docs/content/ExecutionEnvironment.html index 3439e97b51..ea4a27aaaa 100644 --- a/com.avaloq.tools.ddk.check.test.runtime/docs/content/ExecutionEnvironment.html +++ b/com.avaloq.tools.ddk.check.test.runtime/docs/content/ExecutionEnvironment.html @@ -1,22 +1,168 @@ - - + + - - + + ExecutionEnvironment + - -

Check Catalog ExecutionEnvironment

-
-

Test category

- Checks the greeting name length -
-

Greeting name length (error)

- Checks the greeting name length -

Message: Greeting name ...

-
-
+
+

ExecutionEnvironment

+ +
+
+
+

Test category

+

Checks the greeting name length

+
+
+

Greeting name length #

+ error +
+ Checks the greeting name length +
Greeting name ...
+
+
+
- diff --git a/com.avaloq.tools.ddk.check.test.runtime/docs/content/LibraryChecks.html b/com.avaloq.tools.ddk.check.test.runtime/docs/content/LibraryChecks.html index bcf5eaa3b9..a84e860e46 100644 --- a/com.avaloq.tools.ddk.check.test.runtime/docs/content/LibraryChecks.html +++ b/com.avaloq.tools.ddk.check.test.runtime/docs/content/LibraryChecks.html @@ -1,42 +1,198 @@ - - + + - - + + LibraryChecks + - -

Check Catalog LibraryChecks

-

Check catalog for com.avaloq.tools.ddk.check.TestLanguage

-
-

Checks on injections in check catalogs.

- Warning to indicate that this catalog is active. -
-

Check catalog is active (warning)

- Warning to indicate that this catalog is active. -

Message: Catalog is active

-
-
-

Cache injection failed (error)

- Error if the injection didn't work. -

Message: Cache was not injected

-
-
-

Cache doesn't work (error)

- Error if values cannot be read from cache. -

Message: ...

-
-
-
-

Checks on formal parameters

- Test formal parameter access. -
-

Formal Parameters (error)

- Test formal parameter access. -

Message: ...

-
-
+
+

LibraryChecks

+

Check catalog for com.avaloq.tools.ddk.check.TestLanguage

+ +
+
+
+

Checks on injections in check catalogs.

+

Warning to indicate that this catalog is active.

+
+
+

Check catalog is active #

+ warning +
+ Warning to indicate that this catalog is active. +
Catalog is active
+
+
+
+

Cache injection failed #

+ error +
+ Error if the injection didn't work. +
Cache was not injected
+
+
+
+

Cache doesn't work #

+ error +
+ Error if values cannot be read from cache. +
...
+
+
+
+

Checks on formal parameters

+

Test formal parameter access.

+
+
+

Formal Parameters #

+ error +
+ Test formal parameter access. +
...
+
+
+
- diff --git a/com.avaloq.tools.ddk.check.test.runtime/docs/contexts.xml b/com.avaloq.tools.ddk.check.test.runtime/docs/contexts.xml index f88e0238ba..9c88fab9f7 100644 --- a/com.avaloq.tools.ddk.check.test.runtime/docs/contexts.xml +++ b/com.avaloq.tools.ddk.check.test.runtime/docs/contexts.xml @@ -1,18 +1,18 @@ - - - - - - - - - - - - - - - - \ No newline at end of file + + + + + + + + + + + + + + + + diff --git a/com.avaloq.tools.ddk.check.test.runtime/docs/index.html b/com.avaloq.tools.ddk.check.test.runtime/docs/index.html new file mode 100644 index 0000000000..559ea01ded --- /dev/null +++ b/com.avaloq.tools.ddk.check.test.runtime/docs/index.html @@ -0,0 +1,160 @@ + + + + + + Check Catalogs + + + +
+

Check Catalogs

+

2 catalogs documented.

+
+
+ +
+ + diff --git a/com.avaloq.tools.ddk.check.test.runtime/docs/toc.xml b/com.avaloq.tools.ddk.check.test.runtime/docs/toc.xml index 1ac3dd2a3e..8f38986abc 100644 --- a/com.avaloq.tools.ddk.check.test.runtime/docs/toc.xml +++ b/com.avaloq.tools.ddk.check.test.runtime/docs/toc.xml @@ -1,23 +1,23 @@ - - - + + + - - - - - - - + + - - - + + + + + + + + - \ No newline at end of file + diff --git a/com.avaloq.tools.ddk.check.test.runtime/pom.xml b/com.avaloq.tools.ddk.check.test.runtime/pom.xml index bd279fd000..639d5405d6 100644 --- a/com.avaloq.tools.ddk.check.test.runtime/pom.xml +++ b/com.avaloq.tools.ddk.check.test.runtime/pom.xml @@ -9,4 +9,92 @@ com.avaloq.tools.ddk.check.test.runtime eclipse-plugin - \ No newline at end of file + + + + + generateCheckDocs + + + com.avaloq.tools.ddk + ddk-repository + 17.3.0-SNAPSHOT + eclipse-repository + + + + + + org.eclipse.tycho + tycho-eclipse-plugin + ${tycho.version} + + + generate-check-docs + generate-resources + + eclipse-run + + + JavaSE-21 + + -application + com.avaloq.tools.ddk.check.core.docApplication + ${project.basedir}/src + ${project.basedir}/docs + + + + reactor-p2 + p2 + file:${project.basedir}/../ddk-repository/target/repository/ + + + eclipse-release + p2 + https://download.eclipse.org/releases/2026-03/ + + + eclipse-emf + p2 + https://download.eclipse.org/modeling/emf/emf/builds/release/2.39.0/ + + + eclipse-xtext + p2 + https://download.eclipse.org/modeling/tmf/xtext/updates/releases/2.43.0/ + + + eclipse-mwe + p2 + https://download.eclipse.org/modeling/emft/mwe/updates/releases/2.25.0/ + + + eclipse-orbit + p2 + https://download.eclipse.org/tools/orbit/simrel/orbit-aggregation/release/4.39.0 + + + + + com.avaloq.tools.ddk.check.core + eclipse-plugin + + + + + + + + + + + From 2d57b1073d72597a18a1008b9e78d4fcca72dc42 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dinis=20Ferreira?= Date: Wed, 27 May 2026 11:00:40 +0200 Subject: [PATCH 06/10] docs: add downstream Tycho consumer recipe Document the workflow for a downstream Tycho project to consume the published p2 site and invoke the headless CheckDocApplication on its own .check sources. Covers target file entry, the ~25-line tycho-eclipse-plugin pom snippet (which differs from the in-repo POC by omitting the reactor edge), the generate-resources invocation, the output layout, and three common failure modes. Establishes the repo's docs/ convention (no top-level docs/ existed yet). Co-Authored-By: Claude Opus 4.7 --- docs/check-doc-generation.md | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) create mode 100644 docs/check-doc-generation.md diff --git a/docs/check-doc-generation.md b/docs/check-doc-generation.md new file mode 100644 index 0000000000..98da950f8d --- /dev/null +++ b/docs/check-doc-generation.md @@ -0,0 +1,86 @@ +# Generating Check catalog documentation + +Generate browsable HTML docs for your Check catalogs by running a headless application against your bundle's `.check` sources. The application emits: + +- `docs/index.html` — landing page listing every catalog (self-contained, opens in any browser). +- `docs/content/.html` — one styled page per catalog with severity badges and deep-link anchors. +- `docs/toc.xml`, `docs/contexts.xml` — Eclipse Help integration artifacts (skip if you only need the browser pages). + +The styling is inline; no external CSS, JS or images. Dark mode follows the OS preference. + +## Prerequisites + +A Tycho-based project with a target platform file. Plain-Maven projects are not supported — the generator runs inside an Equinox runtime started by `tycho-eclipse-plugin:eclipse-run`. + +## 1. Add dsl-devkit to your target platform + +In your `.target` file, add the dsl-devkit p2 update site as a location and include `com.avaloq.tools.ddk.check.core`: + +```xml + + + + +``` + +For snapshots, use `https://dsldevkit.github.io/dsl-devkit/p2/snapshots/latest/` instead. To pin to a specific version, use `p2/releases//` or `p2/snapshots//`. + +## 2. Add the profile to the consumer pom + +In the bundle whose `.check` sources you want documented: + +```xml + + + generateCheckDocs + + + + org.eclipse.tycho + tycho-eclipse-plugin + + + generate-check-docs + generate-resources + eclipse-run + + JavaSE-21 + + -application + com.avaloq.tools.ddk.check.core.docApplication + ${project.basedir}/src + ${project.basedir}/docs + + + + com.avaloq.tools.ddk.check.core + eclipse-plugin + + + + + + + + + + +``` + +The application takes two args: `` (walked recursively for `*.check` files) and `` (written into). + +No `` block is needed — `eclipse-run` resolves against your project's target platform. + +## 3. Invoke + +```bash +mvn -PgenerateCheckDocs -DskipTests package +``` + +Then open `docs/index.html` in any browser. + +## Troubleshooting + +- **"Cannot resolve unit com.avaloq.tools.ddk.check.core"** — the dsl-devkit p2 site is not in your target platform. Re-resolve the target after adding it. +- **"No catalogs found"** — `` does not contain any `.check` files. The application walks the directory recursively; check the path you passed as the first ``. +- **"Application com.avaloq.tools.ddk.check.core.docApplication could not be found"** — the bundle is missing from the `` list of the `eclipse-run` execution (it is *not* enough to have it on the target platform; `eclipse-run` only installs what you list). From 18bf6cf21e04fb0c2925d282c4bc09b1075e6e01 Mon Sep 17 00:00:00 2001 From: Joao Ferreira Date: Wed, 27 May 2026 12:52:24 +0200 Subject: [PATCH 07/10] feat(check): add back-link to catalog pages and filter target/ from doc walk MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Add '← All catalogs' back-link at top of each per-catalog HTML page - Add .back-link CSS to shared STYLE block - Exclude target/ directories from .check file discovery so downstream repos with compiled output don't produce duplicate catalog entries --- .../ddk/check/generator/CheckDocumentationTemplates.xtend | 2 ++ .../com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend | 1 + .../tools/ddk/check/standalone/CheckDocApplication.java | 4 +++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend index 7d1ef605b1..e2744221ae 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend @@ -82,6 +82,8 @@ class CheckDocumentationTemplates { a:hover { text-decoration: underline; } header.catalog-header { margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 1px solid var(--border); } header.catalog-header p { color: var(--text-muted); } + a.back-link { display: inline-block; margin-bottom: 0.75rem; font-size: 0.875rem; color: var(--text-muted); } + a.back-link:hover { color: var(--link); } nav.jump { margin-top: 1rem; padding: 0.75rem 1rem; diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend index f376881976..8ade0ec40e 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend @@ -74,6 +74,7 @@ class CheckGenerator extends JvmModelGenerator {
+ ← All catalogs

«catalog.name»

«val formattedDescription = catalog.description.formatDescription» «IF formattedDescription !== null» diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java index 5af6b3bb34..a90a96a497 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java @@ -66,7 +66,9 @@ public Object start(final IApplicationContext context) throws IOException { List checkFiles = new ArrayList<>(); try (Stream walk = Files.walk(sourceDir)) { - walk.filter(p -> p.toString().endsWith(".check")).forEach(checkFiles::add); + walk.filter(p -> p.toString().endsWith(".check")) + .filter(p -> p.toString().replace('\\', '/').contains("/target/") == false) + .forEach(checkFiles::add); } List catalogs = new ArrayList<>(); From 1ab09fbd3dd9ec3924f1a8d8c24832032c98e669 Mon Sep 17 00:00:00 2001 From: Joao Ferreira Date: Wed, 27 May 2026 13:02:26 +0200 Subject: [PATCH 08/10] fix(check): exclude hidden dirs and target/ from doc walk; anchor back-link - Filter out hidden directories (.*/) and target/ from .check file discovery so compiled copies and VCS worktrees are not duplicated - Add id= to index.html
  • entries so the back-link can anchor directly to the catalog's position in the list --- .../tools/ddk/check/generator/CheckDocumentationTemplates.xtend | 2 +- .../com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend | 2 +- .../avaloq/tools/ddk/check/standalone/CheckDocApplication.java | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend index e2744221ae..681fe4ef16 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend @@ -239,7 +239,7 @@ class CheckDocumentationTemplates {
      «FOR catalog : sorted» -
    • +
    • «catalog.name»

      «val description = catalog.description.formatDescription» «IF description !== null» diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend index 8ade0ec40e..89989dc423 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend @@ -74,7 +74,7 @@ class CheckGenerator extends JvmModelGenerator {
      - ← All catalogs + ← All catalogs

      «catalog.name»

      «val formattedDescription = catalog.description.formatDescription» «IF formattedDescription !== null» diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java index a90a96a497..f5cbd91f2b 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java @@ -67,7 +67,7 @@ public Object start(final IApplicationContext context) throws IOException { List checkFiles = new ArrayList<>(); try (Stream walk = Files.walk(sourceDir)) { walk.filter(p -> p.toString().endsWith(".check")) - .filter(p -> p.toString().replace('\\', '/').contains("/target/") == false) + .filter(p -> { String n = p.toString().replace('\\', '/'); return !n.contains("/target/") && !n.matches(".*\\/\\.[^/]+/.*"); }) .forEach(checkFiles::add); } From 924572bc78a766e608b0511adce880c3ff8345ba Mon Sep 17 00:00:00 2001 From: Joao Ferreira Date: Wed, 27 May 2026 13:11:26 +0200 Subject: [PATCH 09/10] fix(check): use Path segments to exclude target/ and hidden dirs from walk --- .../avaloq/tools/ddk/check/standalone/CheckDocApplication.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java index f5cbd91f2b..5e6ec3c70c 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java @@ -67,7 +67,7 @@ public Object start(final IApplicationContext context) throws IOException { List checkFiles = new ArrayList<>(); try (Stream walk = Files.walk(sourceDir)) { walk.filter(p -> p.toString().endsWith(".check")) - .filter(p -> { String n = p.toString().replace('\\', '/'); return !n.contains("/target/") && !n.matches(".*\\/\\.[^/]+/.*"); }) + .filter(p -> { for (Path seg : p) { String s = seg.toString(); if (s.equals("target") || s.startsWith(".")) return false; } return true; }) .forEach(checkFiles::add); } From 0d11abc4a63d1fe25b815e9f099677c6f871cff0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jo=C3=A3o=20Dinis=20Ferreira?= Date: Wed, 27 May 2026 13:18:47 +0200 Subject: [PATCH 10/10] fix(check): extract isUserSource predicate to satisfy checkstyle MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The inlined for-loop lambda from the previous commit tripped two Checkstyle rules in check.core: LeftCurly (no break after the lambda's '{') and OneStatementPerLine (multiple statements packed on one line). Extract the per-segment filter into a named static helper so each statement gets its own line and the call site reduces to a method reference. No behaviour change. Also refresh sample.helloworld/docs/* — its committed copy was stale relative to the back-link / target-filter template changes. Co-Authored-By: Claude Opus 4.7 --- .../ddk/check/standalone/CheckDocApplication.java | 13 ++++++++++++- .../docs/content/ExecutionEnvironment.html | 3 +++ .../docs/content/LibraryChecks.html | 3 +++ .../docs/index.html | 6 ++++-- 4 files changed, 22 insertions(+), 3 deletions(-) diff --git a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java index 5e6ec3c70c..3a8af560a3 100644 --- a/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java @@ -67,7 +67,7 @@ public Object start(final IApplicationContext context) throws IOException { List checkFiles = new ArrayList<>(); try (Stream walk = Files.walk(sourceDir)) { walk.filter(p -> p.toString().endsWith(".check")) - .filter(p -> { for (Path seg : p) { String s = seg.toString(); if (s.equals("target") || s.startsWith(".")) return false; } return true; }) + .filter(CheckDocApplication::isUserSource) .forEach(checkFiles::add); } @@ -100,6 +100,17 @@ public Object start(final IApplicationContext context) throws IOException { return IApplication.EXIT_OK; } + /** True iff {@code p} contains no path segment named {@code target} or starting with a dot. */ + private static boolean isUserSource(final Path p) { + for (Path segment : p) { + String name = segment.toString(); + if (name.equals("target") || name.startsWith(".")) { + return false; + } + } + return true; + } + @Override public void stop() { // no-op diff --git a/com.avaloq.tools.ddk.sample.helloworld/docs/content/ExecutionEnvironment.html b/com.avaloq.tools.ddk.sample.helloworld/docs/content/ExecutionEnvironment.html index ea4a27aaaa..2a754921cf 100644 --- a/com.avaloq.tools.ddk.sample.helloworld/docs/content/ExecutionEnvironment.html +++ b/com.avaloq.tools.ddk.sample.helloworld/docs/content/ExecutionEnvironment.html @@ -54,6 +54,8 @@ a:hover { text-decoration: underline; } header.catalog-header { margin-bottom: 1.5rem; padding-bottom: 1rem; border-bottom: 1px solid var(--border); } header.catalog-header p { color: var(--text-muted); } +a.back-link { display: inline-block; margin-bottom: 0.75rem; font-size: 0.875rem; color: var(--text-muted); } +a.back-link:hover { color: var(--link); } nav.jump { margin-top: 1rem; padding: 0.75rem 1rem; @@ -142,6 +144,7 @@
      + ← All catalogs

      ExecutionEnvironment