diff --git a/maven/pom.xml b/maven/pom.xml
index d8d7c723eb9fc..962fe0f502789 100644
--- a/maven/pom.xml
+++ b/maven/pom.xml
@@ -27,6 +27,11 @@
shamrock-maven-plugin
maven-plugin
+
+
+ ${project.version}
+
+
@@ -37,9 +42,7 @@
org.apache.maven
maven-core
-
-
-
+
org.apache.maven.plugin-tools
maven-plugin-annotations
@@ -65,7 +68,141 @@
org.jboss.shamrock
shamrock-development-mode
+
+
+
+ jline
+ jline
+ 2.14.6
+
+
+
+
+ org.freemarker
+ freemarker
+ 2.3.28
+
+
+
+
+ com.fasterxml.jackson.core
+ jackson-databind
+ 2.9.7
+
+
+
+
+ junit
+ junit
+ test
+
+
+ org.assertj
+ assertj-core
+ 3.11.1
+ test
+
+
+ org.apache.maven.shared
+ maven-invoker
+ 3.0.1
+ test
+
+
+
+
+ src/main/resources
+ true
+
+ *.ftl
+
+
+
+
+
+ org.codehaus.plexus
+ plexus-component-metadata
+ 1.7.1
+
+ ${basedir}/target/filtered-resources/META-INF/plexus
+
+
+
+
+ generate-metadata
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-plugin-plugin
+ 3.5.2
+
+ shamrock
+ true
+
+
+
+ help-goal
+
+ helpmojo
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-invoker-plugin
+ 3.1.0
+
+ ${project.build.directory}/it
+ true
+ src/it/settings.xml
+ ${project.build.directory}/local-repo
+ verify
+ true
+ ${skipTests}
+ true
+ invoker.properties
+
+
+
+ integration-tests
+
+ install
+ run
+ verify
+
+
+
+
+
+
+ org.apache.maven.plugins
+ maven-failsafe-plugin
+
+
+
+ integration-test
+ verify
+
+
+
+
+
+
+ ${maven.home}
+ ${settings.localRepository}
+
+
+
+
+
+
\ No newline at end of file
diff --git a/maven/src/it/settings.xml b/maven/src/it/settings.xml
new file mode 100644
index 0000000000000..2d90068bb65a7
--- /dev/null
+++ b/maven/src/it/settings.xml
@@ -0,0 +1,35 @@
+
+
+
+
+ it-repo
+
+ true
+
+
+
+ local.central
+ @localRepositoryUrl@
+
+ true
+
+
+ true
+
+
+
+
+
+ local.central
+ @localRepositoryUrl@
+
+ true
+
+
+ true
+
+
+
+
+
+
diff --git a/maven/src/it/setup-on-existing-pom-it/invoker.properties b/maven/src/it/setup-on-existing-pom-it/invoker.properties
new file mode 100644
index 0000000000000..7eadca9f7e5ee
--- /dev/null
+++ b/maven/src/it/setup-on-existing-pom-it/invoker.properties
@@ -0,0 +1 @@
+invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:create
diff --git a/maven/src/it/setup-on-existing-pom-it/pom.xml b/maven/src/it/setup-on-existing-pom-it/pom.xml
new file mode 100644
index 0000000000000..cf1865f996e43
--- /dev/null
+++ b/maven/src/it/setup-on-existing-pom-it/pom.xml
@@ -0,0 +1,31 @@
+
+
+ 4.0.0
+ org.acme
+ shamrock-setup-demo
+ 0.1-SNAPSHOT
+ jar
+
+
+
+ maven-compiler-plugin
+
+
+ 1.8
+
+
+
+
+
+ UTF-8
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
diff --git a/maven/src/it/setup-on-existing-pom-it/verify.groovy b/maven/src/it/setup-on-existing-pom-it/verify.groovy
new file mode 100644
index 0000000000000..4dfddb1e06564
--- /dev/null
+++ b/maven/src/it/setup-on-existing-pom-it/verify.groovy
@@ -0,0 +1,6 @@
+import org.jboss.shamrock.maven.it.SetupVerifier
+
+String base = basedir
+File pomFile = new File(base, "pom.xml")
+
+SetupVerifier.verifySetup(pomFile)
diff --git a/maven/src/it/setup-on-min-pom-it/invoker.properties b/maven/src/it/setup-on-min-pom-it/invoker.properties
new file mode 100644
index 0000000000000..7eadca9f7e5ee
--- /dev/null
+++ b/maven/src/it/setup-on-min-pom-it/invoker.properties
@@ -0,0 +1 @@
+invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:create
diff --git a/maven/src/it/setup-on-min-pom-it/pom.xml b/maven/src/it/setup-on-min-pom-it/pom.xml
new file mode 100644
index 0000000000000..c1812e524ac72
--- /dev/null
+++ b/maven/src/it/setup-on-min-pom-it/pom.xml
@@ -0,0 +1,25 @@
+
+
+
+
+ 4.0.0
+ org.acme
+ shamrock-setup-demo
+ 0.1-SNAPSHOT
+
diff --git a/maven/src/it/setup-on-min-pom-it/verify.groovy b/maven/src/it/setup-on-min-pom-it/verify.groovy
new file mode 100644
index 0000000000000..4dfddb1e06564
--- /dev/null
+++ b/maven/src/it/setup-on-min-pom-it/verify.groovy
@@ -0,0 +1,6 @@
+import org.jboss.shamrock.maven.it.SetupVerifier
+
+String base = basedir
+File pomFile = new File(base, "pom.xml")
+
+SetupVerifier.verifySetup(pomFile)
diff --git a/maven/src/it/setup-with-custom-shamrock-version-it/invoker.properties b/maven/src/it/setup-with-custom-shamrock-version-it/invoker.properties
new file mode 100644
index 0000000000000..3ef60fed3b388
--- /dev/null
+++ b/maven/src/it/setup-with-custom-shamrock-version-it/invoker.properties
@@ -0,0 +1 @@
+invoker.goals=${project.groupId}:${project.artifactId}:${project.version}:create -DshamrockVersion=0.0.0
diff --git a/maven/src/it/setup-with-custom-shamrock-version-it/pom.xml b/maven/src/it/setup-with-custom-shamrock-version-it/pom.xml
new file mode 100644
index 0000000000000..9be7221ebf23c
--- /dev/null
+++ b/maven/src/it/setup-with-custom-shamrock-version-it/pom.xml
@@ -0,0 +1,30 @@
+
+
+ 4.0.0
+ org.acme
+ shamrock-setup-demo
+ 0.1-SNAPSHOT
+
+
+
+ maven-compiler-plugin
+
+
+ 1.8
+
+
+
+
+
+ UTF-8
+
+
+
+ junit
+ junit
+ 4.12
+ test
+
+
+
diff --git a/maven/src/it/setup-with-custom-shamrock-version-it/verify.groovy b/maven/src/it/setup-with-custom-shamrock-version-it/verify.groovy
new file mode 100644
index 0000000000000..944cff7d9180d
--- /dev/null
+++ b/maven/src/it/setup-with-custom-shamrock-version-it/verify.groovy
@@ -0,0 +1,6 @@
+import org.jboss.shamrock.maven.it.SetupVerifier
+
+String base = basedir
+File pomFile = new File(base, "pom.xml")
+
+SetupVerifier.verifySetupWithVersion(pomFile)
diff --git a/maven/src/main/java/org/jboss/shamrock/maven/AddExtensionMojo.java b/maven/src/main/java/org/jboss/shamrock/maven/AddExtensionMojo.java
new file mode 100644
index 0000000000000..9cfdbe2c163a9
--- /dev/null
+++ b/maven/src/main/java/org/jboss/shamrock/maven/AddExtensionMojo.java
@@ -0,0 +1,50 @@
+package org.jboss.shamrock.maven;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.apache.maven.plugins.annotations.Parameter;
+import org.apache.maven.project.MavenProject;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.List;
+
+import static org.jboss.shamrock.maven.components.dependencies.Extensions.addExtensions;
+
+@Mojo(name = "add-extension", requiresProject = true)
+public class AddExtensionMojo extends AbstractMojo {
+
+ /**
+ * The Maven project which will define and configure the shamrock-maven-plugin
+ */
+ @Parameter(defaultValue = "${project}")
+ protected MavenProject project;
+
+ @Parameter(property = "extensions")
+ private List extensions;
+
+
+ @Override
+ public void execute() throws MojoExecutionException {
+ Model model = project.getOriginalModel().clone();
+ if (addExtensions(model, extensions, getLog())) {
+ File pomFile = project.getFile();
+ save(pomFile, model);
+ }
+ }
+
+ private void save(File pomFile, Model model) throws MojoExecutionException {
+ MavenXpp3Writer xpp3Writer = new MavenXpp3Writer();
+ try (FileWriter pomFileWriter = new FileWriter(pomFile)) {
+ xpp3Writer.write(pomFileWriter, model);
+ pomFileWriter.flush();
+ } catch (IOException e) {
+ throw new MojoExecutionException("Unable to write the pom.xml file", e);
+ }
+ }
+
+}
diff --git a/maven/src/main/java/org/jboss/shamrock/maven/CreateProjectMojo.java b/maven/src/main/java/org/jboss/shamrock/maven/CreateProjectMojo.java
new file mode 100644
index 0000000000000..4f70cf45ac3fa
--- /dev/null
+++ b/maven/src/main/java/org/jboss/shamrock/maven/CreateProjectMojo.java
@@ -0,0 +1,311 @@
+/*
+ *
+ * Copyright (c) 2016-2018 Red Hat, Inc.
+ *
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.jboss.shamrock.maven;
+
+import org.apache.maven.model.*;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.model.io.xpp3.MavenXpp3Writer;
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugin.MojoExecutionException;
+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.jboss.shamrock.maven.components.Prompter;
+import org.jboss.shamrock.maven.components.SetupTemplates;
+import org.jboss.shamrock.maven.utilities.MojoUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.util.*;
+
+import static org.jboss.shamrock.maven.components.dependencies.Extensions.addExtensions;
+import static org.jboss.shamrock.maven.utilities.MojoUtils.configuration;
+import static org.jboss.shamrock.maven.utilities.MojoUtils.plugin;
+
+/**
+ * This goal helps in setting up Shamrock Maven project with shamrock-maven-plugin, with sensible defaults
+ */
+@Mojo(name = "create", requiresProject = false)
+public class CreateProjectMojo extends AbstractMojo {
+
+ private static final String JAVA_EXTENSION = ".java";
+ public static final String VERSION_PROP = "shamrock-version";
+ public static final String PLUGIN_VERSION_PROPERTY_NAME = "shamrock.version";
+ public static final String PLUGIN_VERSION_PROPERTY = "${" + PLUGIN_VERSION_PROPERTY_NAME + "}";
+ public static final String PLUGIN_GROUPID = "org.jboss.shamrock";
+ public static final String PLUGIN_ARTIFACTID = "shamrock-maven-plugin";
+ public static final String PLUGIN_KEY = PLUGIN_GROUPID + ":" + PLUGIN_ARTIFACTID;
+
+ /**
+ * The Maven project which will define and configure the shamrock-maven-plugin
+ */
+ @Parameter(defaultValue = "${project}")
+ protected MavenProject project;
+
+ @Parameter(property = "projectGroupId")
+ private String projectGroupId;
+
+ @Parameter(property = "projectArtifactId")
+ private String projectArtifactId;
+
+ @Parameter(property = "projectVersion", defaultValue = "1.0-SNAPSHOT")
+ private String projectVersion;
+
+ @Parameter(property = "shamrockVersion")
+ private String shamrockVersion;
+
+ @Parameter(property = "path", defaultValue = "/hello")
+ protected String path;
+
+ @Parameter(property = "className")
+ private String className;
+
+ @Parameter(property = "root", defaultValue = "/app")
+ private String root;
+
+ @Parameter(property = "extensions")
+ private List extensions;
+
+ @Component
+ private Prompter prompter;
+
+ @Component
+ private SetupTemplates templates;
+
+ @Override
+ public void execute() throws MojoExecutionException {
+ getLog().info("Executing...");
+ File pomFile = project.getFile();
+
+ Model model;
+ //Create pom.xml if not
+ if (pomFile == null || !pomFile.isFile()) {
+ pomFile = createPomFileFromUserInputs();
+ }
+
+ //We should get cloned of the OriginalModel, as project.getModel will return effective model
+ model = project.getOriginalModel().clone();
+
+ createDirectories();
+ templates.generate(project, root, path, className, getLog());
+ Optional maybe = MojoUtils.hasPlugin(project, PLUGIN_KEY);
+ if (maybe.isPresent()) {
+ return;
+ }
+
+ // The plugin is not configured, add it.
+ addVersionProperty(model);
+ addMainPluginConfig(model);
+ addExtensions(model, extensions, getLog());
+ addNativeProfile(model);
+ save(pomFile, model);
+ }
+
+ private void addNativeProfile(Model model) {
+ Profile profile = new Profile();
+ profile.setId("native");
+ BuildBase buildBase = new BuildBase();
+ Plugin plg = plugin(PLUGIN_GROUPID, PLUGIN_ARTIFACTID, PLUGIN_VERSION_PROPERTY);
+ PluginExecution exec = new PluginExecution();
+ exec.addGoal("native-image");
+ MojoUtils.Element element = new MojoUtils.Element("enableHttpUrlHandler", "true");
+ exec.setConfiguration(configuration(element));
+ plg.addExecution(exec);
+ buildBase.addPlugin(plg);
+ profile.setBuild(buildBase);
+ model.addProfile(profile);
+ }
+
+ private void addMainPluginConfig(Model model) {
+ Plugin plugin = plugin(PLUGIN_GROUPID, PLUGIN_ARTIFACTID, PLUGIN_VERSION_PROPERTY);
+ if (isParentPom(model)) {
+ addPluginManagementSection(model, plugin);
+ //strip the shamrockVersion off
+ plugin = plugin(PLUGIN_GROUPID, PLUGIN_ARTIFACTID);
+ } else {
+ plugin = plugin(PLUGIN_GROUPID, PLUGIN_ARTIFACTID, PLUGIN_VERSION_PROPERTY);
+ }
+ PluginExecution pluginExec = new PluginExecution();
+ pluginExec.addGoal("build");
+ plugin.addExecution(pluginExec);
+ Build build = createBuildSectionIfRequired(model);
+ build.getPlugins().add(plugin);
+ }
+
+ private void addVersionProperty(Model model) {
+ //Set a property at maven project level for Shamrock maven plugin versions
+ shamrockVersion = shamrockVersion == null ? MojoUtils.getVersion(VERSION_PROP) : shamrockVersion;
+ model.getProperties().putIfAbsent(PLUGIN_VERSION_PROPERTY_NAME, shamrockVersion);
+ }
+
+ private Build createBuildSectionIfRequired(Model model) {
+ Build build = model.getBuild();
+ if (build == null) {
+ build = new Build();
+ model.setBuild(build);
+ }
+ if (build.getPlugins() == null) {
+ build.setPlugins(new ArrayList<>());
+ }
+ return build;
+ }
+
+ private void addPluginManagementSection(Model model, Plugin plugin) {
+ if (model.getBuild().getPluginManagement() != null) {
+ if (model.getBuild().getPluginManagement().getPlugins() == null) {
+ model.getBuild().getPluginManagement().setPlugins(new ArrayList<>());
+ }
+ model.getBuild().getPluginManagement().getPlugins().add(plugin);
+ }
+ }
+
+ private File createPomFileFromUserInputs() throws MojoExecutionException {
+ Model model;
+ String workingdDir = System.getProperty("user.dir");
+ File pomFile = new File(workingdDir, "pom.xml");
+ try {
+
+ if (projectGroupId == null) {
+ projectGroupId = prompter.promptWithDefaultValue("Set the project groupId",
+ "io.jboss.shamrock.sample");
+ }
+
+ // If the user does not specify the artifactId, we switch to the interactive mode.
+ if (projectArtifactId == null) {
+ projectArtifactId = prompter.promptWithDefaultValue("Set the project artifactId",
+ "my-shamrock-project");
+
+ // Ask for version only if we asked for the artifactId
+ projectVersion = prompter.promptWithDefaultValue("Set the project version", "1.0-SNAPSHOT");
+
+ // Ask for maven version if not set
+ if (shamrockVersion == null) {
+ shamrockVersion = prompter.promptWithDefaultValue("Set the Shamrock version",
+ MojoUtils.getVersion(VERSION_PROP));
+ }
+
+ if (className == null) {
+ className = prompter.promptWithDefaultValue("Set the resource class name",
+ projectGroupId.replace("-", ".").replace("_", ".")
+ + ".HelloResource");
+
+ if (className != null && className.endsWith(JAVA_EXTENSION)) {
+ className = className.substring(0, className.length() - JAVA_EXTENSION.length());
+ }
+ }
+
+ if (root == null) {
+ root = prompter.promptWithDefaultValue("Set the application root ",
+ "/app");
+ if (!root.startsWith("/")) {
+ root = "/" + root;
+ }
+ }
+
+ if (path == null) {
+ path = prompter.promptWithDefaultValue("Set the resource path ",
+ "/hello");
+ if (!path.startsWith("/")) {
+ path = "/" + path;
+ }
+ }
+ }
+
+ // Create directory if the current one is not empty.
+ File wkDir = new File(workingdDir);
+ String[] children = wkDir.list();
+ if (children != null && children.length != 0) {
+ // Need to generate directory
+ File sub = new File(wkDir, projectArtifactId);
+ sub.mkdirs();
+ getLog().info("Directory " + projectArtifactId + " created");
+ // This updates the project pom file but also the base directory.
+ pomFile = new File(sub, "pom.xml");
+ project.setFile(pomFile);
+ }
+
+
+ Map context = new HashMap<>();
+ context.put("mProjectGroupId", projectGroupId);
+ context.put("mProjectArtifactId", projectArtifactId);
+ context.put("mProjectVersion", projectVersion);
+ context.put("shamrockVersion", shamrockVersion != null ? shamrockVersion : MojoUtils.getVersion(VERSION_PROP));
+
+ context.put("className", className);
+ context.put("root", root);
+ context.put("path", path);
+
+ templates.createNewProjectPomFile(context, pomFile);
+
+ //The project should be recreated and set with right model
+ MavenXpp3Reader xpp3Reader = new MavenXpp3Reader();
+
+ model = xpp3Reader.read(new FileInputStream(pomFile));
+ } catch (Exception e) {
+ throw new MojoExecutionException("Error while setup of shamrock-maven-plugin", e);
+ }
+
+ project = new MavenProject(model);
+ project.setFile(pomFile);
+ project.setPomFile(pomFile);
+ project.setOriginalModel(model); // the current model is the original model as well
+
+ addExtensions(model, extensions, getLog());
+ save(pomFile, model);
+ return pomFile;
+ }
+
+ private void save(File pomFile, Model model) throws MojoExecutionException {
+ MavenXpp3Writer xpp3Writer = new MavenXpp3Writer();
+ try (FileWriter pomFileWriter = new FileWriter(pomFile)) {
+ xpp3Writer.write(pomFileWriter, model);
+ pomFileWriter.flush();
+ } catch (IOException e) {
+ throw new MojoExecutionException("Unable to write the pom.xml file", e);
+ }
+ }
+
+ private void createDirectories() {
+ File base = project.getBasedir();
+ File source = new File(base, "src/main/java");
+ File resources = new File(base, "src/main/resources");
+ File test = new File(base, "src/test/java");
+
+ String prefix = "Creation of ";
+ if (!source.isDirectory()) {
+ boolean res = source.mkdirs();
+ getLog().debug(prefix + source.getAbsolutePath() + " : " + res);
+ }
+ if (!resources.isDirectory()) {
+ boolean res = resources.mkdirs();
+ getLog().debug(prefix + resources.getAbsolutePath() + " : " + res);
+ }
+ if (!test.isDirectory()) {
+ boolean res = test.mkdirs();
+ getLog().debug(prefix + test.getAbsolutePath() + " : " + res);
+ }
+ }
+
+ private boolean isParentPom(Model model) {
+ return "pom".equals(model.getPackaging());
+ }
+
+}
diff --git a/maven/src/main/java/org/jboss/shamrock/maven/ListExtensionsMojo.java b/maven/src/main/java/org/jboss/shamrock/maven/ListExtensionsMojo.java
new file mode 100644
index 0000000000000..dad4b4afeb6b5
--- /dev/null
+++ b/maven/src/main/java/org/jboss/shamrock/maven/ListExtensionsMojo.java
@@ -0,0 +1,20 @@
+package org.jboss.shamrock.maven;
+
+import org.apache.maven.plugin.AbstractMojo;
+import org.apache.maven.plugins.annotations.Mojo;
+import org.jboss.shamrock.maven.components.dependencies.Extensions;
+
+@Mojo(name = "list-extensions", requiresProject = false)
+public class ListExtensionsMojo extends AbstractMojo {
+
+ @Override
+ public void execute() {
+ getLog().info("Available extensions:");
+ Extensions.get().stream()
+ .sorted((o1, o2) -> o1.getName().compareToIgnoreCase(o2.getName()))
+ .forEach(ext -> getLog().info("\t * " + ext.getName() + " (" + ext.getGroupId() + ":" + ext.getArtifactId() + ")"));
+
+ getLog().info("\nAdd an extension to your project by adding the dependency to your " +
+ "project or use `mvn shamrock:add-extension -Dextensions=\"name\"`");
+ }
+}
diff --git a/maven/src/main/java/org/jboss/shamrock/maven/components/Prompter.java b/maven/src/main/java/org/jboss/shamrock/maven/components/Prompter.java
new file mode 100644
index 0000000000000..f3c4c8bbb7361
--- /dev/null
+++ b/maven/src/main/java/org/jboss/shamrock/maven/components/Prompter.java
@@ -0,0 +1,84 @@
+/*
+ *
+ * Copyright (c) 2016-2018 Red Hat, Inc.
+ *
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package org.jboss.shamrock.maven.components;
+
+import jline.console.ConsoleReader;
+import org.apache.commons.lang3.StringUtils;
+import org.codehaus.plexus.component.annotations.Component;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.Objects;
+
+/**
+ * Prompt implementation.
+ *
+ * @author Clement Escoffier
+ */
+@Component(role = Prompter.class, instantiationStrategy = "per-lookup")
+public class Prompter {
+
+ private final ConsoleReader console;
+
+ public Prompter() throws IOException {
+ this.console = new ConsoleReader();
+ console.setHistoryEnabled(false);
+ console.setExpandEvents(false);
+ }
+
+ public Prompter(InputStream in, OutputStream out) throws IOException {
+ this.console = new ConsoleReader(in, out);
+ console.setHistoryEnabled(false);
+ console.setExpandEvents(false);
+ }
+
+ public ConsoleReader getConsole() {
+ return console;
+ }
+
+ public String prompt(final String message, final Character mask) throws IOException {
+ Objects.requireNonNull(message);
+
+ final String prompt = String.format("%s: ", message);
+ String value;
+ do {
+ value = console.readLine(prompt, mask);
+ }
+ while (StringUtils.isBlank(value));
+ return value;
+ }
+
+
+ public String prompt(final String message) throws IOException {
+ Objects.requireNonNull(message);
+ return prompt(message, null);
+ }
+
+ public String promptWithDefaultValue(final String message, final String defaultValue) throws IOException {
+ Objects.requireNonNull(message);
+ Objects.requireNonNull(defaultValue);
+
+ final String prompt = String.format("%s [%s]: ", message, defaultValue);
+ String value = console.readLine(prompt);
+ if (StringUtils.isBlank(value)) {
+ return defaultValue;
+ }
+ return value;
+ }
+
+}
diff --git a/maven/src/main/java/org/jboss/shamrock/maven/components/SetupTemplates.java b/maven/src/main/java/org/jboss/shamrock/maven/components/SetupTemplates.java
new file mode 100644
index 0000000000000..5911b3a2422a7
--- /dev/null
+++ b/maven/src/main/java/org/jboss/shamrock/maven/components/SetupTemplates.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright (c) 2016-2018 Red Hat, Inc.
+ *
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.jboss.shamrock.maven.components;
+
+import com.google.common.base.Strings;
+import freemarker.cache.ClassTemplateLoader;
+import freemarker.template.Configuration;
+import freemarker.template.Template;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.logging.Log;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.component.annotations.Component;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.Writer;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * Prompt implementation.
+ *
+ * @author Clement Escoffier
+ */
+@Component(role = SetupTemplates.class, instantiationStrategy = "singleton")
+public class SetupTemplates {
+
+ private static final Configuration cfg;
+ private static final String JAVA_EXTENSION = ".java";
+
+ static {
+ cfg = new Configuration(Configuration.VERSION_2_3_23);
+ cfg.setTemplateLoader(new ClassTemplateLoader(SetupTemplates.class, "/"));
+ }
+
+ public void createNewProjectPomFile(Map context, File pomFile) throws MojoExecutionException {
+ try {
+ Template temp = cfg.getTemplate("templates/pom-template.ftl");
+ Writer out = new FileWriter(pomFile);
+ temp.process(context, out);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to generate pom.xml", e);
+ }
+ }
+
+ public void generate(MavenProject project, String rootPath, String path, String className, Log log) throws MojoExecutionException {
+ if (Strings.isNullOrEmpty(className)) {
+ return;
+ }
+ log.info("Creating resource " + className);
+
+ File root = new File(project.getBasedir(), "src/main/java");
+ File testRoot = new File(project.getBasedir(), "src/test/java");
+
+ String packageName = null;
+ if (className.endsWith(JAVA_EXTENSION)) {
+ className = className.substring(0, className.length() - JAVA_EXTENSION.length());
+ }
+
+ if (className.contains(".")) {
+ int idx = className.lastIndexOf('.');
+ packageName = className.substring(0, idx);
+ className = className.substring(idx + 1);
+ }
+
+ if (packageName != null) {
+ File packageDir = new File(root, packageName.replace('.', '/'));
+ if (!packageDir.exists()) {
+ packageDir.mkdirs();
+ log.info("Creating directory " + packageDir.getAbsolutePath());
+ }
+ root = packageDir;
+
+ File testPackageDir = new File(testRoot, packageName.replace('.', '/'));
+ if (!testPackageDir.exists()) {
+ testPackageDir.mkdirs();
+ log.info("Creating directory " + packageDir.getAbsolutePath());
+ }
+ testRoot = testPackageDir;
+ }
+
+ File classFile = new File(root, className + JAVA_EXTENSION);
+ File testClassFile = new File(testRoot, className + "Test" + JAVA_EXTENSION);
+ Map context = new HashMap<>();
+ context.put("classname", className);
+ context.put("root_prefix", rootPath);
+ context.put("path", path);
+ if (packageName != null) {
+ context.put("packageName", packageName);
+ }
+ try {
+ Template temp = cfg.getTemplate("templates/resource-template.ftl");
+ Writer out = new FileWriter(classFile);
+ temp.process(context, out);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to generate resource code", e);
+ }
+
+ // Generate test resources.
+ try {
+ Template temp = cfg.getTemplate("templates/test-resource-template.ftl");
+ Writer out = new FileWriter(testClassFile);
+ temp.process(context, out);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to generate test code", e);
+ }
+
+ // Generate application.
+ File appClassFile = new File(root, "ShamrockApplication.java");
+ try {
+ Template temp = cfg.getTemplate("templates/application-template.ftl");
+ Writer out = new FileWriter(appClassFile);
+ temp.process(context, out);
+ } catch (Exception e) {
+ throw new MojoExecutionException("Unable to generate Application class", e);
+ }
+
+ }
+
+}
diff --git a/maven/src/main/java/org/jboss/shamrock/maven/components/dependencies/Extension.java b/maven/src/main/java/org/jboss/shamrock/maven/components/dependencies/Extension.java
new file mode 100644
index 0000000000000..676fc4789811a
--- /dev/null
+++ b/maven/src/main/java/org/jboss/shamrock/maven/components/dependencies/Extension.java
@@ -0,0 +1,149 @@
+/*
+ *
+ * Copyright (c) 2016-2018 Red Hat, Inc.
+ *
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package org.jboss.shamrock.maven.components.dependencies;
+
+import org.apache.maven.model.Dependency;
+import org.jboss.shamrock.maven.CreateProjectMojo;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * @author Clement Escoffier
+ */
+public class Extension {
+
+ private String artifactId;
+ private String groupId;
+ private String scope;
+ private String version = CreateProjectMojo.PLUGIN_VERSION_PROPERTY;
+
+ private String type;
+ private String classifier;
+
+ private String name;
+ private String[] labels;
+
+ public Extension() {
+ // Use by mapper.
+ }
+
+
+ public String getArtifactId() {
+ return artifactId;
+ }
+
+ public Extension setArtifactId(String artifactId) {
+ this.artifactId = artifactId;
+ return this;
+ }
+
+ public String getGroupId() {
+ return groupId;
+ }
+
+ public Extension setGroupId(String groupId) {
+ this.groupId = groupId;
+ return this;
+ }
+
+ public String getScope() {
+ return scope;
+ }
+
+ public Extension setScope(String scope) {
+ this.scope = scope;
+ return this;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public Extension setVersion(String version) {
+ this.version = version;
+ return this;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public Extension setType(String type) {
+ this.type = type;
+ return this;
+ }
+
+ public String getClassifier() {
+ return classifier;
+ }
+
+ public Extension setClassifier(String classifier) {
+ this.classifier = classifier;
+ return this;
+ }
+
+ public String[] getLabels() {
+ return labels;
+ }
+
+ public Extension setLabels(String[] labels) {
+ this.labels = labels;
+ return this;
+ }
+
+ public String getName() {
+ return name;
+ }
+
+ public Extension setName(String name) {
+ this.name = name;
+ return this;
+ }
+
+ public List labels() {
+ List list = new ArrayList<>();
+ if (labels != null) {
+ list.addAll(Stream.of(labels).map(String::toLowerCase).collect(Collectors.toList()));
+ }
+ list.add(artifactId.toLowerCase());
+ return list;
+ }
+
+ public Dependency toDependency() {
+ Dependency dependency = new Dependency();
+ dependency.setGroupId(groupId);
+ dependency.setArtifactId(artifactId);
+ if (scope != null && !scope.isEmpty()) {
+ dependency.setScope(scope);
+ }
+ if (classifier != null && !classifier.isEmpty()) {
+ dependency.setClassifier(classifier);
+ }
+ if (version != null && ! version.isEmpty()) {
+ dependency.setVersion(version);
+ }
+ return dependency;
+ }
+
+ public String toCoordinates() {
+ return getGroupId() + ":" + getArtifactId();
+ }
+}
+
diff --git a/maven/src/main/java/org/jboss/shamrock/maven/components/dependencies/Extensions.java b/maven/src/main/java/org/jboss/shamrock/maven/components/dependencies/Extensions.java
new file mode 100644
index 0000000000000..b25b419b71319
--- /dev/null
+++ b/maven/src/main/java/org/jboss/shamrock/maven/components/dependencies/Extensions.java
@@ -0,0 +1,116 @@
+/*
+ *
+ * Copyright (c) 2016-2018 Red Hat, Inc.
+ *
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+package org.jboss.shamrock.maven.components.dependencies;
+
+import com.fasterxml.jackson.core.JsonParser;
+import com.fasterxml.jackson.core.type.TypeReference;
+import com.fasterxml.jackson.databind.ObjectMapper;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.plugin.logging.Log;
+import org.jboss.shamrock.maven.utilities.MojoUtils;
+
+import java.io.IOException;
+import java.net.URL;
+import java.util.List;
+import java.util.Optional;
+
+/**
+ * @author Clement Escoffier
+ */
+public class Extensions {
+
+ private Extensions() {
+ // avoid direct instantiation
+ }
+
+ public static List get() {
+ ObjectMapper mapper = new ObjectMapper()
+ .enable(JsonParser.Feature.ALLOW_COMMENTS)
+ .enable(JsonParser.Feature.ALLOW_NUMERIC_LEADING_ZEROS);
+ URL url = Extensions.class.getClassLoader().getResource("extensions.json");
+ try {
+ return mapper.readValue(url, new TypeReference>() {
+ // Do nothing.
+ });
+ } catch (IOException e) {
+ throw new RuntimeException("Unable to load the extensions.json file", e);
+ }
+ }
+
+ public static Dependency parse(String dependency, Log log) {
+ Dependency res = new Dependency();
+ String[] segments = dependency.split(":");
+ if (segments.length >= 2) {
+ res.setGroupId(segments[0]);
+ res.setArtifactId(segments[1]);
+ if (segments.length >= 3 && !segments[2].isEmpty()) {
+ res.setVersion(segments[2]);
+ }
+ if (segments.length >= 4) {
+ res.setClassifier(segments[3]);
+ }
+ return res;
+ } else {
+ log.warn("Invalid dependency description '" + dependency + "'");
+ return null;
+ }
+ }
+
+ public static boolean addExtensions(Model model, List extensions, Log log) {
+ if (extensions == null || extensions.isEmpty()) {
+ return false;
+ }
+
+ boolean updated = false;
+ List exts = Extensions.get();
+ for (String dependency : extensions) {
+ Optional optional = exts.stream()
+ .filter(d ->{
+ boolean hasTag = d.labels().contains(dependency.trim().toLowerCase());
+ boolean machName = d.getName().toLowerCase().contains(dependency.trim().toLowerCase());
+ return hasTag || machName;
+ })
+ .findAny();
+
+ if (optional.isPresent()) {
+ if (! MojoUtils.hasDependency(model, optional.get().getGroupId(), optional.get().getArtifactId())) {
+ log.info("Adding extension " + optional.get().toCoordinates());
+ model.addDependency(optional.get().toDependency());
+ updated = true;
+ } else {
+ log.info("Extension already present - skipping");
+ }
+
+ } else if (dependency.contains(":")) {
+ // Add it as a dependency
+ // groupId:artifactId:version:classifier
+ Dependency parsed = Extensions.parse(dependency, log);
+ if (parsed != null) {
+ log.info("Adding dependency " + parsed.getManagementKey());
+ model.addDependency(parsed);
+ updated = true;
+ }
+ } else {
+ log.warn("Cannot find a dependency matching '" + dependency + "'");
+ }
+ }
+
+ return updated;
+ }
+
+}
diff --git a/maven/src/main/java/org/jboss/shamrock/maven/utilities/MojoUtils.java b/maven/src/main/java/org/jboss/shamrock/maven/utilities/MojoUtils.java
new file mode 100644
index 0000000000000..6ae7001a7eada
--- /dev/null
+++ b/maven/src/main/java/org/jboss/shamrock/maven/utilities/MojoUtils.java
@@ -0,0 +1,223 @@
+/*
+ *
+ * Copyright (c) 2016-2018 Red Hat, Inc.
+ *
+ * Red Hat licenses this file to you under the Apache License, version
+ * 2.0 (the "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ * implied. See the License for the specific language governing
+ * permissions and limitations under the License.
+ */
+
+package org.jboss.shamrock.maven.utilities;
+
+
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.URL;
+import java.util.*;
+
+/**
+ * @author kameshs
+ */
+public class MojoUtils {
+
+ private static final Properties properties = new Properties();
+
+ static {
+ loadProperties();
+ }
+
+ private MojoUtils() {
+ // Avoid direct instantiation
+ }
+
+ /**
+ * Checks whether or not the given project has a plugin with the given key. The key is given using the
+ * "groupId:artifactId" syntax.
+ *
+ * @param project the project
+ * @param pluginKey the plugin
+ * @return an Optional completed if the plugin is found.
+ */
+ public static Optional hasPlugin(MavenProject project, String pluginKey) {
+ Optional optPlugin = project.getBuildPlugins().stream()
+ .filter(plugin -> pluginKey.equals(plugin.getKey()))
+ .findFirst();
+
+ if (!optPlugin.isPresent() && project.getPluginManagement() != null) {
+ optPlugin = project.getPluginManagement().getPlugins().stream()
+ .filter(plugin -> pluginKey.equals(plugin.getKey()))
+ .findFirst();
+ }
+ return optPlugin;
+ }
+
+ /**
+ * Checks whether the project has the dependency
+ *
+ * @param model - the project to check existence of dependency
+ * @param groupId - the dependency groupId
+ * @param artifactId - the dependency artifactId
+ * @return true if the project has the dependency
+ */
+ public static boolean hasDependency(Model model, String groupId, String artifactId) {
+ return model.getDependencies().stream()
+ .anyMatch(d -> groupId.equals(d.getGroupId())
+ && artifactId.equals(d.getArtifactId()));
+ }
+
+ private static void loadProperties() {
+ URL url = MojoUtils.class.getClassLoader().getResource("shamrock-maven-plugin.properties");
+ Objects.requireNonNull(url);
+ try (InputStream in = url.openStream()) {
+ properties.load(in);
+ } catch (IOException e) {
+ throw new IllegalStateException("Invalid packaging of the shamrock-maven-plugin, the shamrock-maven-plugin" +
+ ".properties file cannot be read", e);
+ }
+ }
+
+ public static String getVersion(String key) {
+ return properties.getProperty(key);
+ }
+
+ /**
+ * Builds the configuration for the goal using Elements
+ *
+ * @param elements A list of elements for the configuration section
+ * @return The elements transformed into the Maven-native XML format
+ */
+ public static Xpp3Dom configuration(Element... elements) {
+ Xpp3Dom dom = new Xpp3Dom("configuration");
+ for (Element e : elements) {
+ dom.addChild(e.toDom());
+ }
+ return dom;
+ }
+
+ /**
+ * Defines the plugin without its version or extensions.
+ *
+ * @param groupId The group id
+ * @param artifactId The artifact id
+ * @return The plugin instance
+ */
+ public static Plugin plugin(String groupId, String artifactId) {
+ return plugin(groupId, artifactId, null);
+ }
+
+ /**
+ * Defines a plugin without extensions.
+ *
+ * @param groupId The group id
+ * @param artifactId The artifact id
+ * @param version The plugin version
+ * @return The plugin instance
+ */
+ public static Plugin plugin(String groupId, String artifactId, String version) {
+ return plugin(groupId, artifactId, version, Collections.emptyList());
+ }
+
+ /**
+ * Defines a plugin.
+ *
+ * @param groupId The group id
+ * @param artifactId The artifact id
+ * @param version The plugin version
+ * @param dependencies The plugin extensions
+ * @return The plugin instance
+ */
+ public static Plugin plugin(String groupId, String artifactId, String version, List dependencies) {
+ Plugin plugin = new Plugin();
+ plugin.setArtifactId(artifactId);
+ plugin.setGroupId(groupId);
+ plugin.setVersion(version);
+ plugin.setDependencies(dependencies);
+ return plugin;
+ }
+
+ /**
+ * Element wrapper class for configuration elements
+ */
+ public static class Element {
+ private final Element[] children;
+ private final String name;
+ private final String text;
+ private final Attributes attributes;
+
+ public Element(String name, Element... children) {
+ this(name, null, new Attributes(), children);
+ }
+
+ public Element(String name, Attributes attributes, Element... children) {
+ this(name, null, attributes, children);
+ }
+
+ public Element(String name, String text, Element... children) {
+ this.name = name;
+ this.text = text;
+ this.children = children;
+ this.attributes = new Attributes();
+ }
+
+ public Element(String name, String text, Attributes attributes, Element... children) {
+ this.name = name;
+ this.text = text;
+ this.children = children;
+ this.attributes = attributes;
+ }
+
+ public Xpp3Dom toDom() {
+ Xpp3Dom dom = new Xpp3Dom(name);
+ if (text != null) {
+ dom.setValue(text);
+ }
+ for (Element e : children) {
+ dom.addChild(e.toDom());
+ }
+ for(Attribute attribute : attributes.attributes) {
+ dom.setAttribute(attribute.name, attribute.value);
+ }
+
+ return dom;
+ }
+ }
+
+ /**
+ * Collection of attributes wrapper class
+ */
+ public static class Attributes {
+ private List attributes;
+
+ public Attributes(Attribute ... attributes) {
+ this.attributes = Arrays.asList(attributes);
+ }
+ }
+
+ /**
+ * Attribute wrapper class
+ */
+ public static class Attribute {
+ private final String name;
+ private final String value;
+
+ public Attribute(String name, String value) {
+ this.name = name;
+ this.value = value;
+ }
+ }
+
+}
diff --git a/maven/src/main/resources/extensions.json b/maven/src/main/resources/extensions.json
new file mode 100644
index 0000000000000..765fa398b3f64
--- /dev/null
+++ b/maven/src/main/resources/extensions.json
@@ -0,0 +1,185 @@
+[
+ {
+ "name": "Agroal",
+ "labels": [
+ "agroal",
+ "database-connection-pool"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-agroal-deployment"
+ },
+ {
+ "name": "Arc",
+ "labels": [
+ "arc",
+ "cdi",
+ "dependency-injection",
+ "di"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-arc-deployment"
+ },
+ {
+ "name": "Bean Validation",
+ "labels": [
+ "bean-validation",
+ "validation"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-bean-validation"
+ },
+ {
+ "name": "Fault Tolerance",
+ "labels": [
+ "fault-tolerance",
+ "microprofile-fault-tolerance",
+ "circuit-breaker",
+ "bulkhead"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-fault-tolerance-deployment"
+ },
+ {
+ "name": "Health",
+ "labels": [
+ "health-check",
+ "health",
+ "microprofile-health",
+ "microprofile-health-check"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-health-deployment"
+ },
+ {
+ "name": "JaxRS",
+ "labels": [
+ "jaxrs",
+ "resteasy",
+ "web",
+ "rest"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-jaxrs-deployment"
+ },
+ {
+ "name": "JPA",
+ "labels": [
+ "jpa",
+ "hibernate"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-jpa-deployment"
+ },
+ {
+ "name": "Logging",
+ "labels": [
+ "log",
+ "logging",
+ "slf4j",
+ "log4j"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-logging-deployment"
+ },
+ {
+ "name": "Metrics",
+ "labels": [
+ "metrics",
+ "metric",
+ "prometheus",
+ "monitoring"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-metrics-deployment"
+ },
+ {
+ "name": "OpenAPI",
+ "labels": [
+ "openapi",
+ "open-api"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-openapi-deployment"
+ },
+ {
+ "name": "Open Tracing",
+ "labels": [
+ "open-tracing",
+ "tracing",
+ "distributed-tracing",
+ "jaeger"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-opentracing-deployment"
+ },
+ {
+ "name": "Reactive Streams",
+ "labels": [
+ "reactive-streams",
+ "microprofile-reactive-streams"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-reactive-streams-operators-deployment"
+ },
+ {
+ "name": "Rest Client",
+ "labels": [
+ "rest-client",
+ "web-client",
+ "microprofile-rest-client"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-rest-client-deployment"
+ },
+ {
+ "name": "Scheduler",
+ "labels": [
+ "scheduler",
+ "tasks",
+ "periodic-tasks"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-scheduler-deployment"
+ },
+ {
+ "name": "Transactions",
+ "labels": [
+ "transactions",
+ "transaction",
+ "tx",
+ "txs"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-transactions-deployment"
+ },
+ {
+ "name": "Servlet",
+ "labels": [
+ "servlet",
+ "undertow"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-undertow-deployment"
+ },
+ {
+ "name": "Eclipse Vert.x",
+ "labels": [
+ "eclipse-vert.x",
+ "vertx",
+ "vert.x"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-vertx-deployment"
+ },
+ {
+ "name": "Web Sockets",
+ "labels": [
+ "websocket",
+ "websockets",
+ "web-socket",
+ "web-sockets"
+ ],
+ "groupId": "org.jboss.shamrock",
+ "artifactId": "shamrock-websockets-deployment"
+ }
+]
diff --git a/maven/src/main/resources/shamrock-maven-plugin.properties b/maven/src/main/resources/shamrock-maven-plugin.properties
new file mode 100644
index 0000000000000..d8ad9fa51d556
--- /dev/null
+++ b/maven/src/main/resources/shamrock-maven-plugin.properties
@@ -0,0 +1,20 @@
+#
+#
+# Copyright (c) 2016-2018 Red Hat, Inc.
+#
+# Red Hat licenses this file to you under the Apache License, version
+# 2.0 (the "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS,
+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+# implied. See the License for the specific language governing
+# permissions and limitations under the License.
+#
+maven-compiler-plugin-version=3.8.0
+maven-jar-plugin-version=3.1.0
+maven-resources-plugin=3.1.0
+shamrock-version=${shamrock.version}
diff --git a/maven/src/main/resources/templates/application-template.ftl b/maven/src/main/resources/templates/application-template.ftl
new file mode 100644
index 0000000000000..09816500361e0
--- /dev/null
+++ b/maven/src/main/resources/templates/application-template.ftl
@@ -0,0 +1,11 @@
+<#if packageName??>
+package ${packageName};
+#if>
+
+import javax.ws.rs.ApplicationPath;
+import javax.ws.rs.core.Application;
+
+@ApplicationPath("${root_prefix}")
+public class ShamrockApplication extends Application {
+
+}
diff --git a/maven/src/main/resources/templates/pom-template.ftl b/maven/src/main/resources/templates/pom-template.ftl
new file mode 100644
index 0000000000000..2bcf2f5fbbccf
--- /dev/null
+++ b/maven/src/main/resources/templates/pom-template.ftl
@@ -0,0 +1,93 @@
+
+ 4.0.0
+ ${mProjectGroupId}
+ ${mProjectArtifactId}
+ ${mProjectVersion}
+
+ UTF-8
+ UTF-8
+ 1.8
+ 1.8
+
+ ${shamrockVersion}
+
+
+
+
+ org.jboss.shamrock
+ shamrock-jaxrs-deployment
+ provided
+ ${r"${shamrock.version}"}
+
+
+ org.jboss.shamrock
+ shamrock-arc-deployment
+ provided
+ ${r"${shamrock.version}"}
+
+
+ org.jboss.shamrock
+ shamrock-logging-deployment
+ provided
+ ${r"${shamrock.version}"}
+
+
+
+
+ org.jboss.shamrock
+ shamrock-junit
+ ${r"${shamrock.version}"}
+ test
+
+
+ io.rest-assured
+ rest-assured
+ 3.2.0
+ test
+
+
+
+
+
+
+ org.jboss.shamrock
+ shamrock-maven-plugin
+ ${r"${shamrock.version}"}
+
+
+
+ build
+
+
+
+
+
+
+
+
+
+ native
+
+
+
+ org.jboss.shamrock
+ shamrock-maven-plugin
+ ${r"${shamrock.version}"}
+
+
+
+ native-image
+
+
+ true
+
+
+
+
+
+
+
+
+
+
diff --git a/maven/src/main/resources/templates/resource-template.ftl b/maven/src/main/resources/templates/resource-template.ftl
new file mode 100644
index 0000000000000..35040f41fb6f5
--- /dev/null
+++ b/maven/src/main/resources/templates/resource-template.ftl
@@ -0,0 +1,18 @@
+<#if packageName??>
+package ${packageName};
+#if>
+
+import javax.ws.rs.GET;
+import javax.ws.rs.Path;
+import javax.ws.rs.Produces;
+import javax.ws.rs.core.MediaType;
+
+@Path("${path}")
+public class ${classname} {
+
+ @GET
+ @Produces(MediaType.TEXT_PLAIN)
+ public String hello() {
+ return "hello";
+ }
+}
diff --git a/maven/src/main/resources/templates/test-resource-template.ftl b/maven/src/main/resources/templates/test-resource-template.ftl
new file mode 100644
index 0000000000000..d966c20d63d99
--- /dev/null
+++ b/maven/src/main/resources/templates/test-resource-template.ftl
@@ -0,0 +1,24 @@
+<#if packageName??>
+package ${packageName};
+#if>
+
+import org.jboss.shamrock.test.ShamrockTest;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import static io.restassured.RestAssured.given;
+import static org.hamcrest.CoreMatchers.is;
+
+@RunWith(ShamrockTest.class)
+public class ${classname}Test {
+
+ @Test
+ public void testHelloEndpoint() {
+ given()
+ .when().get("${root_prefix}${path}")
+ .then()
+ .statusCode(200)
+ .body(is("hello"));
+ }
+
+}
diff --git a/maven/src/test/java/org/jboss/shamrock/maven/it/CreateProjectMojoIT.java b/maven/src/test/java/org/jboss/shamrock/maven/it/CreateProjectMojoIT.java
new file mode 100644
index 0000000000000..fdd979b09641d
--- /dev/null
+++ b/maven/src/test/java/org/jboss/shamrock/maven/it/CreateProjectMojoIT.java
@@ -0,0 +1,166 @@
+package org.jboss.shamrock.maven.it;
+
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.shared.invoker.*;
+import org.jboss.shamrock.maven.CreateProjectMojo;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.util.Collections;
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+/**
+ * @author Clement Escoffier
+ */
+public class CreateProjectMojoIT extends MojoTestBase {
+
+ private Invoker invoker;
+ private File testDir;
+
+ private void init(File root) {
+ invoker = new DefaultInvoker();
+ invoker.setWorkingDirectory(root);
+ String repo = System.getProperty("maven.repo");
+ if (repo == null) {
+ repo = new File(System.getProperty("user.home"), ".m2/repository").getAbsolutePath();
+ }
+ invoker.setLocalRepositoryDirectory(new File(repo));
+ installPluginToLocalRepository(invoker.getLocalRepositoryDirectory());
+ }
+
+ @Test
+ public void testProjectGenerationFromScratch() throws MavenInvocationException, FileNotFoundException {
+ testDir = initEmptyProject("projects/project-generation");
+ assertThat(testDir).isDirectory();
+ init(testDir);
+ Properties properties = new Properties();
+ properties.put("projectGroupId", "org.acme");
+ properties.put("projectArtifactId", "acme");
+ setup(properties);
+ assertThat(new File(testDir, "pom.xml")).isFile();
+ assertThat(new File(testDir, "src/main/java")).isDirectory();
+ }
+
+ @Test
+ public void testProjectGenerationFromMinimalPom() throws Exception {
+ testDir = initProject("projects/simple-pom-it", "projects/project-generation-from-empty-pom");
+ assertThat(testDir).isDirectory();
+ init(testDir);
+ setup(new Properties());
+ assertThat(new File(testDir, "pom.xml")).isFile();
+ assertThat(FileUtils.readFileToString(new File(testDir, "pom.xml"), "UTF-8"))
+ .contains(CreateProjectMojo.PLUGIN_ARTIFACTID, CreateProjectMojo.PLUGIN_VERSION_PROPERTY, CreateProjectMojo.PLUGIN_GROUPID);
+ assertThat(new File(testDir, "src/main/java")).isDirectory();
+ }
+
+ @Test
+ public void testProjectGenerationFromScratchWithResource() throws Exception {
+ testDir = initEmptyProject("projects/project-generation-with-resource");
+ assertThat(testDir).isDirectory();
+ init(testDir);
+ Properties properties = new Properties();
+ properties.put("projectGroupId", "org.acme");
+ properties.put("projectArtifactId", "acme");
+ properties.put("className", "org.acme.MyResource.java");
+ setup(properties);
+ assertThat(new File(testDir, "pom.xml")).isFile();
+ assertThat(new File(testDir, "src/main/java")).isDirectory();
+ assertThat(new File(testDir, "src/main/java/org/acme/MyResource.java")).isFile();
+ assertThat(new File(testDir, "src/main/java/org/acme/ShamrockApplication.java")).isFile();
+ }
+
+ @Test
+ public void testProjectGenerationFromMinimalPomWithResource() throws Exception {
+ testDir = initProject("projects/simple-pom-it", "projects/project-generation-from-empty-pom-with-resource");
+ assertThat(testDir).isDirectory();
+ init(testDir);
+ Properties properties = new Properties();
+ properties.put("projectGroupId", "org.acme");
+ properties.put("projectArtifactId", "acme");
+ properties.put("className", "org.acme.MyResource.java");
+ setup(properties);
+ assertThat(new File(testDir, "pom.xml")).isFile();
+ assertThat(FileUtils.readFileToString(new File(testDir, "pom.xml"), "UTF-8"))
+ .contains("shamrock.version");
+ assertThat(new File(testDir, "src/main/java")).isDirectory();
+ assertThat(new File(testDir, "src/main/java/org/acme/MyResource.java")).isFile();
+ assertThat(new File(testDir, "src/main/java/org/acme/ShamrockApplication.java")).isFile();
+ }
+
+ @Test
+ public void testProjectGenerationFromScratchWithExtensions() throws Exception {
+ testDir = initEmptyProject("projects/project-generation-with-resources-and-extension");
+ assertThat(testDir).isDirectory();
+ init(testDir);
+ Properties properties = new Properties();
+ properties.put("projectGroupId", "org.acme");
+ properties.put("projectArtifactId", "acme");
+ properties.put("className", "org.acme.MyResource");
+ properties.put("extensions", "web,metrics,missing");
+
+ setup(properties);
+ assertThat(new File(testDir, "pom.xml")).isFile();
+ assertThat(new File(testDir, "src/main/java")).isDirectory();
+ assertThat(new File(testDir, "src/main/java/org/acme/MyResource.java")).isFile();
+ assertThat(new File(testDir, "src/main/java/org/acme/ShamrockApplication.java")).isFile();
+ assertThat(FileUtils.readFileToString(new File(testDir, "pom.xml"), "UTF-8"))
+ .contains("shamrock-jaxrs-deployment", "shamrock-metrics-deployment").doesNotContain("missing");
+ }
+
+ @Test
+ public void testProjectGenerationFromScratchWithCustomDependencies() throws Exception {
+ testDir = initEmptyProject("projects/project-generation-with-resource-and-custom-deps");
+ assertThat(testDir).isDirectory();
+ init(testDir);
+ Properties properties = new Properties();
+ properties.put("projectGroupId", "org.acme");
+ properties.put("projectArtifactId", "acme");
+ properties.put("className", "org.acme.MyResource");
+ properties.put("extensions", "commons-io:commons-io:2.5");
+ setup(properties);
+ assertThat(new File(testDir, "pom.xml")).isFile();
+ assertThat(new File(testDir, "src/main/java/org/acme/MyResource.java")).isFile();
+ assertThat(new File(testDir, "src/main/java/org/acme/ShamrockApplication.java")).isFile();
+ assertThat(FileUtils.readFileToString(new File(testDir, "pom.xml"), "UTF-8"))
+ .contains("commons-io");
+ }
+
+ @Test
+ public void testProjectGenerationFromMinimalPomWithDependencies() throws Exception {
+ testDir = initProject("projects/simple-pom-it",
+ "projects/project-generation-from-minimal-pom-with-extensions");
+ assertThat(testDir).isDirectory();
+ init(testDir);
+ Properties properties = new Properties();
+ properties.put("projectGroupId", "org.acme");
+ properties.put("projectArtifactId", "acme");
+ properties.put("className", "org.acme.MyResource");
+ properties.put("extensions", "commons-io:commons-io:2.5");
+ setup(properties);
+ assertThat(new File(testDir, "pom.xml")).isFile();
+ assertThat(new File(testDir, "src/main/java/org/acme/MyResource.java")).isFile();
+ assertThat(new File(testDir, "src/main/java/org/acme/ShamrockApplication.java")).isFile();
+ assertThat(FileUtils.readFileToString(new File(testDir, "pom.xml"), "UTF-8"))
+ .contains("commons-io");
+ }
+
+ private void setup(Properties params) throws MavenInvocationException, FileNotFoundException {
+ InvocationRequest request = new DefaultInvocationRequest();
+ request.setBatchMode(true);
+ request.setGoals(Collections.singletonList(
+ CreateProjectMojo.PLUGIN_KEY + ":" + MojoTestBase.VERSION + ":create"
+ ));
+ request.setProperties(params);
+ getEnv().forEach(request::addShellEnvironment);
+ PrintStreamLogger logger = new PrintStreamLogger(new PrintStream(new FileOutputStream("build-create.log")),
+ InvokerLogger.DEBUG);
+ invoker.setLogger(logger);
+ invoker.execute(request);
+ }
+
+}
diff --git a/maven/src/test/java/org/jboss/shamrock/maven/it/JarVerifier.java b/maven/src/test/java/org/jboss/shamrock/maven/it/JarVerifier.java
new file mode 100644
index 0000000000000..2a3aaada95fdb
--- /dev/null
+++ b/maven/src/test/java/org/jboss/shamrock/maven/it/JarVerifier.java
@@ -0,0 +1,59 @@
+package org.jboss.shamrock.maven.it;
+
+import sun.tools.jar.resources.jar;
+
+import java.io.*;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.stream.Collectors;
+import java.util.zip.ZipEntry;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+class JarVerifier {
+
+ private File jarFile;
+
+ JarVerifier(File jarFile) {
+ this.jarFile = jarFile;
+ }
+
+ void assertThatJarIsCreated() {
+ assertThat(jarFile).isNotNull();
+ assertThat(jarFile).isFile();
+ }
+
+ void assertThatJarHasManifest() throws Exception {
+ try (JarFile jf = new JarFile(jarFile)){
+ Manifest manifest = jf.getManifest();
+ assertThat(manifest).isNotNull();
+ }
+ }
+
+ void assertThatFileIsContained(String file) throws Exception {
+ try (JarFile jf = new JarFile(jarFile)){
+ assertThat(jf.getJarEntry(file)).isNotNull();
+ }
+ }
+
+ void assertThatFileIsNotContained(String file) throws Exception {
+ try (JarFile jf = new JarFile(jarFile)){
+ assertThat(jf.getJarEntry(file)).isNull();
+ }
+ }
+
+ void assertThatFileContains(String path, String[] lines) throws Exception {
+ try (JarFile jf = new JarFile(jarFile)) {
+ ZipEntry entry = jf.getEntry(path);
+ assertThat(entry).isNotNull();
+ String content = read(jf.getInputStream(entry));
+ assertThat(content).containsSubsequence(lines);
+ }
+ }
+
+ private static String read(InputStream input) throws IOException {
+ try (BufferedReader buffer = new BufferedReader(new InputStreamReader(input))) {
+ return buffer.lines().collect(Collectors.joining("\n"));
+ }
+ }
+}
diff --git a/maven/src/test/java/org/jboss/shamrock/maven/it/MojoTestBase.java b/maven/src/test/java/org/jboss/shamrock/maven/it/MojoTestBase.java
new file mode 100644
index 0000000000000..70376883f8a0d
--- /dev/null
+++ b/maven/src/test/java/org/jboss/shamrock/maven/it/MojoTestBase.java
@@ -0,0 +1,153 @@
+package org.jboss.shamrock.maven.it;
+
+
+import com.google.common.collect.ImmutableMap;
+import org.apache.commons.io.FileUtils;
+import org.apache.maven.shared.utils.StringUtils;
+import org.jboss.shamrock.maven.CreateProjectMojo;
+import org.jboss.shamrock.maven.utilities.MojoUtils;
+import org.junit.BeforeClass;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.logging.Level;
+import java.util.logging.Logger;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class MojoTestBase {
+ static String VERSION;
+ private static ImmutableMap VARIABLES;
+
+ @BeforeClass
+ public static void init() {
+ VERSION = MojoUtils.getVersion(CreateProjectMojo.VERSION_PROP);
+ assertThat(VERSION).isNotNull();
+
+ VARIABLES = ImmutableMap.of(
+ "@project.groupId@", CreateProjectMojo.PLUGIN_GROUPID,
+ "@project.artifactId@", CreateProjectMojo.PLUGIN_ARTIFACTID,
+ "@project.version@", VERSION);
+ }
+
+ boolean isCoverage() {
+ return System.getProperty("coverage") != null;
+ }
+
+
+ static File initProject(String name) {
+ return initProject(name, name);
+ }
+
+ static File initEmptyProject(String name) {
+ File tc = new File("target/test-classes/" + name);
+ if (tc.isDirectory()) {
+ boolean delete = tc.delete();
+ Logger.getLogger(MojoTestBase.class.getName())
+ .log(Level.FINE, "test-classes deleted? " + delete);
+ }
+ boolean mkdirs = tc.mkdirs();
+ Logger.getLogger(MojoTestBase.class.getName())
+ .log(Level.FINE, "test-classes created? " + mkdirs);
+ return tc;
+ }
+
+ public static File initProject(String name, String output) {
+ File tc = new File("target/test-classes");
+ if (!tc.isDirectory()) {
+ boolean mkdirs = tc.mkdirs();
+ Logger.getLogger(MojoTestBase.class.getName())
+ .log(Level.FINE, "test-classes created? " + mkdirs);
+ }
+
+ File in = new File("src/test/resources", name);
+ if (!in.isDirectory()) {
+ throw new RuntimeException("Cannot find directory: " + in.getAbsolutePath());
+ }
+
+ File out = new File(tc, output);
+ if (out.isDirectory()) {
+ FileUtils.deleteQuietly(out);
+ }
+ boolean mkdirs = out.mkdirs();
+ Logger.getLogger(MojoTestBase.class.getName())
+ .log(Level.FINE, out.getAbsolutePath() + " created? " + mkdirs);
+ try {
+ System.out.println("Copying " + in.getAbsolutePath() + " to " + out.getParentFile().getAbsolutePath());
+ org.codehaus.plexus.util.FileUtils.copyDirectoryStructure(in, out);
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot copy project resources", e);
+ }
+ return out;
+ }
+
+ static void installPluginToLocalRepository(File local) {
+ File repo = new File(local, CreateProjectMojo.PLUGIN_GROUPID.replace(".", "/") + "/"
+ + CreateProjectMojo.PLUGIN_ARTIFACTID + "/" + MojoTestBase.VERSION);
+ if (!repo.isDirectory()) {
+ boolean mkdirs = repo.mkdirs();
+ Logger.getLogger(MojoTestBase.class.getName())
+ .log(Level.FINE, repo.getAbsolutePath() + " created? " + mkdirs);
+ }
+
+ File plugin = new File("target", CreateProjectMojo.PLUGIN_ARTIFACTID + "-" + MojoTestBase.VERSION + ".jar");
+
+ try {
+ FileUtils.copyFileToDirectory(plugin, repo);
+ String installedPomName = CreateProjectMojo.PLUGIN_ARTIFACTID + "-" + MojoTestBase.VERSION + ".pom";
+ FileUtils.copyFile(new File("pom.xml"), new File(repo, installedPomName));
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot copy the plugin jar, or the pom file, to the local repository", e);
+ }
+ }
+
+ static void installJarToLocalRepository(String local, String name, File jar) {
+ File repo = new File(local, "org/acme/" + name + "/1.0");
+ if (!repo.isDirectory()) {
+ boolean mkdirs = repo.mkdirs();
+ Logger.getLogger(MojoTestBase.class.getName())
+ .log(Level.FINE, repo.getAbsolutePath() + " created? " + mkdirs);
+ }
+
+ try {
+ FileUtils.copyFileToDirectory(jar, repo);
+ String installedPomName = name + "-1.0.pom";
+ FileUtils.write(new File(repo, installedPomName), "\n" +
+ " 4.0.0\n" +
+ " org.acme\n" +
+ " " + name + "\n" +
+ " 1.0\n" +
+ "", "UTF-8");
+ } catch (IOException e) {
+ throw new RuntimeException("Cannot copy the jar, or the pom file, to the local repository", e);
+ }
+ }
+
+ static void prepareProject(File testDir) throws IOException {
+ File pom = new File(testDir, "pom.xml");
+ assertThat(pom).isFile();
+ filter(pom, VARIABLES);
+ }
+
+ static void filter(File input, Map variables) throws IOException {
+ assertThat(input).isFile();
+ String data = FileUtils.readFileToString(input, "UTF-8");
+
+ for (Map.Entry token : variables.entrySet()) {
+ String value = String.valueOf(token.getValue());
+ data = StringUtils.replace(data, token.getKey(), value);
+ }
+ FileUtils.write(input, data, "UTF-8");
+ }
+
+ Map getEnv() {
+ String opts = System.getProperty("mavenOpts");
+ Map env = new HashMap<>();
+ if (opts != null) {
+ env.put("MAVEN_OPTS", opts);
+ }
+ return env;
+ }
+}
diff --git a/maven/src/test/java/org/jboss/shamrock/maven/it/SetupVerifier.java b/maven/src/test/java/org/jboss/shamrock/maven/it/SetupVerifier.java
new file mode 100644
index 0000000000000..cd762535660c4
--- /dev/null
+++ b/maven/src/test/java/org/jboss/shamrock/maven/it/SetupVerifier.java
@@ -0,0 +1,97 @@
+package org.jboss.shamrock.maven.it;
+
+import org.apache.maven.model.Model;
+import org.apache.maven.model.Plugin;
+import org.apache.maven.model.Profile;
+import org.apache.maven.model.io.xpp3.MavenXpp3Reader;
+import org.apache.maven.project.MavenProject;
+import org.codehaus.plexus.util.xml.Xpp3Dom;
+import org.jboss.shamrock.maven.CreateProjectMojo;
+import org.jboss.shamrock.maven.utilities.MojoUtils;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.util.Optional;
+import java.util.Properties;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.jboss.shamrock.maven.CreateProjectMojo.PLUGIN_VERSION_PROPERTY_NAME;
+import static org.junit.Assert.*;
+
+public class SetupVerifier {
+
+ public static void assertThatJarExists(File archive) throws Exception {
+ JarVerifier jarVerifier = new JarVerifier(archive);
+ jarVerifier.assertThatJarIsCreated();
+ jarVerifier.assertThatJarHasManifest();
+ }
+
+ public static void assertThatJarContainsFile(File archive, String file) throws Exception {
+ JarVerifier jarVerifier = new JarVerifier(archive);
+ jarVerifier.assertThatFileIsContained(file);
+ }
+
+ public static void assertThatJarDoesNotContainFile(File archive, String file) throws Exception {
+ JarVerifier jarVerifier = new JarVerifier(archive);
+ jarVerifier.assertThatFileIsNotContained(file);
+ }
+
+ public static void assertThatJarContainsFileWithContent(File archive, String path, String... lines) throws Exception {
+ JarVerifier jarVerifier = new JarVerifier(archive);
+ jarVerifier.assertThatFileContains(path, lines);
+ }
+
+ public static void verifySetup(File pomFile) throws Exception {
+ assertNotNull("Unable to find pom.xml", pomFile);
+ MavenXpp3Reader xpp3Reader = new MavenXpp3Reader();
+ Model model = xpp3Reader.read(new FileInputStream(pomFile));
+
+ MavenProject project = new MavenProject(model);
+
+ Optional maybe = MojoUtils.hasPlugin(project, CreateProjectMojo.PLUGIN_KEY);
+ assertThat(maybe).isNotEmpty();
+
+ //Check if the properties have been set correctly
+ Properties properties = model.getProperties();
+ assertThat(properties.containsKey(PLUGIN_VERSION_PROPERTY_NAME)).isTrue();
+
+ // Check plugin is set
+ Plugin plugin = maybe.orElseThrow(() -> new AssertionError("Plugin expected"));
+ assertThat(plugin).isNotNull().satisfies(p -> {
+ assertThat(p.getArtifactId()).isEqualTo(CreateProjectMojo.PLUGIN_ARTIFACTID);
+ assertThat(p.getGroupId()).isEqualTo(CreateProjectMojo.PLUGIN_GROUPID);
+ assertThat(p.getVersion()).isEqualTo(CreateProjectMojo.PLUGIN_VERSION_PROPERTY);
+ });
+
+ // Check build execution Configuration
+ assertThat(plugin.getExecutions()).hasSize(1).allSatisfy(execution -> {
+ assertThat(execution.getGoals()).containsExactly("build");
+ assertThat(execution.getConfiguration()).isNull();
+ });
+
+
+ // Check profile
+ assertThat(model.getProfiles()).hasSize(1);
+ Profile profile = model.getProfiles().get(0);
+ assertThat(profile.getId()).isEqualTo("native");
+ Plugin actual = profile.getBuild().getPluginsAsMap().get(CreateProjectMojo.PLUGIN_KEY);
+ assertThat(actual).isNotNull();
+ assertThat(actual.getExecutions()).hasSize(1).allSatisfy(exec -> {
+ assertThat(exec.getGoals()).containsExactly("native-image");
+ assertThat(exec.getConfiguration()).isInstanceOf(Xpp3Dom.class)
+ .satisfies(o -> assertThat(o.toString()).contains("enableHttpUrlHandler"));
+ });
+ }
+
+ public static void verifySetupWithVersion(File pomFile) throws Exception {
+ MavenXpp3Reader xpp3Reader = new MavenXpp3Reader();
+ Model model = xpp3Reader.read(new FileInputStream(pomFile));
+
+ MavenProject project = new MavenProject(model);
+ Properties projectProps = project.getProperties();
+ assertNotNull(projectProps);
+ assertFalse(projectProps.isEmpty());
+ assertEquals(projectProps.getProperty("shamrock.version"), "0.0.0");
+ }
+
+}
diff --git a/maven/src/test/resources/projects/simple-pom-it/pom.xml b/maven/src/test/resources/projects/simple-pom-it/pom.xml
new file mode 100644
index 0000000000000..6e05400d24d45
--- /dev/null
+++ b/maven/src/test/resources/projects/simple-pom-it/pom.xml
@@ -0,0 +1,9 @@
+
+
+
+ 4.0.0
+ io.acme.it
+ acme-empty-pom
+ 0.0.1.BUILD-SNAPSHOT
+