Skip to content

feat: Make the DSL generator runnable by plugin authors - #1387

Open
TimothyJones wants to merge 5 commits into
claude/plugin-loadingfrom
claude/dsl-generator-cli
Open

feat: Make the DSL generator runnable by plugin authors#1387
TimothyJones wants to merge 5 commits into
claude/plugin-loadingfrom
claude/dsl-generator-cli

Conversation

@TimothyJones

Copy link
Copy Markdown
Member

Stacked on #1386 (claude/plugin-loading) — completes the DSL generator todo: it can now be run outside the ContractCase repository, via a new CLI command.

The generator package

@contract-case/definition-generator's entry point was a maintainer script with hardcoded /Users/home/office/... paths that ran generation as an import side effect. Now:

  • The entry point is a proper API barrel
  • generatePluginDsl() loads plugin packages by name — with the same loading rules as loadPlugins for a test run, via the loadPluginModuleContents helper extracted into case-plugin-base (this PR's first commit moves it there from BoundaryPluginLoader, which now consumes it; no behaviour change)
  • Core DSL generation moved to a bin script with repo-relative paths, run with npm run generate:core-dsls, which properly awaits generation (previously errors were unhandled rejections and the two language passes raced)
  • A plugin without a dsl property is reported as a CaseConfigurationError (BAD_DSL_DECLARATION) instead of a plain Error, so the CLI classifies it as a configuration problem rather than a crash
  • Fixed a latent Java-generator bug: interaction parameters without a jsonPropertyName defaulted to _case:interaction:<name> where the TypeScript generator produces _case:mock:<name>. No shipped declaration relied on the default, so no generated output changes.

The CLI command

ContractCase generate-plugin-dsl @yourorg/your-plugin --languages java,ts --output-dir .

Files are written to the conventional paths beneath the output directory (src/main/java/... for Java, src/boundaries/dsl/... for TypeScript).

Verification

  • 5 new tests generate from a fixture plugin package loaded by name and assert the emitted files land in the right places for both languages; existing generator suite (39 tests) passes, snapshots unchanged
  • The CLI command was smoke-tested end to end, including the error classification for a DSL-less plugin
  • npm run generate:core-dsls reproduces the committed Java DSL — the only diffs (committed separately as a chore) are a documentation link that had been updated in the declaration data since the files were last generated, and two prettier-java line-wrapping changes from the current formatter version

Known limitation (documented, not addressed)

Generated Java classes for third-party plugins currently land under ContractCase's own package namespace (io.contract_testing.contractcase.dsl.<kind>.<category>), with the plugin's category as the leaf. The docs note this and invite an issue if it's a problem — making the namespace configurable touches the renderer and the marker-interface imports, so it felt like its own piece of work.

Docs updated: the generate-plugin-dsl command in the CLI reference, the plugin DSL page's work-in-progress caveats replaced with usage instructions, regeneration instructions in docs/maintainers/DslGenerators.md, and the todo ticked.

🤖 Generated with Claude Code

https://claude.ai/code/session_014mD6p9EEmftbpBQHZZBWB1


Generated by Claude Code

claude added 5 commits August 13, 2026 03:24
Extracts the name validation, working-directory resolution and dynamic
import (with its fallbacks) from BoundaryPluginLoader into a reusable
loadPluginModuleContents helper, so that the DSL generator can load
plugin modules the same way the connector does. No behaviour change.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mD6p9EEmftbpBQHZZBWB1
…hors

The generator's entry point was a maintainer script with hardcoded local
paths that ran generation as an import side effect. Now:

- The package's entry point is a proper API barrel
- generatePluginDsl() loads plugin packages by name (with the same rules
  as loading a plugin for a test run) and generates their declared DSLs
- The core DSL generation moved to a bin script with repo-relative paths,
  run with 'npm run generate:core-dsls', which now awaits the generation
  (previously errors were unhandled rejections)
- A missing 'dsl' property is now reported as a CaseConfigurationError
  rather than a plain Error, so the CLI classifies it correctly
- Interaction parameters without a jsonPropertyName now default to
  '_case:mock:<name>' in the Java generator, matching the TypeScript
  generator (previously '_case:interaction:<name>'; no shipped
  declaration relied on the default, so no generated output changes)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mD6p9EEmftbpBQHZZBWB1
Generates the DSL classes declared by a ContractCase plugin, in Java
and/or TypeScript. This makes the DSL generator usable outside the
ContractCase repository for the first time.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mD6p9EEmftbpBQHZZBWB1
Two files pick up formatting changes from the current prettier-java, and
ChangeLogLevel picks up a documentation link that had been updated in the
DSL declaration since the file was last generated.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mD6p9EEmftbpBQHZZBWB1
Documents the generate-plugin-dsl command in the CLI reference and the
plugin DSL documentation, removes the work-in-progress caveats now that
the generator can be run outside the repository, adds regeneration
instructions to the maintainer docs, and ticks off the todo item.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_014mD6p9EEmftbpBQHZZBWB1
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