diff --git a/plugin-modernizer-core/pom.xml b/plugin-modernizer-core/pom.xml
index e14e03b3..74d4ac17 100644
--- a/plugin-modernizer-core/pom.xml
+++ b/plugin-modernizer-core/pom.xml
@@ -260,6 +260,17 @@
javax.servlet-api
4.0.1
+
+
+ org.testcontainers
+ testcontainers
+ 1.20.4
+
+
+ org.jenkins-ci.test
+ docker-fixtures
+ 200.v22a_e8766731c
+
org.jenkins-ci.plugins
diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/JavaFileVisitor.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/JavaFileVisitor.java
new file mode 100644
index 00000000..24692c27
--- /dev/null
+++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/JavaFileVisitor.java
@@ -0,0 +1,32 @@
+package io.jenkins.tools.pluginmodernizer.core.extractor;
+
+import org.openrewrite.java.JavaIsoVisitor;
+import org.openrewrite.java.tree.J;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * A visitor to extract metadata from Java files.
+ */
+public class JavaFileVisitor extends JavaIsoVisitor {
+
+ /**
+ * LOGGER.
+ */
+ private static final Logger LOG = LoggerFactory.getLogger(JavaFileVisitor.class);
+
+ @Override
+ public J.Import visitImport(J.Import _import, PluginMetadata pluginMetadata) {
+ _import = super.visitImport(_import, pluginMetadata);
+ // Rather a naive approach, but let's assume we can detect testcontainers usage by the package name
+ if (_import.getPackageName().startsWith("org.testcontainers.containers")) {
+ LOG.info("Found testcontainers import: {}. Plugin is using container tests", _import.getPackageName());
+ pluginMetadata.setUseContainerTests(true);
+ }
+ if (_import.getPackageName().startsWith("org.jenkinsci.test.acceptance.docker")) {
+ LOG.info("Found docker-fixtures import: {}. Plugin is using container tests", _import.getPackageName());
+ pluginMetadata.setUseContainerTests(true);
+ }
+ return _import;
+ }
+}
diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataFinalizerVisitor.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataFinalizerVisitor.java
index 7193d95d..903d4bf4 100644
--- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataFinalizerVisitor.java
+++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataFinalizerVisitor.java
@@ -1,6 +1,9 @@
package io.jenkins.tools.pluginmodernizer.core.extractor;
-import io.jenkins.tools.pluginmodernizer.core.utils.JsonUtils;
+import static io.jenkins.tools.pluginmodernizer.core.utils.JsonUtils.fromJson;
+import static io.jenkins.tools.pluginmodernizer.core.utils.JsonUtils.merge;
+import static io.jenkins.tools.pluginmodernizer.core.utils.JsonUtils.toJson;
+
import org.openrewrite.ExecutionContext;
import org.openrewrite.Tree;
import org.openrewrite.TreeVisitor;
@@ -22,22 +25,24 @@ public Tree visit(Tree tree, ExecutionContext ctx) {
PluginMetadata mergedMetadata = ctx.getMessage("mergedMetadata", new PluginMetadata());
PluginMetadata commonMetadata = ctx.getMessage("commonMetadata", new PluginMetadata());
- PluginMetadata pluginMetadata = ctx.getMessage("pomMetadata", new PluginMetadata());
+ PluginMetadata pomMetadata = ctx.getMessage("pomMetadata", new PluginMetadata());
+ PluginMetadata javaMetadata = ctx.getMessage("javaMetadata", new PluginMetadata());
PluginMetadata jenkinsFileMetadata = ctx.getMessage("jenkinsFileMetadata", new PluginMetadata());
// Merge the metadata
- PluginMetadata merged = JsonUtils.fromJson(
- JsonUtils.merge(pluginMetadata.toJson(), jenkinsFileMetadata.toJson()), PluginMetadata.class);
- merged = JsonUtils.fromJson(JsonUtils.merge(commonMetadata.toJson(), merged.toJson()), PluginMetadata.class);
- merged = JsonUtils.fromJson(JsonUtils.merge(mergedMetadata.toJson(), merged.toJson()), PluginMetadata.class);
+ PluginMetadata merged =
+ fromJson(merge(pomMetadata.toJson(), jenkinsFileMetadata.toJson()), PluginMetadata.class);
+ merged = fromJson(merge(commonMetadata.toJson(), merged.toJson()), PluginMetadata.class);
+ merged = fromJson(merge(javaMetadata.toJson(), merged.toJson()), PluginMetadata.class);
+ merged = fromJson(merge(mergedMetadata.toJson(), merged.toJson()), PluginMetadata.class);
- LOG.debug("Merged metadata: {}", JsonUtils.toJson(merged));
+ LOG.debug("Merged metadata: {}", toJson(merged));
// Write the metadata to a file for later use by the plugin modernizer.
merged.save();
LOG.debug("Plugin metadata written to {}", merged.getRelativePath());
ctx.putMessage("mergedMetadata", merged);
- LOG.debug(JsonUtils.toJson(merged));
+ LOG.debug(toJson(merged));
return tree;
}
diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataVisitor.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataVisitor.java
index 87bc1730..d43c4ef1 100644
--- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataVisitor.java
+++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataVisitor.java
@@ -55,6 +55,14 @@ else if (PathUtils.matchesGlob(sourceFile.getSourcePath(), "**/pom.xml")) {
executionContext.putMessage("pomMetadata", pomMetadata); // Is there better than context messaging ?
return tree;
}
+ // Extract metadata from java file
+ else if (PathUtils.matchesGlob(sourceFile.getSourcePath(), "**/*.java")) {
+ LOG.debug("Visiting Java file {}", sourceFile.getSourcePath());
+ PluginMetadata javaMetadata = new JavaFileVisitor().reduce(tree, commonMetadata);
+ LOG.debug("Java metadata: {}", JsonUtils.toJson(javaMetadata));
+ executionContext.putMessage("javaMetadata", javaMetadata); // Is there better than context messaging ?
+ return tree;
+ }
// Just add the common
else {
diff --git a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PluginMetadata.java b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PluginMetadata.java
index 275f0b11..8dafda28 100644
--- a/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PluginMetadata.java
+++ b/plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PluginMetadata.java
@@ -16,6 +16,7 @@
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
+import java.util.Objects;
import java.util.Set;
/**
@@ -53,6 +54,11 @@ public class PluginMetadata extends CacheEntry {
*/
private Boolean useContainerAgent;
+ /**
+ * If the plugin is using container tests
+ */
+ private Boolean useContainerTests;
+
/**
* forkCount extracted from Jenkinsfile
*/
@@ -240,6 +246,14 @@ public void setUseContainerAgent(Boolean useContainerAgent) {
this.useContainerAgent = useContainerAgent;
}
+ public Boolean isUseContainerTests() {
+ return Objects.requireNonNullElse(useContainerTests, false);
+ }
+
+ public void setUseContainerTests(Boolean useContainerTests) {
+ this.useContainerTests = useContainerTests;
+ }
+
public String getForkCount() {
return forkCount;
}
diff --git a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/extractor/FetchMetadataTest.java b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/extractor/FetchMetadataTest.java
index 22a45161..e7b4a167 100644
--- a/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/extractor/FetchMetadataTest.java
+++ b/plugin-modernizer-core/src/test/java/io/jenkins/tools/pluginmodernizer/core/extractor/FetchMetadataTest.java
@@ -9,6 +9,7 @@
import io.jenkins.tools.pluginmodernizer.core.model.JDK;
import io.jenkins.tools.pluginmodernizer.core.model.Platform;
+import io.jenkins.tools.pluginmodernizer.core.recipes.DeclarativeRecipesTest;
import io.jenkins.tools.pluginmodernizer.core.recipes.FetchMetadata;
import java.util.LinkedHashMap;
import java.util.LinkedHashSet;
@@ -19,6 +20,7 @@
import org.intellij.lang.annotations.Language;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
+import org.openrewrite.java.JavaParser;
import org.openrewrite.test.RewriteTest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -40,6 +42,7 @@ public class FetchMetadataTest implements RewriteTest {
EXPECTED_METADATA.setBomArtifactId("bom-2.414.x");
EXPECTED_METADATA.setBomVersion("2950.va_633b_f42f759");
EXPECTED_METADATA.setUseContainerAgent(null);
+ EXPECTED_METADATA.setUseContainerTests(null);
EXPECTED_METADATA.setForkCount(null);
Map properties = new LinkedHashMap<>();
properties.put("revision", "1.8.1");
@@ -295,9 +298,15 @@ class FooBar {}
}
@Test
- void testWithManyCommonFiles() throws Exception {
+ void testWithManyCommonFilesAndTestContainers() throws Exception {
rewriteRun(
- recipeSpec -> recipeSpec.recipe(new FetchMetadata()),
+ spec -> {
+ var parser = JavaParser.fromJavaVersion().logCompilationWarningsAndErrors(true);
+ DeclarativeRecipesTest.collectRewriteTestDependencies().stream()
+ .filter(entry -> entry.getFileName().toString().contains("testcontainers"))
+ .forEach(parser::addClasspathEntry);
+ spec.recipe(new FetchMetadata()).parser(parser);
+ },
pomXml(POM_XML),
// language=groovy
groovy(
@@ -314,6 +323,7 @@ void testWithManyCommonFiles() throws Exception {
java(
"""
package com.uppercase.camelcase;
+ import org.testcontainers.containers.GenericContainer;
class FooBar {}
"""),
// language=yaml
@@ -356,7 +366,8 @@ class FooBar {}
// Check rest
Set jdkVersion = pluginMetadata.getJdks();
assertEquals(2, jdkVersion.size());
- assertTrue(pluginMetadata.isUseContainerAgent());
+ assertTrue(pluginMetadata.isUseContainerAgent(), "Should use container agent");
+ assertTrue(pluginMetadata.isUseContainerTests(), "Should use container tests");
assertEquals(EXPECTED_METADATA.getParentVersion(), pluginMetadata.getParentVersion());
assertEquals(EXPECTED_METADATA.getPluginName(), pluginMetadata.getPluginName());
assertEquals(EXPECTED_METADATA.getJenkinsVersion(), pluginMetadata.getJenkinsVersion());
@@ -365,6 +376,31 @@ class FooBar {}
assertEquals(EXPECTED_METADATA.getFlags(), pluginMetadata.getFlags());
}
+ @Test
+ void testWithDockerFixtures() throws Exception {
+ rewriteRun(
+ spec -> {
+ var parser = JavaParser.fromJavaVersion().logCompilationWarningsAndErrors(true);
+ DeclarativeRecipesTest.collectRewriteTestDependencies().stream()
+ .filter(entry -> entry.getFileName().toString().contains("docker-fixtures"))
+ .forEach(parser::addClasspathEntry);
+ spec.recipe(new FetchMetadata()).parser(parser);
+ },
+ // language=java
+ java(
+ """
+ package com.uppercase.camelcase;
+ import org.jenkinsci.test.acceptance.docker.DockerClassRule;
+ class FooBar {}
+ """));
+
+ PluginMetadata pluginMetadata = new PluginMetadata().refresh();
+ assertNotNull(pluginMetadata, "Plugin metadata was not written by the recipe");
+
+ // Check use container test
+ assertTrue(pluginMetadata.isUseContainerTests(), "Should use container tests");
+ }
+
@Test
void testWithJenkinsfileOnly() throws Exception {
rewriteRun(
@@ -398,6 +434,8 @@ void testWithJenkinsfileOnly() throws Exception {
assertEquals(2, platforms.size());
assertTrue(platforms.contains(Platform.WINDOWS));
assertTrue(platforms.contains(Platform.LINUX));
+
+ assertFalse(pluginMetadata.isUseContainerTests());
}
@Test