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 bb3b31dd8..c4caf4671 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 7edc2a56d..81f2b8b7c 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/generator/CheckDocumentationTemplates.xtend b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend new file mode 100644 index 000000000..681fe4ef1 --- /dev/null +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckDocumentationTemplates.xtend @@ -0,0 +1,285 @@ +/******************************************************************************* + * 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, plus the + * standalone-browser {@code index.html} landing page. Also exposes the shared + * {@link #STYLE} block used by both the index and the per-catalog pages. + */ +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/" + + /** + * Single-source-of-truth stylesheet used by the index page and every per-catalog + * HTML page. Inlined into the page {@code } so the output is self-contained + * and renders in any standard browser without external assets. + */ + public static val String STYLE = ''' + :root { + --bg: #ffffff; + --text: #1f2328; + --text-muted: #57606a; + --border: #d0d7de; + --card-bg: #f6f8fa; + --code-bg: #f6f8fa; + --link: #0969da; + --accent: #218bff; + --sev-error-bg: #ffe5e5; --sev-error-text: #82071e; --sev-error-border: #ffadb0; + --sev-warning-bg: #fff8c5; --sev-warning-text: #633c01; --sev-warning-border: #f3df5b; + --sev-info-bg: #ddf4ff; --sev-info-text: #054a72; --sev-info-border: #80ccff; + --sev-ignore-bg: #eaeef2; --sev-ignore-text: #57606a; --sev-ignore-border: #d0d7de; + } + @media (prefers-color-scheme: dark) { + :root { + --bg: #0d1117; + --text: #e6edf3; + --text-muted: #8d96a0; + --border: #30363d; + --card-bg: #161b22; + --code-bg: #161b22; + --link: #58a6ff; + --accent: #1f6feb; + --sev-error-bg: #3d1419; --sev-error-text: #ffa198; --sev-error-border: #6e1216; + --sev-warning-bg: #3a2c00; --sev-warning-text: #f0d97c; --sev-warning-border: #7a5a00; + --sev-info-bg: #0c2d4a; --sev-info-text: #79c0ff; --sev-info-border: #1f6feb; + --sev-ignore-bg: #1c2128; --sev-ignore-text: #8d96a0; --sev-ignore-border: #30363d; + } + } + * { box-sizing: border-box; } + body { + font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, "Helvetica Neue", Arial, sans-serif; + font-size: 16px; + line-height: 1.55; + color: var(--text); + background: var(--bg); + max-width: 820px; + margin: 0 auto; + padding: 2rem 1.25rem 4rem; + } + h1 { font-size: 1.875rem; margin: 0 0 0.5rem; } + h2 { font-size: 1.375rem; margin: 2rem 0 1rem; padding-bottom: 0.4rem; border-bottom: 1px solid var(--border); } + h3 { font-size: 1.05rem; margin: 0; } + p { margin: 0.5rem 0; } + a { color: var(--link); text-decoration: none; } + 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; + background: var(--card-bg); + border: 1px solid var(--border); + border-radius: 6px; + font-size: 0.9rem; + } + nav.jump strong { display: block; margin-bottom: 0.4rem; font-size: 0.8rem; text-transform: uppercase; letter-spacing: 0.05em; color: var(--text-muted); } + nav.jump ul { margin: 0; padding-left: 1.25rem; } + nav.jump li { margin: 0.15rem 0; } + section.category { margin: 2rem 0; } + section.category > p { color: var(--text-muted); margin-bottom: 0.75rem; } + article.check { + margin: 0.75rem 0; + padding: 0.85rem 1.15rem; + background: var(--card-bg); + border: 1px solid var(--border); + border-radius: 6px; + } + article.check > header { + display: flex; + align-items: baseline; + gap: 0.6rem; + flex-wrap: wrap; + } + article.check a.anchor { + visibility: hidden; + color: var(--text-muted); + font-weight: 400; + font-size: 0.85em; + } + article.check > header:hover a.anchor { visibility: visible; } + article.check:target { + border-color: var(--accent); + box-shadow: 0 0 0 3px rgba(33, 139, 255, 0.18); + } + .severity { + display: inline-block; + padding: 0.1rem 0.6rem; + font-size: 0.72rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + border-radius: 999px; + border: 1px solid transparent; + white-space: nowrap; + } + .severity.sev-error { background: var(--sev-error-bg); color: var(--sev-error-text); border-color: var(--sev-error-border); } + .severity.sev-warning { background: var(--sev-warning-bg); color: var(--sev-warning-text); border-color: var(--sev-warning-border); } + .severity.sev-info { background: var(--sev-info-bg); color: var(--sev-info-text); border-color: var(--sev-info-border); } + .severity.sev-ignore { background: var(--sev-ignore-bg); color: var(--sev-ignore-text); border-color: var(--sev-ignore-border); } + pre.message { + margin: 0.6rem 0 0; + padding: 0.55rem 0.8rem; + background: var(--code-bg); + border: 1px solid var(--border); + border-radius: 6px; + font-family: ui-monospace, SFMono-Regular, "SF Mono", Menlo, Consolas, monospace; + font-size: 0.85rem; + white-space: pre-wrap; + word-break: break-word; + } + pre.message::before { + content: "Message"; + display: block; + font-family: inherit; + font-size: 0.68rem; + font-weight: 600; + text-transform: uppercase; + letter-spacing: 0.05em; + color: var(--text-muted); + margin-bottom: 0.2rem; + } + ul.catalog-list { list-style: none; padding: 0; margin: 1.5rem 0 0; } + ul.catalog-list li { + margin: 0.75rem 0; + padding: 1rem 1.25rem; + background: var(--card-bg); + border: 1px solid var(--border); + border-radius: 6px; + } + ul.catalog-list li h2 { margin: 0; border-bottom: none; padding-bottom: 0; font-size: 1.2rem; } + ul.catalog-list li p { color: var(--text-muted); margin: 0.25rem 0 0; } + ''' + + @Inject extension CheckGeneratorNaming naming + @Inject extension CheckGeneratorExtensions extensions + + /** 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» + + ''' + } + + /** Build the contents of {@code docs/index.html} listing every catalog with a link to its page. */ + def CharSequence compileIndex(Iterable catalogs) { + val sorted = catalogs.sortBy[name] + ''' + + + + + + Check Catalogs + + + +
+

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 + } + + def private CheckCatalog parentCatalog(org.eclipse.emf.ecore.EObject o) { + 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("&", "&") + ?.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/generator/CheckGenerator.xtend b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/generator/CheckGenerator.xtend index 083ddc9b2..89989dc42 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,79 @@ 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» +
+ ← All catalogs +

«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 new file mode 100644 index 000000000..3a8af560a --- /dev/null +++ b/com.avaloq.tools.ddk.check.core/src/com/avaloq/tools/ddk/check/standalone/CheckDocApplication.java @@ -0,0 +1,118 @@ +/******************************************************************************* + * 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.CheckDocumentationTemplates; +import com.avaloq.tools.ddk.check.generator.CheckGenerator; +import com.google.inject.Injector; +import com.google.inject.Provider; + + +/** + * 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 } 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 { + + @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 1; + } + Path sourceDir = Path.of(args[0]); + 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(); + + List checkFiles = new ArrayList<>(); + try (Stream walk = Files.walk(sourceDir)) { + walk.filter(p -> p.toString().endsWith(".check")) + .filter(CheckDocApplication::isUserSource) + .forEach(checkFiles::add); + } + + 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) { + catalogs.add(catalog); + Path target = contentDir.resolve(catalog.getName() + ".html"); + Files.writeString(target, generator.compileDoc(catalog).toString()); + System.out.println("Wrote " + target); + } + } + } + + 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); + 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)"); + 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.check.runtime.ui/build.properties b/com.avaloq.tools.ddk.check.runtime.ui/build.properties index 688aa6599..404b564d5 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 dc5829178..000000000 --- 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.check.test.runtime/docs/content/ExecutionEnvironment.html b/com.avaloq.tools.ddk.check.test.runtime/docs/content/ExecutionEnvironment.html index 3439e97b5..ea4a27aaa 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 bcf5eaa3b..a84e860e4 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 f88e0238b..9c88fab9f 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 000000000..559ea01de --- /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 1ac3dd2a3..8f38986ab 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 bd279fd00..639d5405d 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 + + + + + + + + + + + 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 000000000..2a754921c --- /dev/null +++ b/com.avaloq.tools.ddk.sample.helloworld/docs/content/ExecutionEnvironment.html @@ -0,0 +1,171 @@ + + + + + + ExecutionEnvironment + + + +
+ ← All catalogs +

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 000000000..a308f02e0 --- /dev/null +++ b/com.avaloq.tools.ddk.sample.helloworld/docs/content/LibraryChecks.html @@ -0,0 +1,200 @@ + + + + + + LibraryChecks + + + +
+ ← All catalogs +

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 6d5090641..9c88fab9f 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 000000000..1123fc36b --- /dev/null +++ b/com.avaloq.tools.ddk.sample.helloworld/docs/index.html @@ -0,0 +1,161 @@ + + + + + + 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 62d47779b..8f38986ab 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 + + + + + + + + + + + + + + + + + + + + + + diff --git a/com.avaloq.tools.ddk.sample.helloworld/pom.xml b/com.avaloq.tools.ddk.sample.helloworld/pom.xml index 22294deeb..c1e936e0a 100644 --- a/com.avaloq.tools.ddk.sample.helloworld/pom.xml +++ b/com.avaloq.tools.ddk.sample.helloworld/pom.xml @@ -9,4 +9,100 @@ com.avaloq.tools.ddk com.avaloq.tools.ddk.sample.helloworld eclipse-plugin + + + + + 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 + + + + + + + + + + diff --git a/docs/check-doc-generation.md b/docs/check-doc-generation.md new file mode 100644 index 000000000..98da950f8 --- /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).