GITBOOK-364: change request with no subject merged in GitBook
BIN
.gitbook/assets/common-static-analysis-list.png
Normal file
|
After Width: | Height: | Size: 385 KiB |
91
.gitbook/assets/configure-build.patch
Normal file
@@ -0,0 +1,91 @@
|
||||
diff --git a/build.gradle b/build.gradle
|
||||
index c517cfc..c040d7d 100644
|
||||
--- a/build.gradle
|
||||
+++ b/build.gradle
|
||||
@@ -1,17 +1,18 @@
|
||||
-buildscript {
|
||||
- dependencies {
|
||||
- classpath 'ro.isdc.wro4j.gradle:wro4j-gradle-plugin:1.8.0.Beta4'
|
||||
- }
|
||||
-}
|
||||
+//buildscript {
|
||||
+// dependencies {
|
||||
+// classpath 'ro.isdc.wro4j.gradle:wro4j-gradle-plugin:1.8.0.Beta4'
|
||||
+// }
|
||||
+//}
|
||||
|
||||
plugins {
|
||||
id 'org.springframework.boot' version '2.4.5'
|
||||
id 'io.spring.dependency-management' version '1.0.11.RELEASE'
|
||||
id 'java'
|
||||
+ id 'org.openrewrite.rewrite' version '6.4.3'
|
||||
}
|
||||
|
||||
apply plugin: 'java'
|
||||
-apply plugin: 'wro4j'
|
||||
+//apply plugin: 'wro4j'
|
||||
|
||||
group = 'org.springframework.samples'
|
||||
version = '2.4.5'
|
||||
@@ -32,29 +33,35 @@ dependencies {
|
||||
implementation 'org.springframework.boot:spring-boot-starter-web'
|
||||
implementation 'org.springframework.boot:spring-boot-starter-validation'
|
||||
implementation 'javax.cache:cache-api'
|
||||
- webjarsRuntime 'org.webjars:webjars-locator-core'
|
||||
- webjarsRuntime "org.webjars:jquery:${webjarsJqueryVersion}"
|
||||
- webjarsRuntime "org.webjars:jquery-ui:${webjarsJqueryUiVersion}"
|
||||
- webjarsRuntime "org.webjars:bootstrap:${webjarsBootstrapVersion}"
|
||||
- webjarsRuntime "org.webjars:bootstrap:${webjarsBootstrapVersion}"
|
||||
+// webjarsRuntime 'org.webjars:webjars-locator-core'
|
||||
+// webjarsRuntime "org.webjars:jquery:${webjarsJqueryVersion}"
|
||||
+// webjarsRuntime "org.webjars:jquery-ui:${webjarsJqueryUiVersion}"
|
||||
+// webjarsRuntime "org.webjars:bootstrap:${webjarsBootstrapVersion}"
|
||||
+// webjarsRuntime "org.webjars:bootstrap:${webjarsBootstrapVersion}"
|
||||
runtimeOnly 'org.ehcache:ehcache'
|
||||
runtimeOnly 'com.h2database:h2'
|
||||
runtimeOnly 'mysql:mysql-connector-java'
|
||||
developmentOnly 'org.springframework.boot:spring-boot-devtools'
|
||||
testImplementation 'org.springframework.boot:spring-boot-starter-test'
|
||||
+
|
||||
+ rewrite 'org.openrewrite.recipe:rewrite-static-analysis:latest.release'
|
||||
+}
|
||||
+
|
||||
+rewrite {
|
||||
+ activeRecipe 'org.openrewrite.staticanalysis.CommonStaticAnalysis'
|
||||
}
|
||||
|
||||
test {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
|
||||
-webResources {
|
||||
- srcMainDir = layout.projectDirectory.dir('src/main').asFile
|
||||
- dstStaticFolder = 'static/resources/css'
|
||||
- bundle ('petclinic') {
|
||||
- css 'webjars/bootstrap/3.3.6/less/bootstrap.less'
|
||||
- css 'less/petclinic.less'
|
||||
- preProcessor 'lessCssImport'
|
||||
- postProcessor 'less4j'
|
||||
- }
|
||||
-}
|
||||
+//webResources {
|
||||
+// srcMainDir = layout.projectDirectory.dir('src/main').asFile
|
||||
+// dstStaticFolder = 'static/resources/css'
|
||||
+// bundle ('petclinic') {
|
||||
+// css 'webjars/bootstrap/3.3.6/less/bootstrap.less'
|
||||
+// css 'less/petclinic.less'
|
||||
+// preProcessor 'lessCssImport'
|
||||
+// postProcessor 'less4j'
|
||||
+// }
|
||||
+//}
|
||||
diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties
|
||||
index 442d913..98debb8 100644
|
||||
--- a/gradle/wrapper/gradle-wrapper.properties
|
||||
+++ b/gradle/wrapper/gradle-wrapper.properties
|
||||
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
-distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
|
||||
+distributionUrl=https\://services.gradle.org/distributions/gradle-7.6.2-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
BIN
.gitbook/assets/image (1) (1) (1) (1) (1) (1).png
Normal file
|
After Width: | Height: | Size: 4.9 KiB |
|
Before Width: | Height: | Size: 4.9 KiB After Width: | Height: | Size: 54 KiB |
|
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 6.0 KiB |
|
Before Width: | Height: | Size: 6.0 KiB After Width: | Height: | Size: 226 KiB |
|
Before Width: | Height: | Size: 226 KiB After Width: | Height: | Size: 55 KiB |
|
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 178 KiB |
26
.gitbook/assets/init.gradle
Normal file
@@ -0,0 +1,26 @@
|
||||
initscript {
|
||||
repositories {
|
||||
maven { url "https://plugins.gradle.org/m2" }
|
||||
}
|
||||
|
||||
dependencies {
|
||||
classpath("org.openrewrite:plugin:latest.release")
|
||||
}
|
||||
}
|
||||
|
||||
rootProject {
|
||||
plugins.apply(org.openrewrite.gradle.RewritePlugin)
|
||||
dependencies {
|
||||
rewrite("org.openrewrite.recipe:rewrite-spring:latest.release")
|
||||
}
|
||||
rewrite {
|
||||
activeRecipe("org.openrewrite.java.spring.boot3.UpgradeSpringBoot_3_1")
|
||||
}
|
||||
afterEvaluate {
|
||||
if (repositories.isEmpty()) {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
BIN
.gitbook/assets/mod-org (1).png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
.gitbook/assets/mod-org (2).png
Normal file
|
After Width: | Height: | Size: 25 KiB |
BIN
.gitbook/assets/mod-org.png
Normal file
|
After Width: | Height: | Size: 14 KiB |
BIN
.gitbook/assets/more-details.png
Normal file
|
After Width: | Height: | Size: 51 KiB |
BIN
.gitbook/assets/organizations-and-repos.png
Normal file
|
After Width: | Height: | Size: 571 KiB |
BIN
.gitbook/assets/support-timelines.png
Normal file
|
After Width: | Height: | Size: 23 KiB |
BIN
.gitbook/assets/why-did-this-change (1).png
Normal file
|
After Width: | Height: | Size: 33 KiB |
|
Before Width: | Height: | Size: 33 KiB After Width: | Height: | Size: 215 KiB |
10
SUMMARY.md
@@ -63,6 +63,16 @@
|
||||
* [Concepts](administrator-documentation/references/concepts/README.md)
|
||||
* [Lossless semantic trees](administrator-documentation/references/concepts/lossless-semantic-trees.md)
|
||||
|
||||
## Workshops
|
||||
|
||||
* [Spring Boot migration workshop](workshops/spring-boot-migration-workshop/README.md)
|
||||
* [Maven plugin exercise](workshops/spring-boot-migration-workshop/maven-plugin-exercise.md)
|
||||
* [Gradle plugin exercise](workshops/spring-boot-migration-workshop/gradle-plugin-exercise.md)
|
||||
* [Moderne CLI exercise](workshops/spring-boot-migration-workshop/moderne-cli-exercise.md)
|
||||
* [Moderne platform exercise](workshops/spring-boot-migration-workshop/moderne-platform-exercise.md)
|
||||
* [Migrate your own project](workshops/spring-boot-migration-workshop/migrate-your-own-project.md)
|
||||
* [Recipe development](workshops/spring-boot-migration-workshop/recipe-development.md)
|
||||
|
||||
## Releases
|
||||
|
||||
* [Agent releases](releases/agent-releases.md)
|
||||
|
||||
@@ -16,9 +16,9 @@ Moderne offers three types of reports for administrators:
|
||||
|
||||
Audit logs are accessible from https://\<TENANT>.moderne.io/admin/audit-logs, and can be viewed in the UI, accessed from the API, or downloaded in [CEF format](https://www.microfocus.com/documentation/arcsight/arcsight-smartconnectors-8.3/cef-implementation-standard/#CEF/Chapter%201%20What%20is%20CEF.htm?TocPath=\_\_\_\_\_2).
|
||||
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
<figure><img src="../../.gitbook/assets/image (1) (1) (1).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
To download audit logs, use the "Export to CEF" button:  (1) (1).png>)
|
||||
To download audit logs, use the "Export to CEF" button:  (1) (1) (1).png>)
|
||||
|
||||
## Other reports (recipe runs and commits)
|
||||
|
||||
|
||||
@@ -40,7 +40,7 @@ feat/add-yielded-state
|
||||
We have plans to overhaul the iconography to create better visual consistency and clarity.
|
||||
|
||||
This journey begins this version with a rework of the left navigation icons:\
|
||||
.png>)
|
||||
 (1).png>)
|
||||
|
||||
### UI v9.173.0 (2023/10/17)
|
||||
|
||||
@@ -249,7 +249,7 @@ We've done a little tidying up on the recipe run result page. _**Visualizations*
|
||||
|
||||
#### Add dropdown options to share button
|
||||
|
||||
 (1) (1) (1).png>)
|
||||
 (1) (1) (1) (1).png>)
|
||||
|
||||
When sharing a recipe from the recipes details, you can now select whether or not to include your current organizations.
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ You can click on any of the repositories to look at the suggested changes and le
|
||||
|
||||
If you want to learn more about _why_ the code is changing, you can press the three dots (`...`) in the top right-hand corner of any file and select `Why did this change?`:
|
||||
|
||||

|
||||
.png>)
|
||||
|
||||
This will display a list of all of the recipes that affected the selected file along with a sentence or two describing the rule in more detail:
|
||||
|
||||
|
||||
31
workshops/spring-boot-migration-workshop/README.md
Normal file
@@ -0,0 +1,31 @@
|
||||
# Spring Boot migration workshop
|
||||
|
||||
In this workshop, you'll find a variety of exercises that demonstrate the different ways you can automatically migrate or upgrade an application to Spring Boot 3. The core technology behind each of these exercises is [OpenRewrite](https://github.com/openrewrite/rewrite).
|
||||
|
||||
You do not need to complete all of these exercises. Instead, please pick the ones that are more interesting or relevant to your needs.
|
||||
|
||||
Regardless of which exercise you pick, you will migrate an old version of the [Spring PetClinic repository ](https://github.com/spring-projects/spring-petclinic/)to Spring Boot 3.
|
||||
|
||||
### Introduction
|
||||
|
||||
There's a small introductory presentation to accompany this workshop that you can find at the following link: [Spring Boot 3 is here; Where are you?](https://docs.google.com/presentation/d/1JZYjOfnmFX3l2q1wrOPpcGLba-kwmA\_gbuX5V\_2lZNg/edit#slide=id.g27b5a4473e1\_0\_187)
|
||||
|
||||
### Requirements
|
||||
|
||||
To complete our exercises, you will need:
|
||||
|
||||
* Some basic Spring and Git knowledge
|
||||
* To have Java 8 and Java 17 installed
|
||||
* A GitHub account
|
||||
* An IDE of your choice (although we recommend [Visual Studio Code](../../user-documentation/getting-started/) for the Spring Tools 4 exercise).
|
||||
|
||||
### Exercises
|
||||
|
||||
Get started with any of the following exercises:
|
||||
|
||||
* [Maven plugin exercise](maven-plugin-exercise.md)
|
||||
* [Gradle plugin exercise](gradle-plugin-exercise.md)
|
||||
* [Moderne CLI exercise](moderne-cli-exercise.md)
|
||||
* [Moderne platform exercise](moderne-platform-exercise.md)
|
||||
* [Migrate your own project](migrate-your-own-project.md)
|
||||
* [Recipe development](recipe-development.md)
|
||||
1876
workshops/spring-boot-migration-workshop/gradle-plugin-exercise.md
Normal file
1609
workshops/spring-boot-migration-workshop/maven-plugin-exercise.md
Normal file
@@ -0,0 +1,55 @@
|
||||
# Migrate your own project
|
||||
|
||||
### Support timelines
|
||||
|
||||
[OSS support for Spring Boot](https://spring.io/projects/spring-boot#support) 2.7 will end on November 18th, 2023, while support for Spring Boot 3.0 will end on November 24th, 2023. So if you haven't already, now's the time to migrate your project to Spring Boot 3.1!
|
||||
|
||||
<figure><img src="../../.gitbook/assets/support-timelines.png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
### Leap to Spring Boot 3.1
|
||||
|
||||
This guide will help you migrate your own project to Spring Boot 3.1. You've already seen various ways of running OpenRewrite recipes by now; pick the one that best suits your project for this migration. For a recap and detailed instructions see each of the indivual exercises:
|
||||
|
||||
* [Maven plugin](maven-plugin-exercise.md)
|
||||
* [Gradle plugin](gradle-plugin-exercise.md)
|
||||
* [Moderne CLI](moderne-cli-exercise.md)
|
||||
|
||||
You will want to [run the Migrate to Spring Boot 3.1 recipe](https://docs.openrewrite.org/recipes/java/spring/boot3/upgradespringboot\_3\_1), which runs you through all the steps of migrating to Spring Boot 3.1, no matter what version you're coming from.
|
||||
|
||||
### Migrate in steps
|
||||
|
||||
If you'd rather migrate in steps, you can also run recipes individually. This can be helpful if you'd like to review and build confidence in the changes, or need to troubleshoot a particular aspect.
|
||||
|
||||
As you can see in [the Migrate to Spring Boot 3.1 recipe](https://docs.openrewrite.org/recipes/java/spring/boot3/upgradespringboot\_3\_1), that first takes you [to Spring Boot 3.0](https://docs.openrewrite.org/recipes/java/spring/boot3/upgradespringboot\_3\_0), which first takes you [to Spring Boot 2.7](https://docs.openrewrite.org/recipes/java/spring/boot2/upgradespringboot\_2\_7), which first takes you [to Spring Boot 2.6](https://docs.openrewrite.org/recipes/java/spring/boot2/upgradespringboot\_2\_6), ... You can run any of these intermediate recipes, to pick up the changes up to that point.
|
||||
|
||||
You can also pick out specific migrations, for as much as you aren't up-to-date already, such as:
|
||||
|
||||
* [Migrate Spring Boot 2.x projects to JUnit 5 from JUnit 4](https://docs.openrewrite.org/recipes/java/spring/boot2/springboot2junit4to5migration)
|
||||
* [Migrate to Java 17](https://docs.openrewrite.org/recipes/java/migrate/upgradetojava17), which of course includes [Migrate to Java 11](https://docs.openrewrite.org/recipes/java/migrate/java8tojava11)
|
||||
* [Migrate to Spring Security 5.8](https://docs.openrewrite.org/recipes/java/spring/security5/upgradespringsecurity\_5\_8)
|
||||
* [Spring Boot 2.x best practices](https://docs.openrewrite.org/recipes/java/spring/boot2/springboot2bestpractices)
|
||||
|
||||
### Best practices after you migrate
|
||||
|
||||
After you've migrated to Spring Boot 3.1, you might want to consider some of the following best practices:
|
||||
|
||||
* [Common static analysis issues](https://docs.openrewrite.org/recipes/staticanalysis/commonstaticanalysis)
|
||||
* [JUnit Jupiter best practices](https://docs.openrewrite.org/recipes/java/testing/junit5/junit5bestpractices)
|
||||
* [AssertJ best practices](https://docs.openrewrite.org/recipes/java/testing/assertj/assertj)
|
||||
* [SLF4J best practices](https://docs.openrewrite.org/recipes/java/logging/slf4j/slf4jbestpractices)
|
||||
* [Java security best practices](https://docs.openrewrite.org/recipes/java/security/javasecuritybestpractices)
|
||||
* [Find and fix vulnerable dependencies](https://docs.openrewrite.org/recipes/java/dependencies/dependencyvulnerabilitycheck)
|
||||
|
||||
You might even want to run some of these recipes periodically, to keep your projects up-to-date continuously.
|
||||
|
||||
### Helpful resources
|
||||
|
||||
Here's a number of links that might be helpful in case you encounter edge cases not yet covered:
|
||||
|
||||
* [https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Migration-Guide)
|
||||
* [https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.1-Release-Notes)
|
||||
* [https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-3.0-Release-Notes)
|
||||
* [https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.7-Release-Notes](https://github.com/spring-projects/spring-boot/wiki/Spring-Boot-2.7-Release-Notes)
|
||||
* [https://docs.spring.io/spring-security/reference/migration/index.html](https://docs.spring.io/spring-security/reference/migration/index.html)
|
||||
* [https://github.com/spring-projects/spring-data-commons/wiki/](https://github.com/spring-projects/spring-data-commons/wiki/)
|
||||
* [https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2022.0-Release-Notes](https://github.com/spring-cloud/spring-cloud-release/wiki/Spring-Cloud-2022.0-Release-Notes)
|
||||
1659
workshops/spring-boot-migration-workshop/moderne-cli-exercise.md
Normal file
@@ -0,0 +1,52 @@
|
||||
# Moderne platform exercise
|
||||
|
||||
In this exercise, you will utilize the [Moderne platform](https://app.moderne.io/) to:
|
||||
|
||||
* Run static code analysis recipes across repositories from different GitHub organizations
|
||||
* Fix security vulnerabilities across hundreds of open-source projects.
|
||||
|
||||
### Prepare your environment
|
||||
|
||||
Go to [https://app.moderne.io/](https://app.moderne.io/) and register with your GitHub account. Once you've signed in, you'll find more than 31,000 open-source repositories that can be used to test OpenRewrite recipes without you having to configure anything.
|
||||
|
||||
### Running recipes with the Moderne platform
|
||||
|
||||
1. Once you're logged in to [Moderne](https://app.moderne.io/), you will see that the `Default` organization (a grouping of repositories) is selected in the sidebar.
|
||||
|
||||
<figure><img src="../../.gitbook/assets/mod-org (2).png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
2. With the organization selected, you can go to the[ repositories page](https://app.moderne.io/organizations) and see what repositories are included. There are a few repositories selected from the Netflix, spring-cloud, and spring-projects GitHub organizations.
|
||||
|
||||
<figure><img src="../../.gitbook/assets/organizations-and-repos.png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{% hint style="info" %}
|
||||
The default group has a small set of repositories so recipes will run quickly. If you would rather see more results, you can choose to use the `Netflix + Spring` organization which consists of more than 100 repositories by clicking on `Default` and selecting the new organization.
|
||||
{% endhint %}
|
||||
|
||||
3. With the organization selected, please go to the [Moderne Marketplace](https://app.moderne.io/marketplace). From there, click on `Static analysis and remediation`, and finally select `Common static analysis issues`. 
|
||||
4. Click on the `More Details` link. You should now be on the [common static analysis issues recipe page](https://app.moderne.io/recipes/org.openrewrite.staticanalysis.CommonStaticAnalysis). From there, you can see that there are many different sonarqube rules under the recipe list. This is because common static analysis issues is a composition of other recipes. You can restrict the ones you want to apply to see the results of a particular recipe by using the [recipe builder](https://app.moderne.io/recipes/builder).
|
||||
|
||||
<figure><img src="../../.gitbook/assets/common-static-analysis-list.png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
5. To begin running the recipe, click on the `DRY RUN` button.
|
||||
6. You will now be redirected to a page that shows all the relevant recipe run information. Once it's finished, you can click on each repository name to see the results.
|
||||
7. If you look at the results, you might want to understand why a change has been introduced. Every single change has three dots you can click on in the top right corner of the change. From there, you can select `Why did this change?` to find out more information.
|
||||
|
||||
<figure><img src="../../.gitbook/assets/why-did-this-change.png" alt=""><figcaption></figcaption></figure>
|
||||
|
||||
{% hint style="warning" %}
|
||||
Please, do not create pull requests with the results produced by the Moderne platform if you are not an active contributor of those repositories.
|
||||
{% endhint %}
|
||||
|
||||
### Fixing security vulnerabilities with the Moderne platform
|
||||
|
||||
Another substantial use case for the Moderne platform is detecting and potentially resolving CVEs in your projects and their dependencies. Since the Moderne platform supports complex refactoring recipes (such as the Spring Boot 3 migration), the community can contribute and provide recipes for other major migrations that do more than bump a dependency version.
|
||||
|
||||
In this part of the exercise, let's use the Moderne platform to get a list of vulnerabilities in open-source repositories.
|
||||
|
||||
1. Begin by navigating to the [Check for dependency vulnerabilities recipe](https://app.moderne.io/recipes/org.openrewrite.java.dependencies.DependencyVulnerabilityCheck).
|
||||
2. Select `compile` for the first option (`scope`), `true`, for the second option (`override managed version`), and leave the third option as blank (`add markers`).
|
||||
3. Click on the `DRY RUN` button to begin executing this recipe. It should take a few minutes to run.
|
||||
4. Once the recipe is done running, you can click on the individual repositories to see suggested changes that fix some vulnerabilities.
|
||||
5. You can also click on the `Data Tables` tab to get taken to a page that allows you to download a CSV or Excel file that contains a list of CVEs that the repositories are vulnerable to. Download the CSV vulnerability report and open the CSV with your preferred CSV reader. You will see that the CSV contains an entry per vulnerability, dependency, and repository. Take special note of the column called `fixedVersion`. That tells you what version fixes that vulnerability. Also take note of the `depth` column, which lets you see how many dependencies away it is from your original dependency.
|
||||
6. You can also click on the `Visualizations` tab to get a quick high over insight into the number of known vulnerabilities associated with dependencies in the projects.
|
||||
@@ -0,0 +1,15 @@
|
||||
# Recipe development
|
||||
|
||||
The Java ecosystem is vast, and continuously evolving. As such, it's possible OpenRewrite does not yet cover some parts of your migration. We're always looking for help to expand the coverage of migration recipes, and we've made it as easy as possible to get started with recipe development.
|
||||
|
||||
Should you find any parts of your migration are not yet covered, then the first thing to check is whether there is already a corresponding [issue on the backlog](https://github.com/orgs/openrewrite/projects/4/views/10), perhaps with some pointers on an implementation. If not, you can [create a new issue](https://github.com/openrewrite/rewrite-spring/issues/new/choose) to discuss the recipe you'd like to develop. Note that there are separate modules for Spring recipes, Java recipes, testing recipes, logging recipes, and many more. It helps to browse the existing modules for any related work that might be similar and start from there.
|
||||
|
||||
### Types of recipes
|
||||
|
||||
If there's no existing recipe that covers your use case, then you can write your own. There are three types of recipes you can write, each with their own tradeoffs.
|
||||
|
||||
1. [Declarative recipes](https://docs.openrewrite.org/authoring-recipes/types-of-recipes#declarative-recipes) are the simplest to write, and are the most common type of recipe. They are written in YAML, and often tie together existing recipe building blocks with some light configuration.
|
||||
2. [Refaster rules ](https://docs.openrewrite.org/authoring-recipes/types-of-recipes#refaster-templates)bring you the benefit of compiler support, and work best for straightforward replacements. They generate recipes that can also be used as a starting point for more complex recipe implementations.
|
||||
3. [Imperative recipes](https://docs.openrewrite.org/authoring-recipes/types-of-recipes#imperative-recipes) are the most powerful, and allow you to write Java code to implement your recipe. By [using the `JavaTemplate` builder](https://docs.openrewrite.org/authoring-recipes/modifying-methods-with-javatemplate), you can keep complexity down, as you define arbitrary code changes.
|
||||
|
||||
No matter which method of recipe development you choose, you can always [write unit tests for your recipe](https://docs.openrewrite.org/authoring-recipes/recipe-testing). Beyond that there are [best practices for writing recipes](https://docs.openrewrite.org/authoring-recipes/recipe-conventions-and-best-practices), such as ensuring idempotence, and avoiding harmful changes. In rare cases, such as with Spring, you might need to [use multiple versions of a dependency](https://docs.openrewrite.org/authoring-recipes/multiple-versions). When you get started, be sure to set up the recommended [recipe development environment](https://docs.openrewrite.org/authoring-recipes/recipe-development-environment).
|
||||