Skip to main content

Singleton

org.openrewrite.Singleton

Used as a precondition to ensure that a recipe attempts to make changes only once. Accidentally including multiple copies/instances of the same large composite recipes is a common mistake. If those recipes are marked with this precondition the performance penalty is limited. This recipe does nothing useful run on its own.

Usage in YAML recipes

Add org.openrewrite.Singleton as a precondition:

---
type: specs.openrewrite.org/v1beta/recipe
name: com.example.Append
displayName: My recipe
preconditions:
- org.openrewrite.Singleton
recipeList:
- org.openrewrite.text.AppendToTextFile:
relativeFileName: report.txt
content: 'Recipe executed'
```## Usage in Java recipes

Wrap visitors with `Singleton.singleton(this, visitor)` to ensure only the first *equivalent* recipe instance makes changes:

```java
@Override
public TreeVisitor<?, ExecutionContext> getVisitor(Accumulator acc) {
return singleton(this, new TreeVisitor<Tree, ExecutionContext>() {
@Override
public Tree visit(@Nullable Tree tree, ExecutionContext ctx) {
// Your transformation logic
return tree;
}
});
}
@Override
public Collection<SourceFile> generate(Accumulator acc, ExecutionContext ctx) {
if (!isSingleton(this, ctx)) {
return Collections.emptyList();
}
// Generate new sources
return results;
}

@Override
public TreeVisitor<?, ExecutionContext> getVisitor(Accumulator acc) {
return singleton(this, new TreeVisitor<Tree, ExecutionContext>() {
// Visitor logic
});
}

Note: Singleton status is determined by the recipe's equals() and hashCode() methods. If equivalent instances of a recipe are not considered singletons, ensure your recipe class correctly implements these methods. The easiest way is to use Lombok's @Value annotation on your recipe class, which automatically generates correct equals() and hashCode() implementations based on all fields.

Recipe source

GitHub: Singleton.java, Issue Tracker, Maven Central

This recipe is available under the Apache License Version 2.0.

Usage

This recipe has no required configuration parameters and comes from a rewrite core library. It can be activated directly without adding any dependencies.

  1. Add the following to your build.gradle file:
build.gradle
plugins {
id("org.openrewrite.rewrite") version("latest.release")
}

rewrite {
activeRecipe("org.openrewrite.Singleton")
setExportDatatables(true)
}

repositories {
mavenCentral()
}

  1. Run gradle rewriteRun to run the recipe.

See how this recipe works across multiple open-source repositories

Run this recipe on OSS repos at scale with the Moderne SaaS.

The community edition of the Moderne platform enables you to easily run recipes across thousands of open-source repositories.

Please contact Moderne for more information about safely running the recipes on your own codebase in a private SaaS.

Data Tables

Source files that had results

org.openrewrite.table.SourcesFileResults

Source files that were modified by the recipe run.

Column NameDescription
Source path before the runThe source path of the file before the run. null when a source file was created during the run.
Source path after the runA recipe may modify the source path. This is the path after the run. null when a source file was deleted during the run.
Parent of the recipe that made changesIn a hierarchical recipe, the parent of the recipe that made a change. Empty if this is the root of a hierarchy or if the recipe is not hierarchical at all.
Recipe that made changesThe specific recipe that made a change.
Estimated time savingAn estimated effort that a developer to fix manually instead of using this recipe, in unit of seconds.
CycleThe recipe cycle in which the change was made.