diff --git a/devtools/maven/src/main/java/io/quarkus/maven/CreateExtensionMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/CreateExtensionMojo.java
index d79ffbc02..93ea97e25 100644
--- a/devtools/maven/src/main/java/io/quarkus/maven/CreateExtensionMojo.java
+++ b/devtools/maven/src/main/java/io/quarkus/maven/CreateExtensionMojo.java
@@ -1,5 +1,6 @@
package io.quarkus.maven;
+import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.Writer;
@@ -19,15 +20,21 @@ import java.util.stream.Collectors;
import javax.lang.model.SourceVersion;
import org.apache.maven.model.Model;
-import org.apache.maven.model.Plugin;
import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
+import org.eclipse.aether.RepositorySystem;
+import org.eclipse.aether.RepositorySystemSession;
+import org.eclipse.aether.artifact.DefaultArtifact;
+import org.eclipse.aether.graph.Dependency;
+import org.eclipse.aether.repository.RemoteRepository;
+import org.eclipse.aether.resolution.ArtifactDescriptorResult;
import org.jboss.logging.Logger;
import freemarker.cache.ClassTemplateLoader;
@@ -38,6 +45,11 @@ import freemarker.template.Configuration;
import freemarker.template.Template;
import freemarker.template.TemplateException;
import freemarker.template.TemplateExceptionHandler;
+import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver;
+import io.quarkus.bootstrap.resolver.maven.MavenRepoInitializer;
+import io.quarkus.bootstrap.resolver.maven.workspace.LocalProject;
+import io.quarkus.bootstrap.resolver.maven.workspace.LocalWorkspace;
+import io.quarkus.maven.utilities.MojoUtils;
import io.quarkus.maven.utilities.PomTransformer;
import io.quarkus.maven.utilities.PomTransformer.Gavtcs;
import io.quarkus.maven.utilities.PomTransformer.Transformation;
@@ -66,20 +78,46 @@ public class CreateExtensionMojo extends AbstractMojo {
private static final String CLASSPATH_PREFIX = "classpath:";
private static final String FILE_PREFIX = "file:";
+ private static final String QUARKUS_VERSION_PROP = "quarkus.version";
+
static final String DEFAULT_ENCODING = "utf-8";
- static final String DEFAULT_QUARKUS_VERSION = "@{quarkus.version}";
+ static final String DEFAULT_QUARKUS_VERSION = "@{" + QUARKUS_VERSION_PROP + "}";
+ static final String QUARKUS_VERSION_POM_EXPR = "${" + QUARKUS_VERSION_PROP + "}";
static final String DEFAULT_BOM_ENTRY_VERSION = "@{project.version}";
static final String DEFAULT_TEMPLATES_URI_BASE = "classpath:/create-extension-templates";
static final String DEFAULT_NAME_SEGMENT_DELIMITER = " - ";
static final Pattern PLACEHOLDER_PATTERN = Pattern.compile("@\\{([^\\}]+)\\}");
+ static final String PLATFORM_DEFAULT_GROUP_ID = "io.quarkus";
+ static final String PLATFORM_DEFAULT_ARTIFACT_ID = "quarkus-bom-deployment";
+
+ static final String COMPILER_PLUGIN_VERSION_PROP = "compiler-plugin.version";
+ static final String COMPILER_PLUGIN_VERSION_POM_EXPR = "${" + COMPILER_PLUGIN_VERSION_PROP + "}";
+ static final String COMPILER_PLUGIN_DEFAULT_VERSION = "3.8.1";
+ private static final String COMPILER_PLUGIN_GROUP_ID = "org.apache.maven.plugins";
+ private static final String COMPILER_PLUGIN_ARTIFACT_ID = "maven-compiler-plugin";
+ private static final String COMPILER_PLUGIN_KEY = COMPILER_PLUGIN_GROUP_ID + ":"
+ + COMPILER_PLUGIN_ARTIFACT_ID;
+
/**
* Directory where the changes should be performed. Default is the current directory of the current Java process.
*
* @since 0.20.0
*/
@Parameter(property = "quarkus.basedir")
- Path basedir;
+ File basedir;
+
+ /**
+ * The {@code groupId} of the Quarkus platform's BOM containing deployment dependencies.
+ */
+ @Parameter(property = "platformGroupId", defaultValue = PLATFORM_DEFAULT_GROUP_ID)
+ String platformGroupId;
+
+ /**
+ * The {@code artifactId} of the Quarkus platform's BOM containing deployment dependencies.
+ */
+ @Parameter(property = "platformArtifactId", defaultValue = PLATFORM_DEFAULT_ARTIFACT_ID)
+ String platformArtifactId;
/**
* The {@code groupId} for the newly created Maven modules. If {@code groupId} is left unset, the {@code groupId}
@@ -87,9 +125,19 @@ public class CreateExtensionMojo extends AbstractMojo {
*
* @since 0.20.0
*/
- @Parameter(property = "quarkus.groupId")
+ @Parameter(property = "groupId")
String groupId;
+ /**
+ * This parameter was introduced to change the property of {@code groupId} parameter from {@code quarkus.groupId} to
+ * {@code groupId}
+ *
+ * @since 1.3.0
+ */
+ @Deprecated
+ @Parameter(property = "quarkus.groupId")
+ String deprecatedGroupId;
+
/**
* {@code artifactId} of the runtime module. The {@code artifactId}s of the extension parent
* (${artifactId}-parent) and deployment (${artifactId}-deployment) modules will be based
@@ -104,21 +152,31 @@ public class CreateExtensionMojo extends AbstractMojo {
*
* @since 0.20.0
*/
- @Parameter(property = "quarkus.artifactId")
+ @Parameter(property = "artifactId")
String artifactId;
+ /**
+ * This parameter was introduced to change the property of {@code artifactId} parameter from {@code quarkus.artifactId} to
+ * {@code artifactId}
+ *
+ * @since 1.3.0
+ */
+ @Deprecated
+ @Parameter(property = "quarkus.artifactId")
+ String deprecatedArtifactId;
+
/**
* A prefix common to all extension artifactIds in the current source tree. If you set {@link #artifactIdPrefix},
* set also {@link #artifactIdBase}, but do not set {@link #artifactId}.
*
* @since 0.20.0
*/
- @Parameter(property = "quarkus.artifactIdPrefix")
+ @Parameter(property = "quarkus.artifactIdPrefix", defaultValue = "")
String artifactIdPrefix;
/**
- * The unique part of the {@link #artifactId}. If you set {@link #artifactIdBase}, set also
- * {@link #artifactIdPrefix}, but do not set {@link #artifactId}.
+ * The unique part of the {@link #artifactId}. If you set {@link #artifactIdBase}, {@link #artifactIdPrefix}
+ * may also be set, but not {@link #artifactId}.
*
* @since 0.20.0
*/
@@ -131,9 +189,19 @@ public class CreateExtensionMojo extends AbstractMojo {
*
* @since 0.20.0
*/
- @Parameter(property = "quarkus.artifactVersion")
+ @Parameter(property = "version")
String version;
+ /**
+ * This parameter was introduced to change the property of {@code version} parameter from {@code quarkus.artifactVersion} to
+ * {@code version}
+ *
+ * @since 1.3.0
+ */
+ @Deprecated
+ @Parameter(property = "quarkus.artifactVersion")
+ String deprecatedVersion;
+
/**
* The {@code name} of the runtime module. The {@code name}s of the extension parent and deployment modules will be
* based on this {@code name} too.
@@ -253,17 +321,25 @@ public class CreateExtensionMojo extends AbstractMojo {
*
* @since 0.20.0
*/
- @Parameter(defaultValue = DEFAULT_QUARKUS_VERSION, required = true, property = "quarkus.quarkusVersion")
+ @Parameter(defaultValue = DEFAULT_QUARKUS_VERSION, required = true, property = "quarkus.version")
String quarkusVersion;
+ /**
+ * This parameter was introduced to change the property of {@code artifactId} parameter from {@code quarkus.artifactId} to
+ * {@code artifactId}
+ *
+ * @since 1.3.0
+ */
+ @Deprecated
+ @Parameter(property = "quarkus.quarkusVersion")
+ String deprecatedQuarkusVersion;
+
/**
* If {@code true} the Maven dependencies in Runtime and Deployment modules will not have their versions set and the
* {@code quarkus-bootstrap-maven-plugin} in the Runtime module will not have its version set and it will have no
* executions configured. If {@code false} the version set in {@link #quarkusVersion} will be used where applicable
* and {@code quarkus-bootstrap-maven-plugin} in the Runtime module will be configured explicitly. If the value is
- * {@code null} the mojo attempts to autodetect the value inspecting the POM hierarchy of the current project: The
- * value is {@code true} if {@code quarkus-bootstrap-maven-plugin} is defined in the {@code pluginManagement}
- * section of the effective model of the current Maven module; otherwise the value is {@code false}.
+ * {@code null} the parameter will be treated as it was initialized to {@code false}.
*
* @since 0.20.0
*/
@@ -307,7 +383,7 @@ public class CreateExtensionMojo extends AbstractMojo {
/**
* Path relative to {@link #basedir} pointing at a {@code pom.xml} file containing the BOM (Bill of Materials) that
* manages runtime extension artifacts. If set, the newly created Runtime module will be added to
- * {@code } section of this bom; otherwise the newly created Runtime module will not be added
+ * {@code } section of this bom; otherwise the newly created Runtime module will not be added
* to any BOM.
*
* @since 0.21.0
@@ -318,7 +394,7 @@ public class CreateExtensionMojo extends AbstractMojo {
/**
* Path relative to {@link #basedir} pointing at a {@code pom.xml} file containing the BOM (Bill of Materials) that
* manages deployment time extension artifacts. If set, the newly created Deployment module will be added to
- * {@code } section of this bom; otherwise the newly created Deployment module will not be
+ * {@code } section of this bom; otherwise the newly created Deployment module will not be
* added to any BOM.
*
* @since 0.21.0
@@ -370,18 +446,89 @@ public class CreateExtensionMojo extends AbstractMojo {
@Parameter(defaultValue = "${project}", readonly = true)
MavenProject project;
+ /**
+ * The entry point to Aether, i.e. the component doing all the work.
+ *
+ * @component
+ */
+ @Component
+ private RepositorySystem repoSystem;
+
+ /**
+ * The current repository/network configuration of Maven.
+ *
+ * @parameter default-value="${repositorySystemSession}"
+ * @readonly
+ */
+ @Parameter(defaultValue = "${repositorySystemSession}", readonly = true)
+ private RepositorySystemSession repoSession;
+
+ /**
+ * The project's remote repositories to use for the resolution of artifacts and their dependencies.
+ *
+ * @parameter default-value="${project.remoteProjectRepositories}"
+ * @readonly
+ */
+ @Parameter(defaultValue = "${project.remoteProjectRepositories}", readonly = true, required = true)
+ private List repos;
+
+ /**
+ * The version of {@code org.apache.maven.plugins:maven-compiler-plugin} that should be used for
+ * the extension project.
+ */
+ @Parameter(defaultValue = COMPILER_PLUGIN_DEFAULT_VERSION, required = true, property = "quarkus.mavenCompilerPluginVersion")
+ String compilerPluginVersion;
+
+ boolean currentProjectIsBaseDir;
+
+ Charset charset;
+
@Override
public void execute() throws MojoExecutionException, MojoFailureException {
if (this.basedir == null) {
- this.basedir = Paths.get(".").toAbsolutePath().normalize();
+ currentProjectIsBaseDir = true;
+ this.basedir = new File(".").getAbsoluteFile();
}
+
+ if (deprecatedGroupId != null) {
+ if (groupId != null) {
+ throw new MojoExecutionException("Either groupId or deprecatedGroupId can be set at a time but got groupId="
+ + groupId + " and deprecatedGroupId=" + deprecatedGroupId);
+ }
+ groupId = deprecatedGroupId;
+ }
+ if (deprecatedArtifactId != null) {
+ if (artifactId != null) {
+ throw new MojoExecutionException(
+ "Either artifactId or deprecatedArtifactId can be set at a time but got artifactId=" + artifactId
+ + " and deprecatedArtifactId=" + deprecatedArtifactId);
+ }
+ artifactId = deprecatedArtifactId;
+ }
+ if (deprecatedVersion != null) {
+ if (version != null) {
+ throw new MojoExecutionException("Either version or deprecatedVersion can be set at a time but got version="
+ + version + " and deprecatedVersion=" + deprecatedVersion);
+ }
+ version = deprecatedVersion;
+ }
+ if (deprecatedQuarkusVersion != null) {
+ if (quarkusVersion != null && !DEFAULT_QUARKUS_VERSION.equals(quarkusVersion)) {
+ throw new MojoExecutionException(
+ "Either quarkusVersion or deprecatedQuarkusVersion can be set at a time but got quarkusVersion="
+ + quarkusVersion + " and deprecatedQuarkusVersion=" + deprecatedQuarkusVersion);
+ }
+ quarkusVersion = deprecatedQuarkusVersion;
+ }
+
if (artifactId != null) {
artifactIdBase = artifactIdBase(artifactId);
artifactIdPrefix = artifactId.substring(0, artifactId.length() - artifactIdBase.length());
artifactId = BRACKETS_PATTERN.matcher(artifactId).replaceAll("");
- } else if (artifactIdPrefix != null && artifactIdBase != null) {
- artifactId = artifactIdPrefix + artifactIdBase;
+ } else if (artifactIdBase != null) {
+ artifactId = artifactIdPrefix == null || artifactIdPrefix.isEmpty() ? artifactIdBase
+ : artifactIdPrefix + artifactIdBase;
} else {
throw new MojoFailureException(String.format(
"Either artifactId or both artifactIdPrefix and artifactIdBase must be specified; found: artifactId=[%s], artifactIdPrefix=[%s], artifactIdBase[%s]",
@@ -411,123 +558,318 @@ public class CreateExtensionMojo extends AbstractMojo {
}
if (runtimeBomPath != null) {
- runtimeBomPath = basedir.resolve(runtimeBomPath);
+ runtimeBomPath = basedir.toPath().resolve(runtimeBomPath);
if (!Files.exists(runtimeBomPath)) {
throw new MojoFailureException("runtimeBomPath does not exist: " + runtimeBomPath);
}
}
if (deploymentBomPath != null) {
- deploymentBomPath = basedir.resolve(deploymentBomPath);
+ deploymentBomPath = basedir.toPath().resolve(deploymentBomPath);
if (!Files.exists(deploymentBomPath)) {
throw new MojoFailureException("deploymentBomPath does not exist: " + deploymentBomPath);
}
}
- final Charset charset = Charset.forName(encoding);
+ charset = Charset.forName(encoding);
- final Path basePomXml = basedir.resolve("pom.xml");
- if (Files.exists(basePomXml)) {
- try (Reader r = Files.newBufferedReader(basePomXml, charset)) {
- Model basePom = new MavenXpp3Reader().read(r);
- if (!"pom".equals(basePom.getPackaging())) {
+ try {
+ File rootPom = null;
+ Model rootModel = null;
+ boolean importDeploymentBom = true;
+ boolean setCompilerPluginVersion = true;
+ boolean setQuarkusVersionProp = true;
+ if (isCurrentProjectExists()) {
+ rootPom = getCurrentProjectPom();
+ rootModel = MojoUtils.readPom(rootPom);
+ if (!"pom".equals(rootModel.getPackaging())) {
throw new MojoFailureException(
"Can add extension modules only under a project with packaging 'pom'; found: "
- + basePom.getPackaging() + "");
+ + rootModel.getPackaging() + "");
+ }
+
+ if (rootPom.equals(project.getFile())) {
+ importDeploymentBom = !hasQuarkusDeploymentBom();
+ setCompilerPluginVersion = !project.getPluginManagement().getPluginsAsMap()
+ .containsKey(COMPILER_PLUGIN_KEY);
+ setQuarkusVersionProp = !project.getProperties().containsKey(QUARKUS_VERSION_PROP);
+ } else {
+ // aloubyansky: not sure we should support this case and not sure it ever worked properly
+ // this is about creating an extension project not in the context of the current project from the Maven's plugin perspective
+ // kind of a pathological use-case from the Maven's perspective, imo
+ final DefaultArtifact rootArtifact = new DefaultArtifact(getGroupId(rootModel),
+ rootModel.getArtifactId(), null, rootModel.getPackaging(), getVersion(rootModel));
+ try {
+ final LocalWorkspace ws = LocalProject.loadWorkspace(rootPom.getParentFile().toPath()).getWorkspace();
+ final MavenArtifactResolver mvn = MavenArtifactResolver.builder()
+ .setRepositorySystem(MavenRepoInitializer.getRepositorySystem(repoSession.isOffline(), ws))
+ .setRepositorySystemSession(repoSession)
+ .setRemoteRepositories(repos)
+ .setWorkspace(LocalProject.loadWorkspace(rootPom.getParentFile().toPath()).getWorkspace())
+ .build();
+ final ArtifactDescriptorResult rootDescr = mvn.resolveDescriptor(rootArtifact);
+ importDeploymentBom = !hasQuarkusDeploymentBom(rootDescr.getManagedDependencies());
+ // TODO determine whether the compiler plugin is configured for the project
+ setQuarkusVersionProp = !rootDescr.getProperties().containsKey(QUARKUS_VERSION_PROP);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Failed to resolve " + rootArtifact + " descriptor", e);
+ }
+ }
+ } else if (this.grandParentRelativePath != null) {
+ // aloubyansky: not sure we should support this case, same as above
+ final File gpPom = getExtensionProjectBaseDir().resolve(this.grandParentRelativePath).normalize()
+ .toAbsolutePath().toFile();
+ if (gpPom.exists()) {
+ rootPom = gpPom;
+ rootModel = MojoUtils.readPom(gpPom);
+ final DefaultArtifact rootArtifact = new DefaultArtifact(getGroupId(rootModel),
+ rootModel.getArtifactId(), null, rootModel.getPackaging(), getVersion(rootModel));
+ try {
+ final LocalWorkspace ws = LocalProject.loadWorkspace(rootPom.getParentFile().toPath()).getWorkspace();
+ final MavenArtifactResolver mvn = MavenArtifactResolver.builder()
+ .setRepositorySystem(MavenRepoInitializer.getRepositorySystem(repoSession.isOffline(), ws))
+ .setRepositorySystemSession(repoSession)
+ .setRemoteRepositories(repos)
+ .setWorkspace(ws)
+ .build();
+ final ArtifactDescriptorResult rootDescr = mvn.resolveDescriptor(rootArtifact);
+ importDeploymentBom = !hasQuarkusDeploymentBom(rootDescr.getManagedDependencies());
+ // TODO determine whether the compiler plugin is configured for the project
+ setQuarkusVersionProp = !rootDescr.getProperties().containsKey(QUARKUS_VERSION_PROP);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Failed to resolve " + rootArtifact + " descriptor", e);
+ }
}
- addModules(basePomXml, basePom, charset);
- } catch (IOException e) {
- throw new MojoExecutionException(String.format("Could not read %s", basePomXml), e);
- } catch (XmlPullParserException e) {
- throw new MojoExecutionException(String.format("Could not parse %s", basePomXml), e);
- } catch (TemplateException e) {
- throw new MojoExecutionException(String.format("Could not process a FreeMarker template"), e);
}
- } else {
- newParent(basedir);
+
+ final TemplateParams templateParams = getTemplateParams(rootModel);
+ final Configuration cfg = getTemplateConfig();
+
+ generateExtensionProjects(cfg, templateParams);
+ if (setQuarkusVersionProp) {
+ setQuarkusVersionProp(getExtensionProjectBaseDir().resolve("pom.xml").toFile());
+ }
+ if (importDeploymentBom) {
+ addQuarkusDeploymentBom(getExtensionProjectBaseDir().resolve("pom.xml").toFile());
+ }
+ if (setCompilerPluginVersion) {
+ setCompilerPluginVersion(getExtensionProjectBaseDir().resolve("pom.xml").toFile());
+ }
+ if (rootModel != null) {
+ addModules(rootPom.toPath(), templateParams, rootModel);
+ }
+
+ if (runtimeBomPath != null) {
+ getLog().info(
+ String.format("Adding [%s] to dependencyManagement in [%s]", templateParams.artifactId,
+ runtimeBomPath));
+ List transformations = new ArrayList();
+ transformations
+ .add(Transformation.addManagedDependency(templateParams.groupId, templateParams.artifactId,
+ templateParams.bomEntryVersion));
+ for (Gavtcs gavtcs : templateParams.additionalRuntimeDependencies) {
+ getLog().info(String.format("Adding [%s] to dependencyManagement in [%s]", gavtcs, runtimeBomPath));
+ transformations.add(Transformation.addManagedDependency(gavtcs));
+ }
+ pomTransformer(runtimeBomPath).transform(transformations);
+ }
+ if (deploymentBomPath != null) {
+ final String aId = templateParams.artifactId + "-deployment";
+ getLog().info(String.format("Adding [%s] to dependencyManagement in [%s]", aId, deploymentBomPath));
+ pomTransformer(deploymentBomPath)
+ .transform(Transformation.addManagedDependency(templateParams.groupId, aId,
+ templateParams.bomEntryVersion));
+ }
+ if (itestParentPath != null) {
+ generateItest(cfg, templateParams);
+ }
+ } catch (IOException e) {
+ throw new MojoExecutionException(String.format("Could not read %s", project.getFile()), e);
+ } catch (TemplateException e) {
+ throw new MojoExecutionException(String.format("Could not process a FreeMarker template"), e);
}
}
- void addModules(Path basePomXml, Model basePom, Charset charset)
+ private void setQuarkusVersionProp(File pom) throws IOException, MojoExecutionException {
+ pomTransformer(pom.toPath()).transform(Transformation.addProperty(QUARKUS_VERSION_PROP,
+ quarkusVersion.equals(DEFAULT_QUARKUS_VERSION) ? getPluginVersion() : quarkusVersion));
+ }
+
+ private void setCompilerPluginVersion(File pom) throws IOException {
+ pomTransformer(pom.toPath()).transform(Transformation.addProperty(COMPILER_PLUGIN_VERSION_PROP, compilerPluginVersion));
+ pomTransformer(pom.toPath())
+ .transform(Transformation.addManagedPlugin(
+ MojoUtils.plugin(COMPILER_PLUGIN_GROUP_ID, COMPILER_PLUGIN_ARTIFACT_ID,
+ COMPILER_PLUGIN_VERSION_POM_EXPR)));
+ }
+
+ private void addQuarkusDeploymentBom(File pom) throws IOException, MojoExecutionException {
+ addQuarkusDeploymentBom(MojoUtils.readPom(pom), pom);
+ }
+
+ private void addQuarkusDeploymentBom(Model model, File file) throws IOException, MojoExecutionException {
+ pomTransformer(file.toPath())
+ .transform(Transformation.addManagedDependency(
+ new Gavtcs(platformGroupId, platformArtifactId, QUARKUS_VERSION_POM_EXPR, "pom", null, "import")));
+ }
+
+ private String getPluginVersion() throws MojoExecutionException {
+ return CreateUtils.resolvePluginInfo(CreateExtensionMojo.class).getVersion();
+ }
+
+ private boolean hasQuarkusDeploymentBom() {
+ if (project.getDependencyManagement() == null) {
+ return false;
+ }
+ for (org.apache.maven.model.Dependency dep : project.getDependencyManagement().getDependencies()) {
+ if (dep.getArtifactId().equals("quarkus-core-deployment")
+ && dep.getGroupId().equals("io.quarkus")) {
+ // this is not a 100% accurate check but practically valid
+ return true;
+ }
+ }
+ return false;
+ }
+
+ private boolean hasQuarkusDeploymentBom(List deps) {
+ if (deps == null) {
+ return false;
+ }
+ for (Dependency dep : deps) {
+ if (dep.getArtifact().getArtifactId().equals("quarkus-core-deployment")
+ && dep.getArtifact().getGroupId().equals("io.quarkus")) {
+ // this is not a 100% accurate check but practically valid
+ return true;
+ }
+ }
+ return false;
+ }
+
+ /**
+ * @return true if the goal is executed in an existing project
+ */
+ private boolean isCurrentProjectExists() {
+ return currentProjectIsBaseDir ? project.getFile() != null
+ : Files.exists(basedir.toPath().resolve("pom.xml"));
+ }
+
+ private File getCurrentProjectPom() {
+ if (currentProjectIsBaseDir) {
+ return project.getFile() == null ? new File(project.getBasedir(), "pom.xml") : project.getFile();
+ }
+ return new File(basedir, "pom.xml");
+ }
+
+ private Path getExtensionProjectBaseDir() {
+ if (currentProjectIsBaseDir) {
+ return project.getBasedir() == null ? basedir.toPath().resolve(artifactIdBase)
+ : project.getBasedir().toPath().resolve(artifactIdBase);
+ }
+ return new File(basedir, artifactIdBase).toPath();
+ }
+
+ private Path getExtensionRuntimeBaseDir() {
+ return getExtensionProjectBaseDir().resolve("runtime");
+ }
+
+ private Path getExtensionDeploymentBaseDir() {
+ return getExtensionProjectBaseDir().resolve("deployment");
+ }
+
+ void addModules(Path basePomXml, TemplateParams templateParams, Model basePom)
throws IOException, TemplateException, MojoFailureException, MojoExecutionException {
-
- final Configuration cfg = new Configuration(Configuration.VERSION_2_3_28);
- cfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
- cfg.setTemplateLoader(createTemplateLoader(basedir, templatesUriBase));
- cfg.setDefaultEncoding(charset.name());
- cfg.setInterpolationSyntax(Configuration.SQUARE_BRACKET_INTERPOLATION_SYNTAX);
- cfg.setTagSyntax(Configuration.SQUARE_BRACKET_TAG_SYNTAX);
-
- TemplateParams model = new TemplateParams();
-
- model.artifactId = artifactId;
- model.artifactIdPrefix = artifactIdPrefix;
- model.artifactIdBase = artifactIdBase;
- model.artifactIdBaseCamelCase = toCapCamelCase(model.artifactIdBase);
-
- model.groupId = this.groupId != null ? this.groupId : getGroupId(basePom);
- model.version = this.version != null ? this.version : getVersion(basePom);
-
- model.namePrefix = namePrefix;
- model.nameBase = nameBase;
- model.nameSegmentDelimiter = nameSegmentDelimiter;
- model.assumeManaged = detectAssumeManaged();
- model.quarkusVersion = quarkusVersion.replace('@', '$');
- model.bomEntryVersion = bomEntryVersion.replace('@', '$');
-
- model.grandParentGroupId = grandParentGroupId != null ? grandParentGroupId : getGroupId(basePom);
- model.grandParentArtifactId = grandParentArtifactId != null ? grandParentArtifactId : basePom.getArtifactId();
- model.grandParentVersion = grandParentVersion != null ? grandParentVersion : getVersion(basePom);
- model.grandParentRelativePath = grandParentRelativePath != null ? grandParentRelativePath : "../pom.xml";
- model.javaPackageBase = javaPackageBase != null ? javaPackageBase
- : getJavaPackage(model.groupId, javaPackageInfix, artifactId);
- model.additionalRuntimeDependencies = getAdditionalRuntimeDependencies();
- model.runtimeBomPathSet = runtimeBomPath != null;
-
- evalTemplate(cfg, "parent-pom.xml", basedir.resolve(model.artifactIdBase + "/pom.xml"), charset, model);
-
- Files.createDirectories(basedir
- .resolve(model.artifactIdBase + "/runtime/src/main/java/" + model.javaPackageBase.replace('.', '/')));
- evalTemplate(cfg, "runtime-pom.xml", basedir.resolve(model.artifactIdBase + "/runtime/pom.xml"), charset,
- model);
-
- evalTemplate(cfg, "deployment-pom.xml", basedir.resolve(model.artifactIdBase + "/deployment/pom.xml"), charset,
- model);
- final Path processorPath = basedir
- .resolve(model.artifactIdBase + "/deployment/src/main/java/" + model.javaPackageBase.replace('.', '/')
- + "/deployment/" + model.artifactIdBaseCamelCase + "Processor.java");
- evalTemplate(cfg, "Processor.java", processorPath, charset, model);
-
- if (!basePom.getModules().contains(model.artifactIdBase)) {
- getLog().info(String.format("Adding module [%s] to [%s]", model.artifactIdBase, basePomXml));
- new PomTransformer(basePomXml, charset).transform(Transformation.addModule(model.artifactIdBase));
+ if (!basePom.getModules().contains(templateParams.artifactIdBase)) {
+ getLog().info(String.format("Adding module [%s] to [%s]", templateParams.artifactIdBase, basePomXml));
+ pomTransformer(basePomXml).transform(Transformation.addModule(templateParams.artifactIdBase));
}
- if (runtimeBomPath != null) {
- getLog().info(
- String.format("Adding [%s] to dependencyManagement in [%s]", model.artifactId, runtimeBomPath));
- List transformations = new ArrayList();
- transformations
- .add(Transformation.addManagedDependency(model.groupId, model.artifactId, model.bomEntryVersion));
- for (Gavtcs gavtcs : model.additionalRuntimeDependencies) {
- getLog().info(String.format("Adding [%s] to dependencyManagement in [%s]", gavtcs, runtimeBomPath));
- transformations.add(Transformation.addManagedDependency(gavtcs));
- }
- new PomTransformer(runtimeBomPath, charset).transform(transformations);
- }
- if (deploymentBomPath != null) {
- final String aId = model.artifactId + "-deployment";
- getLog().info(String.format("Adding [%s] to dependencyManagement in [%s]", aId, deploymentBomPath));
- new PomTransformer(deploymentBomPath, charset)
- .transform(Transformation.addManagedDependency(model.groupId, aId, model.bomEntryVersion));
- }
- if (itestParentPath != null) {
- generateItest(cfg, charset, model);
- }
-
}
- void generateItest(Configuration cfg, Charset charset, TemplateParams model)
- throws MojoFailureException, MojoExecutionException, TemplateException {
- final Path itestParentAbsPath = basedir.resolve(itestParentPath).toAbsolutePath();
+ private void generateExtensionProjects(Configuration cfg, TemplateParams templateParams)
+ throws IOException, TemplateException, MojoExecutionException {
+ evalTemplate(cfg, "parent-pom.xml", getExtensionProjectBaseDir().resolve("pom.xml"), templateParams);
+
+ Files.createDirectories(
+ getExtensionRuntimeBaseDir().resolve("src/main/java")
+ .resolve(templateParams.javaPackageBase.replace('.', '/')));
+ evalTemplate(cfg, "runtime-pom.xml", getExtensionRuntimeBaseDir().resolve("pom.xml"),
+ templateParams);
+
+ evalTemplate(cfg, "deployment-pom.xml", getExtensionDeploymentBaseDir().resolve("pom.xml"),
+ templateParams);
+ final Path processorPath = getExtensionDeploymentBaseDir()
+ .resolve("src/main/java")
+ .resolve(templateParams.javaPackageBase.replace('.', '/'))
+ .resolve("deployment")
+ .resolve(templateParams.artifactIdBaseCamelCase + "Processor.java");
+ evalTemplate(cfg, "Processor.java", processorPath, templateParams);
+ }
+
+ private PomTransformer pomTransformer(Path basePomXml) {
+ return new PomTransformer(basePomXml, charset);
+ }
+
+ private TemplateParams getTemplateParams(Model basePom) throws MojoExecutionException {
+ final TemplateParams templateParams = new TemplateParams();
+
+ templateParams.artifactId = artifactId;
+ templateParams.artifactIdPrefix = artifactIdPrefix;
+ templateParams.artifactIdBase = artifactIdBase;
+ templateParams.artifactIdBaseCamelCase = toCapCamelCase(templateParams.artifactIdBase);
+
+ if (groupId == null) {
+ if (basePom == null) {
+ throw new MojoExecutionException(
+ "Please provide the desired groupId for the project by setting groupId parameter");
+ }
+ templateParams.groupId = getGroupId(basePom);
+ } else {
+ templateParams.groupId = groupId;
+ }
+
+ if (version == null) {
+ if (basePom == null) {
+ throw new MojoExecutionException(
+ "Please provide the desired version for the project by setting version parameter");
+ }
+ templateParams.version = getVersion(basePom);
+ } else {
+ templateParams.version = version;
+ }
+
+ templateParams.namePrefix = namePrefix;
+ templateParams.nameBase = nameBase;
+ templateParams.nameSegmentDelimiter = nameSegmentDelimiter;
+ templateParams.assumeManaged = detectAssumeManaged();
+ templateParams.quarkusVersion = QUARKUS_VERSION_POM_EXPR;
+ templateParams.bomEntryVersion = bomEntryVersion.replace('@', '$');
+
+ if (basePom != null) {
+ templateParams.grandParentGroupId = grandParentGroupId != null ? grandParentGroupId : getGroupId(basePom);
+ templateParams.grandParentArtifactId = grandParentArtifactId != null ? grandParentArtifactId
+ : basePom.getArtifactId();
+ templateParams.grandParentVersion = grandParentVersion != null ? grandParentVersion : getVersion(basePom);
+ templateParams.grandParentRelativePath = grandParentRelativePath != null ? grandParentRelativePath : "../pom.xml";
+ }
+
+ templateParams.javaPackageBase = javaPackageBase != null ? javaPackageBase
+ : getJavaPackage(templateParams.groupId, javaPackageInfix, artifactId);
+ templateParams.additionalRuntimeDependencies = getAdditionalRuntimeDependencies();
+ templateParams.runtimeBomPathSet = runtimeBomPath != null;
+ return templateParams;
+ }
+
+ private Configuration getTemplateConfig() throws IOException {
+ final Configuration templateCfg = new Configuration(Configuration.VERSION_2_3_28);
+ templateCfg.setTemplateExceptionHandler(TemplateExceptionHandler.RETHROW_HANDLER);
+ templateCfg.setTemplateLoader(createTemplateLoader(basedir, templatesUriBase));
+ templateCfg.setDefaultEncoding(encoding);
+ templateCfg.setInterpolationSyntax(Configuration.SQUARE_BRACKET_INTERPOLATION_SYNTAX);
+ templateCfg.setTagSyntax(Configuration.SQUARE_BRACKET_TAG_SYNTAX);
+ return templateCfg;
+ }
+
+ void generateItest(Configuration cfg, TemplateParams model)
+ throws MojoFailureException, MojoExecutionException, TemplateException, IOException {
+ final Path itestParentAbsPath = basedir.toPath().resolve(itestParentPath);
try (Reader r = Files.newBufferedReader(itestParentAbsPath, charset)) {
final Model itestParent = new MavenXpp3Reader().read(r);
if (!"pom".equals(itestParent.getPackaging())) {
@@ -541,20 +883,20 @@ public class CreateExtensionMojo extends AbstractMojo {
model.itestParentRelativePath = "../pom.xml";
final Path itestDir = itestParentAbsPath.getParent().resolve(model.artifactIdBase);
- evalTemplate(cfg, "integration-test-pom.xml", itestDir.resolve("pom.xml"), charset, model);
+ evalTemplate(cfg, "integration-test-pom.xml", itestDir.resolve("pom.xml"), model);
final Path testResourcePath = itestDir.resolve("src/main/java/" + model.javaPackageBase.replace('.', '/')
+ "/it/" + model.artifactIdBaseCamelCase + "Resource.java");
- evalTemplate(cfg, "TestResource.java", testResourcePath, charset, model);
+ evalTemplate(cfg, "TestResource.java", testResourcePath, model);
final Path testClassDir = itestDir
.resolve("src/test/java/" + model.javaPackageBase.replace('.', '/') + "/it");
- evalTemplate(cfg, "Test.java", testClassDir.resolve(model.artifactIdBaseCamelCase + "Test.java"), charset,
+ evalTemplate(cfg, "Test.java", testClassDir.resolve(model.artifactIdBaseCamelCase + "Test.java"),
model);
- evalTemplate(cfg, "IT.java", testClassDir.resolve(model.artifactIdBaseCamelCase + "IT.java"), charset,
+ evalTemplate(cfg, "IT.java", testClassDir.resolve(model.artifactIdBaseCamelCase + "IT.java"),
model);
getLog().info(String.format("Adding module [%s] to [%s]", model.artifactIdBase, itestParentAbsPath));
- new PomTransformer(itestParentAbsPath, charset).transform(Transformation.addModule(model.artifactIdBase));
+ pomTransformer(itestParentAbsPath).transform(Transformation.addModule(model.artifactIdBase));
} catch (IOException e) {
throw new MojoExecutionException(String.format("Could not read %s", itestParentAbsPath), e);
@@ -605,20 +947,7 @@ public class CreateExtensionMojo extends AbstractMojo {
}
boolean detectAssumeManaged() {
- if (assumeManaged != null) {
- return assumeManaged.booleanValue();
- } else {
- if (project != null && project.getPluginManagement() != null
- && project.getPluginManagement().getPlugins() != null) {
- for (Plugin plugin : project.getPluginManagement().getPlugins()) {
- if ("io.quarkus".equals(plugin.getGroupId())
- && "quarkus-bootstrap-maven-plugin".equals(plugin.getArtifactId())) {
- return true;
- }
- }
- }
- return false;
- }
+ return assumeManaged == null ? false : assumeManaged;
}
static String getGroupId(Model basePom) {
@@ -683,12 +1012,7 @@ public class CreateExtensionMojo extends AbstractMojo {
.collect(Collectors.joining("."));
}
- void newParent(Path path) {
- throw new UnsupportedOperationException(
- "Creating standalone extension projects is not supported yet. Only adding modules under and existing pom.xml file is supported.");
- }
-
- static TemplateLoader createTemplateLoader(Path basedir, String templatesUriBase) throws IOException {
+ static TemplateLoader createTemplateLoader(File basedir, String templatesUriBase) throws IOException {
final TemplateLoader defaultLoader = new ClassTemplateLoader(CreateExtensionMojo.class,
DEFAULT_TEMPLATES_URI_BASE.substring(CLASSPATH_PREFIX.length()));
if (DEFAULT_TEMPLATES_URI_BASE.equals(templatesUriBase)) {
@@ -704,7 +1028,7 @@ public class CreateExtensionMojo extends AbstractMojo {
return new MultiTemplateLoader( //
new TemplateLoader[] { //
new FileTemplateLoader(
- basedir.resolve(templatesUriBase.substring(FILE_PREFIX.length())).toFile()), //
+ new File(basedir, templatesUriBase.substring(FILE_PREFIX.length()))), //
defaultLoader //
});
} else {
@@ -714,7 +1038,7 @@ public class CreateExtensionMojo extends AbstractMojo {
}
}
- static void evalTemplate(Configuration cfg, String templateUri, Path dest, Charset charset, TemplateParams model)
+ static void evalTemplate(Configuration cfg, String templateUri, Path dest, TemplateParams model)
throws IOException, TemplateException {
log.infof("Adding '%s'", dest);
final Template template = cfg.getTemplate(templateUri);
@@ -746,6 +1070,12 @@ public class CreateExtensionMojo extends AbstractMojo {
this.itestParentPath = Paths.get(itestParentPath);
}
+ private void debug(String format, Object... args) {
+ if (getLog().isDebugEnabled()) {
+ getLog().debug(String.format(format, args));
+ }
+ }
+
public static class TemplateParams {
String grandParentRelativePath;
String grandParentVersion;
diff --git a/devtools/maven/src/main/java/io/quarkus/maven/CreateUtils.java b/devtools/maven/src/main/java/io/quarkus/maven/CreateUtils.java
index 2c4ffe167..e7bf3840e 100644
--- a/devtools/maven/src/main/java/io/quarkus/maven/CreateUtils.java
+++ b/devtools/maven/src/main/java/io/quarkus/maven/CreateUtils.java
@@ -94,7 +94,7 @@ public final class CreateUtils {
try {
final Path classOrigin = MojoUtils.getClassOrigin(cls);
if (Files.isDirectory(classOrigin)) {
- return resolvePluginInfo(classOrigin);
+ return resolvePluginInfo(classOrigin.resolve("META-INF").resolve("maven").resolve("plugin.xml"));
}
try (FileSystem fs = ZipUtils.newFileSystem(classOrigin)) {
return resolvePluginInfo(fs.getPath("META-INF", "maven", "plugin.xml"));
diff --git a/devtools/maven/src/main/resources/create-extension-templates/deployment-pom.xml b/devtools/maven/src/main/resources/create-extension-templates/deployment-pom.xml
index 13933a831..9ef285fd3 100644
--- a/devtools/maven/src/main/resources/create-extension-templates/deployment-pom.xml
+++ b/devtools/maven/src/main/resources/create-extension-templates/deployment-pom.xml
@@ -18,8 +18,6 @@
io.quarkus
quarkus-core-deployment
-[#if !assumeManaged ] [=quarkusVersion]
-[/#if]
[=groupId]
diff --git a/devtools/maven/src/main/resources/create-extension-templates/parent-pom.xml b/devtools/maven/src/main/resources/create-extension-templates/parent-pom.xml
index cdd46a5a0..1255350a5 100644
--- a/devtools/maven/src/main/resources/create-extension-templates/parent-pom.xml
+++ b/devtools/maven/src/main/resources/create-extension-templates/parent-pom.xml
@@ -11,10 +11,10 @@
[/#if]
-[#if groupId?? && groupId != grandParentGroupId ] [=groupId]
+[#if grandParentGroupId?? ][#if groupId != grandParentGroupId ] [=groupId][/#if][#else ] [=groupId]
[/#if]
[=artifactId]-parent
-[#if groupId?? && groupId != grandParentGroupId && version?? && version != grandParentVersion ] [=version]
+[#if groupId?? && (!grandParentGroupId?? || groupId != grandParentGroupId) && version?? && (!grandParentVersion?? || version != grandParentVersion) ] [=version]
[/#if]
[#if nameBase?? ] [=namePrefix][=nameBase][=nameSegmentDelimiter]Parent
[/#if]
diff --git a/devtools/maven/src/main/resources/create-extension-templates/runtime-pom.xml b/devtools/maven/src/main/resources/create-extension-templates/runtime-pom.xml
index cdfe44c85..bee5fd63f 100644
--- a/devtools/maven/src/main/resources/create-extension-templates/runtime-pom.xml
+++ b/devtools/maven/src/main/resources/create-extension-templates/runtime-pom.xml
@@ -13,9 +13,13 @@
[=artifactId]
[#if nameBase?? ] [=namePrefix][=nameBase][=nameSegmentDelimiter]Runtime
[/#if]
-[#if additionalRuntimeDependencies?size > 0 ]
+
+ io.quarkus
+ quarkus-core
+
+[#if additionalRuntimeDependencies?size > 0 ]
[#list additionalRuntimeDependencies as dep]
[=dep.groupId]
@@ -30,8 +34,8 @@
[/#if]
[/#list]
-
[/#if]
+
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/file/BuildFile.java b/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/file/BuildFile.java
index 5169fea4f..85934c147 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/file/BuildFile.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/file/BuildFile.java
@@ -63,7 +63,7 @@ public abstract class BuildFile implements Closeable {
protected abstract boolean hasDependency(Extension extension) throws IOException;
public boolean addExtensionAsGAV(String query) throws IOException {
- Dependency parsed = MojoUtils.parse(query.trim().toLowerCase());
+ Dependency parsed = MojoUtils.parse(query.trim());
boolean alreadyThere = getDependencies().stream()
.anyMatch(d -> d.getManagementKey().equalsIgnoreCase(parsed.getManagementKey()));
if (!alreadyThere) {
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/maven/utilities/MojoUtils.java b/independent-projects/tools/common/src/main/java/io/quarkus/maven/utilities/MojoUtils.java
index a7c37e39a..ff9445c4e 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/maven/utilities/MojoUtils.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/maven/utilities/MojoUtils.java
@@ -76,13 +76,13 @@ public class MojoUtils {
Dependency res = new Dependency();
String[] segments = dependency.split(":");
if (segments.length >= 2) {
- res.setGroupId(segments[0]);
- res.setArtifactId(segments[1]);
+ res.setGroupId(segments[0].toLowerCase());
+ res.setArtifactId(segments[1].toLowerCase());
if (segments.length >= 3 && !segments[2].isEmpty()) {
res.setVersion(segments[2]);
}
if (segments.length >= 4) {
- res.setClassifier(segments[3]);
+ res.setClassifier(segments[3].toLowerCase());
}
return res;
} else {
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/maven/utilities/PomTransformer.java b/independent-projects/tools/common/src/main/java/io/quarkus/maven/utilities/PomTransformer.java
index 245bb1c51..c105f8f6e 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/maven/utilities/PomTransformer.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/maven/utilities/PomTransformer.java
@@ -26,6 +26,7 @@ import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathExpressionException;
import javax.xml.xpath.XPathFactory;
+import org.apache.maven.model.Plugin;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Node;
@@ -304,6 +305,59 @@ public class PomTransformer {
};
}
+ public static Transformation addProperty(String name, String value) {
+ return (Document document, TransformationContext context) -> {
+ try {
+ Node props = (Node) context.getXPath().evaluate(anyNs("project", "properties"), document,
+ XPathConstants.NODE);
+ if (props == null) {
+ final Node propsIndent = context.indent(1);
+ props = document.createElement("properties");
+ props.appendChild(context.indent(1));
+
+ final Node project = (Node) context.getXPath().evaluate(anyNs("project"), document,
+ XPathConstants.NODE);
+ if (project == null) {
+ throw new IllegalStateException(
+ String.format("No in file [%s]", context.getPomXmlPath()));
+ }
+ /* ideally before modules */
+ Node refNode = (Node) context.getXPath().evaluate(anyNs("project", "modules"),
+ document, XPathConstants.NODE);
+ Node ws;
+ if (refNode != null) {
+ ws = refNode.getPreviousSibling();
+ if (ws == null || ws.getNodeType() != Node.TEXT_NODE) {
+ project.insertBefore(ws = context.indent(1), refNode);
+ }
+ } else {
+ ws = project.getLastChild();
+ if (ws == null || ws.getNodeType() != Node.TEXT_NODE) {
+ project.appendChild(ws = context.indent(0));
+ }
+ }
+ project.insertBefore(propsIndent, ws);
+ project.insertBefore(props, ws);
+ }
+
+ final Node propNode = document.createElement(name);
+ propNode.appendChild(document.createTextNode(value));
+
+ final NodeList modulesChildren = props.getChildNodes();
+ final int len = modulesChildren.getLength();
+ Node ws;
+ if (len == 0 || (ws = modulesChildren.item(len - 1)).getNodeType() != Node.TEXT_NODE) {
+ ws = context.indent(1);
+ props.appendChild(ws);
+ }
+ props.insertBefore(context.indent(2), ws);
+ props.insertBefore(propNode, ws);
+ } catch (XPathExpressionException | DOMException e) {
+ throw new RuntimeException(e);
+ }
+ };
+ }
+
public static Transformation addDependencyManagementIfNeeded() {
return (Document document, TransformationContext context) -> {
try {
@@ -358,6 +412,55 @@ public class PomTransformer {
};
}
+ public static Transformation addPluginManagementIfNeeded() {
+ return (Document document, TransformationContext context) -> {
+ try {
+ Node plugins = (Node) context.getXPath().evaluate(
+ anyNs("project", "build", "pluginManagement", "plugins"), document, XPathConstants.NODE);
+ if (plugins == null) {
+ Node build = (Node) context.getXPath()
+ .evaluate(anyNs("project", "build"), document, XPathConstants.NODE);
+ if (build == null) {
+ Node project = (Node) context.getXPath().evaluate(anyNs("project"), document,
+ XPathConstants.NODE);
+ if (project == null) {
+ throw new IllegalStateException(
+ String.format("//project not found in [%s]", context.getPomXmlPath()));
+ }
+ build = document.createElement("build");
+ Node ws = project.getLastChild();
+ if (ws == null || ws.getNodeType() != Node.TEXT_NODE) {
+ project.appendChild(ws = context.indent(0));
+ }
+ project.insertBefore(build, ws);
+ project.insertBefore(context.indent(1), build);
+ }
+ Node pluginManagement = (Node) context.getXPath()
+ .evaluate(anyNs("project", "build", "pluginManagement"), document, XPathConstants.NODE);
+ if (pluginManagement == null) {
+ pluginManagement = document.createElement("pluginManagement");
+ Node ws = build.getLastChild();
+ if (ws == null || ws.getNodeType() != Node.TEXT_NODE) {
+ build.appendChild(ws = context.indent(1));
+ }
+ build.insertBefore(pluginManagement, ws);
+ build.insertBefore(context.indent(2), pluginManagement);
+ }
+ plugins = document.createElement("plugins");
+ plugins.appendChild(context.indent(3));
+ Node ws = pluginManagement.getLastChild();
+ if (ws == null || ws.getNodeType() != Node.TEXT_NODE) {
+ pluginManagement.appendChild(ws = context.indent(2));
+ }
+ pluginManagement.insertBefore(plugins, ws);
+ pluginManagement.insertBefore(context.indent(3), plugins);
+ }
+ } catch (XPathExpressionException | DOMException e) {
+ throw new RuntimeException(e);
+ }
+ };
+ }
+
public static Transformation addManagedDependency(String groupId, String artifactId, String version) {
return addManagedDependency(new Gavtcs(groupId, artifactId, version, null, null, null));
}
@@ -406,6 +509,38 @@ public class PomTransformer {
};
}
+ public static Transformation addManagedPlugin(Plugin plugin) {
+ return (Document document, TransformationContext context) -> {
+ try {
+ addPluginManagementIfNeeded().perform(document, context);
+ Node managedPlugins = (Node) context.getXPath().evaluate(
+ anyNs("project", "build", "pluginManagement", "plugins"), document, XPathConstants.NODE);
+ final NodeList pluginsChildren = managedPlugins.getChildNodes();
+ Node ws = null;
+ if (pluginsChildren.getLength() > 0) {
+ ws = pluginsChildren.item(pluginsChildren.getLength() - 1);
+ }
+ if (ws == null || ws.getNodeType() != Node.TEXT_NODE) {
+ ws = context.indent(4);
+ managedPlugins.appendChild(ws);
+ }
+
+ managedPlugins.insertBefore(context.indent(4), ws);
+ final Node dep = document.createElement("plugin");
+ dep.appendChild(context.indent(5));
+ dep.appendChild(context.textElement("groupId", plugin.getGroupId()));
+ dep.appendChild(context.indent(5));
+ dep.appendChild(context.textElement("artifactId", plugin.getArtifactId()));
+ dep.appendChild(context.indent(5));
+ dep.appendChild(context.textElement("version", plugin.getVersion()));
+ dep.appendChild(context.indent(4));
+ managedPlugins.insertBefore(dep, ws);
+ } catch (XPathExpressionException | DOMException e) {
+ throw new RuntimeException(e);
+ }
+ };
+ }
+
/**
* Perform this {@link Transformation} on the given {@code document}
*
diff --git a/integration-tests/maven/src/test/java/io/quarkus/maven/CreateExtensionMojoTest.java b/integration-tests/maven/src/test/java/io/quarkus/maven/CreateExtensionMojoTest.java
index ced952f9e..bb06b65c9 100644
--- a/integration-tests/maven/src/test/java/io/quarkus/maven/CreateExtensionMojoTest.java
+++ b/integration-tests/maven/src/test/java/io/quarkus/maven/CreateExtensionMojoTest.java
@@ -3,6 +3,7 @@ package io.quarkus.maven;
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.fail;
+import java.io.File;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
@@ -10,49 +11,108 @@ import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.LinkedHashSet;
+import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.stream.Collectors;
+import org.apache.maven.model.Build;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.PluginManagement;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
+import org.apache.maven.project.MavenProject;
import org.junit.jupiter.api.Test;
+import io.quarkus.maven.utilities.MojoUtils;
+
public class CreateExtensionMojoTest {
- static CreateExtensionMojo createMojo(String testProjectName) throws IllegalArgumentException,
- IllegalAccessException, IOException, NoSuchFieldException, SecurityException {
- final Path srcDir = Paths.get("src/test/resources/projects/" + testProjectName);
- /*
- * We want to run on the same project multiple times with different args so let's create a copy with a random
- * suffix
- */
- final Path copyDir = getCopyDir(testProjectName);
- Files.walk(srcDir).forEach(source -> {
- try {
- final Path dest = copyDir.resolve(srcDir.relativize(source));
- Files.copy(source, dest);
- } catch (IOException e) {
- throw new RuntimeException(e);
- }
- });
-
+ private static CreateExtensionMojo initMojo(final Path projectDir) throws IOException {
final CreateExtensionMojo mojo = new CreateExtensionMojo();
- mojo.basedir = copyDir;
+ mojo.project = new MavenProject();
+ mojo.basedir = projectDir.toFile();
+
+ final File pom = new File(projectDir.toFile(), "pom.xml");
+ if (pom.exists()) {
+ mojo.project.setFile(pom);
+ final Model rawModel = MojoUtils.readPom(pom);
+ // the project would have an interpolated model at runtime, which we can't fully init here
+ // here are just some key parts
+ if (rawModel.getDependencyManagement() != null) {
+ List deps = rawModel.getDependencyManagement().getDependencies();
+ if (deps != null && !deps.isEmpty()) {
+ Dependency deploymentBom = null;
+ for (Dependency dep : deps) {
+ if (dep.getArtifactId().equals("quarkus-bom-deployment") && dep.getGroupId().equals("io.quarkus")) {
+ deploymentBom = dep;
+ }
+ }
+ if (deploymentBom != null) {
+ String version = deploymentBom.getVersion();
+ if (CreateExtensionMojo.QUARKUS_VERSION_POM_EXPR.equals(version)) {
+ version = rawModel.getProperties().getProperty(version.substring(2, version.length() - 1));
+ if (version == null) {
+ throw new IllegalStateException(
+ "Failed to resolve " + deploymentBom.getVersion() + " from " + pom);
+ }
+ }
+ Dependency dep = new Dependency();
+ dep.setGroupId("io.quarkus");
+ dep.setArtifactId("quarkus-core-deployment");
+ dep.setType("jar");
+ dep.setVersion(version);
+ deps.add(dep);
+ }
+ }
+ }
+ mojo.project.setModel(rawModel);
+ }
+
+ Build build = mojo.project.getBuild();
+ if (build.getPluginManagement() == null) {
+ build.setPluginManagement(new PluginManagement());
+ }
+
mojo.encoding = CreateExtensionMojo.DEFAULT_ENCODING;
mojo.templatesUriBase = CreateExtensionMojo.DEFAULT_TEMPLATES_URI_BASE;
mojo.quarkusVersion = CreateExtensionMojo.DEFAULT_QUARKUS_VERSION;
mojo.bomEntryVersion = CreateExtensionMojo.DEFAULT_BOM_ENTRY_VERSION;
mojo.assumeManaged = true;
mojo.nameSegmentDelimiter = CreateExtensionMojo.DEFAULT_NAME_SEGMENT_DELIMITER;
+ mojo.platformGroupId = CreateExtensionMojo.PLATFORM_DEFAULT_GROUP_ID;
+ mojo.platformArtifactId = CreateExtensionMojo.PLATFORM_DEFAULT_ARTIFACT_ID;
+ mojo.compilerPluginVersion = CreateExtensionMojo.COMPILER_PLUGIN_DEFAULT_VERSION;
return mojo;
}
- private static Path getCopyDir(String testProjectName) {
+ private static Path createProjectFromTemplate(String testProjectName) throws IOException {
+ final Path srcDir = Paths.get("src/test/resources/projects/" + testProjectName);
+ /*
+ * We want to run on the same project multiple times with different args so let's create a copy with a random
+ * suffix
+ */
+ final Path copyDir = newProjectDir(testProjectName);
+ Files.walk(srcDir).forEach(source -> {
+ final Path dest = copyDir.resolve(srcDir.relativize(source));
+ try {
+ Files.copy(source, dest);
+ } catch (IOException e) {
+ if (!Files.isDirectory(dest)) {
+ throw new RuntimeException(e);
+ }
+ }
+ });
+ return copyDir;
+ }
+
+ private static Path newProjectDir(String testProjectName) throws IOException {
int count = 0;
while (count < 100) {
Path path = Paths.get("target/test-classes/projects/" + testProjectName + "-" + UUID.randomUUID());
if (!Files.exists(path)) {
+ Files.createDirectories(path);
return path;
}
count++;
@@ -65,19 +125,19 @@ public class CreateExtensionMojoTest {
@Test
void createExtensionUnderExistingPomMinimal() throws MojoExecutionException, MojoFailureException,
IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, IOException {
- final CreateExtensionMojo mojo = createMojo("create-extension-pom");
+ final CreateExtensionMojo mojo = initMojo(createProjectFromTemplate("create-extension-pom"));
mojo.artifactId = "my-project-(minimal-extension)";
mojo.assumeManaged = false;
mojo.execute();
assertTreesMatch(Paths.get("src/test/resources/expected/create-extension-pom-minimal"),
- mojo.basedir);
+ mojo.basedir.toPath());
}
@Test
void createExtensionUnderExistingPomWithAdditionalRuntimeDependencies() throws MojoExecutionException, MojoFailureException,
IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, IOException {
- final CreateExtensionMojo mojo = createMojo("create-extension-pom");
+ final CreateExtensionMojo mojo = initMojo(createProjectFromTemplate("create-extension-pom"));
mojo.artifactId = "my-project-(add-to-bom)";
mojo.assumeManaged = false;
mojo.runtimeBomPath = Paths.get("boms/runtime/pom.xml");
@@ -86,38 +146,50 @@ public class CreateExtensionMojoTest {
mojo.execute();
assertTreesMatch(Paths.get("src/test/resources/expected/create-extension-pom-add-to-bom"),
- mojo.basedir);
+ mojo.basedir.toPath());
}
@Test
void createExtensionUnderExistingPomWithItest() throws MojoExecutionException, MojoFailureException,
IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, IOException {
- final CreateExtensionMojo mojo = createMojo("create-extension-pom");
+ final CreateExtensionMojo mojo = initMojo(createProjectFromTemplate("create-extension-pom"));
mojo.artifactId = "my-project-(itest)";
mojo.assumeManaged = false;
mojo.itestParentPath = Paths.get("integration-tests/pom.xml");
mojo.execute();
assertTreesMatch(Paths.get("src/test/resources/expected/create-extension-pom-itest"),
- mojo.basedir);
+ mojo.basedir.toPath());
}
@Test
void createExtensionUnderExistingPomCustomGrandParent() throws MojoExecutionException, MojoFailureException,
IllegalArgumentException, IllegalAccessException, NoSuchFieldException, SecurityException, IOException {
- final CreateExtensionMojo mojo = createMojo("create-extension-pom");
+ final CreateExtensionMojo mojo = initMojo(createProjectFromTemplate("create-extension-pom"));
mojo.artifactId = "myproject-(with-grand-parent)";
- mojo.grandParentArtifactId = "build-bom";
- mojo.grandParentRelativePath = "../../build-bom/pom.xml";
+ mojo.grandParentArtifactId = "grand-parent";
+ mojo.grandParentRelativePath = "../pom.xml";
mojo.templatesUriBase = "file:templates";
mojo.runtimeBomPath = Paths.get("boms/runtime/pom.xml");
mojo.deploymentBomPath = Paths.get("boms/deployment/pom.xml");
mojo.execute();
-
assertTreesMatch(
Paths.get("src/test/resources/expected/create-extension-pom-with-grand-parent"),
- mojo.basedir);
+ mojo.basedir.toPath());
+ }
+
+ @Test
+ void createNewExtensionProject() throws Exception {
+ final CreateExtensionMojo mojo = initMojo(newProjectDir("new-ext-project"));
+ mojo.groupId = "org.acme";
+ mojo.artifactId = "my-ext";
+ mojo.version = "1.0-SNAPSHOT";
+ mojo.assumeManaged = null;
+ mojo.execute();
+ assertTreesMatch(
+ Paths.get("src/test/resources/expected/new-extension-project"),
+ mojo.basedir.toPath());
}
static void assertTreesMatch(Path expected, Path actual) throws IOException {
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/add-to-bom/deployment/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/add-to-bom/deployment/pom.xml
index 07b184bee..9635c6798 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/add-to-bom/deployment/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/add-to-bom/deployment/pom.xml
@@ -17,7 +17,6 @@
io.quarkus
quarkus-core-deployment
- ${quarkus.version}
org.acme
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/add-to-bom/runtime/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/add-to-bom/runtime/pom.xml
index 8e5c26dc7..5311c743f 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/add-to-bom/runtime/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/add-to-bom/runtime/pom.xml
@@ -14,6 +14,10 @@
Add To Bom - Runtime
+
+ io.quarkus
+ quarkus-core
+
org.example
example-1
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/pom.xml
index b8c90525b..8e23f9c65 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-add-to-bom/pom.xml
@@ -9,10 +9,34 @@
0.19.0
3.3.0
+ 3.8.1
integration-tests
add-to-bom
+
+
+
+
+ io.quarkus
+ quarkus-bom-deployment
+ ${quarkus.version}
+ pom
+ import
+
+
+
+
+
+
+
+
+ maven-compiler-plugin
+ ${compiler-plugin.version}
+
+
+
+
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/itest/deployment/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/itest/deployment/pom.xml
index 5c24622b2..f0cc10e74 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/itest/deployment/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/itest/deployment/pom.xml
@@ -17,7 +17,6 @@
io.quarkus
quarkus-core-deployment
- ${quarkus.version}
org.acme
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/itest/runtime/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/itest/runtime/pom.xml
index 1b157ce50..2ac672f68 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/itest/runtime/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/itest/runtime/pom.xml
@@ -13,6 +13,13 @@
my-project-itest
Itest - Runtime
+
+
+ io.quarkus
+ quarkus-core
+
+
+
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/pom.xml
index 696158f85..70a6610f4 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-itest/pom.xml
@@ -9,10 +9,34 @@
0.19.0
3.3.0
+ 3.8.1
integration-tests
itest
+
+
+
+
+ io.quarkus
+ quarkus-bom-deployment
+ ${quarkus.version}
+ pom
+ import
+
+
+
+
+
+
+
+
+ maven-compiler-plugin
+ ${compiler-plugin.version}
+
+
+
+
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/minimal-extension/deployment/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/minimal-extension/deployment/pom.xml
index cccab7d27..7eac593db 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/minimal-extension/deployment/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/minimal-extension/deployment/pom.xml
@@ -17,7 +17,6 @@
io.quarkus
quarkus-core-deployment
- ${quarkus.version}
org.acme
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/minimal-extension/runtime/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/minimal-extension/runtime/pom.xml
index 487e07fb6..0d1169881 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/minimal-extension/runtime/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/minimal-extension/runtime/pom.xml
@@ -13,6 +13,13 @@
my-project-minimal-extension
Minimal Extension - Runtime
+
+
+ io.quarkus
+ quarkus-core
+
+
+
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/pom.xml
index bbee27ef6..bea4052c9 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-minimal/pom.xml
@@ -9,10 +9,34 @@
0.19.0
3.3.0
+ 3.8.1
integration-tests
minimal-extension
+
+
+
+
+ io.quarkus
+ quarkus-bom-deployment
+ ${quarkus.version}
+ pom
+ import
+
+
+
+
+
+
+
+
+ maven-compiler-plugin
+ ${compiler-plugin.version}
+
+
+
+
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/pom.xml
index 6e6238e1a..a058eaa67 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/pom.xml
@@ -9,10 +9,34 @@
0.19.0
3.3.0
+ 3.8.1
integration-tests
with-grand-parent
+
+
+
+
+ io.quarkus
+ quarkus-bom-deployment
+ ${quarkus.version}
+ pom
+ import
+
+
+
+
+
+
+
+
+ maven-compiler-plugin
+ ${compiler-plugin.version}
+
+
+
+
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/with-grand-parent/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/with-grand-parent/pom.xml
index daa32c114..b5041c44c 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/with-grand-parent/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/with-grand-parent/pom.xml
@@ -5,9 +5,9 @@
4.0.0
org.acme
- build-bom
+ grand-parent
0.1-SNAPSHOT
- ../../build-bom/pom.xml
+ ../pom.xml
myproject-with-grand-parent-parent
diff --git a/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/with-grand-parent/runtime/pom.xml b/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/with-grand-parent/runtime/pom.xml
index 35b4d7f69..2e6adfc80 100644
--- a/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/with-grand-parent/runtime/pom.xml
+++ b/integration-tests/maven/src/test/resources/expected/create-extension-pom-with-grand-parent/with-grand-parent/runtime/pom.xml
@@ -13,6 +13,13 @@
myproject-with-grand-parent
With Grand Parent - Runtime
+
+
+ io.quarkus
+ quarkus-core
+
+
+
diff --git a/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/deployment/pom.xml b/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/deployment/pom.xml
new file mode 100644
index 000000000..4e5b0a537
--- /dev/null
+++ b/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/deployment/pom.xml
@@ -0,0 +1,46 @@
+
+
+ 4.0.0
+
+ org.acme
+ my-ext-parent
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ my-ext-deployment
+ My Ext - Deployment
+
+
+
+ io.quarkus
+ quarkus-core-deployment
+
+
+ org.acme
+ my-ext
+ ${project.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+ io.quarkus
+ quarkus-extension-processor
+ ${quarkus.version}
+
+
+
+
+
+
+
+
diff --git a/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/deployment/src/main/java/org/acme/my/ext/deployment/MyExtProcessor.java b/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/deployment/src/main/java/org/acme/my/ext/deployment/MyExtProcessor.java
new file mode 100644
index 000000000..0b9fa976a
--- /dev/null
+++ b/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/deployment/src/main/java/org/acme/my/ext/deployment/MyExtProcessor.java
@@ -0,0 +1,15 @@
+package org.acme.my.ext.deployment;
+
+import io.quarkus.deployment.annotations.BuildStep;
+import io.quarkus.deployment.builditem.FeatureBuildItem;
+
+class MyExtProcessor {
+
+ private static final String FEATURE = "my-ext";
+
+ @BuildStep
+ FeatureBuildItem feature() {
+ return new FeatureBuildItem(FEATURE);
+ }
+
+}
diff --git a/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/pom.xml b/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/pom.xml
new file mode 100644
index 000000000..14e70f0c6
--- /dev/null
+++ b/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/pom.xml
@@ -0,0 +1,43 @@
+
+
+ 4.0.0
+
+ org.acme
+ my-ext-parent
+ 1.0-SNAPSHOT
+ My Ext - Parent
+
+ pom
+
+ 999-SNAPSHOT
+ 3.8.1
+
+
+ deployment
+ runtime
+
+
+
+
+ io.quarkus
+ quarkus-bom-deployment
+ ${quarkus.version}
+ pom
+ import
+
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+ ${compiler-plugin.version}
+
+
+
+
+
diff --git a/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/runtime/pom.xml b/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/runtime/pom.xml
new file mode 100644
index 000000000..6c51dbff6
--- /dev/null
+++ b/integration-tests/maven/src/test/resources/expected/new-extension-project/my-ext/runtime/pom.xml
@@ -0,0 +1,57 @@
+
+
+ 4.0.0
+
+ org.acme
+ my-ext-parent
+ 1.0-SNAPSHOT
+ ../pom.xml
+
+
+ my-ext
+ My Ext - Runtime
+
+
+
+ io.quarkus
+ quarkus-core
+
+
+
+
+
+
+ io.quarkus
+ quarkus-bootstrap-maven-plugin
+ ${quarkus.version}
+
+
+
+ extension-descriptor
+
+ compile
+
+ ${project.groupId}:${project.artifactId}-deployment:${project.version}
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-compiler-plugin
+
+
+
+ io.quarkus
+ quarkus-extension-processor
+ ${quarkus.version}
+
+
+
+
+
+
+
diff --git a/integration-tests/maven/src/test/resources/projects/create-extension-pom/pom.xml b/integration-tests/maven/src/test/resources/projects/create-extension-pom/pom.xml
index efbce18ef..dfaaaed1d 100644
--- a/integration-tests/maven/src/test/resources/projects/create-extension-pom/pom.xml
+++ b/integration-tests/maven/src/test/resources/projects/create-extension-pom/pom.xml
@@ -9,9 +9,33 @@
0.19.0
3.3.0
+ 3.8.1
integration-tests
+
+
+
+
+ io.quarkus
+ quarkus-bom-deployment
+ ${quarkus.version}
+ pom
+ import
+
+
+
+
+
+
+
+
+ maven-compiler-plugin
+ ${compiler-plugin.version}
+
+
+
+