-
Notifications
You must be signed in to change notification settings - Fork 2.1k
Writing OpenRewrite Migrations for Track 2 Libraries
The goal of this wiki is to provide relevant information to assist in writing OpenRewrite migrations for Track 2 libraries. It is not a comprehensive guide of all capabilities provided by OpenRewrite. If you are unfamiliar with OpenRewrite, please review the official OpenRewrite documentation from Moderne.
The uber-recipe containing all of the Azure OpenRewrite migrations is thr rewrite.yml
recipe, located in the ..\azure-openrewrite\src\main\resources\META-INF\
directory. The recipeList
for this recipe should only contain migration recipes. Recipes that directly perform the code migrations should not be placed here and should instead be encapsulated by migration recipes (often multi-encapsulated within package-level recipes).
Migration Recipes: recipes responsible for containing the recipes related to the migration of a singular SDK
A migration recipe is the representation of all OpenRewrite recipes pertaining to a particular SDK. There should always be a one-to-one mapping between SDK libraries and migration recipes. When writing a migration recipe, the recipe should be identified by the following:
- The recipe's
name
should be prefixed with "com.azure.openrewrite.migration". It should then be followed by the SDK's module name (excluding "com.").- ex.:
com.azure.openrewrite.migration.azure.core
- ex.:
- The recipe file should exist under the following directory structure:
..\azure-openrewrite\src\main\resources\META-INF\rewrite\migrationRecipes\<SdkName>\LibraryMigration.yml
.- ex.: The
azure-core
migration recipe exists in the file..\azure-openrewrite\src\main\resources\META-INF\rewrite\migrationRecipes\core\LibraryMigration.yml
- ex.: The
Package recipes contain a collection of related translation recipes. The relation used to identify which package recipe a translation recipe should be placed within is the containing package for the API that the translation recipe manipulates (hence the name "package recipe"). This layer of encapsulation is intended to maintain readability of the recipe files and to improve the recipe debugging experience. When writing a package recipe, the recipe should be identified by the following:
- The recipe
name
should be prefixed with "com.azure.openrewrite.recipe". It should then be followed by the package name of the SDK package that it represents translations for.- ex.:
com.azure.openrewrite.recipe.azure.core.exception
- ex.:
- The file containing the package recipe should be a yaml file with a name mirroring the package name (as identified by an import statement).
- ex.: The azure core exception yaml file name would be
com.azure.core.exception.yml
- ex.: The azure core exception yaml file name would be
- The recipe file should live in a directory structure of the following format:
..\azure-openrewrite\src\main\resources\META-INF\rewrite\migrationRecipes\<SdkName>\
- ex.: The azure.core.http package recipe location is:
..\azure-openrewrite\src\main\resources\META-INF\rewrite\migrationRecipes\core\com.azure.core.http.yml
- ex.: The azure.core.http package recipe location is:
These are the recipes that fundamentally preform the migration tasks. These recipes will either be declarative (recipes written in yaml) or imperative (recipes written in Java).
When writing a declarative recipe, one should write it directly into the recipe list of the encapsulating package recipe. Reference the recipe using the recipe name which is either provided (when using a recipe from the OpenRewrite Java catalog) or identified deterministically by the combination of the Java recipe file name prefixed by its containing package (when using an imperative recipe written locally elsewhere within Azure OpenRewrite)
When writing an imperative recipe, one should write it in a java file mirroring it's containing package recipe's name. The name of the recipe should also contain the phrase "custom" to indicate that the recipe performs api-specifc migrations not possible through use of declarative recipes alone.
Example:
To be completed
Due to the IDEs ability to view the diff of an AssertionError
, it is highly suggested that you use Intellij when testing recipes.
The testGoldenImage
test within the FullSampleMigrationTest
test class is the test that runs the migration tests on all samples. The test is configured using the uber-recipe, meaning that the testGoldenImage
test will run all recipes on all samples. The testing suite is configured to run recipes on all samples, presuming that they follow a specified directory structure. When adding additional samples to be tested, the test class FullSampleMigrationTest
does not need to be altered.
When adding samples, be sure to verify that the samples compile to ensure that the migration accurately reflect what's available within public api for your library.
For the FullSampleMigrationTest
to work correctly, the samples must adhere to a specific directory structure:
- A library's samples directory must be as follows:
<path_to_root>/sdk/tools/azure-openrewrite/src/test/resources/migrationExamples/<library-directory>
- Samples run individually as parameterized test cases. Each sample must have it's own encapsulating directory. Ex:
/migrationExamples/azure-core/sample1
/migrationExamples/azure-core/sample2
- Within each sample there must exist two directories with the names
v1
andv2
, wherev1
contains all pre-migration sample java files (using the Track 2 library) andv2
contains all post-migration sample files (using Track 3 library). Ex:-
/migrationExamples/azure-core/sample1/v1
: All unmigrated Track 2 java files that collectively represent sample 1. -
/migrationExamples/azure-core/sample1/v2
: All migrated Track 3 java files that collectively represent sample 1.
-
- For every file within the
v1
directory of a sample, there must be a file in thev2
directory for that sample with a matching filename.
To ensure that our samples are an accurate representation of both our Track 2 and Track 3 libraries, we make use of the azure-openrewrite-compiler-plugin
, an internal tool that compiles both the pre- and post-migration samples using the Track 2 and Track 3 libraries respectively. To keep track of these dependency versions, we make use of maven profiles: Profile v1
to represent the Track 2 libraries dependencies and profile v2
to represent the Track 3 libraries dependencies. When adding samples for a new library, be sure to update the azure-openrewrite
pom.xml file's v1
and v2
profiles with the appropriate dependencies for each.
Running the sample compiler requires two steps:
- You compile the plugin using the command:
../sdk/tools> mvn clean install -f ./azure-openrewrite-compiler-maven-plugin/pom.xml
- You run the plugin on azure-openrewrite using the command:
../sdk/tools> mvn com.azure:azure-openrewrite-compiler-maven-plugin:compile-golden-image -f ./azure-openrewrite/pom.xml
To be completed
- Frequently Asked Questions
- Azure Identity Examples
- Configuration
- Performance Tuning
- Android Support
- Unit Testing
- Test Proxy Migration
- Azure Json Migration
- New Checkstyle and Spotbugs pattern migration
- Protocol Methods
- TypeSpec-Java Quickstart
- Getting Started Guidance
- Adding a Module
- Building
- Writing Performance Tests
- Working with AutoRest
- Deprecation
- BOM guidelines
- Release process
- Access helpers