Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -276,6 +276,7 @@ Do **not** widen by reintroducing wildcards or a config-driven allow-list — th
- **Always log the throwable.** Every `catch` block's log call must pass the exception as the trailing SLF4J argument so the stack trace lands in the log — at every level, including DEBUG. Never log only `ex.getMessage()` and drop the rest. SLF4J's parameterised form `logger.X(format, …, throwable)` treats the trailing throwable as out-of-band; the `{}` placeholder count vs. format-arg count stays balanced. Even for cases where the exception "feels expected" (an `IOException` in a daemon log pump that just means the child closed its pipe), keep the throwable so an operator who bumps the level can investigate. Skip the throwable only when there is genuinely no exception in scope (validation failures detected via `if`, not `try`).
- **Code formatting is enforced — always run `mvn formatter:format` before every commit and push.** This is mandatory: the `code-style` CI job (`.github/workflows/build.yml`) runs `mvn formatter:validate` and fails the build on any violation, so unformatted code will not merge. Run `mvn formatter:format` (scoped to the changed module with `-pl` for speed) as the final step before staging, every time. The IDE setup (Eclipse / IntelliJ / VS Code) for importing `dirigible-formatter.xml` is documented in `CONTRIBUTING.md`.
- **Javadoc has to compile cleanly on every Maven module that participates in the release** (anything under `components/`, `modules/`, `dependencies/`, `build/`, `tests/tests-framework`, `cli/`). The release profile attaches the `maven-javadoc-plugin:jar` execution and treats any `error:` from javadoc as fatal; the `default` profile silently skips javadoc, so problems are invisible in normal `mvn install` and only surface in `.github/workflows/release.yml`. **Run `mvn -P release -Dgpg.skip=true -DskipTests -Dlicense.skip=true -Dformatter.skip=true install` on the modules you've touched before pushing anything that adds or changes javadoc.** The recurring failure modes:
- **Malformed HTML from a bare `<`.** Javadoc prose is HTML — doclint parses any bare `<` as a tag start, including inside `<pre>` blocks. ASCII arrows are the classic trap: `# child field <- literal` in a `<pre>` YAML example fails as `error: malformed HTML` (broke the 2026-07-10 release via `ExpansionIntent.java`). Escape as `&lt;` (`&lt;-`), or wrap the whole example in `<pre>{@code ... }</pre>` so nothing inside is HTML-parsed. Same for `>`/`&` when ambiguous.
- **Unterminated inline tag.** `{@code` / `{@link` parse braces inside their argument as inline-tag delimiters. `{@code {{ }}}` — the inner `{{` opens a phantom tag and javadoc can't find the matching `}` until the next paragraph break. Escape with `<code>&#123;&#123; &#125;&#125;</code>` or rephrase to avoid braces inside braces.
- **`@link` reference not found.** `{@link some.external.Type}` only resolves when that type is on the javadoc tool's classpath. JUnit Jupiter, Lombok, optional-test deps and friends are typically not. Use `{@code some.external.Type}` (plain text formatting, no resolution) when the reference is purely documentation; keep `{@link …}` only for types this module compiles against.
- **`no comment` warning.** Add a one-liner Javadoc to every `public` member of an exported SDK class — javadoc 17+ promotes these to errors under `-Xdoclint:all`, and even today they look untidy in the published API docs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
* unit: month # day (default) | week | month
* between: { start: startDate, end: endDate } # date fields of the master
* skipDays: [0, 6] # unit day only: weekdays skipped (0=Sun..6=Sat)
* map: { dueDate: period } # child date field <- the iterated period date
* defaults: { note: generated } # child field <- literal
* map: { dueDate: period } # child date field &lt;- the iterated period date
* defaults: { note: generated } # child field &lt;- literal
* spread: { total: principal, into: amount, round: 2 } # divide a master total across the rows
* count: periods # write the generated row count to a master field
* </pre>
Expand Down
Loading