Skip to content

Commit 93bce58

Browse files
authored
Merge pull request #516 from jonesbusy/feature/various-cleanup-and-tests
Add is/missing common file conditional recipes and some cleanup
2 parents 7330237 + e0e45f6 commit 93bce58

27 files changed

Lines changed: 2318 additions & 1558 deletions

plugin-modernizer-cli/src/test/java/io/jenkins/tools/pluginmodernizer/cli/CommandLineITCase.java

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -339,6 +339,46 @@ public void testDryRunReplaceLibrariesWithApiPlugin(WireMockRuntimeInfo wmRuntim
339339
}
340340
}
341341

342+
@Test
343+
public void testDryRunAddDependabot(WireMockRuntimeInfo wmRuntimeInfo) throws Exception {
344+
345+
Path logFile = setupLogs("testDryRunAddDependabot");
346+
347+
final String plugin = "empty";
348+
final String recipe = "SetupDependabot";
349+
350+
// Junit attachment with logs file for the plugin build
351+
System.out.printf(
352+
"[[ATTACHMENT|%s]]%n", Plugin.build(plugin).getLogFile().toAbsolutePath());
353+
System.out.printf("[[ATTACHMENT|%s]]%n", logFile.toAbsolutePath());
354+
355+
try (GitHubServerContainer gitRemote = new GitHubServerContainer(wmRuntimeInfo, keysPath, plugin, "main")) {
356+
357+
gitRemote.start();
358+
359+
Invoker invoker = buildInvoker();
360+
InvocationRequest request = buildRequest(
361+
"dry-run --recipe %s %s".formatted(recipe, getRunArgs(wmRuntimeInfo, plugin)), logFile);
362+
InvocationResult result = invoker.execute(request);
363+
364+
// Assert output
365+
assertAll(
366+
() -> assertEquals(0, result.getExitCode()),
367+
() -> assertTrue(Files.readAllLines(logFile).stream()
368+
.anyMatch(line -> line.matches("(.*)Dry run mode. Changes were commited on (.*)"))));
369+
370+
// Check that new file was created
371+
assertTrue(
372+
Files.exists(cachePath
373+
.resolve("jenkins-plugin-modernizer-cli")
374+
.resolve(plugin)
375+
.resolve("sources")
376+
.resolve(".github")
377+
.resolve("dependabot.yml")),
378+
"Dependabot file was not created");
379+
}
380+
}
381+
342382
/**
343383
* Build the invoker
344384
* @return the invoker

plugin-modernizer-core/pom.xml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -177,8 +177,6 @@
177177
<version>4.0.1</version>
178178
<scope>test</scope>
179179
</dependency>
180-
181-
<!-- Recipes test dependencies -->
182180
<dependency>
183181
<groupId>org.kohsuke.stapler</groupId>
184182
<artifactId>stapler</artifactId>
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
package io.jenkins.tools.pluginmodernizer.core.config;
2+
3+
/**
4+
* Constants for the recipes.
5+
*/
6+
public final class RecipesConsts {
7+
8+
/**
9+
* Utility class.
10+
*/
11+
private RecipesConsts() {
12+
// Utility class
13+
}
14+
15+
public static final String PLUGINS_BOM_GROUP_ID = "io.jenkins.tools.bom";
16+
public static final String VERSION_METADATA_PATTERN = "\\.v[a-f0-9_]+";
17+
}

plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/ArchetypeCommonFile.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package io.jenkins.tools.pluginmodernizer.core.extractor;
22

3+
import java.nio.file.Path;
4+
35
/**
46
* An archetype repository file with location
57
* Used to create metadata and store information about file presence or changes
@@ -108,7 +110,7 @@ public enum ArchetypeCommonFile {
108110
*/
109111
public static ArchetypeCommonFile fromFile(String file) {
110112
for (ArchetypeCommonFile f : ArchetypeCommonFile.values()) {
111-
if (f.getPath().equals(file)) {
113+
if (Path.of(f.getPath()).equals(Path.of(file))) {
112114
return f;
113115
}
114116
}
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
package io.jenkins.tools.pluginmodernizer.core.extractor;
2+
3+
import org.openrewrite.SourceFile;
4+
import org.openrewrite.Tree;
5+
import org.openrewrite.TreeVisitor;
6+
import org.slf4j.Logger;
7+
import org.slf4j.LoggerFactory;
8+
9+
/**
10+
* A tree visitor that visit a tree and populate the metadata with common files.
11+
*/
12+
public class ArchetypeCommonFileVisitor extends TreeVisitor<Tree, PluginMetadata> {
13+
14+
/**
15+
* LOGGER.
16+
*/
17+
private static final Logger LOG = LoggerFactory.getLogger(ArchetypeCommonFileVisitor.class);
18+
19+
@Override
20+
public Tree visit(Tree tree, PluginMetadata pluginMetadata) {
21+
22+
SourceFile sourceFile = (SourceFile) tree;
23+
24+
ArchetypeCommonFile commonFile =
25+
ArchetypeCommonFile.fromFile(sourceFile.getSourcePath().toString());
26+
27+
// Store common files into metadata
28+
if (commonFile != null) {
29+
if (pluginMetadata.hasCommonFile(commonFile)) {
30+
LOG.debug("File {} is already a common file", sourceFile.getSourcePath());
31+
} else {
32+
LOG.debug("File {} is a common file", sourceFile.getSourcePath());
33+
pluginMetadata.addCommonFile(commonFile);
34+
}
35+
} else {
36+
LOG.debug("File {} is not a common file", sourceFile.getSourcePath());
37+
}
38+
return tree;
39+
}
40+
}

plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/MetadataFinalizerVisitor.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,23 @@ public class MetadataFinalizerVisitor extends TreeVisitor<Tree, ExecutionContext
2020
@Override
2121
public Tree visit(Tree tree, ExecutionContext ctx) {
2222

23+
PluginMetadata mergedMetadata = ctx.getMessage("mergedMetadata", new PluginMetadata());
24+
PluginMetadata commonMetadata = ctx.getMessage("commonMetadata", new PluginMetadata());
2325
PluginMetadata pluginMetadata = ctx.getMessage("pomMetadata", new PluginMetadata());
2426
PluginMetadata jenkinsFileMetadata = ctx.getMessage("jenkinsFileMetadata", new PluginMetadata());
2527

28+
// Merge the metadata
2629
PluginMetadata merged = JsonUtils.fromJson(
2730
JsonUtils.merge(pluginMetadata.toJson(), jenkinsFileMetadata.toJson()), PluginMetadata.class);
28-
;
31+
merged = JsonUtils.fromJson(JsonUtils.merge(commonMetadata.toJson(), merged.toJson()), PluginMetadata.class);
32+
merged = JsonUtils.fromJson(JsonUtils.merge(mergedMetadata.toJson(), merged.toJson()), PluginMetadata.class);
33+
2934
LOG.debug("Merged metadata: {}", JsonUtils.toJson(merged));
3035

3136
// Write the metadata to a file for later use by the plugin modernizer.
3237
merged.save();
3338
LOG.debug("Plugin metadata written to {}", merged.getRelativePath());
39+
ctx.putMessage("mergedMetadata", merged);
3440
LOG.debug(JsonUtils.toJson(merged));
3541

3642
return tree;
Lines changed: 13 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
package io.jenkins.tools.pluginmodernizer.core.extractor;
22

33
import io.jenkins.tools.pluginmodernizer.core.utils.JsonUtils;
4-
import org.jspecify.annotations.NonNull;
5-
import org.jspecify.annotations.Nullable;
64
import org.openrewrite.ExecutionContext;
75
import org.openrewrite.PathUtils;
86
import org.openrewrite.SourceFile;
@@ -23,40 +21,26 @@ public class MetadataVisitor extends TreeVisitor<Tree, ExecutionContext> {
2321

2422
final PluginMetadata pluginMetadata;
2523

24+
/**
25+
* Constructor.
26+
* @param pluginMetadata the plugin metadata
27+
*/
2628
public MetadataVisitor(PluginMetadata pluginMetadata) {
2729
this.pluginMetadata = pluginMetadata;
2830
}
2931

30-
@Override
31-
public @Nullable Tree postVisit(@NonNull Tree tree, ExecutionContext executionContext) {
32-
LOG.debug("Finalizing metadata");
33-
return super.postVisit(tree, executionContext);
34-
}
35-
3632
@Override
3733
public Tree visit(Tree tree, ExecutionContext executionContext) {
3834

3935
SourceFile sourceFile = (SourceFile) tree;
4036

41-
ArchetypeCommonFile commonFile =
42-
ArchetypeCommonFile.fromFile(sourceFile.getSourcePath().toString());
43-
44-
// Store common files into metadata
45-
if (commonFile != null) {
46-
if (pluginMetadata.hasCommonFile(commonFile)) {
47-
LOG.debug("File {} is already a common file", sourceFile.getSourcePath());
48-
} else {
49-
LOG.debug("File {} is a common file", sourceFile.getSourcePath());
50-
pluginMetadata.addCommonFile(commonFile);
51-
}
52-
} else {
53-
LOG.debug("File {} is not a common file", sourceFile.getSourcePath());
54-
}
37+
// Common metadata
38+
PluginMetadata commonMetadata = new ArchetypeCommonFileVisitor().reduce(tree, pluginMetadata);
5539

5640
// Extract metadata from Jenkinsfile
5741
if (PathUtils.matchesGlob(sourceFile.getSourcePath(), "**/Jenkinsfile")) {
5842
LOG.debug("Visiting Jenkinsfile {}", sourceFile.getSourcePath());
59-
PluginMetadata jenkinsFileMetadata = new JenkinsfileVisitor().reduce(tree, pluginMetadata);
43+
PluginMetadata jenkinsFileMetadata = new JenkinsfileVisitor().reduce(tree, commonMetadata);
6044
LOG.debug("Jenkinsfile metadata: {}", JsonUtils.toJson(jenkinsFileMetadata));
6145
executionContext.putMessage(
6246
"jenkinsFileMetadata", jenkinsFileMetadata); // Is there better than context messaging ?
@@ -66,12 +50,17 @@ public Tree visit(Tree tree, ExecutionContext executionContext) {
6650
// Extract metadata from POM
6751
else if (PathUtils.matchesGlob(sourceFile.getSourcePath(), "**/pom.xml")) {
6852
LOG.debug("Visiting POM {}", sourceFile.getSourcePath());
69-
PluginMetadata pomMetadata = new PomResolutionVisitor().reduce(tree, pluginMetadata);
53+
PluginMetadata pomMetadata = new PomResolutionVisitor().reduce(tree, commonMetadata);
7054
LOG.debug("POM metadata: {}", JsonUtils.toJson(pomMetadata));
7155
executionContext.putMessage("pomMetadata", pomMetadata); // Is there better than context messaging ?
7256
return tree;
7357
}
7458

59+
// Just add the common
60+
else {
61+
executionContext.putMessage("commonMetadata", commonMetadata); // Is there better than context messaging ?
62+
}
63+
7564
return tree;
7665
}
7766
}

plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/extractor/PomResolutionVisitor.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.jenkins.tools.pluginmodernizer.core.extractor;
22

3+
import io.jenkins.tools.pluginmodernizer.core.config.RecipesConsts;
34
import java.util.Map;
45
import java.util.Optional;
56
import org.openrewrite.marker.Markers;
@@ -60,7 +61,7 @@ public Xml.Document visitDocument(Xml.Document document, PluginMetadata pluginMe
6061
// Lookup by group ID to set the BOM version if any
6162
pom.getDependencyManagement().stream()
6263
.peek(dependency -> LOG.debug("Dependency: {}", dependency))
63-
.filter(dependency -> "io.jenkins.tools.bom".equals(dependency.getGroupId()))
64+
.filter(dependency -> RecipesConsts.PLUGINS_BOM_GROUP_ID.equals(dependency.getGroupId()))
6465
.findFirst()
6566
.ifPresent(dependency -> {
6667
pluginMetadata.setBomArtifactId(dependency.getArtifactId());

plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/impl/PluginModernizer.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -50,10 +50,12 @@ public void validate() {
5050
* List available recipes
5151
*/
5252
public void listRecipes() {
53-
Settings.AVAILABLE_RECIPES.forEach(recipe -> LOG.info(
54-
"{} - {}",
55-
recipe.getName().replaceAll(Settings.RECIPE_FQDN_PREFIX + ".", ""),
56-
recipe.getDescription()));
53+
Settings.AVAILABLE_RECIPES.stream()
54+
.sorted()
55+
.forEach(recipe -> LOG.info(
56+
"{} - {}",
57+
recipe.getName().replaceAll(Settings.RECIPE_FQDN_PREFIX + ".", ""),
58+
recipe.getDescription()));
5759
}
5860

5961
/**

plugin-modernizer-core/src/main/java/io/jenkins/tools/pluginmodernizer/core/model/Recipe.java

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,32 @@
11
package io.jenkins.tools.pluginmodernizer.core.model;
22

33
import com.fasterxml.jackson.annotation.JsonIgnore;
4+
import java.util.Objects;
45
import java.util.Set;
56

6-
public class Recipe {
7+
/**
8+
* Our own representation of a recipe.
9+
*/
10+
public class Recipe implements Comparable<Recipe> {
711

12+
/**
13+
* Name of the recipe.
14+
*/
815
private String name;
16+
17+
/**
18+
* Display name of the recipe.
19+
*/
920
private String displayName;
21+
22+
/**
23+
* Description of the recipe.
24+
*/
1025
private String description;
26+
27+
/**
28+
* Tags of the recipe.
29+
*/
1130
private Set<String> tags;
1231

1332
@JsonIgnore
@@ -85,4 +104,21 @@ public Boolean getCausesAnotherCycle() {
85104
public void setCausesAnotherCycle(Boolean causesAnotherCycle) {
86105
this.causesAnotherCycle = causesAnotherCycle;
87106
}
107+
108+
@Override
109+
public boolean equals(Object o) {
110+
if (o == null || getClass() != o.getClass()) return false;
111+
Recipe recipe = (Recipe) o;
112+
return Objects.equals(getName(), recipe.getName());
113+
}
114+
115+
@Override
116+
public int hashCode() {
117+
return Objects.hashCode(getName());
118+
}
119+
120+
@Override
121+
public int compareTo(Recipe o) {
122+
return this.getName().compareTo(o.getName());
123+
}
88124
}

0 commit comments

Comments
 (0)