Skip to content

Commit

Permalink
Add logic to load yaml recipes based on the extension.
Browse files Browse the repository at this point in the history
  • Loading branch information
svkcemk authored and ia3andy committed Sep 14, 2023
1 parent 8639153 commit ed0e00e
Show file tree
Hide file tree
Showing 7 changed files with 4,256 additions and 31 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
import io.quarkus.devtools.project.update.rewrite.QuarkusUpdateCommand;
import io.quarkus.devtools.project.update.rewrite.QuarkusUpdates;
import io.quarkus.devtools.project.update.rewrite.QuarkusUpdatesRepository;
import io.quarkus.devtools.project.update.rewrite.QuarkusUpdatesRepository.FetchResult;
import io.quarkus.maven.dependency.ArtifactCoords;
import io.quarkus.platform.tools.ToolsConstants;
import io.quarkus.registry.catalog.ExtensionCatalog;
Expand Down Expand Up @@ -62,14 +63,16 @@ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws
invocation.log().info("Instructions to update this project from '%s' to '%s':",
projectQuarkusPlatformBom.getVersion(), targetPlatformVersion);
final QuarkusProject quarkusProject = invocation.getQuarkusProject();
final ProjectState recommendedState = resolveRecommendedState(currentState, targetCatalog, invocation.log());
final ProjectState recommendedState = resolveRecommendedState(currentState, targetCatalog,
invocation.log());
final ProjectPlatformUpdateInfo platformUpdateInfo = resolvePlatformUpdateInfo(currentState,
recommendedState);
final ProjectExtensionsUpdateInfo extensionsUpdateInfo = ProjectUpdateInfos.resolveExtensionsUpdateInfo(
currentState,
recommendedState);

logUpdates(invocation.getQuarkusProject(), currentState, recommendedState, platformUpdateInfo, extensionsUpdateInfo,
logUpdates(invocation.getQuarkusProject(), currentState, recommendedState, platformUpdateInfo,
extensionsUpdateInfo,
false, perModule,
quarkusProject.log());
final boolean noRewrite = invocation.getValue(UpdateProject.NO_REWRITE, false);
Expand All @@ -95,15 +98,17 @@ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws
Path recipe = null;
try {
recipe = Files.createTempFile("quarkus-project-recipe-", ".yaml");
final String updateRecipesVersion = invocation.getValue(UpdateProject.REWRITE_UPDATE_RECIPES_VERSION,
final String updateRecipesVersion = invocation.getValue(
UpdateProject.REWRITE_UPDATE_RECIPES_VERSION,
QuarkusUpdatesRepository.DEFAULT_UPDATE_RECIPES_VERSION);
final QuarkusUpdatesRepository.FetchResult fetchResult = QuarkusUpdates.createRecipe(invocation.log(),
final FetchResult fetchResult = QuarkusUpdates.createRecipe(invocation.log(),
recipe,
QuarkusProjectHelper.artifactResolver(), buildTool, updateRecipesVersion, request);
invocation.log().info("OpenRewrite recipe generated: %s", recipe);
final String rewritePluginVersion = invocation.getValue(UpdateProject.REWRITE_PLUGIN_VERSION,

String rewritePluginVersion = invocation.getValue(UpdateProject.REWRITE_PLUGIN_VERSION,
fetchResult.getRewritePluginVersion());
final boolean rewriteDryRun = invocation.getValue(UpdateProject.REWRITE_DRY_RUN, false);
boolean rewriteDryRun = invocation.getValue(UpdateProject.REWRITE_DRY_RUN, false);
invocation.log().warn(
"The update feature does not yet handle updates of the extension versions. If needed, update your extensions manually.");
QuarkusUpdateCommand.handle(
Expand All @@ -114,6 +119,7 @@ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws
fetchResult.getRecipesGAV(),
recipe,
rewriteDryRun);

} catch (IOException e) {
throw new QuarkusCommandException("Error while generating the project update script", e);
}
Expand Down Expand Up @@ -216,11 +222,13 @@ private static void logUpdates(QuarkusProject project, ProjectState currentState
break;
case RECOMMEND_PLATFORM_MANAGED:
log.info(String.format(UpdateProjectCommandHandler.ITEM_FORMAT,
UpdateProjectCommandHandler.UPDATE, e.getCurrentDep().getArtifact().toCompactCoords()
UpdateProjectCommandHandler.UPDATE,
e.getCurrentDep().getArtifact().toCompactCoords()
+ " -> drop version (managed by platform)"));
break;
case ADD_VERSION:
log.info(String.format(UpdateProjectCommandHandler.ITEM_FORMAT, UpdateProjectCommandHandler.UPDATE,
log.info(String.format(UpdateProjectCommandHandler.ITEM_FORMAT,
UpdateProjectCommandHandler.UPDATE,
e.getRecommendedDependency().getArtifact().toCompactCoords()
+ " -> add version (managed by platform)"));
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,12 @@ public static FetchResult createRecipe(MessageWriter log, Path target, MavenArti
BuildTool buildTool, String updateRecipesVersion,
ProjectUpdateRequest request)
throws IOException {
final FetchResult result = QuarkusUpdatesRepository.fetchRecipes(log, artifactResolver, buildTool, updateRecipesVersion,
final FetchResult result = QuarkusUpdatesRepository.fetchRecipes(log, artifactResolver, buildTool,
updateRecipesVersion,
request.currentVersion,
request.targetVersion);
request.targetVersion,
request.projectExtensionsUpdateInfo
.getSimpleVersionUpdates());
QuarkusUpdateRecipe recipe = new QuarkusUpdateRecipe()
.buildTool(request.buildTool);
if (request.updateJavaVersion.isPresent()) {
Expand All @@ -47,7 +50,8 @@ public static FetchResult createRecipe(MessageWriter log, Path target, MavenArti
recipe.addOperation(new UpdatePropertyOperation("quarkusPlatformVersion", request.targetVersion))
.addOperation(new UpdatePropertyOperation("quarkusPluginVersion", request.targetVersion));
if (request.kotlinVersion != null) {
recipe.addOperation(new UpgradeGradlePluginOperation("org.jetbrains.kotlin.*", request.kotlinVersion));
recipe.addOperation(
new UpgradeGradlePluginOperation("org.jetbrains.kotlin.*", request.kotlinVersion));
}
break;
}
Expand All @@ -69,6 +73,7 @@ public static FetchResult createRecipe(MessageWriter log, Path target, MavenArti
for (String s : result.getRecipes()) {
recipe.addRecipes(QuarkusUpdateRecipeIO.readRecipesYaml(s));
}

QuarkusUpdateRecipeIO.write(target, recipe);
return result;
}
Expand All @@ -84,10 +89,12 @@ public static class ProjectUpdateRequest {

public ProjectUpdateRequest(String currentVersion, String targetVersion, String kotlinVersion,
Optional<Integer> updateJavaVersion, ProjectExtensionsUpdateInfo projectExtensionsUpdateInfo) {
this(BuildTool.MAVEN, currentVersion, targetVersion, kotlinVersion, updateJavaVersion, projectExtensionsUpdateInfo);
this(BuildTool.MAVEN, currentVersion, targetVersion, kotlinVersion, updateJavaVersion,
projectExtensionsUpdateInfo);
}

public ProjectUpdateRequest(BuildTool buildTool, String currentVersion, String targetVersion, String kotlinVersion,
public ProjectUpdateRequest(BuildTool buildTool, String currentVersion, String targetVersion,
String kotlinVersion,
Optional<Integer> updateJavaVersion, ProjectExtensionsUpdateInfo projectExtensionsUpdateInfo) {
this.buildTool = buildTool;
this.currentVersion = currentVersion;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,10 @@
import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Properties;
import java.util.stream.Collectors;
Expand All @@ -18,6 +21,7 @@
import io.quarkus.bootstrap.util.DependencyUtils;
import io.quarkus.devtools.messagewriter.MessageWriter;
import io.quarkus.devtools.project.BuildTool;
import io.quarkus.devtools.project.update.ExtensionUpdateInfo;
import io.quarkus.platform.descriptor.loader.json.ResourceLoader;
import io.quarkus.platform.descriptor.loader.json.ResourceLoaders;

Expand All @@ -34,29 +38,26 @@ private QuarkusUpdatesRepository() {
public static final String PROP_REWRITE_MAVEN_PLUGIN_VERSION = "rewrite-maven-plugin-version";
public static final String PROP_REWRITE_GRADLE_PLUGIN_VERSION = "rewrite-gradle-plugin-version";

public static FetchResult fetchRecipes(MessageWriter log, MavenArtifactResolver artifactResolver, BuildTool buildTool,
public static FetchResult fetchRecipes(MessageWriter log, MavenArtifactResolver artifactResolver,
BuildTool buildTool,
String recipeVersion, String currentVersion,
String targetVersion) {
String targetVersion, List<ExtensionUpdateInfo> topExtensionDependency) {
final String gav = QUARKUS_RECIPE_GA + ":" + recipeVersion;

Map<String, String[]> recipeDirectoryNames = new LinkedHashMap<>();
recipeDirectoryNames.put("core", new String[] { currentVersion, targetVersion });
for (ExtensionUpdateInfo dep : topExtensionDependency) {
recipeDirectoryNames.put(
dep.getCurrentDep().getArtifact().getArtifactId() + "/"
+ dep.getCurrentDep().getArtifact().getGroupId(),
new String[] { dep.getCurrentDep().getVersion(), dep.getRecommendedDependency().getVersion() });
}

try {
final Artifact artifact = artifactResolver.resolve(DependencyUtils.toArtifact(gav)).getArtifact();
final ResourceLoader resourceLoader = ResourceLoaders.resolveFileResourceLoader(
artifact.getFile());
final List<String> recipes = resourceLoader.loadResourceAsPath("quarkus-updates/core",
path -> {
try (final Stream<Path> pathStream = Files.walk(path)) {
return pathStream
.filter(p -> p.getFileName().toString().matches("^\\d\\H+.ya?ml$"))
.filter(p -> shouldApplyRecipe(p.getFileName().toString(), currentVersion, targetVersion))
.map(p -> {
try {
return new String(Files.readAllBytes(p));
} catch (IOException e) {
throw new RuntimeException(e);
}
}).collect(Collectors.toList());
}
});
final List<String> recipes = fetchRecipesAsList(resourceLoader, "quarkus-updates", recipeDirectoryNames);
final Properties props = resourceLoader.loadResourceAsPath("quarkus-updates/", p -> {
final Properties properties = new Properties();
final Path propPath = p.resolve("recipes.properties");
Expand Down Expand Up @@ -132,4 +133,43 @@ static boolean shouldApplyRecipe(String recipeFileName, String currentVersion, S
final DefaultArtifactVersion targetAVersion = new DefaultArtifactVersion(targetVersion);
return currentAVersion.compareTo(recipeAVersion) < 0 && targetAVersion.compareTo(recipeAVersion) >= 0;
}

static List<String> fetchRecipesAsList(ResourceLoader resourceLoader, String loaction,
Map<String, String[]> recipeDirectoryNames) throws IOException {
return resourceLoader.loadResourceAsPath(loaction,
path -> {
try (final Stream<Path> pathStream = Files.walk(path)) {
return pathStream
.filter(Files::isDirectory)
.flatMap(dir -> {
String key = path.relativize(dir).toString();
String versions[] = recipeDirectoryNames.get(key);
if (versions != null && versions.length != 0) {
try {
Stream<Path> recipePath = Files.walk(dir);
return recipePath
.filter(p -> p.getFileName().toString().matches("^\\d\\H+.ya?ml$"))
.filter(p -> shouldApplyRecipe(p.getFileName().toString(),
versions[0], versions[1]))
.map(p -> {
try {
return new String(Files.readAllBytes(p));
} catch (IOException e) {
throw new RuntimeException("Error reading file: " + p, e);
}
})
.onClose(() -> recipePath.close());
} catch (IOException e) {
throw new RuntimeException("Error traversing directory: " + dir, e);
}
}
return null;

}).filter(Objects::nonNull).collect(Collectors.toList());
} catch (IOException e) {
throw new RuntimeException("Error traversing base directory", e);
}
});

}
}
Original file line number Diff line number Diff line change
@@ -1,11 +1,19 @@
package io.quarkus.devtools.project.update.rewrite;

import static io.quarkus.devtools.project.update.rewrite.QuarkusUpdatesRepository.shouldApplyRecipe;
import static io.quarkus.devtools.project.update.rewrite.QuarkusUpdatesRepository.*;
import static org.junit.jupiter.api.Assertions.*;

import java.io.IOException;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;

import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.CsvFileSource;

import io.quarkus.platform.descriptor.loader.json.ClassPathResourceLoader;

class QuarkusUpdatesRepositoryTest {

@ParameterizedTest
Expand All @@ -16,4 +24,15 @@ void testShouldApplyRecipeWithCSV(String recipeVersion, String currentVersion, S
assertEquals(expectedResult, result);
}

@Test
void testShouldLoadRecipesFromTheDirectory() throws IOException {
Map<String, String[]> recipeDirectoryNames = new LinkedHashMap<>();
recipeDirectoryNames.put("core", new String[] { "2.7", "3.1" });
recipeDirectoryNames.put("org.apache.camel.quarkus/camel-quarkus-core", new String[] { "2.7", "3.0" });
ClassPathResourceLoader resourceLoader = new ClassPathResourceLoader();
List<String> recipes = fetchRecipesAsList(resourceLoader, "dir/quarkus-update", recipeDirectoryNames);
int noOfRecipes = recipes.size();
assertEquals(noOfRecipes, 3);

}
}
Loading

0 comments on commit ed0e00e

Please sign in to comment.