Skip to content

Commit

Permalink
Add DockerImageReference
Browse files Browse the repository at this point in the history
  • Loading branch information
jevanlingen committed Dec 17, 2024
1 parent f8fca6b commit 8e66538
Show file tree
Hide file tree
Showing 11 changed files with 121 additions and 87 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package org.openrewrite.text;

import lombok.Value;
import org.openrewrite.Cursor;
import org.openrewrite.SourceFile;
import org.openrewrite.internal.StringUtils;
import org.openrewrite.trait.Reference;
import org.openrewrite.trait.SimpleTraitMatcher;

@Value
public class DockerImageReference implements Reference {
Cursor cursor;
String value;

@Override
public Kind getKind() {
return Kind.IMAGE;
}

public static class Provider implements Reference.Provider<DockerImageReference> {
@Override
public boolean isAcceptable(SourceFile sourceFile) {
if (sourceFile instanceof PlainText) {
PlainText text = (PlainText) sourceFile;
String fileName = text.getSourcePath().toFile().getName();
return (fileName.equals("Dockerfile") || fileName.equals("Containerfile")) && text.getText().contains("FROM");
}
return false;
}

@Override
public SimpleTraitMatcher<DockerImageReference> getMatcher() {
return new SimpleTraitMatcher<DockerImageReference>() {
@Override
protected DockerImageReference test(Cursor cursor) {
String text = ((PlainText) cursor.getValue()).getText();
int index = StringUtils.indexOfNextNonWhitespace(text.indexOf("FROM") + 4, text);
StringBuilder image = new StringBuilder();
for (char c : text.substring(index).toCharArray()) {
if (Character.isWhitespace(c)) {
break;
}
image.append(c);
}
return new DockerImageReference(cursor, image.toString());
}
};
}
}
}
29 changes: 26 additions & 3 deletions rewrite-core/src/main/java/org/openrewrite/text/PlainText.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
package org.openrewrite.text;

import lombok.*;
import lombok.experimental.NonFinal;
import org.jspecify.annotations.Nullable;
import org.openrewrite.*;
import org.openrewrite.marker.Markers;

import java.lang.ref.SoftReference;
import java.nio.charset.Charset;
import java.nio.charset.StandardCharsets;
import java.nio.file.Path;
Expand All @@ -36,7 +38,7 @@
@Value
@Builder
@AllArgsConstructor
public class PlainText implements SourceFile, Tree {
public class PlainText implements SourceFileWithReferences, Tree {

@Builder.Default
@With
Expand Down Expand Up @@ -82,7 +84,7 @@ public SourceFile withCharset(Charset charset) {
public PlainText withText(String text) {
if (!text.equals(this.text)) {
return new PlainText(this.id, this.sourcePath, this.markers, this.charsetName, this.charsetBomMarked,
this.fileAttributes, this.checksum, text, this.snippets);
this.fileAttributes, this.checksum, text, this.snippets, this.references);
}
return this;
}
Expand Down Expand Up @@ -123,7 +125,28 @@ public PlainText withSnippets(@Nullable List<Snippet> snippets) {
if (this.snippets == snippets) {
return this;
}
return new PlainText(id, sourcePath, markers, charsetName, charsetBomMarked, fileAttributes, checksum, text, snippets);
return new PlainText(id, sourcePath, markers, charsetName, charsetBomMarked, fileAttributes, checksum, text, snippets, references);
}

@Nullable
@NonFinal
@ToString.Exclude
transient SoftReference<References> references;

@Override
public References getReferences() {
References cache;
if (this.references == null) {
cache = References.build(this);
this.references = new SoftReference<>(cache);
} else {
cache = this.references.get();
if (cache == null || cache.getSourceFile() != this) {
cache = References.build(this);
this.references = new SoftReference<>(cache);
}
}
return cache;
}

@Value
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,7 @@ public Stream<SourceFile> parseInputs(Iterable<Input> sources, @Nullable Path re
input.getFileAttributes(),
null,
sourceStr,
null,
null
);
parsingListener.parsed(input, plainText);
Expand Down
15 changes: 12 additions & 3 deletions rewrite-core/src/main/java/org/openrewrite/trait/Reference.java
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import org.openrewrite.*;

import java.util.HashSet;
import java.util.Set;

@Incubating(since = "8.39.0")
Expand Down Expand Up @@ -51,11 +52,19 @@ default Tree rename(Renamer renamer, Cursor cursor, ExecutionContext ctx) {
throw new UnsupportedOperationException();
}

interface Provider {
interface Provider<U extends Reference> {
boolean isAcceptable(SourceFile sourceFile);

Set<Reference> getReferences(SourceFile sourceFile);
SimpleTraitMatcher<U> getMatcher();

boolean isAcceptable(SourceFile sourceFile);
default Set<Reference> getReferences(SourceFile sourceFile) {
Set<Reference> references = new HashSet<>();
getMatcher().asVisitor(reference -> {
references.add(reference);
return reference.getTree();
}).visit(sourceFile, 0);
return references;
}
}

interface Matcher {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
org.openrewrite.text.DockerImageReference$Provider
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,9 @@

import org.junit.jupiter.api.Test;
import org.openrewrite.DocumentExample;
import org.openrewrite.java.table.ImageSourceFiles;
import org.openrewrite.test.RecipeSpec;
import org.openrewrite.test.RewriteTest;

import static org.assertj.core.api.Assertions.assertThat;
import static org.openrewrite.test.SourceSpecs.text;
import static org.openrewrite.yaml.Assertions.yaml;

Expand All @@ -33,7 +31,6 @@ public void defaults(RecipeSpec spec) {
spec.recipe(new FindImage());
}


@DocumentExample
@Test
void gitlabCIFile() {
Expand Down Expand Up @@ -114,7 +111,7 @@ void dockerFile() {
ENTRYPOINT ["java","-jar","/app.jar"]
""",
"""
~~(FROM openjdk:8-jdk-alpine)~~>FROM openjdk:8-jdk-alpine
~~(openjdk:8-jdk-alpine)~~>FROM openjdk:8-jdk-alpine
ARG JAR_FILE=target/*.jar
COPY ${JAR_FILE} app.jar
ENTRYPOINT ["java","-jar","/app.jar"]
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,11 @@
import lombok.Value;
import org.jspecify.annotations.Nullable;
import org.openrewrite.Cursor;
import org.openrewrite.ExecutionContext;
import org.openrewrite.SourceFile;
import org.openrewrite.Tree;
import org.openrewrite.properties.tree.Properties;
import org.openrewrite.trait.Reference;
import org.openrewrite.trait.SimpleTraitMatcher;

import java.util.HashSet;
import java.util.Set;
import java.util.function.Predicate;
import java.util.regex.Pattern;

Expand All @@ -53,39 +49,8 @@ public boolean supportsRename() {
return true;
}

@Override
public Tree rename(Renamer renamer, Cursor cursor, ExecutionContext ctx) {
Tree tree = cursor.getValue();
if (tree instanceof Properties.Entry) {
Properties.Entry entry = (Properties.Entry) tree;
String newValueText = renamer.rename(this);
return entry.withValue(entry.getValue().withText(newValueText));
}
return tree;
}

private static class Matcher extends SimpleTraitMatcher<PropertiesReference> {
private static final Predicate<String> javaFullyQualifiedTypeMatcher = Pattern.compile(
"\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(?:\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*").asPredicate();

@Override
protected @Nullable PropertiesReference test(Cursor cursor) {
Object value = cursor.getValue();
if (value instanceof Properties.Entry &&
javaFullyQualifiedTypeMatcher.test(((Properties.Entry) value).getValue().getText())) {
return new PropertiesReference(cursor, determineKind(((Properties.Entry) value).getValue().getText()));
}
return null;
}

private Kind determineKind(String value) {
return Character.isUpperCase(value.charAt(value.lastIndexOf('.') + 1)) ? Kind.TYPE : Kind.PACKAGE;
}
}

@SuppressWarnings("unused")
public static class Provider implements Reference.Provider {

public static class Provider implements Reference.Provider<PropertiesReference> {
private static final Predicate<String> applicationPropertiesMatcher = Pattern.compile("^application(-\\w+)?\\.properties$").asPredicate();

@Override
Expand All @@ -94,13 +59,25 @@ public boolean isAcceptable(SourceFile sourceFile) {
}

@Override
public Set<Reference> getReferences(SourceFile sourceFile) {
Set<Reference> references = new HashSet<>();
new Matcher().asVisitor(reference -> {
references.add(reference);
return reference.getTree();
}).visit(sourceFile, 0);
return references;
public SimpleTraitMatcher<PropertiesReference> getMatcher() {
return new SimpleTraitMatcher<PropertiesReference>() {
private final Predicate<String> javaFullyQualifiedTypeMatcher = Pattern.compile(
"\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(?:\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*").asPredicate();

@Override
protected @Nullable PropertiesReference test(Cursor cursor) {
Object value = cursor.getValue();
if (value instanceof Properties.Entry &&
javaFullyQualifiedTypeMatcher.test(((Properties.Entry) value).getValue().getText())) {
return new PropertiesReference(cursor, determineKind(((Properties.Entry) value).getValue().getText()));
}
return null;
}

private Kind determineKind(String value) {
return Character.isUpperCase(value.charAt(value.lastIndexOf('.') + 1)) ? Kind.TYPE : Kind.PACKAGE;
}
};
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,11 @@
import org.openrewrite.xml.XPathMatcher;
import org.openrewrite.xml.tree.Xml;

import java.util.HashSet;
import java.util.Optional;
import java.util.Set;
import java.util.regex.Pattern;

@Value
class SpringReference implements Reference {
public class SpringReference implements Reference {
Cursor cursor;
Kind kind;

Expand Down Expand Up @@ -115,18 +113,7 @@ Kind determineKind(String value) {
}
}

@SuppressWarnings("unused")
public static class Provider implements Reference.Provider {

@Override
public Set<Reference> getReferences(SourceFile sourceFile) {
Set<Reference> references = new HashSet<>();
new Matcher().asVisitor(reference -> {
references.add(reference);
return reference.getTree();
}).visit(sourceFile, 0);
return references;
}
public static class Provider implements Reference.Provider<SpringReference> {

@Override
public boolean isAcceptable(SourceFile sourceFile) {
Expand All @@ -143,5 +130,10 @@ public boolean isAcceptable(SourceFile sourceFile) {
}
return false;
}

@Override
public SimpleTraitMatcher<SpringReference> getMatcher() {
return new Matcher();
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ public boolean isAcceptable(SourceFile sourceFile) {
}

@Override
SimpleTraitMatcher<YamlReference> getMatcher() {
public SimpleTraitMatcher<YamlReference> getMatcher() {
return new SimpleTraitMatcher<YamlReference>() {
private final Predicate<String> javaFullyQualifiedTypePattern = Pattern.compile(
"\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*(?:\\.\\p{javaJavaIdentifierStart}\\p{javaJavaIdentifierPart}*)*")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ public Kind getKind() {

public static class Provider extends YamlProvider {
@Override
SimpleTraitMatcher<YamlReference> getMatcher() {
public SimpleTraitMatcher<YamlReference> getMatcher() {
return new SimpleTraitMatcher<YamlReference>() {
private final Predicate<String> image = Pattern.compile("image").asPredicate();
private final AtomicBoolean found = new AtomicBoolean(false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,8 @@

import org.openrewrite.SourceFile;
import org.openrewrite.trait.Reference;
import org.openrewrite.trait.SimpleTraitMatcher;
import org.openrewrite.yaml.tree.Yaml;

import java.util.HashSet;
import java.util.Set;

public abstract class YamlReference implements Reference {
@Override
public String getValue() {
Expand All @@ -37,22 +33,10 @@ public boolean supportsRename() {
return true;
}

static abstract class YamlProvider implements Reference.Provider {
abstract SimpleTraitMatcher<YamlReference> getMatcher();

static abstract class YamlProvider implements Reference.Provider<YamlReference> {
@Override
public boolean isAcceptable(SourceFile sourceFile) {
return sourceFile instanceof Yaml.Documents;
}

@Override
public Set<Reference> getReferences(SourceFile sourceFile) {
Set<Reference> references = new HashSet<>();
getMatcher().asVisitor(reference -> {
references.add(reference);
return reference.getTree();
}).visit(sourceFile, 0);
return references;
}
}
}

0 comments on commit 8e66538

Please sign in to comment.