From 2c12ab4606d290dbc6c415f8d21da36b7563830d Mon Sep 17 00:00:00 2001 From: Alexey Loubyansky Date: Mon, 28 Oct 2024 12:48:39 +0100 Subject: [PATCH 1/8] Introduce QuarkusClassLoader.visitRuntimeResources(name) (cherry picked from commit 5c9cbdfe76132aea2b5c8b983520623d3144a85a) --- .../classloading/QuarkusClassLoader.java | 43 +++++++++++++++---- 1 file changed, 35 insertions(+), 8 deletions(-) diff --git a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java index bcbbc2a491ca2..9368790bf7509 100644 --- a/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java +++ b/independent-projects/bootstrap/core/src/main/java/io/quarkus/bootstrap/classloading/QuarkusClassLoader.java @@ -23,11 +23,13 @@ import java.util.Set; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentMap; +import java.util.function.Consumer; import org.jboss.logging.Logger; import io.quarkus.commons.classloading.ClassLoaderHelper; import io.quarkus.paths.ManifestAttributes; +import io.quarkus.paths.PathVisit; /** * The ClassLoader used for non production Quarkus applications (i.e. dev and test mode). @@ -48,14 +50,42 @@ public class QuarkusClassLoader extends ClassLoader implements Closeable { registerAsParallelCapable(); } + private static RuntimeException nonQuarkusClassLoaderError() { + return new IllegalStateException("The current classloader is not an instance of " + + QuarkusClassLoader.class.getName() + " but " + + Thread.currentThread().getContextClassLoader().getClass().getName()); + } + + /** + * Visits every found runtime resource with a given name. If a resource is not found, the visitor will + * simply not be called. + *

+ * IMPORTANT: this method works only when the current class loader is an instance of {@link QuarkusClassLoader}, + * otherwise it throws an error with the corresponding message. + * + * @param resourceName runtime resource name to visit + * @param visitor runtime resource visitor + */ + public static void visitRuntimeResources(String resourceName, Consumer visitor) { + if (Thread.currentThread().getContextClassLoader() instanceof QuarkusClassLoader classLoader) { + for (var element : classLoader.getElementsWithResource(resourceName)) { + if (element.isRuntime()) { + element.apply(tree -> { + tree.accept(resourceName, visitor); + return null; + }); + } + } + } else { + throw nonQuarkusClassLoaderError(); + } + } + public static List getElements(String resourceName, boolean onlyFromCurrentClassLoader) { if (Thread.currentThread().getContextClassLoader() instanceof QuarkusClassLoader classLoader) { return classLoader.getElementsWithResource(resourceName, onlyFromCurrentClassLoader); } - - throw new IllegalStateException("The current classloader is not an instance of " - + QuarkusClassLoader.class.getName() + " but " - + Thread.currentThread().getContextClassLoader().getClass().getName()); + throw nonQuarkusClassLoaderError(); } /** @@ -78,10 +108,7 @@ public static boolean isApplicationClass(String className) { return classPathResourceIndex.getFirstClassPathElement(resourceName) != null; } - - throw new IllegalStateException("The current classloader is not an instance of " - + QuarkusClassLoader.class.getName() + " but " - + Thread.currentThread().getContextClassLoader().getClass().getName()); + throw nonQuarkusClassLoaderError(); } /** From 09a1a05b49a5fd9f048d7b9c5fcfd5714d52e243 Mon Sep 17 00:00:00 2001 From: Andy Damevin Date: Mon, 28 Oct 2024 11:21:38 +0100 Subject: [PATCH 2/8] Safer lookup and generate static resources for web dep locator (cherry picked from commit 693cdcaa792dec1c3a421e31046880de0bc1f8c6) --- .../main/asciidoc/web-dependency-locator.adoc | 2 +- .../WebDependencyLocatorProcessor.java | 149 ++++++++---------- 2 files changed, 64 insertions(+), 87 deletions(-) diff --git a/docs/src/main/asciidoc/web-dependency-locator.adoc b/docs/src/main/asciidoc/web-dependency-locator.adoc index 4e9b7820eaa1a..6e86ff1743448 100644 --- a/docs/src/main/asciidoc/web-dependency-locator.adoc +++ b/docs/src/main/asciidoc/web-dependency-locator.adoc @@ -113,7 +113,7 @@ This means adding the following to your `index.html` will allow you to import we ===== Automatic imports -You can also automate the imports above. To do this, move your web assets from `src/main/resources/META-INF/resources` to `src/main/web` +You can also automate the imports above. To do this, move your web assets from `src/main/resources/META-INF/resources` to `src/main/resources/web` and now replace the above scripts and imports with `{#bundle /}`: [source,html] diff --git a/extensions/web-dependency-locator/deployment/src/main/java/io/quarkus/webdependency/locator/deployment/WebDependencyLocatorProcessor.java b/extensions/web-dependency-locator/deployment/src/main/java/io/quarkus/webdependency/locator/deployment/WebDependencyLocatorProcessor.java index 5954664dea853..d0a840540fb2d 100644 --- a/extensions/web-dependency-locator/deployment/src/main/java/io/quarkus/webdependency/locator/deployment/WebDependencyLocatorProcessor.java +++ b/extensions/web-dependency-locator/deployment/src/main/java/io/quarkus/webdependency/locator/deployment/WebDependencyLocatorProcessor.java @@ -7,7 +7,6 @@ import java.net.URL; import java.nio.file.Files; import java.nio.file.Path; -import java.nio.file.StandardOpenOption; import java.util.ArrayList; import java.util.HashMap; import java.util.HashSet; @@ -30,10 +29,10 @@ import io.quarkus.deployment.builditem.FeatureBuildItem; import io.quarkus.deployment.builditem.HotDeploymentWatchedFileBuildItem; import io.quarkus.deployment.pkg.builditem.CurateOutcomeBuildItem; -import io.quarkus.deployment.pkg.builditem.OutputTargetBuildItem; import io.quarkus.maven.dependency.ArtifactKey; import io.quarkus.maven.dependency.ResolvedDependency; import io.quarkus.vertx.http.deployment.RouteBuildItem; +import io.quarkus.vertx.http.deployment.spi.GeneratedStaticResourceBuildItem; import io.quarkus.vertx.http.runtime.HttpBuildTimeConfig; import io.quarkus.webdependency.locator.runtime.WebDependencyLocatorRecorder; import io.vertx.core.Handler; @@ -43,96 +42,81 @@ public class WebDependencyLocatorProcessor { private static final Logger log = Logger.getLogger(WebDependencyLocatorProcessor.class.getName()); @BuildStep - public void findRelevantFiles(BuildProducer feature, - BuildProducer hotDeploymentWatchedProducer, - WebDependencyLocatorConfig config, - OutputTargetBuildItem outputTarget) throws IOException { - - Path web = outputTarget.getOutputDirectory().getParent() - .resolve(SRC) - .resolve(MAIN) - .resolve(RESOURCES) - .resolve(config.webRoot); - - if (Files.exists(web)) { - hotDeploymentWatchedProducer.produce(new HotDeploymentWatchedFileBuildItem(config.webRoot + SLASH + STAR + STAR)); - // Find all css and js (under /app) - Path app = web - .resolve(config.appRoot); + public void feature(BuildProducer feature) { + feature.produce(new FeatureBuildItem(Feature.WEB_DEPENDENCY_LOCATOR)); + } - List cssFiles = new ArrayList<>(); - List jsFiles = new ArrayList<>(); + @BuildStep + public void findRelevantFiles(BuildProducer generatedStaticProducer, + BuildProducer hotDeploymentWatchedProducer, + WebDependencyLocatorConfig config) throws IOException { - if (Files.exists(app)) { + QuarkusClassLoader.visitRuntimeResources(config.webRoot, visit -> { + final Path web = visit.getPath(); + if (Files.isDirectory(web)) { hotDeploymentWatchedProducer - .produce(new HotDeploymentWatchedFileBuildItem( - config.webRoot + SLASH + config.appRoot + SLASH + STAR + STAR)); - try (Stream appstream = Files.walk(app)) { - appstream.forEach(path -> { - if (Files.isRegularFile(path) && path.toString().endsWith(DOT_CSS)) { - cssFiles.add(web.relativize(path)); - } else if (Files.isRegularFile(path) && path.toString().endsWith(DOT_JS)) { - jsFiles.add(web.relativize(path)); + .produce(new HotDeploymentWatchedFileBuildItem(config.webRoot + SLASH + STAR + STAR)); + // Find all css and js (under /app) + Path app = web + .resolve(config.appRoot); + + List cssFiles = new ArrayList<>(); + List jsFiles = new ArrayList<>(); + + if (Files.exists(app)) { + hotDeploymentWatchedProducer + .produce(new HotDeploymentWatchedFileBuildItem( + config.webRoot + SLASH + config.appRoot + SLASH + STAR + STAR)); + try (Stream appstream = Files.walk(app)) { + appstream.forEach(path -> { + if (Files.isRegularFile(path) && path.toString().endsWith(DOT_CSS)) { + cssFiles.add(web.relativize(path)); + } else if (Files.isRegularFile(path) && path.toString().endsWith(DOT_JS)) { + jsFiles.add(web.relativize(path)); + } + }); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + + try (Stream webstream = Files.walk(web)) { + + webstream.forEach(path -> { + if (Files.isRegularFile(path)) { + String endpoint = SLASH + web.relativize(path); + try { + if (path.toString().endsWith(DOT_HTML)) { + generatedStaticProducer.produce(new GeneratedStaticResourceBuildItem(endpoint, + processHtml(path, cssFiles, jsFiles))); + } else { + generatedStaticProducer.produce(new GeneratedStaticResourceBuildItem(endpoint, path)); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } } }); + } catch (IOException e) { + throw new UncheckedIOException(e); } } + }); - try (Stream webstream = Files.walk(web)) { - - final Path resourcesDirectory = outputTarget.getOutputDirectory() - .resolve(CLASSES) - .resolve(META_INF) - .resolve(RESOURCES); - Files.createDirectories(resourcesDirectory); - - webstream.forEach(path -> { - if (Files.isRegularFile(path)) { - try { - copyResource(resourcesDirectory, web, path, cssFiles, jsFiles, path.toString().endsWith(DOT_HTML)); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } else if (Files.isRegularFile(path)) { - - } - }); - } catch (IOException e) { - throw new UncheckedIOException(e); - } - } - feature.produce(new FeatureBuildItem(Feature.WEB_DEPENDENCY_LOCATOR)); } - private void copyResource(Path resourcesDirectory, Path webRoot, Path path, List cssFiles, List jsFiles, - boolean filter) + private byte[] processHtml( + Path path, List cssFiles, List jsFiles) throws IOException { - try { + StringJoiner modifiedContent = new StringJoiner(System.lineSeparator()); - Path relativizePath = webRoot.relativize(path); + Files.lines(path).forEach(line -> { + String modifiedLine = processLine(line, cssFiles, jsFiles); + modifiedContent.add(modifiedLine); + }); - byte[] toBeCopied; - if (filter) { - StringJoiner modifiedContent = new StringJoiner(System.lineSeparator()); - - Files.lines(path).forEach(line -> { - String modifiedLine = processLine(line, cssFiles, jsFiles); - modifiedContent.add(modifiedLine); - }); - - String result = modifiedContent.toString(); - toBeCopied = result.getBytes(); - } else { - toBeCopied = Files.readAllBytes(path); - } - - final Path resourceFile = resourcesDirectory.resolve(relativizePath); - Files.createDirectories(resourceFile.getParent()); - Files.write(resourceFile, toBeCopied, StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING); - - } catch (IOException e) { - throw new UncheckedIOException(e); - } + String result = modifiedContent.toString(); + return result.getBytes(); } private static String processLine(String line, List cssFiles, List jsFiles) { @@ -310,13 +294,6 @@ static class LibInfo { private static final String TAB = "\t"; private static final String TAB2 = TAB + TAB; - private static final String CLASSES = "classes"; - private static final String META_INF = "META-INF"; - private static final String RESOURCES = "resources"; - - private static final String SRC = "src"; - private static final String MAIN = "main"; - private static final String SLASH = "/"; private static final String STAR = "*"; From 9900b1b51dd5184eea2074554a858978ff90293c Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 28 Oct 2024 17:37:21 +0100 Subject: [PATCH 3/8] Remove Failsafe plugin config in AWT testing The plugin shouldn't be defined and disabled, it will be automatically enabled by the profile. Fixes #43997 (cherry picked from commit a349b010905b39224d1cd7d2b68f9800f15d8e6a) --- integration-tests/awt/pom.xml | 6 ------ 1 file changed, 6 deletions(-) diff --git a/integration-tests/awt/pom.xml b/integration-tests/awt/pom.xml index f71302da2c204..aacda1d852a3e 100644 --- a/integration-tests/awt/pom.xml +++ b/integration-tests/awt/pom.xml @@ -161,12 +161,6 @@ false - - maven-failsafe-plugin - - true - - From 82eb6f4ca77f8b01b8bc115fb8c38aaa01122c06 Mon Sep 17 00:00:00 2001 From: Jakub Gardo Date: Sat, 26 Oct 2024 22:02:38 +0200 Subject: [PATCH 4/8] Fix Elasticsearch DevService network for @QuarkusIntegrationTest for docker-image-building (cherry picked from commit 8a2ab24d63af4288f74ec71a881a24c1e5f03cc9) --- .../DevServicesElasticsearchProcessor.java | 30 +++++++++++++------ 1 file changed, 21 insertions(+), 9 deletions(-) diff --git a/extensions/elasticsearch-rest-client-common/deployment/src/main/java/io/quarkus/elasticsearch/restclient/common/deployment/DevServicesElasticsearchProcessor.java b/extensions/elasticsearch-rest-client-common/deployment/src/main/java/io/quarkus/elasticsearch/restclient/common/deployment/DevServicesElasticsearchProcessor.java index c66158226f627..0debaa03d35c0 100644 --- a/extensions/elasticsearch-rest-client-common/deployment/src/main/java/io/quarkus/elasticsearch/restclient/common/deployment/DevServicesElasticsearchProcessor.java +++ b/extensions/elasticsearch-rest-client-common/deployment/src/main/java/io/quarkus/elasticsearch/restclient/common/deployment/DevServicesElasticsearchProcessor.java @@ -192,9 +192,10 @@ private DevServicesResultBuildItem.RunningDevService startElasticsearchDevServic // Starting the server final Supplier defaultElasticsearchSupplier = () -> { - GenericContainer container = resolvedDistribution.equals(Distribution.ELASTIC) + CreatedContainer createdContainer = resolvedDistribution.equals(Distribution.ELASTIC) ? createElasticsearchContainer(config, resolvedImageName, useSharedNetwork) : createOpensearchContainer(config, resolvedImageName, useSharedNetwork); + GenericContainer container = createdContainer.genericContainer(); if (config.serviceName != null) { container.withLabel(DEV_SERVICE_LABEL, config.serviceName); @@ -209,11 +210,15 @@ private DevServicesResultBuildItem.RunningDevService startElasticsearchDevServic container.withReuse(config.reuse); container.start(); + + var httpHost = container.getHost() + ":" + container.getMappedPort(ELASTICSEARCH_PORT); + if (createdContainer.hostName() != null) { + httpHost = createdContainer.hostName() + ":" + ELASTICSEARCH_PORT; + } return new DevServicesResultBuildItem.RunningDevService(Feature.ELASTICSEARCH_REST_CLIENT_COMMON.getName(), container.getContainerId(), new ContainerShutdownCloseable(container, "Elasticsearch"), - buildPropertiesMap(buildItemConfig, - container.getHost() + ":" + container.getMappedPort(ELASTICSEARCH_PORT))); + buildPropertiesMap(buildItemConfig, httpHost)); }; return maybeContainerAddress @@ -225,12 +230,13 @@ private DevServicesResultBuildItem.RunningDevService startElasticsearchDevServic .orElseGet(defaultElasticsearchSupplier); } - private GenericContainer createElasticsearchContainer(ElasticsearchDevServicesBuildTimeConfig config, + private CreatedContainer createElasticsearchContainer(ElasticsearchDevServicesBuildTimeConfig config, DockerImageName resolvedImageName, boolean useSharedNetwork) { ElasticsearchContainer container = new ElasticsearchContainer( resolvedImageName.asCompatibleSubstituteFor("docker.elastic.co/elasticsearch/elasticsearch")); + String hostName = null; if (useSharedNetwork) { - ConfigureUtil.configureSharedNetwork(container, DEV_SERVICE_ELASTICSEARCH); + hostName = ConfigureUtil.configureSharedNetwork(container, DEV_SERVICE_ELASTICSEARCH); } // Disable security as else we would need to configure it correctly to avoid tons of WARNING in the log @@ -241,15 +247,17 @@ private GenericContainer createElasticsearchContainer(ElasticsearchDevService // See https://www.elastic.co/guide/en/elasticsearch/reference/current/modules-cluster.html#disk-based-shard-allocation container.addEnv("cluster.routing.allocation.disk.threshold_enabled", "false"); container.addEnv("ES_JAVA_OPTS", config.javaOpts); - return container; + + return new CreatedContainer(container, hostName); } - private GenericContainer createOpensearchContainer(ElasticsearchDevServicesBuildTimeConfig config, + private CreatedContainer createOpensearchContainer(ElasticsearchDevServicesBuildTimeConfig config, DockerImageName resolvedImageName, boolean useSharedNetwork) { OpensearchContainer container = new OpensearchContainer( resolvedImageName.asCompatibleSubstituteFor("opensearchproject/opensearch")); + String hostName = null; if (useSharedNetwork) { - ConfigureUtil.configureSharedNetwork(container, DEV_SERVICE_OPENSEARCH); + hostName = ConfigureUtil.configureSharedNetwork(container, DEV_SERVICE_OPENSEARCH); } container.addEnv("bootstrap.memory_lock", "true"); @@ -264,7 +272,11 @@ private GenericContainer createOpensearchContainer(ElasticsearchDevServicesBu // Considering dev services are transient and not intended for production by nature, // we'll just set some hardcoded password. container.addEnv("OPENSEARCH_INITIAL_ADMIN_PASSWORD", "NotActua11y$trongPa$$word"); - return container; + + return new CreatedContainer(container, hostName); + } + + private record CreatedContainer(GenericContainer genericContainer, String hostName) { } private DockerImageName resolveImageName(ElasticsearchDevServicesBuildTimeConfig config, From c461da59c2a03e8a76423601530b3e4f6f33d904 Mon Sep 17 00:00:00 2001 From: Sergey Beryozkin Date: Tue, 29 Oct 2024 12:16:54 +0000 Subject: [PATCH 5/8] Fix OIDC Bearer tutorial link name (cherry picked from commit 1d2ae457cd8100c7e488285dc7b7b91a13889609) --- .../asciidoc/security-oidc-bearer-token-authentication.adoc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc index eb04efd1c8efd..621d512c15c12 100644 --- a/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc +++ b/docs/src/main/asciidoc/security-oidc-bearer-token-authentication.adoc @@ -49,7 +49,7 @@ Also, if you use Keycloak and bearer tokens, see the Quarkus xref:security-keycl To learn about how you can protect service applications by using OIDC Bearer token authentication, see the following tutorial: -* xref:security-oidc-bearer-token-authentication-tutorial.adoc[Protect a web application by using OpenID Connect (OIDC) authorization code flow]. +* xref:security-oidc-bearer-token-authentication-tutorial.adoc[Protect a service application by using OpenID Connect (OIDC) Bearer token authentication]. For information about how to support multiple tenants, see the Quarkus xref:security-openid-connect-multitenancy.adoc[Using OpenID Connect Multi-Tenancy] guide. From ac0a40a506222d37b0425302465078aac8ff292b Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 29 Oct 2024 13:06:49 +0100 Subject: [PATCH 6/8] Add a capability for OIDC client extension As requested here: https://github.com/quarkiverse/quarkus-openapi-generator/pull/829#pullrequestreview-2393581939 (cherry picked from commit deefc683e7315c0a9ca808a368968e17b91419e3) --- .../src/main/java/io/quarkus/deployment/Capability.java | 1 + extensions/oidc-client/runtime/pom.xml | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/core/deployment/src/main/java/io/quarkus/deployment/Capability.java b/core/deployment/src/main/java/io/quarkus/deployment/Capability.java index e5ed3637c6d39..36c9650df38c8 100644 --- a/core/deployment/src/main/java/io/quarkus/deployment/Capability.java +++ b/core/deployment/src/main/java/io/quarkus/deployment/Capability.java @@ -116,6 +116,7 @@ public interface Capability { String OPENSHIFT_CLIENT = OPENSHIFT + ".client"; String OIDC = QUARKUS_PREFIX + ".oidc"; + String OIDC_CLIENT = OIDC + ".client"; String KEYCLOAK_AUTHORIZATION = QUARKUS_PREFIX + ".keycloak.authorization"; diff --git a/extensions/oidc-client/runtime/pom.xml b/extensions/oidc-client/runtime/pom.xml index 502dc746c7c83..cdace1db1d7a4 100644 --- a/extensions/oidc-client/runtime/pom.xml +++ b/extensions/oidc-client/runtime/pom.xml @@ -41,6 +41,11 @@ io.quarkus quarkus-extension-maven-plugin + + + io.quarkus.oidc.client + + maven-compiler-plugin From 0ed847476b6e983d94139ccf1f717d15ba481ce0 Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Tue, 29 Oct 2024 12:59:28 +0100 Subject: [PATCH 7/8] Upgrade Caffeine to 3.1.8 (cherry picked from commit 3b335c9abf08304a702781fee9a65b83a7eb5ee3) --- bom/application/pom.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bom/application/pom.xml b/bom/application/pom.xml index 43c5b25cd6242..8ec95913d728c 100644 --- a/bom/application/pom.xml +++ b/bom/application/pom.xml @@ -136,7 +136,7 @@ 5.10.5 15.0.10.Final 5.0.12.Final - 3.1.5 + 3.1.8 4.1.111.Final 1.16.0 1.0.4 From 607e6f6a47d57ac13e2a41b34c456ff0fa7d7c7f Mon Sep 17 00:00:00 2001 From: Guillaume Smet Date: Mon, 28 Oct 2024 18:44:48 +0100 Subject: [PATCH 8/8] Codestarts - Do not reference ITs module if extension without ITs When creating a project without ITs, we don't generate the ITs module so we shouldn't reference it in the parent POM. Fixes #37216 (cherry picked from commit a09e7159d7ad91716ccaacf7fe1d27df8967bd00) --- .../quarkus-extension/code/quarkiverse/java/pom.tpl.qute.xml | 2 ++ .../extension/QuarkusExtensionCodestartCatalog.java | 3 ++- .../java/io/quarkus/devtools/commands/CreateExtension.java | 4 ++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus-extension/code/quarkiverse/java/pom.tpl.qute.xml b/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus-extension/code/quarkiverse/java/pom.tpl.qute.xml index 7c22949f418c1..8a49be5802fcd 100644 --- a/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus-extension/code/quarkiverse/java/pom.tpl.qute.xml +++ b/independent-projects/tools/base-codestarts/src/main/resources/codestarts/quarkus-extension/code/quarkiverse/java/pom.tpl.qute.xml @@ -21,6 +21,7 @@ {/if} + {#if has-integration-tests-module} it @@ -35,4 +36,5 @@ + {/if} diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/extension/QuarkusExtensionCodestartCatalog.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/extension/QuarkusExtensionCodestartCatalog.java index c3cedb8417823..3ff7119e2ce10 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/extension/QuarkusExtensionCodestartCatalog.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/codestarts/extension/QuarkusExtensionCodestartCatalog.java @@ -50,7 +50,8 @@ public enum QuarkusExtensionData implements DataKey { IT_PARENT_RELATIVE_PATH("it-parent.relative-path"), MAVEN_QUARKUS_EXTENSION_PLUGIN("maven.quarkus-extension-plugin"), MAVEN_COMPILER_PLUGIN_VERSION("maven.compiler-plugin-version"), - HAS_DOCS_MODULE("has-docs-module"); + HAS_DOCS_MODULE("has-docs-module"), + HAS_INTEGRATION_TESTS_MODULE("has-integration-tests-module"); private final String key; diff --git a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/CreateExtension.java b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/CreateExtension.java index 0b423e0a9ec6c..41437b50048d2 100644 --- a/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/CreateExtension.java +++ b/independent-projects/tools/devtools-common/src/main/java/io/quarkus/devtools/commands/CreateExtension.java @@ -8,6 +8,7 @@ import static io.quarkus.devtools.codestarts.extension.QuarkusExtensionCodestartCatalog.QuarkusExtensionData.EXTENSION_NAME; import static io.quarkus.devtools.codestarts.extension.QuarkusExtensionCodestartCatalog.QuarkusExtensionData.GROUP_ID; import static io.quarkus.devtools.codestarts.extension.QuarkusExtensionCodestartCatalog.QuarkusExtensionData.HAS_DOCS_MODULE; +import static io.quarkus.devtools.codestarts.extension.QuarkusExtensionCodestartCatalog.QuarkusExtensionData.HAS_INTEGRATION_TESTS_MODULE; import static io.quarkus.devtools.codestarts.extension.QuarkusExtensionCodestartCatalog.QuarkusExtensionData.IT_PARENT_ARTIFACT_ID; import static io.quarkus.devtools.codestarts.extension.QuarkusExtensionCodestartCatalog.QuarkusExtensionData.IT_PARENT_GROUP_ID; import static io.quarkus.devtools.codestarts.extension.QuarkusExtensionCodestartCatalog.QuarkusExtensionData.IT_PARENT_RELATIVE_PATH; @@ -105,6 +106,7 @@ public enum LayoutType { private String extensionsRelativeDir = "extensions"; private boolean withCodestart; private String javaVersion; + private boolean hasIntegrationTestsModule; public CreateExtension(final Path baseDir) { this.baseDir = requireNonNull(baseDir, "extensionDirPath is required"); @@ -218,6 +220,7 @@ public CreateExtension withoutDevModeTest(boolean withoutDevModeTest) { } public CreateExtension withoutIntegrationTests(boolean withoutIntegrationTest) { + hasIntegrationTestsModule = !withoutIntegrationTest; this.builder.withoutIntegrationTests(withoutIntegrationTest); return this; } @@ -263,6 +266,7 @@ public CreateExtensionCommandHandler prepare() throws QuarkusCommandException { data.putIfAbsent(CLASS_NAME_BASE, toCapCamelCase(extensionId)); data.put(EXTENSION_FULL_NAME, data.getRequiredStringValue(NAMESPACE_NAME) + data.getRequiredStringValue(EXTENSION_NAME)); + data.put(HAS_INTEGRATION_TESTS_MODULE, hasIntegrationTestsModule); // for now, we only support Java extensions data.put(JAVA_VERSION, javaVersion == null ? JavaVersion.DEFAULT_JAVA_VERSION_FOR_EXTENSION