Thank you for taking the time to contribute to OpenRewrite! All types of contributions are encouraged and valued.
Please make sure to read the relevant section before making your contribution. It will make it a lot easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 😁
In this guide, you will find instructions for the different ways you can contribute to the project, what we expect when you open a pull request, and useful context for setting up your development environment.
Note
This guide, our issue templates and our pull request template are defined once for the whole organization in openrewrite/.github. GitHub applies them to every OpenRewrite repository that doesn't define its own, which also means you won't find them in the repository you cloned.
There are various ways to contribute, each of which we will cover in more detail below.
- Asking questions & reporting issues
- Answering community questions
- Improving the documentation
- Contributing fixes
- Adding new recipes
- New features
When starting out, you will likely have questions about OpenRewrite; we have multiple channels where you can ask questions:
- Slack
- Discord
- https://github.com/openrewrite/rewrite/discussions
- https://github.com/openrewrite/rewrite/issues
- Stack Overflow
We monitor all of these channels and try to respond in a timely manner. Please only post your question in a single channel so that we don't spend time looking into questions that may have already been answered elsewhere.
Furthermore, when asking a question or reporting an issue, please be as specific as possible and include details that will help us immediately dive in. For instance:
- Share what you have read and tried already so that we don't end up sending you to places you've already been.
- Explain how you are running OpenRewrite. Are you using Maven? Gradle? Moderne.io? Something else?
- Provide the version numbers of the Maven or Gradle plugin, OpenRewrite itself, and any rewrite modules you may be using.
- Add as much of your OpenRewrite configuration as you're able to share so that we can rule out configuration issues.
- Let us know what recipe you are running, especially when using a
rewrite.ymlfile. - Include a before and after. Also, what did you expect the after to be?
- When errors occur, please include the output of
--stacktracefor Gradle or--debugfor Maven. - Ensure that you are asking questions or reporting issues on the respective OpenRewrite module if at all possible.
By doing all of these things, you will not only help us get you answers more quickly, but you will help out the community who may search for these details in the future.
Once you get more familiar with OpenRewrite, you might spot questions from within the community that you already know the answer to. Helping answer these questions is a great way to reduce the load on contributors, and very much appreciated.
If you are unsure whether your answer is the best approach, then responding to a question will help you further your own understanding as well. Please feel free to answer questions in any of the channels. By doing so, we can help everyone learn and grow.
As you increase your knowledge of OpenRewrite, you might find mistakes in our documentation, areas where we could be more clear, or topics that are missing. If you have suggestions for any of those, please consider contributing to rewrite-docs. There are further instructions in that project's README. All changes made to that repository are deployed to https://docs.openrewrite.org.
The best way to work towards a fix is to first replicate the issue with a minimal unit test. Nearly every recipe has a dedicated unit test that shows a before and after situation. Usually, you can copy the first unit test for any specific recipe, and adjust that to match the problem case.
Once replicated, please open a draft pull request even if you are unsure whether or not you will be able to contribute a fix. If you do decide that you want to fix it, you can iterate on that PR. By opening one early, you allow us to have a look at the specifics of the issue in our IDE, if necessary.
From there, we generally recommend that people step through the recipe execution using the debugger while running the new unit test. As you make changes to the recipe, you should see the test go from failing to passing. If you get stuck at any point, we’re happy to help. Please feel free to update the PR with questions.
Are you looking for a good place to start contributing? We have added the "Good first issue" label to a few of our backlog items, and added hints on the possible implementation.
Before you add a new recipe, we suggest you first open an issue to discuss the specifics of what you're wanting to achieve. Please include a before and after example so that we're able to judge whether or not the recipe is feasible or desirable. By reaching out before you start implementing, we can also help guide you to similar existing recipes that you might want to borrow parts of or compare your solution to.
Once you start implementing the new recipe, we recommend you start by writing unit tests similar to those discussed in the contributing fixes section. This way you'll be able to step through them with a debugger or the TreeVisitingPrinter to explore what tree elements are available.
An early draft pull request at this stage makes it easier for us to provide you with feedback to improve your implementation – which will result in less work for you in the long run.
Once you mark your implementation as ready for review, we will go through it in detail to get it in shape to merge into OpenRewrite.
If you want to add a new major feature, please reach out to us via Slack to discuss the specifics. By doing so, we can help guide you and ensure that it's feasible before you spend a considerable amount of time.
When you open a pull request, you will be asked to fill in our pull request template. Please tell us what changed and why; the rest of the sections are optional, and you are welcome to delete the ones that don't apply. The sections below explain the checklist at the bottom of that template.
Draft pull requests are encouraged, and there's no need to work through the checklist before opening one. We only expect it to be complete by the time you mark your pull request ready for review.
Please cover both the case that should change, and a similar case that should be left alone, so that we don't regress on either. Our recipe testing documentation covers RewriteTest in detail.
Please keep your diff limited to the lines you actually changed. Our repositories predate any enforced formatting, so they are not uniformly formatter-clean, and running the IntelliJ IDEA auto-formatter over a whole file will reindent unrelated code and bury your change.
In practice that means:
- Match the surrounding code.
- If you use the IntelliJ IDEA auto-formatter, scope it to the lines or the selection you changed rather than the file.
Code | Reformat CodeoffersOnly VCS changed textfor this. - Some repositories ship an
.editorconfigthat IntelliJ IDEA and other editors pick up automatically. Where it exists, it settles final newlines, trailing whitespace, and the indentation used in test sources; anything it doesn't cover is a judgement call best answered by the surrounding code.
We would rather review a small diff with slightly inconsistent whitespace than a large one where the change is hard to find, so please don't spend long on this.
Recipe modules publish a src/main/resources/META-INF/rewrite/recipes.csv describing the recipes they contain. Renaming a recipe, or changing its display name or description, makes that file stale.
You don't need to edit it by hand. ./gradlew build validates the file as part of check and fails when it has drifted, and ./gradlew recipeCsvGenerate regenerates it. Please commit the result along with your change.
For instructions on how to build and develop OpenRewrite projects, please see our Building and developing OpenRewrite doc.