From 0ae63d59354cfca3a32b4006be3ca4dcabeb9870 Mon Sep 17 00:00:00 2001 From: vsevel Date: Wed, 3 Jul 2024 14:21:52 +0200 Subject: [PATCH] Support multiple recipe artifacts in quarkus update --- .../io/quarkus/cli/build/GradleRunner.java | 3 + .../io/quarkus/cli/build/MavenRunner.java | 3 + .../io/quarkus/cli/update/RewriteGroup.java | 4 + .../quarkus/gradle/tasks/QuarkusUpdate.java | 16 +++ .../java/io/quarkus/maven/UpdateMojo.java | 9 ++ .../devtools/commands/UpdateProject.java | 6 + .../handlers/UpdateProjectCommandHandler.java | 6 +- .../update/rewrite/QuarkusUpdateCommand.java | 4 +- .../update/rewrite/QuarkusUpdates.java | 3 +- .../rewrite/QuarkusUpdatesRepository.java | 103 +++++++++++------- 10 files changed, 116 insertions(+), 41 deletions(-) diff --git a/devtools/cli/src/main/java/io/quarkus/cli/build/GradleRunner.java b/devtools/cli/src/main/java/io/quarkus/cli/build/GradleRunner.java index afe7c34c796ab..ee4d6eb6253ea 100644 --- a/devtools/cli/src/main/java/io/quarkus/cli/build/GradleRunner.java +++ b/devtools/cli/src/main/java/io/quarkus/cli/build/GradleRunner.java @@ -173,6 +173,9 @@ public Integer updateProject(TargetQuarkusVersionGroup targetQuarkusVersion, Rew if (rewrite.updateRecipesVersion != null) { args.add("--updateRecipesVersion=" + rewrite.updateRecipesVersion); } + if (rewrite.additionalUpdateRecipeCoords != null) { + args.add("--additionalUpdateRecipeCoords=" + rewrite.additionalUpdateRecipeCoords); + } if (rewrite.noRewrite) { args.add("--noRewrite"); } diff --git a/devtools/cli/src/main/java/io/quarkus/cli/build/MavenRunner.java b/devtools/cli/src/main/java/io/quarkus/cli/build/MavenRunner.java index 632c68c8135ff..b495e8b78f7a4 100644 --- a/devtools/cli/src/main/java/io/quarkus/cli/build/MavenRunner.java +++ b/devtools/cli/src/main/java/io/quarkus/cli/build/MavenRunner.java @@ -176,6 +176,9 @@ public Integer updateProject(TargetQuarkusVersionGroup targetQuarkusVersion, Rew if (rewrite.updateRecipesVersion != null) { args.add("-DupdateRecipesVersion=" + rewrite.updateRecipesVersion); } + if (rewrite.additionalUpdateRecipeCoords != null) { + args.add("-DadditionalUpdateRecipeCoords" + rewrite.additionalUpdateRecipeCoords); + } if (rewrite.dryRun) { args.add("-DrewriteDryRun"); } diff --git a/devtools/cli/src/main/java/io/quarkus/cli/update/RewriteGroup.java b/devtools/cli/src/main/java/io/quarkus/cli/update/RewriteGroup.java index 48bd2a3a94c10..2683d87365fb0 100644 --- a/devtools/cli/src/main/java/io/quarkus/cli/update/RewriteGroup.java +++ b/devtools/cli/src/main/java/io/quarkus/cli/update/RewriteGroup.java @@ -20,4 +20,8 @@ public class RewriteGroup { "--rewrite-plugin-version" }, description = "Use a custom OpenRewrite plugin version.") public String pluginVersion; + @CommandLine.Option(order = 4, names = { + "--additional-update-recipe-coords" }, description = "Specify an additional list of artifacts to retrieve recipes from.") + public String additionalUpdateRecipeCoords; + } diff --git a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusUpdate.java b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusUpdate.java index 6e33b913d8d3d..8e02a5626055c 100644 --- a/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusUpdate.java +++ b/devtools/gradle/gradle-application-plugin/src/main/java/io/quarkus/gradle/tasks/QuarkusUpdate.java @@ -29,6 +29,7 @@ public abstract class QuarkusUpdate extends QuarkusPlatformTask { private String rewritePluginVersion = null; private String rewriteUpdateRecipesVersion = null; + private String rewriteAdditionalUpdateRecipeCoords = null; @Input @Optional @@ -87,6 +88,18 @@ public QuarkusUpdate setRewriteUpdateRecipesVersion(String rewriteUpdateRecipesV return this; } + @Input + @Optional + public String getRewriteAdditionalUpdateRecipeCoords() { + return rewriteAdditionalUpdateRecipeCoords; + } + + @Option(description = " The additional artifacts to retrieve recipes from.", option = "additionalUpdateRecipeCoords") + public QuarkusUpdate setRewriteAdditionalUpdateRecipeCoords(String rewriteAdditionalUpdateRecipeCoords) { + this.rewriteAdditionalUpdateRecipeCoords = rewriteAdditionalUpdateRecipeCoords; + return this; + } + @Input @Optional public String getTargetStreamId() { @@ -143,6 +156,9 @@ public void logUpdates() { if (rewriteUpdateRecipesVersion != null) { invoker.rewriteUpdateRecipesVersion(rewriteUpdateRecipesVersion); } + if (rewriteAdditionalUpdateRecipeCoords != null) { + invoker.rewriteAdditionalUpdateRecipeCoords(rewriteAdditionalUpdateRecipeCoords); + } if (rewritePluginVersion != null) { invoker.rewritePluginVersion(rewritePluginVersion); } diff --git a/devtools/maven/src/main/java/io/quarkus/maven/UpdateMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/UpdateMojo.java index a605646dc177f..54525279dc298 100644 --- a/devtools/maven/src/main/java/io/quarkus/maven/UpdateMojo.java +++ b/devtools/maven/src/main/java/io/quarkus/maven/UpdateMojo.java @@ -65,6 +65,12 @@ public class UpdateMojo extends QuarkusProjectStateMojoBase { @Parameter(property = "updateRecipesVersion", required = false) private String rewriteUpdateRecipesVersion; + /** + * The list of artifacts containing rewrite recipes + */ + @Parameter(property = "additionalUpdateRecipeCoords", required = false) + private String rewriteAdditionalUpdateRecipeCoords; + /** * Target stream (e.g: 2.0) */ @@ -116,6 +122,9 @@ protected void processProjectState(QuarkusProject quarkusProject) throws MojoExe if (rewriteUpdateRecipesVersion != null) { invoker.rewriteUpdateRecipesVersion(rewriteUpdateRecipesVersion); } + if (rewriteAdditionalUpdateRecipeCoords != null) { + invoker.rewriteAdditionalUpdateRecipeCoords(rewriteAdditionalUpdateRecipeCoords); + } invoker.rewriteDryRun(rewriteDryRun); invoker.noRewrite(noRewrite); diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/UpdateProject.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/UpdateProject.java index 92409437a023d..edde73e81b92e 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/UpdateProject.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/UpdateProject.java @@ -25,6 +25,7 @@ public class UpdateProject { public static final String TARGET_PLATFORM_VERSION = "quarkus.update-project.target-platform-version"; public static final String REWRITE_PLUGIN_VERSION = "quarkus.update-project.rewrite.plugin-version"; public static final String REWRITE_UPDATE_RECIPES_VERSION = "quarkus.update-project.rewrite.update-recipes-version"; + public static final String REWRITE_ADDITIONAL_UPDATE_RECIPE_COORDS = "quarkus.update-project.rewrite.additional-update-recipe-coords"; public static final String REWRITE_DRY_RUN = "quarkus.update-project.rewrite.dry-run"; private final QuarkusCommandInvocation invocation; @@ -64,6 +65,11 @@ public UpdateProject rewriteUpdateRecipesVersion(String rewriteUpdateRecipesVers return this; } + public UpdateProject rewriteAdditionalUpdateRecipeCoords(String rewriteAdditionalUpdateRecipeCoords) { + invocation.setValue(REWRITE_ADDITIONAL_UPDATE_RECIPE_COORDS, rewriteAdditionalUpdateRecipeCoords); + return this; + } + public UpdateProject rewriteDryRun(boolean rewriteDryRun) { invocation.setValue(REWRITE_DRY_RUN, rewriteDryRun); return this; diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/UpdateProjectCommandHandler.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/UpdateProjectCommandHandler.java index 9dab75d417447..f8655b01a03a1 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/UpdateProjectCommandHandler.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/UpdateProjectCommandHandler.java @@ -117,9 +117,13 @@ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws final String updateRecipesVersion = invocation.getValue( UpdateProject.REWRITE_UPDATE_RECIPES_VERSION, QuarkusUpdatesRepository.DEFAULT_UPDATE_RECIPES_VERSION); + final String additionalUpdateRecipeCoords = invocation.getValue( + UpdateProject.REWRITE_ADDITIONAL_UPDATE_RECIPE_COORDS, + null); final FetchResult fetchResult = QuarkusUpdates.createRecipe(invocation.log(), recipe, - QuarkusProjectHelper.artifactResolver(), buildTool, updateRecipesVersion, request); + QuarkusProjectHelper.artifactResolver(), buildTool, updateRecipesVersion, + additionalUpdateRecipeCoords, request); invocation.log().info("OpenRewrite recipe generated: %s", recipe); String rewritePluginVersion = invocation.getValue(UpdateProject.REWRITE_PLUGIN_VERSION, diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java index debbf1f24e58d..674bffe72d8cb 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdateCommand.java @@ -65,7 +65,9 @@ private static void runMavenUpdate(MessageWriter log, Path baseDir, String rewri executeCommand(baseDir, getMavenUpdateCommand(mvnBinary, rewritePluginVersion, recipesGAV, recipe, dryRun), log); // format the sources - executeCommand(baseDir, getMavenProcessSourcesCommand(mvnBinary), log); + if (!dryRun) { + executeCommand(baseDir, getMavenProcessSourcesCommand(mvnBinary), log); + } } private static void runGradleUpdate(MessageWriter log, Path baseDir, String rewritePluginVersion, String recipesGAV, diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdates.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdates.java index 9989ca2a42a5f..ff152288495e0 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdates.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdates.java @@ -22,11 +22,12 @@ private QuarkusUpdates() { } public static FetchResult createRecipe(MessageWriter log, Path target, MavenArtifactResolver artifactResolver, - BuildTool buildTool, String updateRecipesVersion, + BuildTool buildTool, String updateRecipesVersion, String additionalUpdateRecipeCoords, ProjectUpdateRequest request) throws IOException { final FetchResult result = QuarkusUpdatesRepository.fetchRecipes(log, artifactResolver, buildTool, updateRecipesVersion, + additionalUpdateRecipeCoords, request.currentVersion, request.targetVersion, request.projectExtensionsUpdateInfo diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdatesRepository.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdatesRepository.java index 57198af695eee..ef00b8eb905b8 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdatesRepository.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/project/update/rewrite/QuarkusUpdatesRepository.java @@ -5,6 +5,8 @@ import java.nio.file.Files; import java.nio.file.Path; import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; @@ -41,50 +43,75 @@ private QuarkusUpdatesRepository() { public static FetchResult fetchRecipes(MessageWriter log, MavenArtifactResolver artifactResolver, BuildTool buildTool, - String recipeVersion, String currentVersion, + String recipeVersion, String additionalUpdateRecipeCoords, String currentVersion, String targetVersion, List topExtensionDependency) { - final String gav = QUARKUS_RECIPE_GA + ":" + recipeVersion; - - Map recipeDirectoryNames = new LinkedHashMap<>(); - recipeDirectoryNames.put("core", new String[] { currentVersion, targetVersion }); - for (ExtensionUpdateInfo dep : topExtensionDependency) { - recipeDirectoryNames.put( - toKey(dep), - new String[] { dep.getCurrentDep().getVersion(), dep.getRecommendedDependency().getVersion() }); + + List gavs = new ArrayList<>(); + gavs.add(QUARKUS_RECIPE_GA + ":" + recipeVersion); + if (additionalUpdateRecipeCoords != null) { + gavs.addAll(Arrays.stream(additionalUpdateRecipeCoords.split(",")).map(String::strip).toList()); } - try { - final Artifact artifact = artifactResolver.resolve(DependencyUtils.toArtifact(gav)).getArtifact(); - final ResourceLoader resourceLoader = ResourceLoaders.resolveFileResourceLoader( - artifact.getFile()); - final Map recipes = fetchUpdateRecipes(resourceLoader, "quarkus-updates", recipeDirectoryNames); - final Properties props = resourceLoader.loadResourceAsPath("quarkus-updates/", p -> { - final Properties properties = new Properties(); - final Path propPath = p.resolve("recipes.properties"); - if (Files.isRegularFile(propPath)) { - try (final InputStream inStream = Files.newInputStream(propPath)) { - properties.load(inStream); + List artifacts = new ArrayList<>(); + Map recipes = new HashMap<>(); + String propRewritePluginVersion = null; + + for (String gav : gavs) { + + Map recipeDirectoryNames = new LinkedHashMap<>(); + recipeDirectoryNames.put("core", new String[] { currentVersion, targetVersion }); + for (ExtensionUpdateInfo dep : topExtensionDependency) { + recipeDirectoryNames.put( + toKey(dep), + new String[] { dep.getCurrentDep().getVersion(), dep.getRecommendedDependency().getVersion() }); + } + + try { + final Artifact artifact = artifactResolver.resolve(DependencyUtils.toArtifact(gav)).getArtifact(); + String resolvedGAV = artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion(); + artifacts.add(resolvedGAV); + final ResourceLoader resourceLoader = ResourceLoaders.resolveFileResourceLoader( + artifact.getFile()); + Map newRecipes = fetchUpdateRecipes(resourceLoader, "quarkus-updates", recipeDirectoryNames); + recipes.putAll(newRecipes); + final Properties props = resourceLoader.loadResourceAsPath("quarkus-updates/", p -> { + final Properties properties = new Properties(); + final Path propPath = p.resolve("recipes.properties"); + if (Files.isRegularFile(propPath)) { + try (final InputStream inStream = Files.newInputStream(propPath)) { + properties.load(inStream); + } } + return properties; + }); + + final String pluginVersion = getPropRewritePluginVersion(props, buildTool); + if (propRewritePluginVersion == null) { + propRewritePluginVersion = pluginVersion; + } else if (!propRewritePluginVersion.equals(pluginVersion)) { + throw new RuntimeException( + "quarkus update artifacts require multiple rewrite plugin versions: " + propRewritePluginVersion + + " and " + pluginVersion); } - return properties; - }); - final String propRewritePluginVersion = getPropRewritePluginVersion(props, buildTool); - - log.info(String.format( - "Resolved io.quarkus:quarkus-updates-recipes:%s with %s recipe(s) to update from %s to %s (initially made for OpenRewrite %s plugin version: %s) ", - artifact.getVersion(), - recipes.size(), - currentVersion, - targetVersion, - buildTool, - propRewritePluginVersion)); - return new FetchResult(artifact.getGroupId() + ":" + artifact.getArtifactId() + ":" + artifact.getVersion(), - new ArrayList<>(recipes.values()), propRewritePluginVersion); - } catch (BootstrapMavenException e) { - throw new RuntimeException("Failed to resolve artifact: " + gav, e); - } catch (IOException e) { - throw new RuntimeException("Failed to load recipes in artifact: " + gav, e); + + log.info(String.format( + "Resolved %s with %s recipe(s) to update from %s to %s (initially made for OpenRewrite %s plugin version: %s) ", + gav, + recipes.size(), + currentVersion, + targetVersion, + buildTool, + propRewritePluginVersion)); + + } catch (BootstrapMavenException e) { + throw new RuntimeException("Failed to resolve artifact: " + gav, e); + } catch (IOException e) { + throw new RuntimeException("Failed to load recipes in artifact: " + gav, e); + } } + + return new FetchResult(String.join(",", artifacts), + new ArrayList<>(recipes.values()), propRewritePluginVersion); } private static String getPropRewritePluginVersion(Properties props, BuildTool buildTool) {