Skip to content

Repository files navigation

Logo

What is this?

This project generates recipe documentation in markdown format for all recipes on the classpath. It produces two separate sets of output:

  • OpenRewrite docs (build/docs/) - Open-source recipes only, for docs.openrewrite.org
  • Moderne docs (build/moderne-docs/) - All recipes including proprietary, for docs.moderne.io

Proprietary recipes (those with a Proprietary license or loaded via TypeScript/Python) are written only to the Moderne docs output. Open-source recipes are written to both.

Go recipes are written only to the Moderne docs too, rewrite-go's open-source license notwithstanding, so the whole Go catalog is documented in one place.

Changelog

This project also builds up a CHANGELOG to track what has changed over time. The way this works is that, every time this project is run, it looks in the /src/main/resources directory for a recipeDescriptors.yml file. It will then parse that file and compare it to the latest information obtained. If there are differences, they will be outlined in a CHANGELOG that will be created in build/docs. After the CHANGELOG is built, the latest information will be stored in the descriptors file for future use.

The CHANGELOG is the one output no workflow publishes, so it has to be moved into the changelog section of the OpenRewrite docs by hand; see Update rewrite-docs.

How docs are published

Doc updates to the OpenRewrite docs and Moderne docs are normally driven by scheduled GitHub Actions in the respective repos, not by humans running this generator locally:

  • openrewrite/rewrite-docs - runs nightly, checks out this repo, runs ./gradlew run, copies the OpenRewrite outputs into rewrite-docs, commits, and pushes.
  • moderneinc/moderne-docs - runs nightly, same shape, but also installs Python and .NET so it can load all RPC-backed recipes (see Prerequisites below).

Both push an [Auto] Update docs commit straight to their default branch instead of opening a pull request, so review the resulting commit rather than waiting for a review request.

Both workflows default to -PlatestVersionsOnly=true, which only refreshes the latest-versions files. To regenerate the full recipe catalog, trigger the workflow manually via workflow_dispatch with "Only update the latest versions of every OpenRewrite module" unchecked.

Because the workflows keep the catalog current, running the generator locally to open a catalog pull request usually produces an empty diff. What they do not publish is the CHANGELOG and the updated recipeDescriptors.yml; those still need a local run and a pull request, as described in Update rewrite-docs and Commit the updated descriptors.

The Generate Latest Versions workflow in this repo only runs with -PlatestVersionsOnly=true, so the full catalog is only ever generated by the two workflows above. To still catch breakage in the recipe generation itself, Generate Per Language generates docs for a single recipe module per language:

./gradlew run -PrecipeArtifacts=rewrite-java,rewrite-javascript,rewrite-python,recipes-code-quality,recipes-go

That takes minutes rather than the best part of an hour, and it fails if any of those languages loads no recipes, so a missing or broken toolchain can't pass unnoticed.

Usage

Prerequisites

The generator loads TypeScript, Python, C#, and Go recipes by spawning external RPC processes. To produce complete docs locally you need all of these on PATH:

  • Java 21 — JVM-based recipes
  • Node.js — TypeScript recipes (rewrite-javascript, rewrite-nodejs, rewrite-angular, rewrite-react)
  • Python 3.10+ and pip — Python recipes (rewrite-python, rewrite-migrate-python, openrewrite-static-analysis)
  • .NET SDK — C# recipes (recipes-code-quality, recipes-migrate-dotnet, recipes-tunit, recipes-csharp-core)
  • Go 1.25+ and the rewrite-go-rpc server — Go recipes (recipes-go). Build the server with go install github.com/openrewrite/rewrite/rewrite-go/cmd/rpc@latest (ideally pinned to the Go-module tag matching the rewrite-go release), then make it discoverable as rewrite-go-rpc on PATH — the go install binary is named rpc, so symlink or copy it (e.g. ln -s "$(go env GOPATH)/bin/rpc" "$(go env GOPATH)/bin/rewrite-go-rpc"). Installing recipes also requires network access so the server can go get the Go recipe module.

OpenRewrite and Moderne artifacts are published to the Code Genome Project before they reach Maven Central. Set codegenomeUsername and codegenomePassword in ~/.gradle/gradle.properties to document the newest releases; without them the build resolves org.openrewrite and io.moderne from Maven Central and documents whatever has made it there.

If a toolchain is missing, the corresponding loader prints a warning and skips those recipes. The build still succeeds, so a local ./gradlew run without all four toolchains silently produces incomplete docs. Most contributors don't have all four installed — if you need a complete regeneration, trigger the scheduled workflows above rather than running locally.

Generate all docs

./gradlew run

This writes OpenRewrite docs to build/docs/ and Moderne docs to build/moderne-docs/. See Prerequisites — without the full toolchain set, non-Java recipes are silently omitted.

Generate docs for only some recipe modules

./gradlew run -PrecipeArtifacts=rewrite-circleci,rewrite-static-analysis

Restricts loading to those artifactIds — jars, and the TypeScript/Python/C#/Go modules registered in the *RecipeLoader classes alike — which is much faster than a full run. Sub-recipes from artifacts left out have empty links. The full classpath is still resolved so transitive and delegatesTo lookups work.

Each language whose module is in the list must load recipes, or the run fails; pass --allow-empty-recipe-sources to downgrade that to a warning when you're missing a toolchain.

Such a run leaves the changelog and recipeDescriptors.yml alone, since diffing part of the catalog against the full baseline would report every recipe it didn't load as removed.

Create only latest versions files

./gradlew run -PlatestVersionsOnly=true
cp build/docs/latest-versions-of-every-openrewrite-module.md ../rewrite-docs/docs/reference/
cp build/docs/latest-versions.js ../rewrite-docs/src/plugins/
cp build/moderne-docs/latest-versions-of-every-openrewrite-module.md ../moderne-docs/docs/user-documentation/recipes/lists/
cp build/moderne-docs/latest-versions.js ../moderne-docs/src/plugins/

The nightly workflows already do exactly this, so these copies are only for a local preview.

Create Markdown files in a specific directory

./gradlew run --args="desired/output/path"

Print additional options

./gradlew run --args="--help"

Update rewrite-docs

The recipe catalog itself is published by the Update docs workflow; the changelog is not, so it takes a local run and a pull request. Assumes you have rewrite-docs checked out in the same parent directory as rewrite-recipe-markdown-generator, and all Prerequisites installed, as a missing toolchain drops those recipes from the changelog without failing the build.

./gradlew run
mv build/docs/*-Release.md ../rewrite-docs/docs/changelog/

Then update ../rewrite-docs/sidebars.ts to include a link to the new changelog, and open a pull request with both changes.

Update moderne-docs

Nothing to do by hand: the Update docs workflow in moderne-docs copies the recipe catalog and lists in full, and there is no Moderne equivalent of the changelog.

Commit the updated descriptors

./gradlew run rewrites src/main/resources/recipeDescriptors.yml with the latest recipe information. Commit and push that change so the next run can diff against it to produce an accurate added/changed/removed list in the CHANGELOG.

git add src/main/resources/recipeDescriptors.yml
git commit -m "Update recipeDescriptors.yml"
git push

About

Utility that generates OpenRewrite recipe documentation in markdown format for all recipes on the classpath.

Resources

Contributing

Stars

9 stars

Watchers

4 watching

Forks

Used by

Contributors

Languages