diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartCatalog.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartCatalog.java index 0db36a4b3ab0b..6768882a92df4 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartCatalog.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartCatalog.java @@ -139,16 +139,16 @@ protected Collection select(QuarkusCodestartProjectInput projectInput .collect(Collectors.toCollection(ArrayList::new)); // include default codestarts depending on the versions and the extensions being chosen or not - Optional selectedDefaultCodeStart = getSelectedDefaultCodeStart(projectInput); + Optional selectedDefaultCodeStart = getSelectedDefaultCodeStart(projectInput); if (projectInput.getAppContent().contains(CODE) && selectedDefaultCodeStart.isPresent() && projectCodestarts.stream() .noneMatch(c -> c.getType() == CodestartType.CODE && !c.getSpec().isPreselected())) { final Codestart defaultCodestart = codestarts.stream() - .filter(c -> c.matches(selectedDefaultCodeStart.get().key())) + .filter(c -> c.matches(selectedDefaultCodeStart.get())) .findFirst().orElseThrow(() -> new CodestartStructureException( - selectedDefaultCodeStart.get().key() + " codestart not found")); + selectedDefaultCodeStart.get() + " codestart not found")); final String languageName = findLanguageName(projectCodestarts); if (defaultCodestart.implementsLanguage(languageName)) { projectCodestarts.add(defaultCodestart); @@ -178,7 +178,7 @@ protected Collection select(QuarkusCodestartProjectInput projectInput return projectCodestarts; } - private Optional getSelectedDefaultCodeStart(QuarkusCodestartProjectInput projectInput) { + private Optional getSelectedDefaultCodeStart(QuarkusCodestartProjectInput projectInput) { // This is very hackyish, we need a better data structure to do better Optional quarkusBom = projectInput.getBoms().stream() .map(ArtifactCoords::fromString) @@ -195,13 +195,17 @@ private Optional getSelectedDefaultCodeStart(QuarkusCodestar if (projectInput.getExtensions().isEmpty() || (projectInput.getExtensions().size() == 1 && isLanguageExtension(projectInput.getExtensions().iterator().next()))) { - return Optional.of(ExtensionCodestart.RESTEASY_REACTIVE); + var defaultCodestart = projectInput.getDefaultCodestart(); + if (defaultCodestart == null) { + defaultCodestart = QuarkusCodestartCatalog.ExtensionCodestart.RESTEASY_REACTIVE.key(); + } + return Optional.of(defaultCodestart); } return Optional.empty(); } - return Optional.of(ExtensionCodestart.RESTEASY); + return Optional.of(ExtensionCodestart.RESTEASY.key()); } private boolean isCoreBom(ArtifactCoords artifactCoords) { diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartProjectInput.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartProjectInput.java index 41222ba6cf44f..10f347c208793 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartProjectInput.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartProjectInput.java @@ -15,7 +15,8 @@ public final class QuarkusCodestartProjectInput extends CodestartProjectInput { private final Collection extensions; private final Collection platforms; private final String example; - private Set appContent; + private final Set appContent; + private final String defaultCodestart; public QuarkusCodestartProjectInput(QuarkusCodestartProjectInputBuilder builder) { super(builder); @@ -24,6 +25,7 @@ public QuarkusCodestartProjectInput(QuarkusCodestartProjectInputBuilder builder) this.example = builder.example; this.buildTool = requireNonNull(builder.buildTool, "buildTool is required"); this.appContent = builder.appContent; + this.defaultCodestart = builder.defaultCodestart; } public static QuarkusCodestartProjectInputBuilder builder() { @@ -49,4 +51,8 @@ public Set getAppContent() { public BuildTool getBuildTool() { return buildTool; } + + public String getDefaultCodestart() { + return defaultCodestart; + } } diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartProjectInputBuilder.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartProjectInputBuilder.java index 452f45a939c89..8652171d831ab 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartProjectInputBuilder.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartProjectInputBuilder.java @@ -27,6 +27,7 @@ public class QuarkusCodestartProjectInputBuilder extends CodestartProjectInputBu Set appContent = new HashSet<>(FULL_CONTENT); String example; BuildTool buildTool = BuildTool.MAVEN; + String defaultCodestart; QuarkusCodestartProjectInputBuilder() { super(); @@ -146,6 +147,13 @@ public QuarkusCodestartProjectInputBuilder buildTool(BuildTool buildTool) { return this; } + public QuarkusCodestartProjectInputBuilder defaultCodestart(String defaultCodestart) { + if (defaultCodestart != null) { + this.defaultCodestart = defaultCodestart; + } + return this; + } + public QuarkusCodestartProjectInput build() { return new QuarkusCodestartProjectInput(this); } diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/CreateProjectCommandHandler.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/CreateProjectCommandHandler.java index 0711461f91d0f..a696b9d5a5654 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/CreateProjectCommandHandler.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/handlers/CreateProjectCommandHandler.java @@ -137,6 +137,7 @@ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws .addData(toCodestartData(invocation.getValues())) .addData(invocation.getValue(DATA, Collections.emptyMap())) .messageWriter(invocation.log()) + .defaultCodestart(getDefaultCodestart(mainCatalog)) .build(); invocation.log().info("-----------"); if (!extensionsToAdd.isEmpty()) { @@ -249,4 +250,20 @@ private void checkMinimumJavaVersion(String javaVersionString, List e .format("Some extensions are not compatible with the selected Java version (%s):\n %s", javaVersion, list)); } } + + private static String getDefaultCodestart(ExtensionCatalog catalog) { + var map = catalog.getMetadata(); + if (map != null && !map.isEmpty()) { + var projectMetadata = map.get("project"); + if (projectMetadata instanceof Map) { + var defaultCodestart = ((Map) projectMetadata).get("default-codestart"); + if (defaultCodestart != null) { + if (defaultCodestart instanceof String) { + return defaultCodestart.toString(); + } + } + } + } + return null; + } } diff --git a/independent-projects/tools/devtools-testing/src/main/java/io/quarkus/devtools/testing/FakeExtensionCatalog.java b/independent-projects/tools/devtools-testing/src/main/java/io/quarkus/devtools/testing/FakeExtensionCatalog.java index d03d08d91ece0..0bf3fa0ff5750 100644 --- a/independent-projects/tools/devtools-testing/src/main/java/io/quarkus/devtools/testing/FakeExtensionCatalog.java +++ b/independent-projects/tools/devtools-testing/src/main/java/io/quarkus/devtools/testing/FakeExtensionCatalog.java @@ -3,6 +3,7 @@ import java.io.IOException; import java.io.InputStream; import java.io.UncheckedIOException; +import java.util.Map; import io.quarkus.devtools.codestarts.quarkus.QuarkusCodestartCatalog; import io.quarkus.registry.catalog.ExtensionCatalog; @@ -36,4 +37,17 @@ public static ExtensionCatalog newFakeExtensionCatalog() { throw new UncheckedIOException(e); } } + + public static String getDefaultCodestart() { + var map = FAKE_EXTENSION_CATALOG.getMetadata().get("project"); + if (map != null) { + if (map instanceof Map) { + var defaultCodestart = ((Map) map).get("default-codestart"); + if (defaultCodestart instanceof String) { + return defaultCodestart.toString(); + } + } + } + return null; + } } diff --git a/independent-projects/tools/devtools-testing/src/main/resources/fake-catalog.json b/independent-projects/tools/devtools-testing/src/main/resources/fake-catalog.json index 89aa29ee4265a..f38313854bd9b 100644 --- a/independent-projects/tools/devtools-testing/src/main/resources/fake-catalog.json +++ b/independent-projects/tools/devtools-testing/src/main/resources/fake-catalog.json @@ -427,6 +427,7 @@ ], "metadata": { "project": { + "default-codestart": "resteasy-reactive", "properties": { "doc-root": "https://quarkus.io", "rest-assured-version": "4.3.2", diff --git a/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartCatalogTest.java b/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartCatalogTest.java index c316da61b6156..5f4b5e32140a7 100644 --- a/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartCatalogTest.java +++ b/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartCatalogTest.java @@ -14,6 +14,7 @@ import io.quarkus.devtools.codestarts.CodestartProjectDefinition; import io.quarkus.devtools.codestarts.CodestartType; import io.quarkus.devtools.project.BuildTool; +import io.quarkus.devtools.testing.FakeExtensionCatalog; import io.quarkus.devtools.testing.SnapshotTesting; import io.quarkus.maven.dependency.ArtifactKey; @@ -47,7 +48,7 @@ void loadTest() throws IOException { @Test void createProjectTestEmpty() throws IOException { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .noCode() .noBuildToolWrapper() .noDockerfiles() @@ -68,7 +69,7 @@ void createProjectTestEmpty() throws IOException { @Test void createProjectTestNoExample() throws IOException { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .noCode() .build(); final CodestartProjectDefinition projectDefinition = getCatalog().createProject(input); @@ -88,7 +89,7 @@ void createProjectTestNoExample() throws IOException { @Test void createProjectTestGradle() throws IOException { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .buildTool(BuildTool.GRADLE) .build(); final CodestartProjectDefinition projectDefinition = getCatalog().createProject(input); @@ -98,7 +99,7 @@ void createProjectTestGradle() throws IOException { @Test void createProjectTestKotlin() throws IOException { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-kotlin")) .build(); final CodestartProjectDefinition projectDefinition = getCatalog().createProject(input); @@ -108,7 +109,7 @@ void createProjectTestKotlin() throws IOException { @Test void prepareProjectTestScala() throws IOException { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-scala")) .build(); final CodestartProjectDefinition projectDefinition = getCatalog().createProject(input); @@ -118,7 +119,7 @@ void prepareProjectTestScala() throws IOException { @Test void prepareProjectTestConfigYaml() throws IOException { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-config-yaml")) .build(); final CodestartProjectDefinition projectDefinition = getCatalog().createProject(input); @@ -128,7 +129,7 @@ void prepareProjectTestConfigYaml() throws IOException { @Test void prepareProjectTestResteasy() throws IOException { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-resteasy")) .build(); final CodestartProjectDefinition projectDefinition = getCatalog().createProject(input); @@ -141,6 +142,10 @@ void prepareProjectTestResteasy() throws IOException { "resteasy-codestart"); } + private static QuarkusCodestartProjectInputBuilder newInputBuilder() { + return QuarkusCodestartProjectInput.builder().defaultCodestart(FakeExtensionCatalog.getDefaultCodestart()); + } + private QuarkusCodestartCatalog getCatalog() throws IOException { return FAKE_QUARKUS_CODESTART_CATALOG; } diff --git a/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartGenerationTest.java b/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartGenerationTest.java index 3df62f156b9b5..3a7cc05b87f20 100644 --- a/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartGenerationTest.java +++ b/independent-projects/tools/devtools-testing/src/test/java/io/quarkus/devtools/codestarts/quarkus/QuarkusCodestartGenerationTest.java @@ -18,6 +18,7 @@ import org.junit.jupiter.api.TestInfo; import io.quarkus.devtools.project.BuildTool; +import io.quarkus.devtools.testing.FakeExtensionCatalog; import io.quarkus.devtools.testing.SnapshotTesting; import io.quarkus.devtools.testing.codestarts.QuarkusCodestartTesting; import io.quarkus.maven.dependency.ArtifactCoords; @@ -38,7 +39,7 @@ private Map getGenerationTestInputData() { @Test void generateDefault(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .noCode() .noDockerfiles() .noBuildToolWrapper() @@ -60,9 +61,13 @@ void generateDefault(TestInfo testInfo) throws Throwable { assertThat(projectDir.resolve("src/main/java")).exists().isEmptyDirectory(); } + private static QuarkusCodestartProjectInputBuilder newInputBuilder() { + return QuarkusCodestartProjectInput.builder().defaultCodestart(FakeExtensionCatalog.getDefaultCodestart()); + } + @Test void generateRESTEasyJavaCustom(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addData(getGenerationTestInputData()) .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-resteasy")) .putData(PROJECT_PACKAGE_NAME.key(), "com.andy") @@ -101,7 +106,7 @@ void verifyIndexExtensionList(TestInfo testInfo) throws Throwable { @Test void generateMavenWithCustomDep(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addData(getGenerationTestInputData()) .addBoms(QuarkusCodestartTesting.getPlatformBoms()) .addExtension(ArtifactCoords.fromString("io.quarkus:quarkus-resteasy:1.8")) @@ -127,7 +132,7 @@ void generateMavenWithCustomDep(TestInfo testInfo) throws Throwable { @Test void generateRESTEasyKotlinCustom(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addData(getGenerationTestInputData()) .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-resteasy")) .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-kotlin")) @@ -160,7 +165,7 @@ void generateRESTEasyKotlinCustom(TestInfo testInfo) throws Throwable { @Test void generateRESTEasyScalaCustom(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addData(getGenerationTestInputData()) .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-resteasy")) .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-scala")) @@ -193,7 +198,7 @@ void generateRESTEasyScalaCustom(TestInfo testInfo) throws Throwable { @Test void generateMavenDefaultJava(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addData(getGenerationTestInputData()) .build(); final Path projectDir = testDirPath.resolve("maven-default-java"); @@ -211,7 +216,7 @@ void generateMavenDefaultJava(TestInfo testInfo) throws Throwable { @Test void generateGradleDefaultJava(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .buildTool(BuildTool.GRADLE) .addData(getGenerationTestInputData()) .build(); @@ -230,7 +235,7 @@ void generateGradleDefaultJava(TestInfo testInfo) throws Throwable { @Test void generateMavenResteasyJava(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-resteasy")) .addData(getGenerationTestInputData()) .build(); @@ -249,7 +254,7 @@ void generateMavenResteasyJava(TestInfo testInfo) throws Throwable { @Test void generateMavenConfigYamlJava(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .addExtension(ArtifactKey.fromString("io.quarkus:quarkus-config-yaml")) .addData(getGenerationTestInputData()) .build(); @@ -264,7 +269,7 @@ void generateMavenConfigYamlJava(TestInfo testInfo) throws Throwable { @Test public void generateGradleWrapperGithubAction(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .buildTool(BuildTool.GRADLE) .addData(getGenerationTestInputData()) .addCodestarts(Collections.singletonList("tooling-github-action")) @@ -280,7 +285,7 @@ public void generateGradleWrapperGithubAction(TestInfo testInfo) throws Throwabl @Test public void generateGradleNoWrapperGithubAction(TestInfo testInfo) throws Throwable { - final QuarkusCodestartProjectInput input = QuarkusCodestartProjectInput.builder() + final QuarkusCodestartProjectInput input = newInputBuilder() .buildTool(BuildTool.GRADLE) .noBuildToolWrapper() .addData(getGenerationTestInputData())