|
| 1 | +# Contributing guide |
| 2 | + |
| 3 | +## How to write a recipe? |
| 4 | + |
| 5 | +All recipe implementations are kept in the `allwrite-recipes` module. |
| 6 | + |
| 7 | +In general, you should follow the official [Authoring Recipes](https://docs.openrewrite.org/authoring-recipes) docs from OpenRewrite. |
| 8 | + |
| 9 | +However, `allwrite` has some custom features that you can use. |
| 10 | + |
| 11 | +### Visibility |
| 12 | + |
| 13 | +Every recipe within `allwrite-recipes` must provide the `visibility:[internal/public]` tag. Public recipes will be presented to the user via |
| 14 | +`allwrite ls` command. |
| 15 | + |
| 16 | +### Friendly names |
| 17 | + |
| 18 | +Every public recipe must provide a friendly name in the form of 2 tags: |
| 19 | +* `group:<someGroup>` |
| 20 | +* `recipe:<someRecipe>` |
| 21 | + |
| 22 | +For example, the following set of tags [`group:workflows`, `recipe:introduceSetupGradle`] will result in a recipe that can be executed like that: |
| 23 | +``` |
| 24 | +allwrite run workflows/introduceSetupGradle |
| 25 | +``` |
| 26 | + |
| 27 | +### Convenient base classes |
| 28 | + |
| 29 | +For convenience, you can extend either `AllegroRecipe` or `AllegroScanningRecipe`. It will build all required tags for you: |
| 30 | +```kotlin |
| 31 | +class SomeRecipe : AllegroRecipe( |
| 32 | + displayName = "Some recipe", // optional, defaults to class name |
| 33 | + description = "Some description.", // optional, defaults to displayName + '.' |
| 34 | + visibility = PUBLIC, // optional, defaults to INTERNAL |
| 35 | + group = "some-group", // required if the visibility is PUBLIC |
| 36 | + recipe = "some-recipe" // required if the visibility is PUBLIC |
| 37 | +) { |
| 38 | + // your implementation |
| 39 | +} |
| 40 | +``` |
| 41 | + |
| 42 | +### Limiting which files should be parsed |
| 43 | + |
| 44 | +> [!TIP] |
| 45 | +> It may be very useful for improving performance and overcoming OpenRewrite issues with parsing Groovy files |
| 46 | +
|
| 47 | +If your recipe is only interested in very specific files (for example it only modifies the `tycho.yaml` file) you can implement the `ParsingAwareRecipe` |
| 48 | +interface: |
| 49 | +```kotlin |
| 50 | +class SomeRecipe : AllegroRecipe(), ParsingAwareRecipe { |
| 51 | + |
| 52 | + override fun selectFilesToParse(inputFiles: List<Path>): List<Path> { |
| 53 | + // return the files to be parsed |
| 54 | + } |
| 55 | +} |
| 56 | +``` |
| 57 | + |
| 58 | +## Architecture |
| 59 | + |
| 60 | +The `allwrite` is a modular project, utilizing dependency injection capabilities from the [Koin](https://github.com/InsertKoinIO/koin) framework. |
| 61 | + |
| 62 | +It consists of the following Gradle modules (that may contain one or more Koin modules): |
| 63 | +* `allwrite-runner` - provides both Application and Infrastructure layers for the CLI app |
| 64 | +* `allwrite-runtime` - provides core implementation interacting directly with the OpenRewrite runtime; equivalent of the Domain layer |
| 65 | +* `allwrite-recipes` - contains OpenRewrite recipes to be executed by `allwrite-runner` |
| 66 | +* `allwrite-completions` - provides annotation processors generating CLI auto-completions |
| 67 | + |
| 68 | +The below diagram shows Koin modules, not Gradle modules. The rule of thumb is: we don't extract Koin module as a separate Gradle module unless required |
| 69 | +by the build logic. For example, `allwrite-runtime` must be Gradle module, because it is used by both `allwrite-runner` (at app runtime) |
| 70 | +and `allwrite-completions` (at app compile time). |
| 71 | + |
| 72 | +Please keep the diagram up-to-date by editing `architecture.puml` file with the help of [PlantUML IntelliJ Plugin](https://plugins.jetbrains.com/plugin/7017-plantuml-integration) and replacing the rendered PNG. |
| 73 | + |
| 74 | +If you don't like installing IntelliJ plugins, edit `architecture.puml` and execute the following command: |
| 75 | +```bash |
| 76 | +docker run --rm -v $(pwd):/app -w /app ghcr.io/plantuml/plantuml plantuml docs/architecture.puml |
| 77 | +``` |
| 78 | + |
| 79 | + |
0 commit comments