Skip to content
Merged
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
43 changes: 42 additions & 1 deletion docs/reference/yaml-format-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -303,7 +303,7 @@ Categories control how recipes are grouped, named, and described in the recipe c
| name | string | A human-readable name for the category |
| description | string | A human-readable description for the category (ends with a period) |
| tags | array of strings | A list of strings that help categorize this category |
| root | boolean | Whether this category is displayed as a top-level entry (defaults to false) |
| root | boolean | Whether this package is only a naming prefix; see [root categories](#root-categories) (defaults to false) |
| priority | integer | Sort order relative to sibling categories; lower sorts first (defaults to 0) |

### Category example
Expand All @@ -317,6 +317,47 @@ description: Recipes for your organization's Java code.
priority: 1
```

### How recipes are placed in categories

A recipe's position in the catalog comes from its name: every package segment ahead of the final class name becomes one level of nesting. `com.yourorg.java.MigrateToSpringBoot3` sits under `com` > `yourorg` > `java`.

For each of those levels OpenRewrite looks for a category whose `packageName` matches the package *up to and including* that segment. Where one exists, its `name`, `description`, and `priority` are used; where none exists, a category is synthesized from the segment with its first letter capitalized. That is why an undeclared package shows up in the catalog as **Yourorg** rather than something readable.

Matching is against the whole partial package, never a bare segment: a category for `com.yourorg` describes `com.yourorg` only, and does not apply to a `yourorg` segment appearing anywhere else.

### Root categories

`root: true` marks a package as a naming prefix rather than a category. A root category is not displayed at all; its subcategories are lifted into its parent, which for a top-level prefix means the top of the catalog. This is what keeps `org.openrewrite.java` recipes under **Java** instead of burying them under **Org** > **Openrewrite** > **Java**.

`rewrite-core` ships root categories for the reverse DNS prefixes it knows about — `com`, `org`, `io`, `ai`, `tech`, and `software`. Newer versions also root common generic and country code top-level domains, such as `uk`, `uk.co`, `de`, and `nl`.

Two things are worth knowing if you publish under a prefix that is not rooted:

* Each level needs its own root category. For `uk.co.acme`, rooting only `uk` promotes **Co** to the top level; you need roots for both `uk` and `uk.co`.
* Declaring a root category that `rewrite-core` already provides does no harm, so when in doubt, declare it.

```yaml
---
type: specs.openrewrite.org/v1beta/category
packageName: uk
root: true
---
type: specs.openrewrite.org/v1beta/category
packageName: uk.co
root: true
---
type: specs.openrewrite.org/v1beta/category
name: Acme
packageName: uk.co.acme
description: Recipes for Acme's codebases.
```

Recipes named `uk.co.acme.*` are now presented under a single top-level **Acme** category, rather than under **Uk** > **Co** > **Acme**.

:::info
`packageName` values are subject to YAML interpretation, so a segment such as `no` or `on` has to be quoted to keep it from being read as a boolean.
:::

## Examples

Examples attach before/after snippets to a recipe so that the generated recipe documentation can show what the recipe does. These are normally **generated** into a module's `META-INF/rewrite/examples.yml` from tests annotated with `@DocumentExample`, rather than written by hand — but it is useful to be able to read them.
Expand Down