Skip to content

Commit

Permalink
feat: Added option to comment out property in yaml
Browse files Browse the repository at this point in the history
Refs: #4740
  • Loading branch information
Andrei Shakirin committed Dec 4, 2024
1 parent f9d71bc commit 229ee4f
Show file tree
Hide file tree
Showing 2 changed files with 248 additions and 17 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,14 @@
*/
package org.openrewrite.yaml;

import lombok.AllArgsConstructor;
import lombok.EqualsAndHashCode;
import lombok.Value;
import org.openrewrite.*;
import org.jetbrains.annotations.NotNull;
import org.openrewrite.ExecutionContext;
import org.openrewrite.Option;
import org.openrewrite.Recipe;
import org.openrewrite.TreeVisitor;
import org.openrewrite.yaml.tree.Yaml;

import java.util.ArrayDeque;
Expand All @@ -28,6 +33,7 @@
import static java.util.stream.StreamSupport.stream;

@Value
@AllArgsConstructor
@EqualsAndHashCode(callSuper = false)
public class CommentOutProperty extends Recipe {
@Option(displayName = "Property key",
Expand All @@ -40,6 +46,23 @@ public class CommentOutProperty extends Recipe {
example = "The `foo` property is deprecated, please migrate")
String commentText;

@Option(example = "true", displayName = "Comment out property",
description = "If false, property wouldn't be commented out, only comment will be added. By default, set to true",
required = false)
Boolean commentOutProperty;

public CommentOutProperty() {
this.propertyKey = "";
this.commentText = "";
this.commentOutProperty = true;
}

public CommentOutProperty(String propertyKey, String commentText) {
this.propertyKey = propertyKey;
this.commentText = commentText;
this.commentOutProperty = true;
}

@Override
public String getDisplayName() {
return "Comment out property";
Expand All @@ -61,6 +84,7 @@ public TreeVisitor<?, ExecutionContext> getVisitor() {
private boolean nextDocNeedsNewline;
private String comment = "";
private String indentation = "";
private boolean isBlockCommentExists;

@Override
public Yaml.Document visitDocument(Yaml.Document document, ExecutionContext ctx) {
Expand All @@ -72,7 +96,7 @@ public Yaml.Document visitDocument(Yaml.Document document, ExecutionContext ctx)
}

// Add any leftover comment to the end of document
if (!comment.isEmpty()) {
if (!comment.isEmpty() && commentOutProperty) {
String newPrefix = String.format("%s# %s%s%s",
indentation,
commentText,
Expand All @@ -89,11 +113,15 @@ public Yaml.Document visitDocument(Yaml.Document document, ExecutionContext ctx)
public Yaml.Sequence.Entry visitSequenceEntry(Yaml.Sequence.Entry entry,
ExecutionContext ctx) {
indentation = entry.getPrefix();
if (!comment.isEmpty()) {
// add comment and return
String newPrefix = entry.getPrefix() + "# " + commentText + comment + entry.getPrefix();
comment = "";
return entry.withPrefix(newPrefix);
if (commentOutProperty) {
if (!comment.isEmpty()) {
// add comment and return
String newPrefix = entry.getPrefix() + "# " + commentText + comment + entry.getPrefix();
comment = "";
return entry.withPrefix(newPrefix);
}
} else {
return addBockCommentIfNecessary(entry, ctx);
}
return super.visitSequenceEntry(entry, ctx);
}
Expand All @@ -103,20 +131,13 @@ public Yaml.Mapping.Entry visitMappingEntry(Yaml.Mapping.Entry entry, ExecutionC
String lastIndentation = indentation;
indentation = entry.getPrefix();

if (!comment.isEmpty()) {
if (!comment.isEmpty() && commentOutProperty) {
String newPrefix = entry.getPrefix() + "# " + commentText + comment + entry.getPrefix();
comment = "";
return entry.withPrefix(newPrefix);
}

Deque<Yaml.Mapping.Entry> propertyEntries = getCursor().getPathAsStream()
.filter(Yaml.Mapping.Entry.class::isInstance)
.map(Yaml.Mapping.Entry.class::cast)
.collect(Collectors.toCollection(ArrayDeque::new));

String prop = stream(spliteratorUnknownSize(propertyEntries.descendingIterator(), 0), false)
.map(e2 -> e2.getKey().getValue())
.collect(Collectors.joining("."));
String prop = calculateCurrentKeyPath();

if (prop.equals(propertyKey)) {
String prefix = entry.getPrefix();
Expand All @@ -128,12 +149,48 @@ public Yaml.Mapping.Entry visitMappingEntry(Yaml.Mapping.Entry entry, ExecutionC
comment = lastIndentation + "#" + entry.print(getCursor().getParentTreeCursor());
}

doAfterVisit(new DeleteProperty(propertyKey, null, null, null).getVisitor());
if (commentOutProperty) {
doAfterVisit(new DeleteProperty(propertyKey, null, null, null).getVisitor());
} else if (!entry.getPrefix().contains(commentText) && !isBlockCommentExists) {
return entry.withPrefix(entry.getPrefix() + "# " + commentText + (entry.getPrefix().contains("\n")? entry.getPrefix() : "\n" + entry.getPrefix()));
}
return entry;
}

return super.visitMappingEntry(entry, ctx);
}

private @NotNull Yaml.Sequence.Entry addBockCommentIfNecessary(Yaml.Sequence.Entry entry, ExecutionContext ctx) {
boolean propertyExistsInSequence = isPropertyExistsInSequence(entry);
if (propertyExistsInSequence) {
isBlockCommentExists = true;
if (!entry.getPrefix().contains(commentText)) {
return entry.withPrefix(entry.getPrefix() + "# " + commentText + (entry.getPrefix().contains("\n") ? entry.getPrefix() : "\n" + entry.getPrefix()));
}
}
return super.visitSequenceEntry(entry, ctx);
}

private boolean isPropertyExistsInSequence(Yaml.Sequence.Entry entry) {
if (!(entry.getBlock() instanceof Yaml.Mapping)) {
return false;
}
Yaml.Mapping mapping = (Yaml.Mapping) entry.getBlock();
String prop = calculateCurrentKeyPath();
return mapping.getEntries().stream()
.anyMatch(e -> propertyKey.equals(prop + "." + e.getKey().getValue()));
}

private @NotNull String calculateCurrentKeyPath() {
Deque<Yaml.Mapping.Entry> propertyEntries = getCursor().getPathAsStream()
.filter(Yaml.Mapping.Entry.class::isInstance)
.map(Yaml.Mapping.Entry.class::cast)
.collect(Collectors.toCollection(ArrayDeque::new));

return stream(spliteratorUnknownSize(propertyEntries.descendingIterator(), 0), false)
.map(e2 -> e2.getKey().getValue())
.collect(Collectors.joining("."));
}
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -172,4 +172,178 @@ void commentLastProperty() {
)
);
}

@DocumentExample("comment out a map entry")
@Test
void sequenceKeepProperty() {
rewriteRun(
spec -> spec.recipe(new CommentOutProperty("foo.bar.sequence.propertyA",
"Some comments", false)),
yaml(
"""
foo:
bar:
sequence:
- name: name
- propertyA: fieldA
- propertyB: fieldB
scalar: value
""",
"""
foo:
bar:
sequence:
- name: name
# Some comments
- propertyA: fieldA
- propertyB: fieldB
scalar: value
"""
)
);
}

@DocumentExample("comment out a map entry")
@Test
void sequenceFirstKeepProperty() {
rewriteRun(
spec -> spec.recipe(new CommentOutProperty("foo.bar.sequence.name",
"Some comments", false)),
yaml(
"""
foo:
bar:
sequence:
- name: name
- propertyA: fieldA
- propertyB: fieldB
scalar: value
""",
"""
foo:
bar:
sequence:
# Some comments
- name: name
- propertyA: fieldA
- propertyB: fieldB
scalar: value
"""
)
);
}

@DocumentExample("comment out entire sequence")
@Test
void commentSequenceKeepProperty() {
rewriteRun(
spec -> spec.recipe(new CommentOutProperty("foo.bar.sequence",
"Some comments", false)),
yaml(
"""
foo:
bar:
sequence:
- name: name
- propertyA: fieldA
- propertyB: fieldB
scalar: value
""",
"""
foo:
bar:
# Some comments
sequence:
- name: name
- propertyA: fieldA
- propertyB: fieldB
scalar: value
"""
)
);
}

@Test
void commentSinglePropertyKeepProperty() {
rewriteRun(
spec -> spec.recipe(new CommentOutProperty("with.java-version",
"Some comments", false)),
yaml(
"""
with:
java-cache: 'maven'
java-version: 11
test: 'bar'
""",
"""
with:
java-cache: 'maven'
# Some comments
java-version: 11
test: 'bar'
"""
)
);
}

@Test
void commentLastPropertyWithIndentKeepProperty() {
rewriteRun(
spec -> spec.recipe(new CommentOutProperty("with.java-version",
"Some comments", false)),
yaml(
"""
with:
java-cache: 'maven'
java-version: 11
""",
"""
with:
java-cache: 'maven'
# Some comments
java-version: 11
"""
)
);
}

@Test
void commentLastPropertyOfFirstDocumentKeepProperty() {
rewriteRun(
spec -> spec.recipe(new CommentOutProperty("with.java-version",
"Some comments", false)),
yaml(
"""
with:
java-cache: 'maven'
java-version: 11
---
""",
"""
with:
java-cache: 'maven'
# Some comments
java-version: 11
---
"""
)
);
}

@Test
void commentLastPropertyKeepProperty() {
rewriteRun(
spec -> spec.recipe(new CommentOutProperty("test",
"Some comments", false)),
yaml(
"""
test: foo
""",
"""
# Some comments
test: foo
"""
)
);
}
}

0 comments on commit 229ee4f

Please sign in to comment.