diff --git a/devtools/aesh/src/main/java/io/quarkus/cli/QuarkusCli.java b/devtools/aesh/src/main/java/io/quarkus/cli/QuarkusCli.java
index 97d3da8324c9c..2e272c4ba5887 100644
--- a/devtools/aesh/src/main/java/io/quarkus/cli/QuarkusCli.java
+++ b/devtools/aesh/src/main/java/io/quarkus/cli/QuarkusCli.java
@@ -12,18 +12,18 @@
import org.aesh.command.validator.CommandValidatorException;
import org.aesh.command.validator.OptionValidatorException;
-import io.quarkus.cli.commands.QuarkusCommand;
+import io.quarkus.devtools.commands.handlers.QuarkusCommandHandler;
public class QuarkusCli {
public static void main(String[] args) throws CommandRegistryException {
CommandRuntime runtime = AeshCommandRuntimeBuilder
.builder()
- .commandRegistry(AeshCommandRegistryBuilder.builder().command(QuarkusCommand.class).create())
+ .commandRegistry(AeshCommandRegistryBuilder.builder().command(QuarkusCommandHandler.class).create())
.build();
if (args.length > 0) {
- StringBuilder sb = new StringBuilder(QuarkusCommand.COMMAND_NAME).append(" ");
+ StringBuilder sb = new StringBuilder(QuarkusCommandHandler.COMMAND_NAME).append(" ");
if (args.length == 1) {
sb.append(args[0]);
} else {
@@ -54,6 +54,6 @@ private static void showHelpIfNeeded(CommandRuntime runtime, Exception e) {
if (e != null) {
System.err.println(e.getMessage());
}
- System.err.println(runtime.commandInfo(QuarkusCommand.COMMAND_NAME));
+ System.err.println(runtime.commandInfo(QuarkusCommandHandler.COMMAND_NAME));
}
}
diff --git a/devtools/aesh/src/main/java/io/quarkus/cli/commands/AddExtensionCommand.java b/devtools/aesh/src/main/java/io/quarkus/cli/commands/AddExtensionCommand.java
index f28858c67e830..d9594101ba9b7 100644
--- a/devtools/aesh/src/main/java/io/quarkus/cli/commands/AddExtensionCommand.java
+++ b/devtools/aesh/src/main/java/io/quarkus/cli/commands/AddExtensionCommand.java
@@ -5,6 +5,8 @@
import java.util.Collections;
import java.util.List;
+import io.quarkus.devtools.commands.AddExtensions;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
import org.aesh.command.Command;
import org.aesh.command.CommandDefinition;
import org.aesh.command.CommandException;
diff --git a/devtools/aesh/src/main/java/io/quarkus/cli/commands/CreateProjectCommand.java b/devtools/aesh/src/main/java/io/quarkus/cli/commands/CreateProjectCommand.java
index 68596a7b528cf..e639f7ca07495 100644
--- a/devtools/aesh/src/main/java/io/quarkus/cli/commands/CreateProjectCommand.java
+++ b/devtools/aesh/src/main/java/io/quarkus/cli/commands/CreateProjectCommand.java
@@ -4,6 +4,7 @@
import java.nio.file.Paths;
import java.util.HashMap;
+import io.quarkus.devtools.commands.CreateProject;
import org.aesh.command.Command;
import org.aesh.command.CommandDefinition;
import org.aesh.command.CommandResult;
diff --git a/devtools/aesh/src/main/java/io/quarkus/cli/commands/ListExtensionsCommand.java b/devtools/aesh/src/main/java/io/quarkus/cli/commands/ListExtensionsCommand.java
index 380c4f6d04a95..98069512e6715 100644
--- a/devtools/aesh/src/main/java/io/quarkus/cli/commands/ListExtensionsCommand.java
+++ b/devtools/aesh/src/main/java/io/quarkus/cli/commands/ListExtensionsCommand.java
@@ -2,6 +2,7 @@
import java.nio.file.Paths;
+import io.quarkus.devtools.commands.ListExtensions;
import org.aesh.command.Command;
import org.aesh.command.CommandDefinition;
import org.aesh.command.CommandException;
diff --git a/devtools/aesh/src/main/java/io/quarkus/cli/commands/QuarkusCommand.java b/devtools/aesh/src/main/java/io/quarkus/cli/commands/QuarkusCommand.java
index 1fec366174193..dc9b15e63fd2e 100644
--- a/devtools/aesh/src/main/java/io/quarkus/cli/commands/QuarkusCommand.java
+++ b/devtools/aesh/src/main/java/io/quarkus/cli/commands/QuarkusCommand.java
@@ -1,5 +1,6 @@
package io.quarkus.cli.commands;
+import io.quarkus.devtools.commands.handlers.QuarkusCommandHandler;
import org.aesh.command.Command;
import org.aesh.command.CommandException;
import org.aesh.command.CommandResult;
@@ -10,7 +11,7 @@
/**
* @author Ståle Pedersen
*/
-@GroupCommandDefinition(name = QuarkusCommand.COMMAND_NAME, groupCommands = { ListExtensionsCommand.class,
+@GroupCommandDefinition(name = QuarkusCommandHandler.COMMAND_NAME, groupCommands = { ListExtensionsCommand.class,
AddExtensionCommand.class,
CreateProjectCommand.class }, description = " [] \n\nThese are the common quarkus commands used in various situations")
public class QuarkusCommand implements Command {
diff --git a/devtools/aesh/src/main/java/io/quarkus/cli/commands/RemoveExtensionCommand.java b/devtools/aesh/src/main/java/io/quarkus/cli/commands/RemoveExtensionCommand.java
index cc3b718276cfc..71e109a00feae 100644
--- a/devtools/aesh/src/main/java/io/quarkus/cli/commands/RemoveExtensionCommand.java
+++ b/devtools/aesh/src/main/java/io/quarkus/cli/commands/RemoveExtensionCommand.java
@@ -5,6 +5,8 @@
import java.util.Collections;
import java.util.List;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+import io.quarkus.devtools.commands.RemoveExtensions;
import org.aesh.command.Command;
import org.aesh.command.CommandDefinition;
import org.aesh.command.CommandException;
diff --git a/devtools/gradle/src/functionalTest/java/io/quarkus/gradle/AddExtensionToModuleInMultiModuleProjectTest.java b/devtools/gradle/src/functionalTest/java/io/quarkus/gradle/AddExtensionToModuleInMultiModuleProjectTest.java
index 00b55e2260616..c992eef547c62 100644
--- a/devtools/gradle/src/functionalTest/java/io/quarkus/gradle/AddExtensionToModuleInMultiModuleProjectTest.java
+++ b/devtools/gradle/src/functionalTest/java/io/quarkus/gradle/AddExtensionToModuleInMultiModuleProjectTest.java
@@ -19,7 +19,6 @@ public class AddExtensionToModuleInMultiModuleProjectTest extends QuarkusGradleT
public void testBasicMultiModuleBuild() throws Exception {
final File projectDir = getProjectDir("add-extension-multi-module");
-
BuildResult build = GradleRunner.create()
.forwardOutput()
.withPluginClasspath()
diff --git a/devtools/gradle/src/functionalTest/java/io/quarkus/gradle/QuarkusPluginFunctionalTest.java b/devtools/gradle/src/functionalTest/java/io/quarkus/gradle/QuarkusPluginFunctionalTest.java
index 38cfcc6d75e9e..63026d1af3a88 100644
--- a/devtools/gradle/src/functionalTest/java/io/quarkus/gradle/QuarkusPluginFunctionalTest.java
+++ b/devtools/gradle/src/functionalTest/java/io/quarkus/gradle/QuarkusPluginFunctionalTest.java
@@ -21,9 +21,9 @@
import com.google.common.collect.ImmutableMap;
-import io.quarkus.cli.commands.CreateProject;
+import io.quarkus.devtools.commands.CreateProject;
import io.quarkus.devtools.project.BuildTool;
-import io.quarkus.generators.SourceType;
+import io.quarkus.devtools.project.codegen.SourceType;
import io.quarkus.platform.tools.config.QuarkusPlatformConfig;
import io.quarkus.test.devmode.util.DevModeTestUtils;
diff --git a/devtools/gradle/src/main/java/io/quarkus/gradle/GradleBuildFileFromConnector.java b/devtools/gradle/src/main/java/io/quarkus/gradle/GradleBuildFileFromConnector.java
index 01c4102868f7b..2cb675e18cd83 100644
--- a/devtools/gradle/src/main/java/io/quarkus/gradle/GradleBuildFileFromConnector.java
+++ b/devtools/gradle/src/main/java/io/quarkus/gradle/GradleBuildFileFromConnector.java
@@ -1,6 +1,7 @@
package io.quarkus.gradle;
import java.io.IOException;
+import java.nio.file.Path;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
@@ -13,16 +14,20 @@
import org.gradle.tooling.model.eclipse.EclipseExternalDependency;
import org.gradle.tooling.model.eclipse.EclipseProject;
-import io.quarkus.devtools.buildfile.GradleBuildFile;
-import io.quarkus.devtools.writer.ProjectWriter;
+import io.quarkus.devtools.project.buildfile.AbstractGradleBuildFile;
+import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
-public class GradleBuildFileFromConnector extends GradleBuildFile {
+public class GradleBuildFileFromConnector extends AbstractGradleBuildFile {
private List dependencies = null;
- public GradleBuildFileFromConnector(ProjectWriter writer) {
- super(writer);
- // we need to initialize here since there is no other single point of entry
+ public GradleBuildFileFromConnector(final Path projectFolderPath, final QuarkusPlatformDescriptor platformDescriptor) {
+ super(projectFolderPath, platformDescriptor);
+ }
+
+ public GradleBuildFileFromConnector(Path projectFolderPath, QuarkusPlatformDescriptor platformDescriptor,
+ Path rootProjectPath) {
+ super(projectFolderPath, platformDescriptor, rootProjectPath);
}
@Override
@@ -30,16 +35,14 @@ public List getDependencies() throws IOException {
if (dependencies == null) {
EclipseProject eclipseProject = null;
if (getBuildContent() != null) {
- if (getWriter().hasFile()) {
- try {
- ProjectConnection connection = GradleConnector.newConnector()
- .forProjectDirectory(getWriter().getProjectFolder())
- .connect();
- eclipseProject = connection.getModel(EclipseProject.class);
- } catch (BuildException e) {
- // ignore this error.
- e.printStackTrace();
- }
+ try {
+ ProjectConnection connection = GradleConnector.newConnector()
+ .forProjectDirectory(getProjectFolderPath().toFile())
+ .connect();
+ eclipseProject = connection.getModel(EclipseProject.class);
+ } catch (BuildException e) {
+ // ignore this error.
+ e.printStackTrace();
}
}
if (eclipseProject != null) {
diff --git a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusAddExtension.java b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusAddExtension.java
index d640818576b84..57c498953d63a 100644
--- a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusAddExtension.java
+++ b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusAddExtension.java
@@ -6,12 +6,13 @@
import java.util.List;
import java.util.Set;
+import org.apache.commons.lang3.exception.ExceptionUtils;
import org.gradle.api.GradleException;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.options.Option;
-import io.quarkus.cli.commands.AddExtensions;
+import io.quarkus.devtools.commands.AddExtensions;
public class QuarkusAddExtension extends QuarkusPlatformTask {
@@ -44,7 +45,7 @@ public void addExtension() {
.extensions(extensionsSet)
.execute();
} catch (Exception e) {
- throw new GradleException("Failed to add extensions " + getExtensionsToAdd(), e);
+ throw new GradleException("Failed to add extensions " + getExtensionsToAdd() + " " + ExceptionUtils.getStackTrace(e), e);
}
}
}
diff --git a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusListExtensions.java b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusListExtensions.java
index 833679f5c61dd..aad55911e3c29 100644
--- a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusListExtensions.java
+++ b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusListExtensions.java
@@ -6,10 +6,7 @@
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.options.Option;
-import io.quarkus.cli.commands.ListExtensions;
-import io.quarkus.devtools.project.QuarkusProject;
-import io.quarkus.devtools.writer.FileProjectWriter;
-import io.quarkus.gradle.GradleBuildFileFromConnector;
+import io.quarkus.devtools.commands.ListExtensions;
public class QuarkusListExtensions extends QuarkusPlatformTask {
@@ -58,11 +55,7 @@ public QuarkusListExtensions() {
@TaskAction
public void listExtensions() {
try {
- final GradleBuildFileFromConnector buildFileFromConnector = new GradleBuildFileFromConnector(
- new FileProjectWriter(getProject().getProjectDir()));
- QuarkusProject quarkusProject = QuarkusProject.of(getProject().getProjectDir().toPath(), platformDescriptor(),
- buildFileFromConnector);
- new ListExtensions(quarkusProject)
+ new ListExtensions(getQuarkusProject())
.all(isAll())
.format(getFormat())
.search(getSearchPattern())
diff --git a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java
index 3433f111bb2ce..e422cb2593ebc 100644
--- a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java
+++ b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusPlatformTask.java
@@ -10,10 +10,9 @@
import org.gradle.api.plugins.JavaPlugin;
import org.gradle.api.tasks.Internal;
-import io.quarkus.devtools.buildfile.GradleBuildFile;
import io.quarkus.devtools.project.QuarkusProject;
-import io.quarkus.devtools.writer.FileProjectWriter;
-import io.quarkus.devtools.writer.ProjectWriter;
+import io.quarkus.devtools.project.buildfile.BuildFile;
+import io.quarkus.gradle.GradleBuildFileFromConnector;
import io.quarkus.platform.descriptor.CombinedQuarkusPlatformDescriptor;
import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
import io.quarkus.platform.descriptor.resolver.json.QuarkusJsonPlatformDescriptorResolver;
@@ -66,12 +65,11 @@ protected QuarkusPlatformDescriptor platformDescriptor() {
}
@Internal
- protected GradleBuildFile getGradleBuildFile() {
- final ProjectWriter writer = new FileProjectWriter(getProject().getProjectDir());
+ protected BuildFile getGradleBuildFile() {
return getProject().getParent() == null
- ? new GradleBuildFile(writer)
- : new GradleBuildFile(writer,
- new FileProjectWriter(getProject().getRootProject().getProjectDir()));
+ ? new GradleBuildFileFromConnector(getProject().getProjectDir().toPath(), platformDescriptor())
+ : new GradleBuildFileFromConnector(getProject().getProjectDir().toPath(), platformDescriptor(),
+ getProject().getRootProject().getProjectDir().toPath());
}
@Internal
diff --git a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusRemoveExtension.java b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusRemoveExtension.java
index 482ed669a8cbc..1adf369f5c415 100644
--- a/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusRemoveExtension.java
+++ b/devtools/gradle/src/main/java/io/quarkus/gradle/tasks/QuarkusRemoveExtension.java
@@ -11,7 +11,7 @@
import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.options.Option;
-import io.quarkus.cli.commands.RemoveExtensions;
+import io.quarkus.devtools.commands.RemoveExtensions;
public class QuarkusRemoveExtension extends QuarkusPlatformTask {
diff --git a/devtools/gradle/src/test/java/io/quarkus/gradle/GradleBuildFileTest.java b/devtools/gradle/src/test/java/io/quarkus/gradle/GradleBuildFileTest.java
index 899513bec48f5..74fdb9c753272 100644
--- a/devtools/gradle/src/test/java/io/quarkus/gradle/GradleBuildFileTest.java
+++ b/devtools/gradle/src/test/java/io/quarkus/gradle/GradleBuildFileTest.java
@@ -20,7 +20,7 @@
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
-import io.quarkus.devtools.writer.FileProjectWriter;
+import io.quarkus.devtools.project.codegen.writer.FileProjectWriter;
class GradleBuildFileTest {
diff --git a/devtools/maven/src/main/java/io/quarkus/maven/AddExtensionMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/AddExtensionMojo.java
index 115d681b095af..4442aa26a4cfb 100644
--- a/devtools/maven/src/main/java/io/quarkus/maven/AddExtensionMojo.java
+++ b/devtools/maven/src/main/java/io/quarkus/maven/AddExtensionMojo.java
@@ -10,8 +10,8 @@
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
-import io.quarkus.cli.commands.AddExtensions;
-import io.quarkus.cli.commands.QuarkusCommandOutcome;
+import io.quarkus.devtools.commands.AddExtensions;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
import io.quarkus.devtools.project.QuarkusProject;
import io.quarkus.platform.tools.MessageWriter;
@@ -22,7 +22,7 @@
* parameters.
*/
@Mojo(name = "add-extension")
-public class AddExtensionMojo extends BuildFileMojoBase {
+public class AddExtensionMojo extends QuarkusProjectMojoBase {
/**
* The list of extensions to be added.
diff --git a/devtools/maven/src/main/java/io/quarkus/maven/CreateProjectMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/CreateProjectMojo.java
index b560894b9ac45..fa68d67e6f3f9 100644
--- a/devtools/maven/src/main/java/io/quarkus/maven/CreateProjectMojo.java
+++ b/devtools/maven/src/main/java/io/quarkus/maven/CreateProjectMojo.java
@@ -46,11 +46,9 @@
import io.quarkus.bootstrap.resolver.AppModelResolverException;
import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver;
-import io.quarkus.cli.commands.AddExtensions;
-import io.quarkus.cli.commands.CreateProject;
+import io.quarkus.devtools.commands.CreateProject;
import io.quarkus.devtools.project.BuildTool;
-import io.quarkus.devtools.project.QuarkusProject;
-import io.quarkus.generators.SourceType;
+import io.quarkus.devtools.project.codegen.SourceType;
import io.quarkus.maven.components.MavenVersionEnforcer;
import io.quarkus.maven.components.Prompter;
import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
@@ -214,11 +212,6 @@ public void execute() throws MojoExecutionException {
success = createProject.execute().isSuccess();
File createdDependenciesBuildFile = new File(projectRoot, buildToolEnum.getDependenciesFile());
- if (success) {
- success = new AddExtensions(QuarkusProject.of(projectFolderPath, platform, buildToolEnum))
- .extensions(extensions).execute()
- .isSuccess();
- }
if (BuildTool.MAVEN.equals(buildToolEnum)) {
createMavenWrapper(createdDependenciesBuildFile, ToolsUtils.readQuarkusProperties(platform));
} else if (BuildTool.GRADLE.equals(buildToolEnum)) {
diff --git a/devtools/maven/src/main/java/io/quarkus/maven/ListExtensionsMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/ListExtensionsMojo.java
index 64486a685a6fa..91ae34967b52d 100644
--- a/devtools/maven/src/main/java/io/quarkus/maven/ListExtensionsMojo.java
+++ b/devtools/maven/src/main/java/io/quarkus/maven/ListExtensionsMojo.java
@@ -4,7 +4,7 @@
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
-import io.quarkus.cli.commands.ListExtensions;
+import io.quarkus.devtools.commands.ListExtensions;
import io.quarkus.devtools.project.QuarkusProject;
import io.quarkus.platform.tools.MessageWriter;
@@ -15,7 +15,7 @@
* You can list all extension or just installable. Choose between 3 output formats: name, concise and full.
*/
@Mojo(name = "list-extensions", requiresProject = false)
-public class ListExtensionsMojo extends BuildFileMojoBase {
+public class ListExtensionsMojo extends QuarkusProjectMojoBase {
/**
* List all extensions or just the installable.
diff --git a/devtools/maven/src/main/java/io/quarkus/maven/BuildFileMojoBase.java b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusProjectMojoBase.java
similarity index 75%
rename from devtools/maven/src/main/java/io/quarkus/maven/BuildFileMojoBase.java
rename to devtools/maven/src/main/java/io/quarkus/maven/QuarkusProjectMojoBase.java
index 961abc3440c53..c3fdcbb89d463 100644
--- a/devtools/maven/src/main/java/io/quarkus/maven/BuildFileMojoBase.java
+++ b/devtools/maven/src/main/java/io/quarkus/maven/QuarkusProjectMojoBase.java
@@ -1,11 +1,13 @@
package io.quarkus.maven;
-import java.io.File;
import java.io.IOException;
+import java.nio.file.Path;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import org.apache.maven.model.Dependency;
+import org.apache.maven.model.DependencyManagement;
import org.apache.maven.plugin.AbstractMojo;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugins.annotations.Component;
@@ -19,11 +21,8 @@
import io.quarkus.bootstrap.resolver.BootstrapAppModelResolver;
import io.quarkus.bootstrap.resolver.maven.MavenArtifactResolver;
-import io.quarkus.devtools.buildfile.BuildFile;
-import io.quarkus.devtools.buildfile.MavenBuildFile;
import io.quarkus.devtools.project.BuildTool;
import io.quarkus.devtools.project.QuarkusProject;
-import io.quarkus.devtools.writer.FileProjectWriter;
import io.quarkus.platform.descriptor.CombinedQuarkusPlatformDescriptor;
import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
import io.quarkus.platform.descriptor.resolver.json.QuarkusJsonPlatformDescriptorResolver;
@@ -31,7 +30,7 @@
import io.quarkus.platform.tools.ToolsConstants;
import io.quarkus.platform.tools.maven.MojoMessageWriter;
-public abstract class BuildFileMojoBase extends AbstractMojo {
+public abstract class QuarkusProjectMojoBase extends AbstractMojo {
@Parameter(defaultValue = "${project}")
protected MavenProject project;
@@ -60,37 +59,31 @@ public void execute() throws MojoExecutionException {
// Validate Mojo parameters
validateParameters();
+ final MessageWriter log = new MojoMessageWriter(getLog());
+ final Path projectFolderPath = project.getBasedir().toPath();
+ final BuildTool buildTool = QuarkusProject.resolveExistingProjectBuildTool(projectFolderPath);
+ final QuarkusPlatformDescriptor platformDescriptor = resolvePlatformDescriptor(log);
+
+ doExecute(QuarkusProject.of(project.getBasedir().toPath(), platformDescriptor, buildTool), log);
+ }
+
+ private QuarkusPlatformDescriptor resolvePlatformDescriptor(final MessageWriter log) throws MojoExecutionException {
// Resolve and setup the platform descriptor
- final MavenArtifactResolver mvn;
try {
- mvn = MavenArtifactResolver.builder().setRepositorySystem(repoSystem).setRepositorySystemSession(repoSession)
+ final MavenArtifactResolver mvn = MavenArtifactResolver.builder().setRepositorySystem(repoSystem)
+ .setRepositorySystemSession(repoSession)
.setRemoteRepositories(repos).build();
- } catch (Exception e) {
- throw new MojoExecutionException("Failed to initialize maven artifact resolver", e);
- }
-
- final MessageWriter log = new MojoMessageWriter(getLog());
-
- QuarkusPlatformDescriptor platformDescr = null;
- BuildTool buildTool = null;
- BuildFile buildFile = null;
- try (FileProjectWriter fileProjectWriter = new FileProjectWriter(project.getBasedir())) {
if (project.getFile() != null) {
- // Maven project
- final MavenBuildFile mvnBuild = new MavenBuildFile(fileProjectWriter);
- buildTool = BuildTool.MAVEN;
- buildFile = new MavenBuildFile(fileProjectWriter);
-
final List descrArtifactList = new ArrayList<>(2);
- for (Dependency dep : mvnBuild.getManagedDependencies()) {
+ for (Dependency dep : getManagedDependencies()) {
if ((dep.getScope() == null || !dep.getScope().equals("import"))
&& (dep.getType() == null || !dep.getType().equals("pom"))) {
continue;
}
// We don't know which BOM is the platform one, so we are trying every BOM here
- final String bomVersion = resolveValue(dep.getVersion(), buildFile);
- final String bomGroupId = resolveValue(dep.getGroupId(), buildFile);
- final String bomArtifactId = resolveValue(dep.getArtifactId(), buildFile);
+ final String bomVersion = resolveValue(dep.getVersion());
+ final String bomGroupId = resolveValue(dep.getGroupId());
+ final String bomArtifactId = resolveValue(dep.getArtifactId());
if (bomVersion == null || bomGroupId == null || bomArtifactId == null) {
continue;
}
@@ -102,28 +95,19 @@ public void execute() throws MojoExecutionException {
}
if (!descrArtifactList.isEmpty()) {
if (descrArtifactList.size() == 1) {
- platformDescr = loadPlatformDescriptor(mvn, log, descrArtifactList.get(0));
+ return loadPlatformDescriptor(mvn, log, descrArtifactList.get(0));
} else {
final CombinedQuarkusPlatformDescriptor.Builder builder = CombinedQuarkusPlatformDescriptor.builder();
for (Artifact descrArtifact : descrArtifactList) {
builder.addPlatform(loadPlatformDescriptor(mvn, log, descrArtifact));
}
- platformDescr = builder.build();
+ return builder.build();
}
}
- } else if (new File(project.getBasedir(), "build.gradle").exists()
- || new File(project.getBasedir(), "build.gradle.kts").exists()) {
- // Gradle project
- buildTool = BuildTool.GRADLE;
}
-
- if (platformDescr == null) {
- platformDescr = CreateUtils.resolvePlatformDescriptor(bomGroupId, bomArtifactId, bomVersion, mvn, getLog());
- }
-
- doExecute(QuarkusProject.of(project.getBasedir().toPath(), platformDescr, buildTool), log);
- } catch (IOException e) {
- throw new MojoExecutionException("Failed to initialize project reading tools", e);
+ return CreateUtils.resolvePlatformDescriptor(bomGroupId, bomArtifactId, bomVersion, mvn, getLog());
+ } catch (Exception e) {
+ throw new MojoExecutionException("Failed to initialize maven artifact resolver", e);
}
}
@@ -166,10 +150,10 @@ protected void validateParameters() throws MojoExecutionException {
protected abstract void doExecute(QuarkusProject quarkusProject, MessageWriter log)
throws MojoExecutionException;
- private String resolveValue(String expr, BuildFile buildFile) throws IOException {
+ private String resolveValue(String expr) throws IOException {
if (expr.startsWith("${") && expr.endsWith("}")) {
final String name = expr.substring(2, expr.length() - 1);
- final String v = buildFile.getProperty(name);
+ final String v = project.getModel().getProperties().getProperty(name);
if (v == null) {
if (getLog().isDebugEnabled()) {
getLog().debug("Failed to resolve property " + name);
@@ -179,4 +163,10 @@ private String resolveValue(String expr, BuildFile buildFile) throws IOException
}
return expr;
}
+
+ private List getManagedDependencies() throws IOException {
+ final DependencyManagement managed = project.getModel().getDependencyManagement();
+ return managed != null ? managed.getDependencies()
+ : Collections.emptyList();
+ }
}
diff --git a/devtools/maven/src/main/java/io/quarkus/maven/RemoveExtensionMojo.java b/devtools/maven/src/main/java/io/quarkus/maven/RemoveExtensionMojo.java
index 827f258f59243..165c951bc4cd6 100644
--- a/devtools/maven/src/main/java/io/quarkus/maven/RemoveExtensionMojo.java
+++ b/devtools/maven/src/main/java/io/quarkus/maven/RemoveExtensionMojo.java
@@ -10,8 +10,8 @@
import org.apache.maven.plugins.annotations.Mojo;
import org.apache.maven.plugins.annotations.Parameter;
-import io.quarkus.cli.commands.QuarkusCommandOutcome;
-import io.quarkus.cli.commands.RemoveExtensions;
+import io.quarkus.devtools.commands.RemoveExtensions;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
import io.quarkus.devtools.project.QuarkusProject;
import io.quarkus.platform.tools.MessageWriter;
@@ -22,7 +22,7 @@
* parameters.
*/
@Mojo(name = "remove-extension")
-public class RemoveExtensionMojo extends BuildFileMojoBase {
+public class RemoveExtensionMojo extends QuarkusProjectMojoBase {
/**
* The list of extensions to be removed.
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/CreateProjectCommandHandler.java b/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/CreateProjectCommandHandler.java
deleted file mode 100644
index 3bd04bea6cd84..0000000000000
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/CreateProjectCommandHandler.java
+++ /dev/null
@@ -1,65 +0,0 @@
-package io.quarkus.cli.commands;
-
-import static io.quarkus.generators.ProjectGenerator.*;
-
-import io.quarkus.devtools.buildfile.BuildFile;
-import io.quarkus.devtools.writer.FileProjectWriter;
-import io.quarkus.devtools.writer.ProjectWriter;
-import io.quarkus.generators.ProjectGeneratorRegistry;
-import io.quarkus.generators.SourceType;
-import io.quarkus.generators.rest.BasicRestProjectGenerator;
-import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
-import io.quarkus.platform.tools.ToolsUtils;
-import java.io.IOException;
-import java.util.Properties;
-
-/**
- * Instances of this class are thread-safe. They create a new project extracting all the necessary properties from an instance
- * of {@link QuarkusCommandInvocation}.
- */
-public class CreateProjectCommandHandler implements QuarkusCommand {
-
- @Override
- public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws QuarkusCommandException {
- final ProjectWriter projectWriter = new FileProjectWriter(
- invocation.getQuarkusProject().getProjectFolderPath().toFile());
- if (!projectWriter.init()) {
- return QuarkusCommandOutcome.failure();
- }
-
- final QuarkusPlatformDescriptor platformDescr = invocation.getPlatformDescriptor();
- invocation.setValue(BOM_GROUP_ID, platformDescr.getBomGroupId());
- invocation.setValue(BOM_ARTIFACT_ID, platformDescr.getBomArtifactId());
- invocation.setValue(QUARKUS_VERSION, platformDescr.getQuarkusVersion());
- invocation.setValue(BOM_VERSION, platformDescr.getBomVersion());
-
- final Properties quarkusProps = ToolsUtils.readQuarkusProperties(platformDescr);
- quarkusProps.forEach((k, v) -> invocation.setValue(k.toString().replace("-", "_"), v.toString()));
-
- try (BuildFile buildFile = invocation.getBuildFile()) {
- String className = invocation.getStringValue(CLASS_NAME);
- if (className != null) {
- className = invocation.getValue(SOURCE_TYPE, SourceType.JAVA).stripExtensionFrom(className);
- int idx = className.lastIndexOf('.');
- if (idx >= 0) {
- String pkgName = invocation.getStringValue(PACKAGE_NAME);
- if (pkgName == null) {
- invocation.setValue(PACKAGE_NAME, className.substring(0, idx));
- }
- className = className.substring(idx + 1);
- }
- invocation.setValue(CLASS_NAME, className);
- }
- ProjectGeneratorRegistry.get(BasicRestProjectGenerator.NAME).generate(projectWriter, invocation);
-
- // call close at the end to save file
- buildFile.completeFile(invocation.getStringValue(PROJECT_GROUP_ID),
- invocation.getStringValue(PROJECT_ARTIFACT_ID),
- invocation.getStringValue(PROJECT_VERSION),
- platformDescr, quarkusProps);
- } catch (IOException e) {
- throw new QuarkusCommandException("Failed to create project", e);
- }
- return QuarkusCommandOutcome.success();
- }
-}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/ListExtensionsCommandHandler.java b/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/ListExtensionsCommandHandler.java
deleted file mode 100644
index 4f5f1fe82ea24..0000000000000
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/ListExtensionsCommandHandler.java
+++ /dev/null
@@ -1,167 +0,0 @@
-package io.quarkus.cli.commands;
-
-import io.quarkus.dependencies.Extension;
-import io.quarkus.devtools.buildfile.BuildFile;
-import io.quarkus.devtools.buildfile.GradleBuildFile;
-import java.io.IOException;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import java.util.function.Consumer;
-import java.util.regex.Pattern;
-import java.util.stream.Collectors;
-import java.util.stream.Stream;
-import org.apache.maven.model.Dependency;
-
-/**
- * Instances of this class are thread-safe. It lists extensions according to the options passed in as properties of
- * {@link QuarkusCommandInvocation}
- */
-public class ListExtensionsCommandHandler implements QuarkusCommand {
-
- private static final String FULL_FORMAT = "%-8s %-50s %-50s %-25s%n%s";
- private static final String CONCISE_FORMAT = "%-50s %-50s";
- private static final String NAME_FORMAT = "%-50s";
-
- @Override
- public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws QuarkusCommandException {
-
- final boolean all = invocation.getValue(ListExtensions.ALL, true);
- final String format = invocation.getValue(ListExtensions.FORMAT, "concise");
- final String search = invocation.getValue(ListExtensions.SEARCH, "*");
-
- Map installed;
- try {
- installed = findInstalled(invocation);
- } catch (IOException e) {
- throw new QuarkusCommandException("Failed to determine the list of installed extensions", e);
- }
-
- Stream extensionsStream = invocation.getPlatformDescriptor().getExtensions().stream();
- extensionsStream = extensionsStream.filter(e -> filterUnlisted(e));
- if (search != null && !"*".equalsIgnoreCase(search)) {
- final Pattern searchPattern = Pattern.compile(".*" + search + ".*", Pattern.CASE_INSENSITIVE);
- extensionsStream = extensionsStream.filter(e -> filterBySearch(searchPattern, e));
- }
- List loadedExtensions = extensionsStream.collect(Collectors.toList());
-
- if (loadedExtensions.isEmpty()) {
- System.out.println("No extension found with this pattern");
- } else {
- String extensionStatus = all ? "available" : "installable";
- System.out.println(String.format("%nCurrent Quarkus extensions %s: ", extensionStatus));
-
- Consumer currentFormatter;
- switch (format.toLowerCase()) {
- case "name":
- currentFormatter = this::nameFormatter;
- break;
- case "full":
- currentFormatter = this::fullFormatter;
- currentFormatter.accept(new String[] { "Status", "Extension", "ArtifactId", "Updated Version", "Guide" });
- break;
- case "concise":
- default:
- currentFormatter = this::conciseFormatter;
- }
-
- final BuildFile buildFile = invocation.getBuildFile();
- loadedExtensions.forEach(extension -> display(extension, installed, all, currentFormatter, buildFile));
-
- if (buildFile != null) {
- if ("concise".equalsIgnoreCase(format)) {
- if (buildFile instanceof GradleBuildFile) {
- System.out.println("\nTo get more information, append --format=full to your command line.");
- } else {
- System.out.println(
- "\nTo get more information, append -Dquarkus.extension.format=full to your command line.");
- }
- }
-
- if (buildFile instanceof GradleBuildFile) {
- System.out.println("\nAdd an extension to your project by adding the dependency to your " +
- "build.gradle or use `./gradlew addExtension --extensions=\"artifactId\"`");
- } else {
- System.out.println("\nAdd an extension to your project by adding the dependency to your " +
- "pom.xml or use `./mvnw quarkus:add-extension -Dextensions=\"artifactId\"`");
- }
- }
- }
-
- return QuarkusCommandOutcome.success();
- }
-
- Map findInstalled(QuarkusCommandInvocation invocation) throws IOException {
- return invocation.getBuildFile().findInstalled();
- }
-
- private boolean filterUnlisted(Extension e) {
- return !e.getMetadata().containsKey("unlisted");
- }
-
- private boolean filterBySearch(final Pattern searchPattern, Extension e) {
- return searchPattern.matcher(e.getName()).matches();
- }
-
- private void conciseFormatter(String[] cols) {
- System.out.println(String.format(CONCISE_FORMAT, cols[1], cols[2], cols[4]));
- }
-
- private void fullFormatter(String[] cols) {
- System.out.println(String.format(FULL_FORMAT, cols[0], cols[1], cols[2], cols[3], cols[4]));
- }
-
- private void nameFormatter(String[] cols) {
- System.out.println(String.format(NAME_FORMAT, cols[2]));
- }
-
- private void display(Extension extension, final Map installed, boolean all,
- Consumer formatter, BuildFile buildFile) {
- final Dependency dependency = installed.get(extension.getGroupId() + ":" + extension.getArtifactId());
- if (!all && dependency != null) {
- return;
- }
-
- String label = "";
- String version = "";
-
- final String extracted = extractVersion(dependency, buildFile);
- if (extracted != null) {
- if (extracted.equalsIgnoreCase(extension.getVersion())) {
- label = "current";
- version = String.format("%s", extracted);
- } else {
- label = "update";
- version = String.format("%s <> %s", extracted, extension.getVersion());
- }
- }
-
- String[] result = new String[] { label, extension.getName(), extension.getArtifactId(), version, extension.getGuide() };
-
- for (int i = 0; i < result.length; i++) {
- result[i] = Objects.toString(result[i], "");
- }
-
- formatter.accept(result);
- }
-
- private String extractVersion(final Dependency dependency, BuildFile buildFile) {
- String version = dependency != null ? dependency.getVersion() : null;
- if (version != null && version.startsWith("$") && buildFile != null) {
- String value = null;
- try {
- value = (String) buildFile.getProperty(propertyName(version));
- } catch (IOException e) {
- // ignore this error.
- }
- if (value != null) {
- version = value;
- }
- }
- return version;
- }
-
- private String propertyName(final String variable) {
- return variable.substring(2, variable.length() - 1);
- }
-}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/Printer.java b/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/Printer.java
deleted file mode 100644
index 1b74c43ca230b..0000000000000
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/Printer.java
+++ /dev/null
@@ -1,24 +0,0 @@
-package io.quarkus.cli.commands;
-
-public class Printer {
- private static final String OK = "\u2705";
- static final String NOK = "\u274c";
- private static final String NOOP = "\uD83D\uDC4D";
-
- public void nok(String content) {
- print(NOK + content);
- }
-
- public void ok(String content) {
- print(OK + content);
- }
-
- public void noop(String content) {
- print(NOOP + content);
- }
-
- void print(String message) {
- System.out.println(message);
- }
-
-}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommand.java b/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommand.java
deleted file mode 100644
index 31025343198fd..0000000000000
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommand.java
+++ /dev/null
@@ -1,6 +0,0 @@
-package io.quarkus.cli.commands;
-
-public interface QuarkusCommand {
-
- QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws QuarkusCommandException;
-}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/RemoveExtensionsCommandHandler.java b/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/RemoveExtensionsCommandHandler.java
deleted file mode 100644
index 24aea2fa73a71..0000000000000
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/RemoveExtensionsCommandHandler.java
+++ /dev/null
@@ -1,79 +0,0 @@
-package io.quarkus.cli.commands;
-
-import io.quarkus.dependencies.Extension;
-import io.quarkus.devtools.buildfile.BuildFile;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Set;
-
-/**
- * This class is thread-safe. It extracts extensions to be removed from the project from an instance of
- * {@link QuarkusCommandInvocation}.
- */
-public class RemoveExtensionsCommandHandler implements QuarkusCommand {
-
- final static Printer PRINTER = new Printer();
-
- @Override
- public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws QuarkusCommandException {
- final Set extensions = invocation.getValue(RemoveExtensions.EXTENSIONS, Collections.emptySet());
- if (extensions.isEmpty()) {
- return QuarkusCommandOutcome.success().setValue(RemoveExtensions.OUTCOME_UPDATED, false);
- }
-
- boolean updated = false;
- boolean success = true;
-
- final List registry = invocation.getPlatformDescriptor().getExtensions();
- final BuildFile buildFile = invocation.getBuildFile();
-
- try {
- for (String query : extensions) {
-
- if (query.contains(":")) {
- // GAV case.
- updated = buildFile.removeExtensionAsGAV(query) || updated;
- } else {
- SelectionResult result = AddExtensionsCommandHandler.select(query, registry, false);
- if (!result.matches()) {
- StringBuilder sb = new StringBuilder();
- // We have 3 cases, we can still have a single candidate, but the match is on label
- // or we have several candidates, or none
- Set candidates = result.getExtensions();
- if (candidates.isEmpty()) {
- // No matches at all.
- PRINTER.nok(" Cannot find a dependency matching '" + query + "', maybe a typo?");
- success = false;
- } else {
- sb.append(Printer.NOK).append(" Multiple extensions matching '").append(query).append("'");
- result.getExtensions()
- .forEach(extension -> sb.append(System.lineSeparator()).append(" * ")
- .append(extension.managementKey()));
- sb.append(System.lineSeparator())
- .append(" Be more specific e.g using the exact name");
- PRINTER.print(sb.toString());
- success = false;
- }
- } else { // Matches.
- for (Extension extension : result) {
- updated = buildFile.removeDependency(invocation.getPlatformDescriptor(), extension) || updated;
- }
- }
- }
- }
- } catch (IOException e) {
- throw new QuarkusCommandException("Failed to add extensions", e);
- }
-
- if (updated) {
- try {
- buildFile.close();
- } catch (IOException e) {
- throw new QuarkusCommandException("Failed to update the project", e);
- }
- }
-
- return new QuarkusCommandOutcome(success).setValue(RemoveExtensions.OUTCOME_UPDATED, updated);
- }
-}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/buildfile/BuildFile.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/buildfile/BuildFile.java
deleted file mode 100644
index 725e0a2e5e8d1..0000000000000
--- a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/buildfile/BuildFile.java
+++ /dev/null
@@ -1,170 +0,0 @@
-package io.quarkus.devtools.buildfile;
-
-import static com.google.common.base.Preconditions.checkNotNull;
-import static io.quarkus.maven.utilities.MojoUtils.credentials;
-import static java.util.stream.Collectors.toList;
-
-import io.quarkus.cli.commands.Printer;
-import io.quarkus.dependencies.Extension;
-import io.quarkus.devtools.project.BuildTool;
-import io.quarkus.devtools.writer.ProjectWriter;
-import io.quarkus.maven.utilities.MojoUtils;
-import io.quarkus.maven.utilities.QuarkusDependencyPredicate;
-import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
-import java.io.Closeable;
-import java.io.IOException;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-import java.util.Properties;
-import java.util.TreeMap;
-import org.apache.maven.model.Dependency;
-
-public abstract class BuildFile implements Closeable {
-
- protected final static Printer PRINTER = new Printer();
-
- private final ProjectWriter writer;
-
- private final BuildTool buildTool;
-
- public BuildFile(final ProjectWriter writer, BuildTool buildTool) {
- this.writer = checkNotNull(writer, "writer is required");
- this.buildTool = checkNotNull(buildTool, "buildTool is required");
- }
-
- protected void write(String fileName, String content) throws IOException {
- writer.write(fileName, content);
- }
-
- public boolean addDependency(QuarkusPlatformDescriptor platform, Extension extension) throws IOException {
- if (!hasDependency(extension)) {
- PRINTER.ok(" Adding extension " + extension.managementKey());
- Dependency dep;
- if (containsBOM(platform.getBomGroupId(), platform.getBomArtifactId())
- && isDefinedInBom(platform.getManagedDependencies(), extension)) {
- dep = extension.toDependency(true);
- } else {
- dep = extension.toDependency(false);
- if (getProperty(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_VERSION_NAME) != null) {
- dep.setVersion(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_VERSION_VALUE);
- }
- }
- addDependencyInBuildFile(dep);
- return true;
- } else {
- PRINTER.noop(" Skipping already present extension " + extension.managementKey());
- return false;
- }
- }
-
- public boolean removeDependency(QuarkusPlatformDescriptor platform, Extension extension) throws IOException {
- if (hasDependency(extension)) {
- PRINTER.ok(" Removing extension " + extension.managementKey());
- Dependency dep;
- if (containsBOM(platform.getBomGroupId(), platform.getBomArtifactId())
- && isDefinedInBom(platform.getManagedDependencies(), extension)) {
- dep = extension.toDependency(true);
- } else {
- dep = extension.toDependency(false);
- if (getProperty(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_VERSION_NAME) != null) {
- dep.setVersion(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_VERSION_VALUE);
- }
- }
- removeDependencyFromBuildFile(dep);
- return true;
- } else {
- PRINTER.noop(" Skipping extension that does not exists " + extension.managementKey());
- return false;
- }
- }
-
- protected abstract void addDependencyInBuildFile(Dependency dependency) throws IOException;
-
- protected abstract void removeDependencyFromBuildFile(Dependency dependency) throws IOException;
-
- protected abstract boolean hasDependency(Extension extension) throws IOException;
-
- public boolean addExtensionAsGAV(String query) throws IOException {
- Dependency parsed = MojoUtils.parse(query.trim());
- boolean alreadyThere = getDependencies().stream()
- .anyMatch(d -> d.getManagementKey().equalsIgnoreCase(parsed.getManagementKey()));
- if (!alreadyThere) {
- PRINTER.ok(" Adding dependency " + parsed.getManagementKey());
- addDependencyInBuildFile(parsed);
- return true;
- } else {
- PRINTER.noop(" Skipping already present dependency " + parsed.getManagementKey());
- return false;
- }
- }
-
- public boolean removeExtensionAsGAV(String query) throws IOException {
- Dependency parsed = MojoUtils.parse(query.trim());
- PRINTER.ok(" Removing dependency " + parsed.getManagementKey());
- removeDependencyFromBuildFile(parsed);
- return true;
- }
-
- protected boolean isDefinedInBom(List dependencies, Extension extension) {
- return dependencies.stream().anyMatch(dependency -> dependency.getGroupId().equalsIgnoreCase(extension.getGroupId())
- && dependency.getArtifactId().equalsIgnoreCase(extension.getArtifactId()));
- }
-
- protected abstract boolean containsBOM(String groupId, String artifactId) throws IOException;
-
- public abstract List getDependencies() throws IOException;
-
- public Map findInstalled() throws IOException {
- return mapDependencies(getDependencies(), loadManaged());
- }
-
- private Map loadManaged() throws IOException {
- final List managedDependencies = getManagedDependencies();
- return managedDependencies.isEmpty() ? Collections.emptyMap()
- : mapDependencies(managedDependencies, Collections.emptyMap());
- }
-
- protected Map mapDependencies(final List dependencies,
- final Map managed) {
- final Map map = new TreeMap<>();
-
- if (dependencies != null) {
- final List listed = dependencies.stream()
- // THIS ASSUMES EXTENSIONS' groupId is always 'io.quarkus' which is wrong
- .filter(new QuarkusDependencyPredicate())
- .collect(toList());
-
- listed.forEach(d -> {
- if (d.getVersion() == null) {
- final Dependency managedDep = managed.get(credentials(d));
- if (managedDep != null) {
- final String version = managedDep.getVersion();
- if (version != null) {
- d.setVersion(version);
- }
- }
- }
-
- map.put(credentials(d), d);
- });
- }
- return map;
- }
-
- public abstract String getProperty(String propertyName) throws IOException;
-
- protected abstract List getManagedDependencies() throws IOException;
-
- public abstract void completeFile(String groupId, String artifactId, String version, QuarkusPlatformDescriptor platform,
- Properties props) throws IOException;
-
- public BuildTool getBuildTool() {
- return buildTool;
- }
-
- protected ProjectWriter getWriter() {
- return writer;
- }
-
-}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/buildfile/MavenBuildFile.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/buildfile/MavenBuildFile.java
deleted file mode 100644
index df55a72c8e6bd..0000000000000
--- a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/buildfile/MavenBuildFile.java
+++ /dev/null
@@ -1,261 +0,0 @@
-package io.quarkus.devtools.buildfile;
-
-import static io.quarkus.maven.utilities.MojoUtils.configuration;
-import static io.quarkus.maven.utilities.MojoUtils.plugin;
-
-import io.quarkus.dependencies.Extension;
-import io.quarkus.devtools.project.BuildTool;
-import io.quarkus.devtools.writer.ProjectWriter;
-import io.quarkus.maven.utilities.MojoUtils;
-import io.quarkus.maven.utilities.MojoUtils.Element;
-import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
-import io.quarkus.platform.tools.ToolsUtils;
-import java.io.ByteArrayInputStream;
-import java.io.ByteArrayOutputStream;
-import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.List;
-import java.util.Properties;
-import org.apache.maven.model.Activation;
-import org.apache.maven.model.ActivationProperty;
-import org.apache.maven.model.Build;
-import org.apache.maven.model.BuildBase;
-import org.apache.maven.model.Dependency;
-import org.apache.maven.model.DependencyManagement;
-import org.apache.maven.model.Model;
-import org.apache.maven.model.Plugin;
-import org.apache.maven.model.PluginExecution;
-import org.apache.maven.model.PluginManagement;
-import org.apache.maven.model.Profile;
-
-public class MavenBuildFile extends BuildFile {
-
- private Model model;
-
- public MavenBuildFile(ProjectWriter writer) {
- super(writer, BuildTool.MAVEN);
- }
-
- private void initModel() throws IOException {
- if (getWriter().exists(BuildTool.MAVEN.getDependenciesFile())) {
- byte[] content = getWriter().getContent(BuildTool.MAVEN.getDependenciesFile());
- this.model = MojoUtils.readPom(new ByteArrayInputStream(content));
- }
- }
-
- @Override
- public void close() throws IOException {
- if (getModel() == null) {
- return;
- }
- try (ByteArrayOutputStream pomOutputStream = new ByteArrayOutputStream()) {
- MojoUtils.write(getModel(), pomOutputStream);
- write(BuildTool.MAVEN.getDependenciesFile(), pomOutputStream.toString("UTF-8"));
- }
- }
-
- @Override
- protected void addDependencyInBuildFile(Dependency dependency) throws IOException {
- if (getModel() != null) {
- getModel().addDependency(dependency);
- }
- }
-
- @Override
- protected void removeDependencyFromBuildFile(Dependency dependency) throws IOException {
- if (getModel() != null) {
- getModel().getDependencies()
- .removeIf(d -> d.getGroupId().equals(dependency.getGroupId())
- && d.getArtifactId().equals(dependency.getArtifactId()));
- }
- }
-
- @Override
- protected boolean hasDependency(Extension extension) throws IOException {
- return getModel() != null && MojoUtils.hasDependency(getModel(), extension.getGroupId(), extension.getArtifactId());
- }
-
- @Override
- public List getDependencies() throws IOException {
- return getModel() == null ? Collections.emptyList() : getModel().getDependencies();
- }
-
- @Override
- protected boolean containsBOM(String groupId, String artifactId) throws IOException {
- if (getModel() == null || getModel().getDependencyManagement() == null) {
- return false;
- }
- List dependencies = getModel().getDependencyManagement().getDependencies();
- return dependencies.stream()
- // Find bom
- .filter(dependency -> "import".equals(dependency.getScope()))
- .filter(dependency -> "pom".equals(dependency.getType()))
- // Does it matches the bom artifact name
- .anyMatch(dependency -> dependency.getArtifactId()
- .equals(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_ARTIFACT_ID_VALUE)
- && dependency.getGroupId().equals(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_GROUP_ID_VALUE));
- }
-
- @Override
- public void completeFile(String groupId, String artifactId, String version, QuarkusPlatformDescriptor platform,
- Properties props) throws IOException {
- addQuarkusProperties(platform);
- addBom(platform);
- final String pluginGroupId = ToolsUtils.getPluginGroupId(props);
- final String pluginArtifactId = ToolsUtils.getPluginArtifactId(props);
- addMainPluginConfig(pluginGroupId, pluginArtifactId);
- addNativeProfile(pluginGroupId, pluginArtifactId);
- }
-
- private void addBom(QuarkusPlatformDescriptor platform) throws IOException {
- boolean hasBom = false;
- DependencyManagement dm = getModel().getDependencyManagement();
- if (dm == null) {
- dm = new DependencyManagement();
- getModel().setDependencyManagement(dm);
- } else {
- hasBom = containsBOM(platform.getBomGroupId(), platform.getBomArtifactId());
- }
-
- if (!hasBom) {
- Dependency bom = new Dependency();
- bom.setGroupId(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_GROUP_ID_VALUE);
- bom.setArtifactId(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_ARTIFACT_ID_VALUE);
- bom.setVersion(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_VERSION_VALUE);
- bom.setType("pom");
- bom.setScope("import");
-
- dm.addDependency(bom);
- }
- }
-
- private void addNativeProfile(String pluginGroupId, String pluginArtifactId) throws IOException {
- final boolean match = getModel().getProfiles().stream().anyMatch(p -> p.getId().equals("native"));
- if (!match) {
- PluginExecution exec = new PluginExecution();
- exec.addGoal("native-image");
- exec.setConfiguration(configuration(new Element("enableHttpUrlHandler", "true")));
-
- Plugin plg = plugin(pluginGroupId, pluginArtifactId, MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLUGIN_VERSION_VALUE);
- plg.addExecution(exec);
-
- BuildBase buildBase = new BuildBase();
- buildBase.addPlugin(plg);
-
- Profile profile = new Profile();
- profile.setId("native");
- profile.setBuild(buildBase);
-
- final Activation activation = new Activation();
- final ActivationProperty property = new ActivationProperty();
- property.setName("native");
-
- activation.setProperty(property);
- profile.setActivation(activation);
- getModel().addProfile(profile);
- }
- }
-
- private void addMainPluginConfig(String groupId, String artifactId) throws IOException {
- if (!hasPlugin(groupId, artifactId)) {
- Build build = createBuildSectionIfRequired();
- Plugin plugin = plugin(groupId, artifactId, MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLUGIN_VERSION_VALUE);
- if (isParentPom()) {
- addPluginManagementSection(plugin);
- //strip the quarkusVersion off
- plugin = plugin(groupId, artifactId);
- }
- PluginExecution pluginExec = new PluginExecution();
- pluginExec.addGoal("build");
- plugin.addExecution(pluginExec);
- build.getPlugins().add(plugin);
- }
- }
-
- private boolean hasPlugin(String groupId, String artifactId) throws IOException {
- if (getModel() == null) {
- return false;
- }
- List plugins = null;
- final Build build = getModel().getBuild();
- if (build != null) {
- if (isParentPom()) {
- final PluginManagement management = build.getPluginManagement();
- if (management != null) {
- plugins = management.getPlugins();
- }
- } else {
- plugins = build.getPlugins();
- }
- }
- return plugins != null && build.getPlugins()
- .stream()
- .anyMatch(p -> p.getGroupId().equalsIgnoreCase(groupId) &&
- p.getArtifactId().equalsIgnoreCase(artifactId));
- }
-
- private void addPluginManagementSection(Plugin plugin) throws IOException {
- final Build build = getModel().getBuild();
- if (build != null && build.getPluginManagement() != null) {
- if (build.getPluginManagement().getPlugins() == null) {
- build.getPluginManagement().setPlugins(new ArrayList<>());
- }
- build.getPluginManagement().getPlugins().add(plugin);
- }
- }
-
- private Build createBuildSectionIfRequired() throws IOException {
- Build build = getModel().getBuild();
- if (build == null) {
- build = new Build();
- getModel().setBuild(build);
- }
- if (build.getPlugins() == null) {
- build.setPlugins(new ArrayList<>());
- }
- return build;
- }
-
- private void addQuarkusProperties(QuarkusPlatformDescriptor platform) throws IOException {
- Properties properties = getModel().getProperties();
- if (properties == null) {
- properties = new Properties();
- getModel().setProperties(properties);
- }
- properties.putIfAbsent(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLUGIN_VERSION_NAME,
- ToolsUtils.getPluginVersion(ToolsUtils.readQuarkusProperties(platform)));
- properties.putIfAbsent(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_GROUP_ID_NAME, platform.getBomGroupId());
- properties.putIfAbsent(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_ARTIFACT_ID_NAME, platform.getBomArtifactId());
- properties.putIfAbsent(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_VERSION_NAME, platform.getBomVersion());
- }
-
- private boolean isParentPom() throws IOException {
- return getModel() != null && "pom".equals(getModel().getPackaging());
- }
-
- @Override
- public List getManagedDependencies() throws IOException {
- if (getModel() == null) {
- return Collections.emptyList();
- }
- final DependencyManagement managed = getModel().getDependencyManagement();
- return managed != null ? managed.getDependencies()
- : Collections.emptyList();
- }
-
- @Override
- public String getProperty(String propertyName) throws IOException {
- if (getModel() == null) {
- return null;
- }
- return getModel().getProperties().getProperty(propertyName);
- }
-
- private Model getModel() throws IOException {
- if (model == null) {
- initModel();
- }
- return model;
- }
-}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/AddExtensions.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/AddExtensions.java
similarity index 52%
rename from independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/AddExtensions.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/AddExtensions.java
index b0b1462bae823..c959edadc6c40 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/AddExtensions.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/AddExtensions.java
@@ -1,6 +1,13 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+import io.quarkus.devtools.commands.handlers.AddExtensionsCommandHandler;
import io.quarkus.devtools.project.QuarkusProject;
+import io.quarkus.devtools.project.extensions.ExtensionsManager;
import io.quarkus.platform.tools.ToolsConstants;
import io.quarkus.platform.tools.ToolsUtils;
import java.util.Set;
@@ -13,19 +20,26 @@ public class AddExtensions {
public static final String NAME = "add-extensions";
public static final String EXTENSIONS = ToolsUtils.dotJoin(ToolsConstants.QUARKUS, NAME, "extensions");
public static final String OUTCOME_UPDATED = ToolsUtils.dotJoin(ToolsConstants.QUARKUS, NAME, "outcome", "updated");
+ public static final String EXTENSIONS_MANAGER = ToolsUtils.dotJoin(ToolsConstants.QUARKUS, NAME, "extensions-manager");
private final QuarkusCommandInvocation invocation;
+ private final AddExtensionsCommandHandler handler = new AddExtensionsCommandHandler();
public AddExtensions(final QuarkusProject quarkusProject) {
this.invocation = new QuarkusCommandInvocation(quarkusProject);
}
+ public AddExtensions extensionsManager(ExtensionsManager extensionsManager) {
+ invocation.setValue(EXTENSIONS_MANAGER, checkNotNull(extensionsManager, "extensionsManager is required"));
+ return this;
+ }
+
public AddExtensions extensions(Set extensions) {
invocation.setValue(EXTENSIONS, extensions);
return this;
}
public QuarkusCommandOutcome execute() throws QuarkusCommandException {
- return new AddExtensionsCommandHandler().execute(invocation);
+ return handler.execute(invocation);
}
}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/CreateProject.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/CreateProject.java
similarity index 81%
rename from independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/CreateProject.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/CreateProject.java
index 0f01b9bc452fc..44ee7e46a2a3e 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/CreateProject.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/CreateProject.java
@@ -1,17 +1,22 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
import static com.google.common.base.Preconditions.checkNotNull;
-import static io.quarkus.generators.ProjectGenerator.CLASS_NAME;
-import static io.quarkus.generators.ProjectGenerator.IS_SPRING;
-import static io.quarkus.generators.ProjectGenerator.JAVA_TARGET;
-import static io.quarkus.generators.ProjectGenerator.PROJECT_ARTIFACT_ID;
-import static io.quarkus.generators.ProjectGenerator.PROJECT_GROUP_ID;
-import static io.quarkus.generators.ProjectGenerator.PROJECT_VERSION;
-import static io.quarkus.generators.ProjectGenerator.SOURCE_TYPE;
-
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.CLASS_NAME;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.EXTENSIONS;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.IS_SPRING;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.JAVA_TARGET;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.PROJECT_ARTIFACT_ID;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.PROJECT_GROUP_ID;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.PROJECT_VERSION;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.SOURCE_TYPE;
+
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+import io.quarkus.devtools.commands.handlers.CreateProjectCommandHandler;
import io.quarkus.devtools.project.BuildTool;
import io.quarkus.devtools.project.QuarkusProject;
-import io.quarkus.generators.SourceType;
+import io.quarkus.devtools.project.codegen.SourceType;
import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
import java.io.IOException;
import java.nio.file.Path;
@@ -81,14 +86,11 @@ public CreateProject className(String className) {
return this;
}
- /**
- * @deprecated in 1.3.0.CR
- */
- @Deprecated
public CreateProject extensions(Set extensions) {
if (isSpringStyle(extensions)) {
setValue(IS_SPRING, true);
}
+ setValue(EXTENSIONS, extensions);
return this;
}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/ListExtensions.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/ListExtensions.java
similarity index 65%
rename from independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/ListExtensions.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/ListExtensions.java
index 6f9fd3adbc438..05b6d85c9808f 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/ListExtensions.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/ListExtensions.java
@@ -1,11 +1,15 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+import io.quarkus.devtools.commands.handlers.ListExtensionsCommandHandler;
import io.quarkus.devtools.project.QuarkusProject;
+import io.quarkus.devtools.project.extensions.ExtensionsManager;
import io.quarkus.platform.tools.ToolsConstants;
import io.quarkus.platform.tools.ToolsUtils;
-import java.io.IOException;
-import java.util.Map;
-import org.apache.maven.model.Dependency;
/**
* Instances of this class are not thread-safe. They are created per single invocation.
@@ -16,6 +20,7 @@ public class ListExtensions {
public static final String ALL = ToolsUtils.dotJoin(PARAM_PREFIX, "all");
public static final String FORMAT = ToolsUtils.dotJoin(PARAM_PREFIX, "format");
public static final String SEARCH = ToolsUtils.dotJoin(PARAM_PREFIX, "search");
+ public static final String EXTENSIONS_MANAGER = ToolsUtils.dotJoin(PARAM_PREFIX, "extensions-manager");
private final QuarkusCommandInvocation invocation;
private final ListExtensionsCommandHandler handler = new ListExtensionsCommandHandler();
@@ -34,32 +39,17 @@ public ListExtensions format(String format) {
return this;
}
- public ListExtensions search(String search) {
- invocation.setValue(SEARCH, search);
+ public ListExtensions extensionsManager(ExtensionsManager extensionsManager) {
+ invocation.setValue(EXTENSIONS_MANAGER, checkNotNull(extensionsManager, "extensionsManager is required"));
return this;
}
- /**
- * @deprecated in 1.3.0.CR1
- * Please use {@link #all(boolean)}, {@link #format(String)} and {@link #search(String)} respectively.
- */
- @Deprecated
- public void listExtensions(boolean all, String format, String search) throws IOException {
- all(all);
- format(format);
- search(search);
- try {
- execute();
- } catch (QuarkusCommandException e) {
- throw new IOException("Failed to list extensions", e);
- }
+ public ListExtensions search(String search) {
+ invocation.setValue(SEARCH, search);
+ return this;
}
public QuarkusCommandOutcome execute() throws QuarkusCommandException {
return handler.execute(invocation);
}
-
- public Map findInstalled() throws IOException {
- return handler.findInstalled(invocation);
- }
}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/RemoveExtensions.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/RemoveExtensions.java
similarity index 57%
rename from independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/RemoveExtensions.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/RemoveExtensions.java
index 5e6c2b6de8ed5..402eced8af3ff 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/RemoveExtensions.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/RemoveExtensions.java
@@ -1,6 +1,13 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
+import static com.google.common.base.Preconditions.checkNotNull;
+
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+import io.quarkus.devtools.commands.handlers.RemoveExtensionsCommandHandler;
import io.quarkus.devtools.project.QuarkusProject;
+import io.quarkus.devtools.project.extensions.ExtensionsManager;
import io.quarkus.platform.tools.ToolsConstants;
import io.quarkus.platform.tools.ToolsUtils;
import java.util.Set;
@@ -13,6 +20,7 @@ public class RemoveExtensions {
public static final String NAME = "remove-extensions";
public static final String EXTENSIONS = ToolsUtils.dotJoin(ToolsConstants.QUARKUS, NAME, "extensions");
public static final String OUTCOME_UPDATED = ToolsUtils.dotJoin(ToolsConstants.QUARKUS, NAME, "outcome", "updated");
+ public static final String EXTENSIONS_MANAGER = ToolsUtils.dotJoin(ToolsConstants.QUARKUS, NAME, "extensions-manager");
private final QuarkusCommandInvocation invocation;
@@ -25,6 +33,11 @@ public RemoveExtensions extensions(Set extensions) {
return this;
}
+ public RemoveExtensions extensionsManager(ExtensionsManager extensionsManager) {
+ invocation.setValue(EXTENSIONS_MANAGER, checkNotNull(extensionsManager, "extensionsManager is required"));
+ return this;
+ }
+
public QuarkusCommandOutcome execute() throws QuarkusCommandException {
return new RemoveExtensionsCommandHandler().execute(invocation);
}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommandException.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/QuarkusCommandException.java
similarity index 87%
rename from independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommandException.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/QuarkusCommandException.java
index e9545c28ae89f..eb13d45624e73 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommandException.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/QuarkusCommandException.java
@@ -1,4 +1,4 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands.data;
public class QuarkusCommandException extends Exception {
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommandInvocation.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/QuarkusCommandInvocation.java
similarity index 87%
rename from independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommandInvocation.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/QuarkusCommandInvocation.java
index 3f2de476c5a9e..c2ff4b506364f 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommandInvocation.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/QuarkusCommandInvocation.java
@@ -1,8 +1,7 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands.data;
import static com.google.common.base.Preconditions.checkNotNull;
-import io.quarkus.devtools.buildfile.BuildFile;
import io.quarkus.devtools.project.QuarkusProject;
import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
import io.quarkus.platform.tools.DefaultMessageWriter;
@@ -43,11 +42,7 @@ public MessageWriter log() {
}
public QuarkusPlatformDescriptor getPlatformDescriptor() {
- return quarkusProject.getDescriptor();
- }
-
- public BuildFile getBuildFile() {
- return quarkusProject.getBuildFile();
+ return quarkusProject.getPlatformDescriptor();
}
}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommandOutcome.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/QuarkusCommandOutcome.java
similarity index 91%
rename from independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommandOutcome.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/QuarkusCommandOutcome.java
index be8747ea3d9df..e04e6e2f6a283 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/QuarkusCommandOutcome.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/QuarkusCommandOutcome.java
@@ -1,4 +1,4 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands.data;
public class QuarkusCommandOutcome extends ValueMap {
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/SelectionResult.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/SelectionResult.java
similarity index 94%
rename from independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/SelectionResult.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/SelectionResult.java
index 3b51911a5794e..c97d6afcc0a31 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/SelectionResult.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/SelectionResult.java
@@ -1,4 +1,4 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands.data;
import io.quarkus.dependencies.Extension;
import java.util.Collections;
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/ValueMap.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/ValueMap.java
similarity index 83%
rename from independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/ValueMap.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/ValueMap.java
index 7636d9a88b5c6..8d99fc794f6e1 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/ValueMap.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/data/ValueMap.java
@@ -1,4 +1,4 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands.data;
import java.util.HashMap;
import java.util.Map;
@@ -48,6 +48,18 @@ public String getStringValue(String name) {
throw new IllegalStateException("value for '" + name + "' must be a String");
}
+ public boolean getBooleanValue(String name) {
+ final Object value = getValue(name, null);
+ if (value == null) {
+ throw new IllegalStateException("value for '" + name + "' must be defined");
+ }
+
+ if (Boolean.class.equals(value.getClass())) {
+ return ((Boolean) value).booleanValue();
+ }
+ return Boolean.parseBoolean(value.toString());
+ }
+
public boolean getValue(String name, boolean defaultValue) {
final Object value = getValue(name, null);
if (value == null) {
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/AddExtensionsCommandHandler.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/AddExtensionsCommandHandler.java
new file mode 100644
index 0000000000000..5cf56a7e0dc42
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/AddExtensionsCommandHandler.java
@@ -0,0 +1,46 @@
+package io.quarkus.devtools.commands.handlers;
+
+import static io.quarkus.devtools.commands.AddExtensions.EXTENSIONS_MANAGER;
+import static io.quarkus.devtools.commands.handlers.QuarkusCommandHandlers.computeExtensionsFromQuery;
+
+import io.quarkus.dependencies.Extension;
+import io.quarkus.devtools.commands.AddExtensions;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+import io.quarkus.devtools.project.extensions.ExtensionsManager;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is thread-safe. It extracts extensions to be added to the project from an instance of
+ * {@link QuarkusCommandInvocation}.
+ */
+public class AddExtensionsCommandHandler implements QuarkusCommandHandler {
+
+ @Override
+ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws QuarkusCommandException {
+ final Set extensionsQuery = invocation.getValue(AddExtensions.EXTENSIONS, Collections.emptySet());
+ if (extensionsQuery.isEmpty()) {
+ return QuarkusCommandOutcome.success().setValue(AddExtensions.OUTCOME_UPDATED, false);
+ }
+
+ final List extensionsToAdd = computeExtensionsFromQuery(invocation, extensionsQuery);
+ final ExtensionsManager extensionsManager = invocation.getValue(EXTENSIONS_MANAGER,
+ invocation.getQuarkusProject().getExtensionsManager());
+ try {
+ if (extensionsToAdd != null) {
+ final int added = extensionsManager.add(extensionsToAdd);
+ return new QuarkusCommandOutcome(true).setValue(AddExtensions.OUTCOME_UPDATED, added > 0);
+ }
+
+ } catch (IOException e) {
+ throw new QuarkusCommandException("Failed to add extensions", e);
+ }
+
+ return new QuarkusCommandOutcome(false).setValue(AddExtensions.OUTCOME_UPDATED, false);
+ }
+
+}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/CreateProjectCommandHandler.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/CreateProjectCommandHandler.java
new file mode 100644
index 0000000000000..d6a4d1569c2ee
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/CreateProjectCommandHandler.java
@@ -0,0 +1,82 @@
+package io.quarkus.devtools.commands.handlers;
+
+import static io.quarkus.devtools.commands.handlers.QuarkusCommandHandlers.computeExtensionsFromQuery;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.*;
+
+import io.quarkus.dependencies.Extension;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+import io.quarkus.devtools.project.BuildTool;
+import io.quarkus.devtools.project.buildfile.GradleBuildFilesCreator;
+import io.quarkus.devtools.project.codegen.ProjectGenerator;
+import io.quarkus.devtools.project.codegen.ProjectGeneratorRegistry;
+import io.quarkus.devtools.project.codegen.SourceType;
+import io.quarkus.devtools.project.codegen.rest.BasicRestProjectGenerator;
+import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
+import io.quarkus.platform.tools.ToolsUtils;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Properties;
+import java.util.Set;
+
+/**
+ * Instances of this class are thread-safe. They create a new project extracting all the necessary properties from an instance
+ * of {@link QuarkusCommandInvocation}.
+ */
+public class CreateProjectCommandHandler implements QuarkusCommandHandler {
+
+ @Override
+ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws QuarkusCommandException {
+ final QuarkusPlatformDescriptor platformDescr = invocation.getPlatformDescriptor();
+ invocation.setValue(BOM_GROUP_ID, platformDescr.getBomGroupId());
+ invocation.setValue(BOM_ARTIFACT_ID, platformDescr.getBomArtifactId());
+ invocation.setValue(QUARKUS_VERSION, platformDescr.getQuarkusVersion());
+ invocation.setValue(BOM_VERSION, platformDescr.getBomVersion());
+ final Set extensionsQuery = invocation.getValue(ProjectGenerator.EXTENSIONS, Collections.emptySet());
+
+ final Properties quarkusProps = ToolsUtils.readQuarkusProperties(platformDescr);
+ quarkusProps.forEach((k, v) -> invocation.setValue(k.toString().replace("-", "_"), v.toString()));
+
+ try {
+ String className = invocation.getStringValue(CLASS_NAME);
+ if (className != null) {
+ className = invocation.getValue(SOURCE_TYPE, SourceType.JAVA).stripExtensionFrom(className);
+ int idx = className.lastIndexOf('.');
+ if (idx >= 0) {
+ String pkgName = invocation.getStringValue(PACKAGE_NAME);
+ if (pkgName == null) {
+ invocation.setValue(PACKAGE_NAME, className.substring(0, idx));
+ }
+ className = className.substring(idx + 1);
+ }
+ invocation.setValue(CLASS_NAME, className);
+ }
+
+ final List extensionsToAdd = computeExtensionsFromQuery(invocation, extensionsQuery);
+
+ // extensionsToAdd is null when an error occurred while matching extensions
+ if (extensionsToAdd != null) {
+ ProjectGeneratorRegistry.get(BasicRestProjectGenerator.NAME).generate(invocation);
+
+ //TODO ia3andy extensions should be added directly during the project generation
+ if (invocation.getQuarkusProject().getBuildTool().equals(BuildTool.GRADLE)) {
+ final GradleBuildFilesCreator creator = new GradleBuildFilesCreator(invocation.getQuarkusProject());
+ creator.create(
+ invocation.getStringValue(PROJECT_GROUP_ID),
+ invocation.getStringValue(PROJECT_ARTIFACT_ID),
+ invocation.getStringValue(PROJECT_VERSION),
+ quarkusProps,
+ extensionsToAdd);
+ } else {
+ invocation.getQuarkusProject().getExtensionsManager().add(extensionsToAdd);
+ }
+ }
+
+ } catch (IOException e) {
+ throw new QuarkusCommandException("Failed to create project", e);
+ }
+ return QuarkusCommandOutcome.success();
+ }
+}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/ListExtensionsCommandHandler.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/ListExtensionsCommandHandler.java
new file mode 100644
index 0000000000000..e77e91c55b54f
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/ListExtensionsCommandHandler.java
@@ -0,0 +1,154 @@
+package io.quarkus.devtools.commands.handlers;
+
+import static java.util.stream.Collectors.toMap;
+
+import io.quarkus.dependencies.Extension;
+import io.quarkus.devtools.commands.ListExtensions;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+import io.quarkus.devtools.project.BuildTool;
+import io.quarkus.devtools.project.extensions.ExtensionsManager;
+import io.quarkus.platform.tools.MessageWriter;
+import java.io.IOException;
+import java.util.List;
+import java.util.Map;
+import java.util.Objects;
+import java.util.function.BiConsumer;
+import java.util.function.Function;
+import java.util.regex.Pattern;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
+
+/**
+ * Instances of this class are thread-safe. It lists extensions according to the options passed in as properties of
+ * {@link QuarkusCommandInvocation}
+ */
+public class ListExtensionsCommandHandler implements QuarkusCommandHandler {
+
+ private static final String FULL_FORMAT = "%-8s %-50s %-50s %-25s%n%s";
+ private static final String CONCISE_FORMAT = "%-50s %-50s";
+ private static final String NAME_FORMAT = "%-50s";
+
+ @Override
+ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws QuarkusCommandException {
+
+ final boolean all = invocation.getValue(ListExtensions.ALL, true);
+ final String format = invocation.getValue(ListExtensions.FORMAT, "concise");
+ final String search = invocation.getValue(ListExtensions.SEARCH, "*");
+ final ExtensionsManager extensionsManager = invocation.getValue(ListExtensions.EXTENSIONS_MANAGER,
+ invocation.getQuarkusProject().getExtensionsManager());
+
+ Map installedByGA;
+ try {
+ installedByGA = extensionsManager.read().stream()
+ .collect(toMap(Extension::managementKey, Function.identity()));
+ } catch (IOException e) {
+ throw new QuarkusCommandException("Failed to determine the list of installed extensions", e);
+ }
+
+ Stream platformExtensionsStream = invocation.getPlatformDescriptor().getExtensions().stream();
+ platformExtensionsStream = platformExtensionsStream.filter(this::filterUnlisted);
+ if (search != null && !"*".equalsIgnoreCase(search)) {
+ final Pattern searchPattern = Pattern.compile(".*" + search + ".*", Pattern.CASE_INSENSITIVE);
+ platformExtensionsStream = platformExtensionsStream.filter(e -> filterBySearch(searchPattern, e));
+ }
+ List platformExtensions = platformExtensionsStream.collect(Collectors.toList());
+
+ if (platformExtensions.isEmpty()) {
+ invocation.log().info("No extension found with this pattern");
+ } else {
+ String extensionStatus = all ? "available" : "installable";
+ invocation.log().info(String.format("%nCurrent Quarkus extensions %s: ", extensionStatus));
+
+ BiConsumer currentFormatter;
+ switch (format.toLowerCase()) {
+ case "name":
+ currentFormatter = this::nameFormatter;
+ break;
+ case "full":
+ currentFormatter = this::fullFormatter;
+ currentFormatter.accept(invocation.log(),
+ new String[] { "Status", "Extension", "ArtifactId", "Updated Version", "Guide" });
+ break;
+ case "concise":
+ default:
+ currentFormatter = this::conciseFormatter;
+ }
+
+ platformExtensions.forEach(platformExtension -> display(invocation.log(), platformExtension,
+ installedByGA.get(platformExtension.managementKey()), all, currentFormatter));
+ final BuildTool buildTool = invocation.getQuarkusProject().getBuildTool();
+ if ("concise".equalsIgnoreCase(format)) {
+ if (BuildTool.GRADLE.equals(buildTool)) {
+ invocation.log().info("\nTo get more information, append --format=full to your command line.");
+ } else {
+ invocation.log().info(
+ "\nTo get more information, append -Dquarkus.extension.format=full to your command line.");
+ }
+ }
+
+ if (BuildTool.GRADLE.equals(buildTool)) {
+ invocation.log().info("\nAdd an extension to your project by adding the dependency to your " +
+ "build.gradle or use `./gradlew addExtension --extensions=\"artifactId\"`");
+ } else {
+ invocation.log().info("\nAdd an extension to your project by adding the dependency to your " +
+ "pom.xml or use `./mvnw quarkus:add-extension -Dextensions=\"artifactId\"`");
+ }
+
+ }
+
+ return QuarkusCommandOutcome.success();
+ }
+
+ private boolean filterUnlisted(Extension e) {
+ return !e.getMetadata().containsKey("unlisted");
+ }
+
+ private boolean filterBySearch(final Pattern searchPattern, Extension e) {
+ return searchPattern.matcher(e.getName()).matches();
+ }
+
+ private void conciseFormatter(MessageWriter writer, String[] cols) {
+ writer.info(String.format(CONCISE_FORMAT, cols[1], cols[2], cols[4]));
+ }
+
+ private void fullFormatter(MessageWriter writer, String[] cols) {
+ writer.info(String.format(FULL_FORMAT, cols[0], cols[1], cols[2], cols[3], cols[4]));
+ }
+
+ private void nameFormatter(MessageWriter writer, String[] cols) {
+ writer.info(String.format(NAME_FORMAT, cols[2]));
+ }
+
+ private void display(MessageWriter messageWriter, final Extension platformExtension, final Extension installed, boolean all,
+ BiConsumer formatter) {
+ if (!all && installed != null) {
+ return;
+ }
+
+ String label = "";
+ String version = "";
+
+ final String installedVersion = installed != null ? installed.getVersion() : null;
+ if (installedVersion != null) {
+ if (installedVersion.equalsIgnoreCase(platformExtension.getVersion())) {
+ label = "current";
+ version = String.format("%s", installedVersion);
+ } else {
+ label = "update";
+ version = String.format("%s <> %s", installedVersion, platformExtension.getVersion());
+ }
+ }
+
+ String[] result = new String[] { label, platformExtension.getName(), platformExtension.getArtifactId(), version,
+ platformExtension.getGuide() };
+
+ for (int i = 0; i < result.length; i++) {
+ result[i] = Objects.toString(result[i], "");
+ }
+
+ formatter.accept(messageWriter, result);
+ }
+
+}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/QuarkusCommandHandler.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/QuarkusCommandHandler.java
new file mode 100644
index 0000000000000..dfc372a8b3ce3
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/QuarkusCommandHandler.java
@@ -0,0 +1,10 @@
+package io.quarkus.devtools.commands.handlers;
+
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+
+public interface QuarkusCommandHandler {
+
+ QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws QuarkusCommandException;
+}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/AddExtensionsCommandHandler.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/QuarkusCommandHandlers.java
similarity index 56%
rename from independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/AddExtensionsCommandHandler.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/QuarkusCommandHandlers.java
index 6541aa6992b7c..8ea62d9ea5b62 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/cli/commands/AddExtensionsCommandHandler.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/QuarkusCommandHandlers.java
@@ -1,8 +1,13 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands.handlers;
+import static io.quarkus.platform.tools.ConsoleMessageFormat.NOK;
+import static io.quarkus.platform.tools.ConsoleMessageFormat.nok;
+
+import com.google.common.collect.ImmutableList;
import io.quarkus.dependencies.Extension;
-import io.quarkus.devtools.buildfile.BuildFile;
-import java.io.IOException;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.SelectionResult;
+import io.quarkus.devtools.project.extensions.Extensions;
import java.util.Collections;
import java.util.LinkedHashSet;
import java.util.List;
@@ -11,101 +16,74 @@
import java.util.regex.PatternSyntaxException;
import java.util.stream.Collectors;
-/**
- * This class is thread-safe. It extracts extensions to be added to the project from an instance of
- * {@link QuarkusCommandInvocation}.
- */
-public class AddExtensionsCommandHandler implements QuarkusCommand {
-
- final static Printer PRINTER = new Printer();
-
- @Override
- public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws QuarkusCommandException {
-
- final Set extensions = invocation.getValue(AddExtensions.EXTENSIONS, Collections.emptySet());
- if (extensions.isEmpty()) {
- return QuarkusCommandOutcome.success().setValue(AddExtensions.OUTCOME_UPDATED, false);
- }
-
- boolean updated = false;
- boolean success = true;
+final class QuarkusCommandHandlers {
- final List registry = invocation.getPlatformDescriptor().getExtensions();
+ private QuarkusCommandHandlers() {
+ }
- final BuildFile buildFile = invocation.getBuildFile();
- try {
- for (String query : extensions) {
- if (query.contains(":")) {
- // GAV case.
- updated = buildFile.addExtensionAsGAV(query) || updated;
- } else {
- SelectionResult result = select(query, registry, false);
- if (!result.matches()) {
- StringBuilder sb = new StringBuilder();
- // We have 3 cases, we can still have a single candidate, but the match is on label
- // or we have several candidates, or none
- Set candidates = result.getExtensions();
- if (candidates.isEmpty()) {
- // No matches at all.
- PRINTER.nok(" Cannot find a dependency matching '" + query + "', maybe a typo?");
- success = false;
- } else {
- sb.append(Printer.NOK).append(" Multiple extensions matching '").append(query).append("'");
- result.getExtensions()
- .forEach(extension -> sb.append(System.lineSeparator()).append(" * ")
- .append(extension.managementKey()));
- sb.append(System.lineSeparator())
- .append(" Be more specific e.g using the exact name or the full GAV.");
- PRINTER.print(sb.toString());
- success = false;
- }
- } else { // Matches.
- for (Extension extension : result) {
- // Don't set success to false even if the dependency is not added; as it's should be idempotent.
- updated = buildFile.addDependency(invocation.getPlatformDescriptor(), extension) || updated;
- }
+ static List computeExtensionsFromQuery(final QuarkusCommandInvocation invocation,
+ final Set extensionsQuery) {
+ final ImmutableList.Builder builder = ImmutableList. builder();
+ for (String query : extensionsQuery) {
+ if (query.contains(":")) {
+ builder.add(Extensions.parse(query));
+ } else {
+ SelectionResult result = select(invocation.getPlatformDescriptor().getExtensions(), query, false);
+ if (!result.matches()) {
+ StringBuilder sb = new StringBuilder();
+ // We have 3 cases, we can still have a single candidate, but the match is on label
+ // or we have several candidates, or none
+ Set candidates = result.getExtensions();
+ if (candidates.isEmpty()) {
+ // No matches at all.
+ invocation.log().info(nok(" Cannot find a dependency matching '" + query + "', maybe a typo?"));
+ return null;
+ } else {
+ sb.append(NOK).append(" Multiple extensions matching '").append(query).append("'");
+ result.getExtensions()
+ .forEach(extension -> sb.append(System.lineSeparator()).append(" * ")
+ .append(extension.managementKey()));
+ sb.append(System.lineSeparator())
+ .append(" Be more specific e.g using the exact name or the full GAV.");
+ invocation.log().info(sb.toString());
+ return null;
+ }
+ } else { // Matches.
+ for (Extension extension : result) {
+ // Don't set success to false even if the dependency is not added; as it's should be idempotent.
+ builder.add(extension);
}
}
}
- } catch (IOException e) {
- throw new QuarkusCommandException("Failed to add extensions", e);
- }
-
- if (buildFile != null && updated) {
- try {
- buildFile.close();
- } catch (IOException e) {
- throw new QuarkusCommandException("Failed to update the project", e);
- }
}
-
- return new QuarkusCommandOutcome(success).setValue(AddExtensions.OUTCOME_UPDATED, updated);
+ return builder.build();
}
/**
* Selection algorithm.
*
+ * @param allPlatformExtensions the list of all platform extensions
* @param query the query
- * @param extensions the extension list
* @param labelLookup whether or not the query must be tested against the labels of the extensions. Should
* be {@code false} by default.
* @return the list of matching candidates and whether or not a match has been found.
*/
- static SelectionResult select(String query, List extensions, boolean labelLookup) {
+ static SelectionResult select(final List allPlatformExtensions, final String query, final boolean labelLookup) {
String q = query.trim().toLowerCase();
// Try exact matches
- Set matchesNameOrArtifactId = extensions.stream()
+ Set matchesNameOrArtifactId = allPlatformExtensions.stream()
.filter(extension -> extension.getName().equalsIgnoreCase(q) || matchesArtifactId(extension.getArtifactId(), q))
.collect(Collectors.toSet());
if (matchesNameOrArtifactId.size() == 1) {
return new SelectionResult(matchesNameOrArtifactId, true);
}
- extensions = extensions.stream().filter(e -> !e.isUnlisted()).collect(Collectors.toList());
+ final List listedPlatformExtensions = allPlatformExtensions.stream()
+ .filter(e -> !e.isUnlisted()).collect(Collectors.toList());
// Try short names
- Set matchesShortName = extensions.stream().filter(extension -> matchesShortName(extension, q))
+ Set matchesShortName = listedPlatformExtensions.stream().filter(extension -> matchesShortName(extension, q))
.collect(Collectors.toSet());
if (matchesShortName.size() == 1 && matchesNameOrArtifactId.isEmpty()) {
@@ -113,9 +91,11 @@ static SelectionResult select(String query, List extensions, boolean
}
// Partial matches on name, artifactId and short names
- Set partialMatches = extensions.stream().filter(extension -> extension.getName().toLowerCase().contains(q)
- || extension.getArtifactId().toLowerCase().contains(q)
- || extension.getShortName().toLowerCase().contains(q)).collect(Collectors.toSet());
+ Set partialMatches = listedPlatformExtensions.stream()
+ .filter(extension -> extension.getName().toLowerCase().contains(q)
+ || extension.getArtifactId().toLowerCase().contains(q)
+ || extension.getShortName().toLowerCase().contains(q))
+ .collect(Collectors.toSet());
// Even if we have a single partial match, if the name, artifactId and short names are ambiguous, so not
// consider it as a match.
if (partialMatches.size() == 1 && matchesNameOrArtifactId.isEmpty() && matchesShortName.isEmpty()) {
@@ -125,7 +105,7 @@ static SelectionResult select(String query, List extensions, boolean
// find by labels
List matchesLabels;
if (labelLookup) {
- matchesLabels = extensions.stream()
+ matchesLabels = listedPlatformExtensions.stream()
.filter(extension -> extension.labelsForMatching().contains(q)).collect(Collectors.toList());
} else {
matchesLabels = Collections.emptyList();
@@ -135,7 +115,7 @@ static SelectionResult select(String query, List extensions, boolean
Set matchesPatterns;
Pattern pattern = toRegex(q);
if (pattern != null) {
- matchesPatterns = extensions.stream()
+ matchesPatterns = listedPlatformExtensions.stream()
.filter(extension -> pattern.matcher(extension.getName().toLowerCase()).matches()
|| pattern.matcher(extension.getArtifactId().toLowerCase()).matches()
|| pattern.matcher(extension.getShortName().toLowerCase()).matches()
@@ -229,4 +209,5 @@ private static boolean matchesArtifactId(String artifactId, String q) {
return artifactId.equalsIgnoreCase(q) ||
artifactId.equalsIgnoreCase("quarkus-" + q);
}
+
}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/RemoveExtensionsCommandHandler.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/RemoveExtensionsCommandHandler.java
new file mode 100644
index 0000000000000..d3f8421825c64
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/commands/handlers/RemoveExtensionsCommandHandler.java
@@ -0,0 +1,45 @@
+package io.quarkus.devtools.commands.handlers;
+
+import static io.quarkus.devtools.commands.RemoveExtensions.EXTENSIONS_MANAGER;
+import static io.quarkus.devtools.commands.handlers.QuarkusCommandHandlers.computeExtensionsFromQuery;
+
+import com.google.common.collect.ImmutableSet;
+import io.quarkus.dependencies.Extension;
+import io.quarkus.devtools.commands.RemoveExtensions;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+import io.quarkus.devtools.project.extensions.ExtensionsManager;
+import java.io.IOException;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This class is thread-safe. It extracts extensions to be removed from the project from an instance of
+ * {@link QuarkusCommandInvocation}.
+ */
+public class RemoveExtensionsCommandHandler implements QuarkusCommandHandler {
+
+ @Override
+ public QuarkusCommandOutcome execute(QuarkusCommandInvocation invocation) throws QuarkusCommandException {
+ final Set extensionsQuery = invocation.getValue(RemoveExtensions.EXTENSIONS, Collections.emptySet());
+ if (extensionsQuery.isEmpty()) {
+ return QuarkusCommandOutcome.success().setValue(RemoveExtensions.OUTCOME_UPDATED, false);
+ }
+
+ final List extensionsToRemove = computeExtensionsFromQuery(invocation, extensionsQuery);
+ final ExtensionsManager extensionsManager = invocation.getValue(EXTENSIONS_MANAGER,
+ invocation.getQuarkusProject().getExtensionsManager());
+ try {
+ if (extensionsToRemove != null) {
+ final int removed = extensionsManager.remove(ImmutableSet.copyOf(extensionsToRemove));
+ return new QuarkusCommandOutcome(true).setValue(RemoveExtensions.OUTCOME_UPDATED, removed > 0);
+ }
+ } catch (IOException e) {
+ throw new QuarkusCommandException("Failed to add extensions", e);
+ }
+
+ return new QuarkusCommandOutcome(true).setValue(RemoveExtensions.OUTCOME_UPDATED, false);
+ }
+}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/BuildTool.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/BuildTool.java
index 0987465b3c1b3..78b5a641c834c 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/BuildTool.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/BuildTool.java
@@ -1,11 +1,10 @@
package io.quarkus.devtools.project;
-import static com.google.common.base.Preconditions.checkNotNull;
-
-import io.quarkus.devtools.buildfile.BuildFile;
-import io.quarkus.devtools.buildfile.GradleBuildFile;
-import io.quarkus.devtools.buildfile.MavenBuildFile;
-import io.quarkus.devtools.writer.ProjectWriter;
+import io.quarkus.devtools.project.buildfile.GenericGradleBuildFile;
+import io.quarkus.devtools.project.buildfile.MavenBuildFile;
+import io.quarkus.devtools.project.extensions.ExtensionsManager;
+import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
+import java.nio.file.Path;
/**
* An enum of build tools, such as Maven and Gradle.
@@ -53,14 +52,14 @@ public String getBuildDirectory() {
return buildDirectory;
}
- public BuildFile createBuildFile(final ProjectWriter writer) {
- checkNotNull(writer, "writer is required");
+ public ExtensionsManager createExtensionManager(final Path projectFolderPath,
+ final QuarkusPlatformDescriptor platformDescriptor) {
switch (this) {
case GRADLE:
- return new GradleBuildFile(writer);
+ return new GenericGradleBuildFile();
case MAVEN:
default:
- return new MavenBuildFile(writer);
+ return new MavenBuildFile(projectFolderPath, platformDescriptor);
}
}
}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/QuarkusProject.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/QuarkusProject.java
index 8d6ef03e40831..a4c9eaa58b639 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/QuarkusProject.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/QuarkusProject.java
@@ -2,33 +2,38 @@
import static com.google.common.base.Preconditions.checkNotNull;
-import io.quarkus.devtools.buildfile.BuildFile;
-import io.quarkus.devtools.writer.FileProjectWriter;
+import io.quarkus.devtools.project.buildfile.MavenBuildFile;
+import io.quarkus.devtools.project.extensions.ExtensionsManager;
import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
import java.nio.file.Path;
public final class QuarkusProject {
private final Path projectFolderPath;
- private final BuildFile buildFile;
- private final QuarkusPlatformDescriptor descriptor;
+ private final QuarkusPlatformDescriptor platformDescriptor;
+ private final ExtensionsManager extensionsManager;
- private QuarkusProject(final Path projectFolderPath, final QuarkusPlatformDescriptor descriptor,
- final BuildFile buildFile) {
+ private QuarkusProject(final Path projectFolderPath, final QuarkusPlatformDescriptor platformDescriptor,
+ final ExtensionsManager extensionsManager) {
this.projectFolderPath = checkNotNull(projectFolderPath, "projectFolderPath is required");
- this.descriptor = checkNotNull(descriptor, "descriptor is required");
- this.buildFile = checkNotNull(buildFile, "buildFile is required");
+ this.platformDescriptor = checkNotNull(platformDescriptor, "platformDescriptor is required");
+ this.extensionsManager = checkNotNull(extensionsManager, "extensionsManager is required");
}
- public static QuarkusProject of(final Path projectFolderPath, final QuarkusPlatformDescriptor descriptor,
+ public static QuarkusProject of(final Path projectFolderPath, final QuarkusPlatformDescriptor platformDescriptor,
+ final ExtensionsManager extensionsManager) {
+ return new QuarkusProject(projectFolderPath, platformDescriptor, extensionsManager);
+ }
+
+ public static QuarkusProject of(final Path projectFolderPath, final QuarkusPlatformDescriptor platformDescriptor,
final BuildTool buildTool) {
- final BuildFile buildFile = buildTool.createBuildFile(new FileProjectWriter(projectFolderPath.toFile()));
- return of(projectFolderPath, descriptor, buildFile);
+ return new QuarkusProject(projectFolderPath, platformDescriptor,
+ buildTool.createExtensionManager(projectFolderPath, platformDescriptor));
}
- public static QuarkusProject of(final Path projectFolderPath, final QuarkusPlatformDescriptor descriptor,
- final BuildFile buildFile) {
- return new QuarkusProject(projectFolderPath, descriptor, buildFile);
+ public static QuarkusProject maven(final Path projectFolderPath, final QuarkusPlatformDescriptor platformDescriptor) {
+ return new QuarkusProject(projectFolderPath, platformDescriptor,
+ new MavenBuildFile(projectFolderPath, platformDescriptor));
}
public static QuarkusProject resolveExistingProject(final Path projectFolderPath,
@@ -44,19 +49,19 @@ public Path getProjectFolderPath() {
return projectFolderPath;
}
- public BuildFile getBuildFile() {
- return buildFile;
+ public BuildTool getBuildTool() {
+ return extensionsManager.getBuildTool();
}
- public BuildTool getBuildTool() {
- return buildFile.getBuildTool();
+ public ExtensionsManager getExtensionsManager() {
+ return extensionsManager;
}
- public QuarkusPlatformDescriptor getDescriptor() {
- return descriptor;
+ public QuarkusPlatformDescriptor getPlatformDescriptor() {
+ return platformDescriptor;
}
- private static BuildTool resolveExistingProjectBuildTool(Path projectFolderPath) {
+ public static BuildTool resolveExistingProjectBuildTool(Path projectFolderPath) {
if (projectFolderPath.resolve("pom.xml").toFile().exists()) {
return BuildTool.MAVEN;
} else if (projectFolderPath.resolve("build.gradle").toFile().exists()
@@ -65,4 +70,5 @@ private static BuildTool resolveExistingProjectBuildTool(Path projectFolderPath)
}
return null;
}
+
}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFile.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFile.java
new file mode 100644
index 0000000000000..bc5b04f511bdd
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/AbstractGradleBuildFile.java
@@ -0,0 +1,242 @@
+package io.quarkus.devtools.project.buildfile;
+
+import io.quarkus.devtools.project.BuildTool;
+import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Optional;
+import java.util.Properties;
+import java.util.Scanner;
+import java.util.concurrent.atomic.AtomicReference;
+import java.util.function.Consumer;
+import org.apache.maven.model.Dependency;
+
+// We keep it here to take advantage of the abstract tests
+public abstract class AbstractGradleBuildFile extends BuildFile {
+
+ private static final String BUILD_GRADLE_PATH = "build.gradle";
+ private static final String SETTINGS_GRADLE_PATH = "settings.gradle";
+ private static final String GRADLE_PROPERTIES_PATH = "gradle.properties";
+
+ private final Optional rootProjectPath;
+
+ private AtomicReference modelReference = new AtomicReference<>();
+
+ public AbstractGradleBuildFile(final Path projectFolderPath, final QuarkusPlatformDescriptor platformDescriptor) {
+ super(projectFolderPath, platformDescriptor);
+ this.rootProjectPath = Optional.empty();
+ }
+
+ public AbstractGradleBuildFile(final Path projectFolderPath, final QuarkusPlatformDescriptor platformDescriptor,
+ Path rootProjectPath) {
+ super(projectFolderPath, platformDescriptor);
+ this.rootProjectPath = Optional.ofNullable(rootProjectPath);
+ }
+
+ @Override
+ public void writeToDisk() throws IOException {
+ if (rootProjectPath.isPresent()) {
+ Files.write(rootProjectPath.get().resolve(SETTINGS_GRADLE_PATH), getModel().getRootSettingsContent().getBytes());
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+ getModel().getRootPropertiesContent().store(out, "Gradle properties");
+ Files.write(rootProjectPath.get().resolve(GRADLE_PROPERTIES_PATH),
+ getModel().getRootSettingsContent().getBytes());
+ }
+ } else {
+ writeToProjectFile(SETTINGS_GRADLE_PATH, getModel().getSettingsContent().getBytes());
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+ getModel().getPropertiesContent().store(out, "Gradle properties");
+ writeToProjectFile(GRADLE_PROPERTIES_PATH, out.toByteArray());
+ }
+ }
+ writeToProjectFile(BUILD_GRADLE_PATH, getModel().getBuildContent().getBytes());
+ }
+
+ @Override
+ protected void addDependencyInBuildFile(Dependency dependency) throws IOException {
+ StringBuilder newBuildContent = new StringBuilder();
+ readLineByLine(getModel().getBuildContent(), currentLine -> {
+ newBuildContent.append(currentLine).append(System.lineSeparator());
+ if (currentLine.startsWith("dependencies {")) {
+ newBuildContent.append(" implementation '")
+ .append(dependency.getGroupId())
+ .append(":")
+ .append(dependency.getArtifactId());
+ if (dependency.getVersion() != null && !dependency.getVersion().isEmpty()) {
+ newBuildContent.append(":")
+ .append(dependency.getVersion());
+ }
+ newBuildContent.append("'")
+ .append(System.lineSeparator());
+ }
+ });
+ getModel().setBuildContent(newBuildContent.toString());
+ }
+
+ @Override
+ protected void removeDependencyFromBuildFile(Dependency dependency) throws IOException {
+ String depString = new StringBuilder("'").append(dependency.getGroupId()).append(":")
+ .append(dependency.getArtifactId()).toString();
+ StringBuilder newBuildContent = new StringBuilder();
+ Scanner scanner = new Scanner(getModel().getBuildContent());
+ while (scanner.hasNextLine()) {
+ String line = scanner.nextLine();
+ if (!line.contains(depString)) {
+ newBuildContent.append(line).append(System.lineSeparator());
+ }
+ }
+ scanner.close();
+ getModel().setBuildContent(newBuildContent.toString());
+ }
+
+ @Override
+ protected boolean containsBOM(String groupId, String artifactId) throws IOException {
+ String buildContent = getModel().getBuildContent();
+ return buildContent.contains("enforcedPlatform(\"${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:")
+ || buildContent.contains("enforcedPlatform(\"" + groupId + ":" + artifactId + ":");
+ }
+
+ @Override
+ public String getProperty(String propertyName) throws IOException {
+ final String property = getModel().getPropertiesContent().getProperty(propertyName);
+ if (property != null || getModel().getRootPropertiesContent() == null) {
+ return property;
+ }
+ return getModel().getRootPropertiesContent().getProperty(propertyName);
+ }
+
+ @Override
+ public BuildTool getBuildTool() {
+ return BuildTool.GRADLE;
+ }
+
+ private void readLineByLine(String content, Consumer lineConsumer) {
+ try (Scanner scanner = new Scanner(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)),
+ StandardCharsets.UTF_8.name())) {
+ while (scanner.hasNextLine()) {
+ String currentLine = scanner.nextLine();
+ lineConsumer.accept(currentLine);
+ }
+ }
+ }
+
+ private Model getModel() throws IOException {
+ return modelReference.updateAndGet(model -> {
+ if (model == null) {
+ try {
+ return readModel();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ return model;
+ });
+ }
+
+ @Override
+ protected void refreshData() {
+ this.modelReference.set(null);
+ }
+
+ private boolean hasRootProjectFile(final String fileName) throws IOException {
+ if (!rootProjectPath.isPresent()) {
+ return false;
+ }
+ final Path filePath = rootProjectPath.get().resolve(fileName);
+ return Files.exists(filePath);
+ }
+
+ private byte[] readRootProjectFile(final String fileName) throws IOException {
+ final Path filePath = rootProjectPath
+ .orElseThrow(() -> new IllegalStateException("There is no rootProject defined in this GradleBuildFile"))
+ .resolve(fileName);
+ return Files.readAllBytes(filePath);
+ }
+
+ private Model readModel() throws IOException {
+ String settingsContent = "";
+ String buildContent = "";
+ Properties propertiesContent = new Properties();
+ String rootSettingsContent = null;
+ Properties rootPropertiesContent = null;
+ if (hasProjectFile(SETTINGS_GRADLE_PATH)) {
+ final byte[] settings = readProjectFile(SETTINGS_GRADLE_PATH);
+ settingsContent = new String(settings, StandardCharsets.UTF_8);
+ }
+ if (hasRootProjectFile(SETTINGS_GRADLE_PATH)) {
+ final byte[] settings = readRootProjectFile(SETTINGS_GRADLE_PATH);
+ rootSettingsContent = new String(settings, StandardCharsets.UTF_8);
+ }
+ if (hasProjectFile(BUILD_GRADLE_PATH)) {
+ final byte[] build = readProjectFile(BUILD_GRADLE_PATH);
+ buildContent = new String(build, StandardCharsets.UTF_8);
+ }
+ if (hasProjectFile(GRADLE_PROPERTIES_PATH)) {
+ final byte[] properties = readProjectFile(GRADLE_PROPERTIES_PATH);
+ propertiesContent.load(new ByteArrayInputStream(properties));
+ }
+ if (hasRootProjectFile(GRADLE_PROPERTIES_PATH)) {
+ final byte[] properties = readRootProjectFile(GRADLE_PROPERTIES_PATH);
+ rootPropertiesContent = new Properties();
+ rootPropertiesContent.load(new ByteArrayInputStream(properties));
+ }
+ return new Model(settingsContent, buildContent, propertiesContent, rootSettingsContent, rootPropertiesContent);
+ }
+
+ protected String getBuildContent() throws IOException {
+ return getModel().getBuildContent();
+ }
+
+ private static class Model {
+ private String settingsContent;
+ private String buildContent;
+ private Properties propertiesContent;
+
+ private String rootSettingsContent;
+ private Properties rootPropertiesContent;
+
+ public Model(String settingsContent, String buildContent, Properties propertiesContent, String rootSettingsContent,
+ Properties rootPropertiesContent) {
+ this.settingsContent = settingsContent;
+ this.buildContent = buildContent;
+ this.propertiesContent = propertiesContent;
+ this.rootSettingsContent = rootSettingsContent;
+ this.rootPropertiesContent = rootPropertiesContent;
+ }
+
+ public String getSettingsContent() {
+ return settingsContent;
+ }
+
+ public String getBuildContent() {
+ return buildContent;
+ }
+
+ public Properties getPropertiesContent() {
+ return propertiesContent;
+ }
+
+ public String getRootSettingsContent() {
+ return rootSettingsContent;
+ }
+
+ public Properties getRootPropertiesContent() {
+ return rootPropertiesContent;
+ }
+
+ public void setSettingsContent(String settingsContent) {
+ this.settingsContent = settingsContent;
+ }
+
+ public void setBuildContent(String buildContent) {
+ this.buildContent = buildContent;
+ }
+
+ }
+
+}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/BuildFile.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/BuildFile.java
new file mode 100644
index 0000000000000..e1b98d35e3cdb
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/BuildFile.java
@@ -0,0 +1,163 @@
+package io.quarkus.devtools.project.buildfile;
+
+import static com.google.common.base.Preconditions.checkNotNull;
+import static io.quarkus.devtools.project.extensions.Extensions.key;
+import static java.util.stream.Collectors.toList;
+
+import io.quarkus.dependencies.Extension;
+import io.quarkus.devtools.project.extensions.Extensions;
+import io.quarkus.devtools.project.extensions.ExtensionsManager;
+import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.List;
+import java.util.Objects;
+import java.util.Optional;
+import java.util.Set;
+import java.util.concurrent.atomic.LongAdder;
+import java.util.stream.Collectors;
+import org.apache.maven.model.Dependency;
+
+public abstract class BuildFile implements ExtensionsManager {
+
+ private final Path projectFolderPath;
+ private final QuarkusPlatformDescriptor platformDescriptor;
+
+ public BuildFile(final Path projectFolderPath, final QuarkusPlatformDescriptor platformDescriptor) {
+ this.projectFolderPath = checkNotNull(projectFolderPath, "projectPath is required");
+ this.platformDescriptor = checkNotNull(platformDescriptor, "platformDescriptor is required");
+ }
+
+ @Override
+ public final boolean hasQuarkusPlatformBom() throws IOException {
+ return containsBOM(platformDescriptor.getBomGroupId(), platformDescriptor.getBomArtifactId());
+ }
+
+ @Override
+ public final int add(List extensions) throws IOException {
+ if (!hasQuarkusPlatformBom()) {
+ throw new IllegalStateException("The Quarkus BOM is required to add a Quarkus extension");
+ }
+ this.refreshData();
+ final Set existingKeys = getDependenciesManagementKeys();
+ final LongAdder counter = new LongAdder();
+ extensions.stream()
+ .filter(a -> !existingKeys.contains(a.managementKey()))
+ .forEach(e -> {
+ try {
+ final boolean isInPlatformBom = isDefinedInRegistry(platformDescriptor.getExtensions(),
+ e.managementKey());
+ // We hardcode the version when it is already defined in the platform bom
+ addDependencyInBuildFile(e.toDependency(isInPlatformBom));
+ counter.increment();
+ } catch (IOException ex) {
+ throw new UncheckedIOException(ex);
+ }
+ });
+ this.writeToDisk();
+ return counter.intValue();
+ }
+
+ @Override
+ public final List read() throws IOException {
+ this.refreshData();
+ return this.getDependencies().stream().filter(d -> this.isRegisteredQuarkusExtension(key(d)))
+ .map(d -> new Extension(d.getGroupId(), d.getArtifactId(), extractVersion(d)))
+ .collect(toList());
+ }
+
+ @Override
+ public final int remove(Set extensions) throws IOException {
+ this.refreshData();
+ final Set existingKeys = getDependenciesManagementKeys();
+ final LongAdder counter = new LongAdder();
+ extensions.stream()
+ .filter(a -> existingKeys.contains(a.managementKey()))
+ .forEach(e -> {
+ try {
+ removeDependencyFromBuildFile(e.toDependency(true));
+ counter.increment();
+ } catch (IOException ex) {
+ throw new UncheckedIOException(ex);
+ }
+ });
+ this.writeToDisk();
+ return counter.intValue();
+ }
+
+ protected abstract void addDependencyInBuildFile(Dependency dependency) throws IOException;
+
+ protected abstract void removeDependencyFromBuildFile(Dependency dependency) throws IOException;
+
+ protected abstract List getDependencies() throws IOException;
+
+ protected abstract void writeToDisk() throws IOException;
+
+ protected abstract String getProperty(String propertyName) throws IOException;
+
+ protected abstract boolean containsBOM(String groupId, String artifactId) throws IOException;
+
+ protected abstract void refreshData();
+
+ protected Path getProjectFolderPath() {
+ return projectFolderPath;
+ }
+
+ protected boolean hasProjectFile(final String fileName) throws IOException {
+ final Path filePath = projectFolderPath.resolve(fileName);
+ return Files.exists(filePath);
+ }
+
+ protected byte[] readProjectFile(final String fileName) throws IOException {
+ final Path filePath = projectFolderPath.resolve(fileName);
+ return Files.readAllBytes(filePath);
+ }
+
+ protected void writeToProjectFile(final String fileName, final byte[] content) throws IOException {
+ Files.write(projectFolderPath.resolve(fileName), content);
+ }
+
+ private boolean isRegisteredQuarkusExtension(final String managementKey) {
+ // This will not always be true as the platform descriptor does not contain the list of all available extensions
+ return isDefinedInRegistry(platformDescriptor.getExtensions(), managementKey);
+ }
+
+ private Set getDependenciesManagementKeys() throws IOException {
+ return getDependencies().stream().map(Extensions::key).collect(Collectors.toSet());
+ }
+
+ private String extractVersion(final Dependency d) {
+ String version = d != null ? d.getVersion() : null;
+ if (version != null && version.startsWith("$")) {
+ String value = null;
+ try {
+ value = (String) this.getProperty(propertyName(version));
+ if (value != null) {
+ return value;
+ }
+ } catch (IOException e) {
+ // ignore this error.
+ }
+ }
+ if (version != null) {
+ return version;
+ }
+ return mapToExtensionFromRegistry(platformDescriptor.getExtensions(), key(d))
+ .map(Extension::getVersion)
+ .orElse(null);
+ }
+
+ private String propertyName(final String variable) {
+ return variable.substring(2, variable.length() - 1);
+ }
+
+ public static boolean isDefinedInRegistry(List registry, final String managementKey) {
+ return mapToExtensionFromRegistry(registry, managementKey).isPresent();
+ }
+
+ public static Optional mapToExtensionFromRegistry(List registry, final String managementKey) {
+ return registry.stream().filter(k -> Objects.equals(k.managementKey(), managementKey)).findFirst();
+ }
+}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/GenericGradleBuildFile.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/GenericGradleBuildFile.java
new file mode 100644
index 0000000000000..829b40465a7af
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/GenericGradleBuildFile.java
@@ -0,0 +1,39 @@
+package io.quarkus.devtools.project.buildfile;
+
+import io.quarkus.dependencies.Extension;
+import io.quarkus.devtools.project.BuildTool;
+import io.quarkus.devtools.project.extensions.ExtensionsManager;
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * TODO We need to find a way to use the gradle api outside of a gradle plugin
+ */
+public class GenericGradleBuildFile implements ExtensionsManager {
+
+ @Override
+ public BuildTool getBuildTool() {
+ return BuildTool.GRADLE;
+ }
+
+ @Override
+ public List read() throws IOException {
+ throw new IllegalStateException("This feature is not yet implemented outside of the Gradle Plugin.");
+ }
+
+ @Override
+ public boolean hasQuarkusPlatformBom() throws IOException {
+ throw new IllegalStateException("This feature is not yet implemented outside of the Gradle Plugin.");
+ }
+
+ @Override
+ public int add(List extensions) throws IOException {
+ throw new IllegalStateException("This feature is not yet implemented outside of the Gradle Plugin.");
+ }
+
+ @Override
+ public int remove(Set extensions) throws IOException {
+ throw new IllegalStateException("This feature is not yet implemented outside of the Gradle Plugin.");
+ }
+}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/buildfile/GradleBuildFile.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/GradleBuildFilesCreator.java
similarity index 52%
rename from independent-projects/tools/common/src/main/java/io/quarkus/devtools/buildfile/GradleBuildFile.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/GradleBuildFilesCreator.java
index e148e30bfe82e..aaf18e4b402ab 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/buildfile/GradleBuildFile.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/GradleBuildFilesCreator.java
@@ -1,77 +1,153 @@
-package io.quarkus.devtools.buildfile;
+package io.quarkus.devtools.project.buildfile;
+
+import static io.quarkus.devtools.project.buildfile.BuildFile.isDefinedInRegistry;
import io.quarkus.dependencies.Extension;
-import io.quarkus.devtools.project.BuildTool;
-import io.quarkus.devtools.writer.ProjectWriter;
-import io.quarkus.maven.utilities.MojoUtils;
+import io.quarkus.devtools.project.QuarkusProject;
import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
import io.quarkus.platform.tools.ToolsUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
+import java.io.UncheckedIOException;
import java.nio.charset.StandardCharsets;
-import java.util.Collections;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.List;
import java.util.Properties;
import java.util.Scanner;
+import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Consumer;
import org.apache.maven.model.Dependency;
-public class GradleBuildFile extends BuildFile {
+public final class GradleBuildFilesCreator {
private static final String BUILD_GRADLE_PATH = "build.gradle";
private static final String SETTINGS_GRADLE_PATH = "settings.gradle";
private static final String GRADLE_PROPERTIES_PATH = "gradle.properties";
+ private final QuarkusProject quarkusProject;
+
+ private AtomicReference modelReference = new AtomicReference<>();
- private final ProjectWriter rootWriter;
+ public GradleBuildFilesCreator(QuarkusProject quarkusProject) {
+ this.quarkusProject = quarkusProject;
+ }
- private Model model;
+ public void create(String groupId, String artifactId, String version,
+ Properties properties, List extensions) throws IOException {
+ createSettingsContent(artifactId);
+ createBuildContent(groupId, version);
+ createProperties();
+ extensions.stream()
+ .forEach(e -> {
+ try {
+ final boolean isInPlatformBom = isDefinedInRegistry(
+ quarkusProject.getPlatformDescriptor().getExtensions(), e.managementKey());
+ // We hardcode the version when it is already defined in the platform bom
+ addDependencyInBuildFile(e.toDependency(isInPlatformBom));
+ } catch (IOException ex) {
+ throw new UncheckedIOException(ex);
+ }
+ });
+ this.writeToDisk();
+ }
- public GradleBuildFile(ProjectWriter writer) {
- super(writer, BuildTool.GRADLE);
- rootWriter = writer;
+ private void writeToDisk() throws IOException {
+ writeToProjectFile(SETTINGS_GRADLE_PATH, getModel().getSettingsContent().getBytes());
+ writeToProjectFile(BUILD_GRADLE_PATH, getModel().getBuildContent().getBytes());
+ try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
+ getModel().getPropertiesContent().store(out, "Gradle properties");
+ writeToProjectFile(GRADLE_PROPERTIES_PATH, out.toByteArray());
+ }
}
- public GradleBuildFile(ProjectWriter writer, ProjectWriter rootWriter) {
- super(writer, BuildTool.GRADLE);
- this.rootWriter = rootWriter;
+ private void addDependencyInBuildFile(Dependency dependency) throws IOException {
+ StringBuilder newBuildContent = new StringBuilder();
+ readLineByLine(getModel().getBuildContent(), currentLine -> {
+ newBuildContent.append(currentLine).append(System.lineSeparator());
+ if (currentLine.startsWith("dependencies {")) {
+ newBuildContent.append(" implementation '")
+ .append(dependency.getGroupId())
+ .append(":")
+ .append(dependency.getArtifactId());
+ if (dependency.getVersion() != null && !dependency.getVersion().isEmpty()) {
+ newBuildContent.append(":")
+ .append(dependency.getVersion());
+ }
+ newBuildContent.append("'")
+ .append(System.lineSeparator());
+ }
+ });
+ getModel().setBuildContent(newBuildContent.toString());
}
- protected void rootWrite(String fileName, String content) throws IOException {
- rootWriter.write(fileName, content);
+ protected boolean containsBOM(String groupId, String artifactId) throws IOException {
+ String buildContent = getModel().getBuildContent();
+ return buildContent.contains("enforcedPlatform(\"${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:")
+ || buildContent.contains("enforcedPlatform(\"" + groupId + ":" + artifactId + ":");
}
- protected ProjectWriter getRootWriter() {
- return rootWriter;
+ public String getProperty(String propertyName) throws IOException {
+ return getModel().getPropertiesContent().getProperty(propertyName);
}
- @Override
- public void close() throws IOException {
- if (getWriter() == getRootWriter()) {
- write(SETTINGS_GRADLE_PATH, getModel().getSettingsContent());
- } else {
- rootWrite(SETTINGS_GRADLE_PATH, getModel().getSettingsContent());
+ private void readLineByLine(String content, Consumer lineConsumer) {
+ try (Scanner scanner = new Scanner(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)),
+ StandardCharsets.UTF_8.name())) {
+ while (scanner.hasNextLine()) {
+ String currentLine = scanner.nextLine();
+ lineConsumer.accept(currentLine);
+ }
}
- write(BUILD_GRADLE_PATH, getModel().getBuildContent());
- try (ByteArrayOutputStream out = new ByteArrayOutputStream()) {
- getModel().getPropertiesContent().store(out, "Gradle properties");
- if (getModel().isRootProperties()) {
- rootWrite(GRADLE_PROPERTIES_PATH, out.toString(StandardCharsets.UTF_8.toString()));
- } else {
- write(GRADLE_PROPERTIES_PATH, out.toString(StandardCharsets.UTF_8.toString()));
+ }
+
+ private Model getModel() throws IOException {
+ return modelReference.updateAndGet(model -> {
+ if (model == null) {
+ try {
+ return readModel();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
}
+ return model;
+ });
+ }
+
+ private Model readModel() throws IOException {
+ String settingsContent = "";
+ String buildContent = "";
+ Properties propertiesContent = new Properties();
+ if (hasProjectFile(SETTINGS_GRADLE_PATH)) {
+ final byte[] settings = readProjectFile(SETTINGS_GRADLE_PATH);
+ settingsContent = new String(settings, StandardCharsets.UTF_8);
+ }
+ if (hasProjectFile(BUILD_GRADLE_PATH)) {
+ final byte[] build = readProjectFile(BUILD_GRADLE_PATH);
+ buildContent = new String(build, StandardCharsets.UTF_8);
}
+ if (hasProjectFile(GRADLE_PROPERTIES_PATH)) {
+ final byte[] properties = readProjectFile(GRADLE_PROPERTIES_PATH);
+ propertiesContent.load(new ByteArrayInputStream(properties));
+ }
+ return new Model(settingsContent, buildContent, propertiesContent);
+ }
+
+ protected boolean hasProjectFile(final String fileName) throws IOException {
+ final Path filePath = quarkusProject.getProjectFolderPath().resolve(fileName);
+ return Files.exists(filePath);
}
- @Override
- public void completeFile(String groupId, String artifactId, String version, QuarkusPlatformDescriptor platform,
- Properties props) throws IOException {
- completeSettingsContent(artifactId);
- completeBuildContent(groupId, version, platform, props);
- completeProperties(platform);
+ protected byte[] readProjectFile(final String fileName) throws IOException {
+ final Path filePath = quarkusProject.getProjectFolderPath().resolve(fileName);
+ return Files.readAllBytes(filePath);
}
- private void completeBuildContent(String groupId, String version, QuarkusPlatformDescriptor platform, Properties props)
+ protected void writeToProjectFile(final String fileName, final byte[] content) throws IOException {
+ Files.write(quarkusProject.getProjectFolderPath().resolve(fileName), content);
+ }
+
+ private void createBuildContent(String groupId, String version)
throws IOException {
final String buildContent = getModel().getBuildContent();
StringBuilder res = new StringBuilder(buildContent);
@@ -81,7 +157,8 @@ private void completeBuildContent(String groupId, String version, QuarkusPlatfor
res.append(System.lineSeparator()).append(" id 'io.quarkus'").append(System.lineSeparator());
res.append("}");
}
- if (!containsBOM(platform.getBomGroupId(), platform.getBomArtifactId())) {
+ if (!containsBOM(quarkusProject.getPlatformDescriptor().getBomGroupId(),
+ quarkusProject.getPlatformDescriptor().getBomArtifactId())) {
res.append(System.lineSeparator());
res.append("dependencies {").append(System.lineSeparator());
res.append(
@@ -113,7 +190,7 @@ private void completeBuildContent(String groupId, String version, QuarkusPlatfor
getModel().setBuildContent(res.toString());
}
- private void completeSettingsContent(String artifactId) throws IOException {
+ private void createSettingsContent(String artifactId) throws IOException {
final String settingsContent = getModel().getSettingsContent();
final StringBuilder res = new StringBuilder();
if (!settingsContent.contains("id 'io.quarkus'")) {
@@ -137,7 +214,8 @@ private void completeSettingsContent(String artifactId) throws IOException {
getModel().setSettingsContent(res.toString());
}
- private void completeProperties(QuarkusPlatformDescriptor platform) throws IOException {
+ private void createProperties() throws IOException {
+ final QuarkusPlatformDescriptor platform = quarkusProject.getPlatformDescriptor();
Properties props = getModel().getPropertiesContent();
if (props.getProperty("quarkusPluginVersion") == null) {
props.setProperty("quarkusPluginVersion", ToolsUtils.getPluginVersion(ToolsUtils.readQuarkusProperties(platform)));
@@ -153,174 +231,15 @@ private void completeProperties(QuarkusPlatformDescriptor platform) throws IOExc
}
}
- @Override
- protected void addDependencyInBuildFile(Dependency dependency) throws IOException {
- StringBuilder newBuildContent = new StringBuilder();
- readLineByLine(getModel().getBuildContent(), new AppendDependency(newBuildContent, dependency));
- getModel().setBuildContent(newBuildContent.toString());
- }
-
- @Override
- public boolean removeDependency(QuarkusPlatformDescriptor platform, Extension extension) throws IOException {
- PRINTER.ok(" Removing extension " + extension.managementKey());
- Dependency dep;
- if (containsBOM(platform.getBomGroupId(), platform.getBomArtifactId())
- && isDefinedInBom(platform.getManagedDependencies(), extension)) {
- dep = extension.toDependency(true);
- } else {
- dep = extension.toDependency(false);
- if (getProperty(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_VERSION_NAME) != null) {
- dep.setVersion(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_VERSION_VALUE);
- }
- }
- removeDependencyFromBuildFile(dep);
- return true;
- }
-
- @Override
- protected void removeDependencyFromBuildFile(Dependency dependency) throws IOException {
- String depString = new StringBuilder("'").append(dependency.getGroupId()).append(":")
- .append(dependency.getArtifactId()).toString();
- StringBuilder newBuildContent = new StringBuilder();
- Scanner scanner = new Scanner(getModel().getBuildContent());
- while (scanner.hasNextLine()) {
- String line = scanner.nextLine();
- if (!line.contains(depString)) {
- newBuildContent.append(line).append(System.lineSeparator());
- }
- }
- scanner.close();
- getModel().setBuildContent(newBuildContent.toString());
- }
-
- private void readLineByLine(String content, Consumer lineConsumer) {
- try (Scanner scanner = new Scanner(new ByteArrayInputStream(content.getBytes(StandardCharsets.UTF_8)),
- StandardCharsets.UTF_8.name())) {
- while (scanner.hasNextLine()) {
- String currentLine = scanner.nextLine();
- lineConsumer.accept(currentLine);
- }
- }
- }
-
- private static class AppendDependency implements Consumer {
-
- private StringBuilder newContent;
- private Dependency dependency;
-
- public AppendDependency(StringBuilder newContent, Dependency dependency) {
- this.newContent = newContent;
- this.dependency = dependency;
- }
-
- @Override
- public void accept(String currentLine) {
- newContent.append(currentLine).append(System.lineSeparator());
- if (currentLine.startsWith("dependencies {")) {
- newContent.append(" implementation '")
- .append(dependency.getGroupId())
- .append(":")
- .append(dependency.getArtifactId());
- if (dependency.getVersion() != null && !dependency.getVersion().isEmpty()) {
- newContent.append(":")
- .append(dependency.getVersion());
- }
- newContent.append("'")
- .append(System.lineSeparator());
- }
- }
-
- }
-
- @Override
- protected boolean hasDependency(Extension extension) throws IOException {
- return getDependencies().stream()
- .anyMatch(d -> extension.getGroupId().equals(d.getGroupId())
- && extension.getArtifactId().equals(d.getArtifactId()));
- }
-
- @Override
- protected boolean containsBOM(String groupId, String artifactId) throws IOException {
- String buildContent = getModel().getBuildContent();
- return buildContent.contains("enforcedPlatform(\"${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:")
- || buildContent.contains("enforcedPlatform(\"" + groupId + ":" + artifactId + ":");
- }
-
- @Override
- public List getDependencies() throws IOException {
- return Collections.emptyList();
- }
-
- @Override
- public String getProperty(String propertyName) throws IOException {
- return getModel().getPropertiesContent().getProperty(propertyName);
- }
-
- @Override
- protected List getManagedDependencies() {
- // Gradle tooling API only provide resolved dependencies.
- return Collections.emptyList();
- }
-
- private Model getModel() throws IOException {
- if (model == null) {
- initModel();
- }
- return model;
- }
-
- protected void initModel() throws IOException {
- String settingsContent = "";
- String buildContent = "";
- Properties propertiesContent = new Properties();
- boolean isRootProperties = false;
- if (getWriter() == getRootWriter()) {
- if (getWriter().exists(SETTINGS_GRADLE_PATH)) {
- final byte[] settings = getWriter().getContent(SETTINGS_GRADLE_PATH);
- settingsContent = new String(settings, StandardCharsets.UTF_8);
- }
- } else {
- if (getRootWriter().exists(SETTINGS_GRADLE_PATH)) {
- final byte[] settings = getRootWriter().getContent(SETTINGS_GRADLE_PATH);
- settingsContent = new String(settings, StandardCharsets.UTF_8);
- }
- }
- if (getWriter().exists(BUILD_GRADLE_PATH)) {
- final byte[] build = getWriter().getContent(BUILD_GRADLE_PATH);
- buildContent = new String(build, StandardCharsets.UTF_8);
- }
- if (getWriter().exists(GRADLE_PROPERTIES_PATH)) {
- final byte[] properties = getWriter().getContent(GRADLE_PROPERTIES_PATH);
- propertiesContent.load(new ByteArrayInputStream(properties));
- }
- if (!propertiesContent.containsKey("quarkusPluginVersion") &&
- !propertiesContent.containsKey("quarkusPlatformGroupId") &&
- !propertiesContent.containsKey("quarkusPlatformArtifactId") &&
- !propertiesContent.containsKey("quarkusPlatformVersion")) {
- if (getRootWriter().exists(GRADLE_PROPERTIES_PATH)) {
- final byte[] properties = getRootWriter().getContent(GRADLE_PROPERTIES_PATH);
- propertiesContent.load(new ByteArrayInputStream(properties));
- }
- isRootProperties = true;
- }
- this.model = new Model(settingsContent, buildContent, propertiesContent, isRootProperties);
- }
-
- protected String getBuildContent() throws IOException {
- return getModel().getBuildContent();
- }
-
private static class Model {
private String settingsContent;
private String buildContent;
private Properties propertiesContent;
- private boolean rootProperties;
- public Model(String settingsContent, String buildContent, Properties propertiesContent, boolean rootProperties) {
+ public Model(String settingsContent, String buildContent, Properties propertiesContent) {
this.settingsContent = settingsContent;
this.buildContent = buildContent;
this.propertiesContent = propertiesContent;
- this.rootProperties = rootProperties;
}
public String getSettingsContent() {
@@ -343,8 +262,5 @@ public void setBuildContent(String buildContent) {
this.buildContent = buildContent;
}
- public boolean isRootProperties() {
- return rootProperties;
- }
}
}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/MavenBuildFile.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/MavenBuildFile.java
new file mode 100644
index 0000000000000..9a79a6017094e
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/buildfile/MavenBuildFile.java
@@ -0,0 +1,108 @@
+package io.quarkus.devtools.project.buildfile;
+
+import io.quarkus.devtools.project.BuildTool;
+import io.quarkus.maven.utilities.MojoUtils;
+import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
+import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+import java.io.UncheckedIOException;
+import java.nio.file.Path;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.atomic.AtomicReference;
+import org.apache.maven.model.Dependency;
+import org.apache.maven.model.Model;
+
+public class MavenBuildFile extends BuildFile {
+
+ private AtomicReference modelRef = new AtomicReference<>();
+
+ public MavenBuildFile(final Path projectFolderPath, final QuarkusPlatformDescriptor platformDescriptor) {
+ super(projectFolderPath, platformDescriptor);
+ }
+
+ @Override
+ public void writeToDisk() throws IOException {
+ if (getModel() == null) {
+ return;
+ }
+ try (ByteArrayOutputStream pomOutputStream = new ByteArrayOutputStream()) {
+ MojoUtils.write(getModel(), pomOutputStream);
+ writeToProjectFile(BuildTool.MAVEN.getDependenciesFile(), pomOutputStream.toByteArray());
+ }
+ }
+
+ @Override
+ protected void addDependencyInBuildFile(Dependency dependency) throws IOException {
+ if (getModel() != null) {
+ getModel().addDependency(dependency);
+ }
+ }
+
+ @Override
+ protected void removeDependencyFromBuildFile(Dependency dependency) throws IOException {
+ if (getModel() != null) {
+ getModel().getDependencies()
+ .removeIf(d -> d.getGroupId().equals(dependency.getGroupId())
+ && d.getArtifactId().equals(dependency.getArtifactId()));
+ }
+ }
+
+ @Override
+ public List getDependencies() throws IOException {
+ return getModel() == null ? Collections.emptyList() : getModel().getDependencies();
+ }
+
+ @Override
+ protected boolean containsBOM(String groupId, String artifactId) throws IOException {
+ if (getModel() == null || getModel().getDependencyManagement() == null) {
+ return false;
+ }
+ List dependencies = getModel().getDependencyManagement().getDependencies();
+ return dependencies.stream()
+ // Find bom
+ .filter(dependency -> "import".equals(dependency.getScope()))
+ .filter(dependency -> "pom".equals(dependency.getType()))
+ // Does it matches the bom artifact name
+ .anyMatch(dependency -> dependency.getArtifactId()
+ .equals(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_ARTIFACT_ID_VALUE)
+ && dependency.getGroupId().equals(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_GROUP_ID_VALUE));
+ }
+
+ @Override
+ protected void refreshData() {
+ this.modelRef.set(null);
+ }
+
+ @Override
+ public String getProperty(String propertyName) throws IOException {
+ if (getModel() == null) {
+ return null;
+ }
+ return getModel().getProperties().getProperty(propertyName);
+ }
+
+ @Override
+ public BuildTool getBuildTool() {
+ return BuildTool.MAVEN;
+ }
+
+ private Model getModel() throws IOException {
+ return modelRef.updateAndGet(model -> {
+ if (model == null) {
+ try {
+ return initModel();
+ } catch (IOException e) {
+ throw new UncheckedIOException(e);
+ }
+ }
+ return model;
+ });
+ }
+
+ private Model initModel() throws IOException {
+ byte[] content = readProjectFile(BuildTool.MAVEN.getDependenciesFile());
+ return MojoUtils.readPom(new ByteArrayInputStream(content));
+ }
+}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/generators/ProjectGenerator.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/ProjectGenerator.java
similarity index 77%
rename from independent-projects/tools/common/src/main/java/io/quarkus/generators/ProjectGenerator.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/ProjectGenerator.java
index 518e86f0505c2..575ac806428bb 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/generators/ProjectGenerator.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/ProjectGenerator.java
@@ -1,7 +1,6 @@
-package io.quarkus.generators;
+package io.quarkus.devtools.project.codegen;
-import io.quarkus.cli.commands.QuarkusCommandInvocation;
-import io.quarkus.devtools.writer.ProjectWriter;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
import java.io.IOException;
public interface ProjectGenerator {
@@ -18,11 +17,12 @@ public interface ProjectGenerator {
String BUILD_DIRECTORY = "build_dir";
String ADDITIONAL_GITIGNORE_ENTRIES = "additional_gitignore_entries";
String CLASS_NAME = "class_name";
+ String EXTENSIONS = "extensions";
String IS_SPRING = "is_spring";
String RESOURCE_PATH = "path";
String JAVA_TARGET = "java_target";
String getName();
- void generate(ProjectWriter writer, QuarkusCommandInvocation invocation) throws IOException;
+ void generate(QuarkusCommandInvocation invocation) throws IOException;
}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/generators/ProjectGeneratorRegistry.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/ProjectGeneratorRegistry.java
similarity index 96%
rename from independent-projects/tools/common/src/main/java/io/quarkus/generators/ProjectGeneratorRegistry.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/ProjectGeneratorRegistry.java
index 14e50d3f9b847..4090c600ef7b5 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/generators/ProjectGeneratorRegistry.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/ProjectGeneratorRegistry.java
@@ -1,4 +1,4 @@
-package io.quarkus.generators;
+package io.quarkus.devtools.project.codegen;
import java.util.Map;
import java.util.NoSuchElementException;
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/generators/SourceType.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/SourceType.java
similarity index 98%
rename from independent-projects/tools/common/src/main/java/io/quarkus/generators/SourceType.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/SourceType.java
index be92d2f2be6b2..3044f4992d372 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/generators/SourceType.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/SourceType.java
@@ -1,4 +1,4 @@
-package io.quarkus.generators;
+package io.quarkus.devtools.project.codegen;
import io.quarkus.maven.utilities.MojoUtils;
import java.util.Arrays;
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/generators/rest/BasicRestProjectGenerator.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/rest/BasicRestProjectGenerator.java
similarity index 92%
rename from independent-projects/tools/common/src/main/java/io/quarkus/generators/rest/BasicRestProjectGenerator.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/rest/BasicRestProjectGenerator.java
index 9578e9be6f54f..06be3d4e82d46 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/generators/rest/BasicRestProjectGenerator.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/rest/BasicRestProjectGenerator.java
@@ -1,12 +1,13 @@
-package io.quarkus.generators.rest;
+package io.quarkus.devtools.project.codegen.rest;
import static java.lang.String.format;
-import io.quarkus.cli.commands.QuarkusCommandInvocation;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
import io.quarkus.devtools.project.BuildTool;
-import io.quarkus.devtools.writer.ProjectWriter;
-import io.quarkus.generators.ProjectGenerator;
-import io.quarkus.generators.SourceType;
+import io.quarkus.devtools.project.codegen.ProjectGenerator;
+import io.quarkus.devtools.project.codegen.SourceType;
+import io.quarkus.devtools.project.codegen.writer.FileProjectWriter;
+import io.quarkus.devtools.project.codegen.writer.ProjectWriter;
import io.quarkus.maven.utilities.MojoUtils;
import java.io.ByteArrayInputStream;
import java.io.IOException;
@@ -25,7 +26,13 @@ public String getName() {
}
@Override
- public void generate(final ProjectWriter writer, QuarkusCommandInvocation invocation) throws IOException {
+ public void generate(QuarkusCommandInvocation invocation) throws IOException {
+ final FileProjectWriter writer = new FileProjectWriter(invocation.getQuarkusProject().getProjectFolderPath().toFile());
+ writer.init();
+ generate(writer, invocation);
+ }
+
+ void generate(ProjectWriter writer, QuarkusCommandInvocation invocation) throws IOException {
final BasicRestProject project = new BasicRestProject(writer, invocation);
project.initProject();
@@ -122,7 +129,7 @@ private boolean initBuildTool() throws IOException {
}
private BuildTool getBuildTool() {
- return invocation.getBuildFile().getBuildTool();
+ return invocation.getQuarkusProject().getBuildTool();
}
private void generate(final String templateName, QuarkusCommandInvocation invocation, final String outputFilePath,
@@ -141,7 +148,7 @@ private void generate(final String templateName, QuarkusCommandInvocation invoca
// do some nasty replacements for Java target if we want to generate Java 11 projects
if ("11".equals(invocation.getValue(JAVA_TARGET))) {
- if (BuildTool.GRADLE.equals(invocation.getBuildFile().getBuildTool())) {
+ if (BuildTool.GRADLE.equals(invocation.getQuarkusProject().getBuildTool())) {
template = template.replace("JavaVersion.VERSION_1_8", "JavaVersion.VERSION_11");
} else {
template = template.replace("1.8",
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/writer/FileProjectWriter.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/writer/FileProjectWriter.java
similarity index 73%
rename from independent-projects/tools/common/src/main/java/io/quarkus/devtools/writer/FileProjectWriter.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/writer/FileProjectWriter.java
index 35e4a2d4e1e52..da284ca0f50c0 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/writer/FileProjectWriter.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/writer/FileProjectWriter.java
@@ -1,7 +1,7 @@
/**
*
*/
-package io.quarkus.devtools.writer;
+package io.quarkus.devtools.project.codegen.writer;
import java.io.File;
import java.io.IOException;
@@ -19,21 +19,21 @@ public FileProjectWriter(final File file) {
}
@Override
- public boolean init() {
- if (root.exists() && !root.isDirectory()) {
- System.out.println("Project root needs to either not exist or be a directory");
- return false;
- } else if (!root.exists()) {
+ public void init() throws IOException {
+ if (!root.exists()) {
boolean mkdirStatus = root.mkdirs();
if (!mkdirStatus) {
- System.out.println("Failed to create root directory");
- return false;
+ throw new IOException("Failed to create root directory");
}
+ return;
+ }
+ if (!root.isDirectory()) {
+ throw new IOException("Project root needs to either not exist or be a directory");
+ }
+ final String[] files = root.list();
+ if (files != null && files.length > 0) {
+ throw new IOException("You can't create a project when the folder is not empty.");
}
-
- System.out.println("Creating a new project in " + root.getAbsolutePath());
-
- return true;
}
@Override
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/writer/ProjectWriter.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/writer/ProjectWriter.java
similarity index 84%
rename from independent-projects/tools/common/src/main/java/io/quarkus/devtools/writer/ProjectWriter.java
rename to independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/writer/ProjectWriter.java
index 45e75607edac7..4b9ecdea8cf5d 100644
--- a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/writer/ProjectWriter.java
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/codegen/writer/ProjectWriter.java
@@ -1,7 +1,7 @@
/**
*
*/
-package io.quarkus.devtools.writer;
+package io.quarkus.devtools.project.codegen.writer;
import java.io.Closeable;
import java.io.File;
@@ -12,9 +12,7 @@
*/
public interface ProjectWriter extends Closeable {
- default boolean init() {
- return true;
- }
+ void init() throws IOException;
void write(String path, String content) throws IOException;
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/extensions/Extensions.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/extensions/Extensions.java
new file mode 100644
index 0000000000000..34af541b140b2
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/extensions/Extensions.java
@@ -0,0 +1,40 @@
+package io.quarkus.devtools.project.extensions;
+
+import io.quarkus.dependencies.Extension;
+import java.util.Objects;
+import org.apache.maven.model.Dependency;
+
+public final class Extensions {
+ private Extensions() {
+ }
+
+ public static String key(final Extension extension) {
+ return extension.managementKey();
+ }
+
+ public static String key(final Dependency dependency) {
+ return dependency.getGroupId() + ":" + dependency.getArtifactId();
+ }
+
+ public static boolean equalsIgnoringVersions(final Extension a, final Extension b) {
+ return Objects.equals(a.getGroupId(), b.getGroupId()) && Objects.equals(a.getArtifactId(), b.getArtifactId());
+ }
+
+ public static Extension parse(String gav) {
+ final Extension res = new Extension();
+ String[] segments = gav.split(":");
+ if (segments.length >= 2) {
+ 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].toLowerCase());
+ }
+ return res;
+ } else {
+ throw new IllegalArgumentException("Invalid GAV '" + gav + "'");
+ }
+ }
+}
diff --git a/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/extensions/ExtensionsManager.java b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/extensions/ExtensionsManager.java
new file mode 100644
index 0000000000000..796823574e651
--- /dev/null
+++ b/independent-projects/tools/common/src/main/java/io/quarkus/devtools/project/extensions/ExtensionsManager.java
@@ -0,0 +1,71 @@
+package io.quarkus.devtools.project.extensions;
+
+import static io.quarkus.devtools.project.extensions.Extensions.equalsIgnoringVersions;
+
+import io.quarkus.dependencies.Extension;
+import io.quarkus.devtools.project.BuildTool;
+import java.io.IOException;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * This interface defines a high level way of managing (read/write) extensions in any QuarkusProject
+ */
+public interface ExtensionsManager {
+
+ /**
+ * @return the {@link BuildTool} of this extension manager
+ */
+ BuildTool getBuildTool();
+
+ /**
+ * Read the build file(s) to get the list of extensions installed in this Quarkus project.
+ *
+ * @return The list of extensions installed in the project build file(s).
+ * @throws IOException if a problem occurs while reading the project build file(s)
+ */
+ List read() throws IOException;
+
+ /**
+ * Read build file(s) to check if an extension is installed in this Quarkus project.
+ *
+ * @param e the extensions to check
+ * @return true if it's installed
+ * @throws IOException if a problem occurs while reading the project build file(s)
+ */
+ default boolean hasExtension(Extension e) throws IOException {
+ return read().stream().anyMatch(i -> equalsIgnoringVersions(i, e));
+ }
+
+ /**
+ * Check that the Quarkus Platform bom is defined in the project.
+ * The Quarkus Platform Bom role is to define version to use for Quarkus extensions.
+ *
+ * @return true if it's defined, false else
+ * @throws IOException if a problem occurs while reading the project build file(s)
+ */
+ boolean hasQuarkusPlatformBom() throws IOException;
+
+ /**
+ * This is going to add all the specified extensions to the project build file(s).
+ *
+ * Extensions which are already installed are ignored.
+ *
+ * @param extensions the list of extensions to add
+ * @return the number of added extensions (excluding already installed)
+ * @throws IOException if a problem occurs while reading/writing the project build file(s)
+ */
+ int add(List extensions) throws IOException;
+
+ /**
+ * This is going to remove all the specified extensions from the project build file(s).
+ *
+ * This is ignoring the {@link Extension} version
+ *
+ * @param extensions the set of extensions to remove
+ * @return the number of removed extensions (excluding already not installed)
+ * @throws IOException if a problem occurs while reading/writing the project build file(s)
+ */
+ int remove(Set extensions) throws IOException;
+
+}
diff --git a/independent-projects/tools/common/src/main/resources/META-INF/services/io.quarkus.devtools.project.codegen.ProjectGenerator b/independent-projects/tools/common/src/main/resources/META-INF/services/io.quarkus.devtools.project.codegen.ProjectGenerator
new file mode 100644
index 0000000000000..41ba05fc1a3e4
--- /dev/null
+++ b/independent-projects/tools/common/src/main/resources/META-INF/services/io.quarkus.devtools.project.codegen.ProjectGenerator
@@ -0,0 +1 @@
+io.quarkus.devtools.project.codegen.rest.BasicRestProjectGenerator
diff --git a/independent-projects/tools/common/src/main/resources/META-INF/services/io.quarkus.generators.ProjectGenerator b/independent-projects/tools/common/src/main/resources/META-INF/services/io.quarkus.generators.ProjectGenerator
deleted file mode 100644
index 481f77c230b6b..0000000000000
--- a/independent-projects/tools/common/src/main/resources/META-INF/services/io.quarkus.generators.ProjectGenerator
+++ /dev/null
@@ -1 +0,0 @@
-io.quarkus.generators.rest.BasicRestProjectGenerator
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/CreateProjectTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/CreateProjectTest.java
deleted file mode 100644
index 44cbd56da51ea..0000000000000
--- a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/CreateProjectTest.java
+++ /dev/null
@@ -1,314 +0,0 @@
-package io.quarkus.cli.commands;
-
-import static org.assertj.core.api.Assertions.assertThat;
-import static org.assertj.core.api.Assertions.contentOf;
-import static org.junit.jupiter.api.Assertions.assertTrue;
-
-import io.quarkus.devtools.project.BuildTool;
-import io.quarkus.devtools.writer.FileProjectWriter;
-import io.quarkus.generators.ProjectGenerator;
-import io.quarkus.maven.utilities.MojoUtils;
-import java.io.File;
-import java.io.IOException;
-import java.io.InputStream;
-import java.nio.charset.StandardCharsets;
-import java.nio.file.Files;
-import java.nio.file.Path;
-import java.util.Comparator;
-import java.util.List;
-import java.util.Properties;
-import java.util.concurrent.Callable;
-import java.util.concurrent.CountDownLatch;
-import java.util.concurrent.ExecutorService;
-import java.util.concurrent.Executors;
-import java.util.stream.Collectors;
-import java.util.stream.IntStream;
-import java.util.stream.Stream;
-import org.apache.maven.model.Model;
-import org.junit.jupiter.api.Assertions;
-import org.junit.jupiter.api.DisplayName;
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.Timeout;
-
-public class CreateProjectTest extends PlatformAwareTestBase {
- @Test
- public void create() throws Exception {
- final File file = new File("target/basic-rest");
- delete(file);
- createProject(file, "io.quarkus", "basic-rest", "1.0.0-SNAPSHOT");
-
- final File gitignore = new File(file, ".gitignore");
- assertTrue(gitignore.exists());
- final String gitignoreContent = new String(Files.readAllBytes(gitignore.toPath()), StandardCharsets.UTF_8);
- assertTrue(gitignoreContent.contains("\ntarget/\n"));
- }
-
- @Test
- public void createGradle() throws Exception {
- final File file = new File("target/basic-rest-gradle");
- delete(file);
- createProject(BuildTool.GRADLE, file, "io.quarkus", "basic-rest", "1.0.0-SNAPSHOT");
-
- final File gitignore = new File(file, ".gitignore");
- assertTrue(gitignore.exists());
- final String gitignoreContent = new String(Files.readAllBytes(gitignore.toPath()), StandardCharsets.UTF_8);
- Assertions.assertFalse(gitignoreContent.contains("\ntarget/\n"));
- assertTrue(gitignoreContent.contains("\nbuild/"));
- assertTrue(gitignoreContent.contains("\n.gradle/\n"));
-
- assertThat(new File(file, "README.md")).exists();
- assertThat(contentOf(new File(file, "README.md"), "UTF-8")).contains("./gradlew");
- }
-
- @Test
- public void createGradleOnExisting() throws Exception {
- final File testDir = new File("target/existing");
- delete(testDir);
- testDir.mkdirs();
-
- final File buildGradle = new File(testDir, "build.gradle");
- buildGradle.createNewFile();
- final File settingsGradle = new File(testDir, "settings.gradle");
- settingsGradle.createNewFile();
-
- createProject(BuildTool.GRADLE, testDir, "io.quarkus", "basic-rest", "1.0.0-SNAPSHOT");
-
- final File gitignore = new File(testDir, ".gitignore");
- assertTrue(gitignore.exists());
- final String gitignoreContent = new String(Files.readAllBytes(gitignore.toPath()), StandardCharsets.UTF_8);
- Assertions.assertFalse(gitignoreContent.contains("\ntarget/\n"));
- assertTrue(gitignoreContent.contains("\nbuild/"));
- assertTrue(gitignoreContent.contains("\n.gradle/\n"));
-
- assertThat(contentOf(new File(testDir, "build.gradle"), "UTF-8"))
- .contains("id 'io.quarkus'")
- .contains("${quarkusPlatformGroupId}:${quarkusPlatformArtifactId}:${quarkusPlatformVersion}");
-
- final Properties props = new Properties();
- try (InputStream is = Files.newInputStream(testDir.toPath().resolve("gradle.properties"))) {
- props.load(is);
- }
- Assertions.assertEquals(getBomGroupId(), props.get("quarkusPlatformGroupId"));
- Assertions.assertEquals(getBomArtifactId(), props.get("quarkusPlatformArtifactId"));
- Assertions.assertEquals(getBomVersion(), props.get("quarkusPlatformVersion"));
-
- assertThat(new File(testDir, "README.md")).exists();
- assertThat(contentOf(new File(testDir, "README.md"), "UTF-8")).contains("./gradlew");
- }
-
- @Test
- public void createOnTopPomWithoutResource() throws Exception {
- final File testDir = new File("target/existing");
- delete(testDir);
- testDir.mkdirs();
-
- Model model = new Model();
- model.setModelVersion("4.0.0");
- model.setGroupId("org.acme");
- model.setArtifactId("foobar");
- model.setVersion("10.1.2");
- final File pom = new File(testDir, "pom.xml");
- MojoUtils.write(model, pom);
- createProject(testDir, "something.is", "wrong", "1.0.0-SNAPSHOT");
-
- assertThat(contentOf(pom, "UTF-8"))
- .contains(getPluginArtifactId(), MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLUGIN_VERSION_VALUE, getPluginGroupId());
-
- assertThat(new File(testDir, "src/main/java")).isDirectory();
- assertThat(new File(testDir, "src/test/java")).isDirectory();
-
- assertThat(new File(testDir, "README.md")).exists();
- assertThat(contentOf(new File(testDir, "README.md"), "UTF-8")).contains("./mvnw");
- assertThat(new File(testDir, "src/main/resources/application.properties")).exists();
- assertThat(new File(testDir, "src/main/resources/META-INF/resources/index.html")).isFile();
- assertThat(new File(testDir, "src/main/java")).isDirectory().matches(f -> {
- String[] list = f.list();
- return list != null && list.length == 0;
- });
- assertThat(new File(testDir, "src/test/java")).isDirectory().matches(f -> {
- String[] list = f.list();
- return list != null && list.length == 0;
- });
-
- assertThat(contentOf(new File(testDir, "pom.xml"), "UTF-8"))
- .contains(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_ARTIFACT_ID_VALUE);
-
- }
-
- @Test
- public void createOnTopPomWithResource() throws Exception {
- final File testDir = new File("target/existing");
- delete(testDir);
- testDir.mkdirs();
-
- Model model = new Model();
- model.setModelVersion("4.0.0");
- model.setGroupId("org.acme");
- model.setArtifactId("foobar");
- model.setVersion("10.1.2");
- final File pom = new File(testDir, "pom.xml");
- MojoUtils.write(model, pom);
-
- final QuarkusCommandOutcome result = new CreateProject(testDir.toPath(), getPlatformDescriptor())
- .groupId("something.is")
- .artifactId("wrong")
- .version("1.0.0-SNAPSHOT")
- .className("org.foo.MyResource")
- .execute();
- assertTrue(result.isSuccess());
-
- assertThat(contentOf(pom, "UTF-8"))
- .contains(getPluginArtifactId(), MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLUGIN_VERSION_VALUE, getPluginGroupId());
-
- assertThat(new File(testDir, "src/main/java")).isDirectory();
- assertThat(new File(testDir, "src/test/java")).isDirectory();
-
- assertThat(new File(testDir, "README.md")).exists();
- assertThat(contentOf(new File(testDir, "README.md"), "UTF-8")).contains("./mvnw");
- assertThat(new File(testDir, "src/main/resources/application.properties")).exists();
- assertThat(new File(testDir, "src/main/resources/META-INF/resources/index.html")).exists();
- assertThat(new File(testDir, "src/main/java")).isDirectory();
- assertThat(new File(testDir, "src/main/java/org/foo/MyResource.java")).isFile();
- assertThat(contentOf(new File(testDir, "src/main/java/org/foo/MyResource.java"), "UTF-8"))
- .contains("@Path", "@GET", "@Produces");
- assertThat(new File(testDir, "src/test/java")).isDirectory();
- assertThat(new File(testDir, "src/test/java/org/foo/MyResourceTest.java")).isFile();
- assertThat(new File(testDir, "src/test/java/org/foo/NativeMyResourceIT.java")).isFile();
-
- assertThat(contentOf(new File(testDir, "pom.xml"))).contains(getBomArtifactId());
-
- }
-
- @Test
- public void createOnTopPomWithSpringController() throws Exception {
- final File testDir = new File("target/existing");
- delete(testDir);
- testDir.mkdirs();
-
- Model model = new Model();
- model.setModelVersion("4.0.0");
- model.setGroupId("org.acme");
- model.setArtifactId("foobar");
- model.setVersion("10.1.2");
- final File pom = new File(testDir, "pom.xml");
- MojoUtils.write(model, pom);
-
- final QuarkusCommandOutcome result = new CreateProject(testDir.toPath(), getPlatformDescriptor())
- .groupId("something.is")
- .artifactId("wrong")
- .version("1.0.0-SNAPSHOT")
- .className("org.foo.MyResource")
- .setValue(ProjectGenerator.IS_SPRING, true)
- .execute();
- assertTrue(result.isSuccess());
-
- assertThat(contentOf(pom, "UTF-8"))
- .contains(getPluginArtifactId(), MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLUGIN_VERSION_VALUE, getPluginGroupId());
-
- assertThat(new File(testDir, "src/main/java")).isDirectory();
- assertThat(new File(testDir, "src/test/java")).isDirectory();
-
- assertThat(new File(testDir, "README.md")).exists();
- assertThat(contentOf(new File(testDir, "README.md"), "UTF-8")).contains("./mvnw");
- assertThat(new File(testDir, "src/main/resources/application.properties")).exists();
- assertThat(new File(testDir, "src/main/resources/META-INF/resources/index.html")).exists();
- assertThat(new File(testDir, "src/main/java")).isDirectory();
- assertThat(new File(testDir, "src/main/java/org/foo/MyResource.java")).isFile();
- assertThat(contentOf(new File(testDir, "src/main/java/org/foo/MyResource.java"), "UTF-8"))
- .contains("@RestController", "@RequestMapping", "@GetMapping");
- assertThat(new File(testDir, "src/test/java")).isDirectory();
- assertThat(new File(testDir, "src/test/java/org/foo/MyResourceTest.java")).isFile();
- assertThat(new File(testDir, "src/test/java/org/foo/NativeMyResourceIT.java")).isFile();
-
- assertThat(contentOf(new File(testDir, "pom.xml"))).contains(getBomArtifactId());
-
- }
-
- @Test
- public void createNewWithCustomizations() throws Exception {
- final File testDir = new File("target/existing");
- delete(testDir);
- testDir.mkdirs();
-
- final QuarkusCommandOutcome result = new CreateProject(testDir.toPath(), getPlatformDescriptor())
- .groupId("org.acme")
- .artifactId("acme")
- .version("1.0.0-SNAPSHOT")
- .className("org.acme.MyResource")
- .execute();
- assertTrue(result.isSuccess());
-
- 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/MyApplication.java")).doesNotExist();
-
- assertThat(contentOf(new File(testDir, "pom.xml"), "UTF-8"))
- .contains(getPluginArtifactId(), MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLUGIN_VERSION_VALUE, getPluginGroupId());
-
- assertThat(new File(testDir, "src/main/java")).isDirectory();
- assertThat(new File(testDir, "src/test/java")).isDirectory();
-
- assertThat(new File(testDir, "src/main/resources/application.properties")).exists();
- assertThat(new File(testDir, "src/main/resources/META-INF/resources/index.html")).exists();
-
- assertThat(contentOf(new File(testDir, "pom.xml"), "UTF-8"))
- .contains(MojoUtils.TEMPLATE_PROPERTY_QUARKUS_PLATFORM_VERSION_VALUE);
-
- }
-
- @Test
- @Timeout(2)
- @DisplayName("Should create correctly multiple times in parallel with multiple threads")
- void createMultipleTimes() throws InterruptedException {
- final ExecutorService executorService = Executors.newFixedThreadPool(4);
- final CountDownLatch latch = new CountDownLatch(20);
-
- List> collect = IntStream.range(0, 20).boxed().map(i -> (Callable) () -> {
- File tempDir = Files.createTempDirectory("test").toFile();
- FileProjectWriter write = new FileProjectWriter(tempDir);
- final QuarkusCommandOutcome result = new CreateProject(tempDir.toPath(), getPlatformDescriptor())
- .groupId("org.acme")
- .artifactId("acme")
- .version("1.0.0-SNAPSHOT")
- .className("org.acme.MyResource")
- .execute();
- assertTrue(result.isSuccess());
- latch.countDown();
- write.close();
- tempDir.delete();
- return null;
- }).collect(Collectors.toList());
- executorService.invokeAll(collect);
- latch.await();
- }
-
- public static void delete(final File file) throws IOException {
-
- if (file.exists()) {
- try (Stream stream = Files.walk(file.toPath())) {
- stream.sorted(Comparator.reverseOrder())
- .map(Path::toFile)
- .forEach(File::delete);
- }
- }
-
- Assertions.assertFalse(
- Files.exists(file.toPath()), "Directory still exists");
- }
-
- private void createProject(final File file, String groupId, String artifactId, String version)
- throws QuarkusCommandException {
- createProject(BuildTool.MAVEN, file, groupId, artifactId, version);
- }
-
- private void createProject(BuildTool buildTool, File file, String groupId, String artifactId, String version)
- throws QuarkusCommandException {
- final QuarkusCommandOutcome result = new CreateProject(file.toPath(), getPlatformDescriptor())
- .buildTool(buildTool)
- .groupId(groupId)
- .artifactId(artifactId)
- .version(version)
- .execute();
- assertTrue(result.isSuccess());
- }
-}
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AbstractAddExtensionsTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AbstractAddExtensionsTest.java
similarity index 93%
rename from independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AbstractAddExtensionsTest.java
rename to independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AbstractAddExtensionsTest.java
index 2e38ffa5b54ca..a8aad92c648cd 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AbstractAddExtensionsTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AbstractAddExtensionsTest.java
@@ -1,7 +1,9 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
import static java.util.Arrays.asList;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -135,25 +137,25 @@ void testPartialMatchConflict() throws Exception {
}
@Test
- void addExistingAndMissingExtensions() throws Exception {
+ void addExistingAndMissingExtensionsWillFailForBoth() throws Exception {
createProject();
final QuarkusCommandOutcome result = addExtensions(asList("missing", "agroal"));
final T project = readProject();
doesNotHaveDependency(project, "quarkus-missing");
- hasDependency(project, "quarkus-agroal");
+ doesNotHaveDependency(project, "quarkus-agroal");
Assertions.assertFalse(result.isSuccess());
- Assertions.assertTrue(result.valueIs(AddExtensions.OUTCOME_UPDATED, true));
+ Assertions.assertFalse(result.valueIs(AddExtensions.OUTCOME_UPDATED, true));
}
@Test
- void addDuplicatedExtension() throws Exception {
+ void doNotAddExtensionWhenMultipleMatch() throws Exception {
createProject();
- addExtensions(asList("agroal", "jdbc", "non-exist-ent"));
+ addExtensions(asList("agroal", "jdbc"));
final T project = readProject();
- hasDependency(project, "quarkus-agroal");
+ doesNotHaveDependency(project, "quarkus-agroal");
doesNotHaveDependency(project, "quarkus-jdbc-postgresql");
doesNotHaveDependency(project, "quarkus-jdbc-h2");
}
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AbstractRemoveExtensionsTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AbstractRemoveExtensionsTest.java
similarity index 93%
rename from independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AbstractRemoveExtensionsTest.java
rename to independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AbstractRemoveExtensionsTest.java
index 1acfd547df718..9be4524fa0508 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AbstractRemoveExtensionsTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AbstractRemoveExtensionsTest.java
@@ -1,7 +1,9 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
import static java.util.Arrays.asList;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
import java.io.IOException;
import java.nio.file.Path;
import java.nio.file.Paths;
@@ -64,12 +66,12 @@ void testRegexpMatches() throws Exception {
final QuarkusCommandOutcome result = addExtensions(asList("Sm??lRye**"));
Assertions.assertTrue(result.isSuccess());
- Assertions.assertTrue(result.valueIs(AddExtensions.OUTCOME_UPDATED, true));
+ Assertions.assertTrue(result.getBooleanValue(AddExtensions.OUTCOME_UPDATED));
final QuarkusCommandOutcome result2 = removeExtensions(asList("Sm??lRye**"));
Assertions.assertTrue(result2.isSuccess());
- Assertions.assertTrue(result2.valueIs(RemoveExtensions.OUTCOME_UPDATED, true));
+ Assertions.assertTrue(result2.getBooleanValue(RemoveExtensions.OUTCOME_UPDATED));
final T project = readProject();
hasNoDependency(project, "quarkus-smallrye-reactive-messaging");
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AddGradleExtensionsTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AddGradleExtensionsTest.java
similarity index 53%
rename from independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AddGradleExtensionsTest.java
rename to independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AddGradleExtensionsTest.java
index f080c5fffff4a..553fcb373760b 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AddGradleExtensionsTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AddGradleExtensionsTest.java
@@ -1,20 +1,23 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
+import com.google.common.collect.ImmutableList;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
import io.quarkus.devtools.project.BuildTool;
import io.quarkus.devtools.project.QuarkusProject;
+import io.quarkus.devtools.project.buildfile.AbstractGradleBuildFile;
+import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.HashSet;
import java.util.List;
-import org.junit.jupiter.api.Disabled;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+import org.apache.maven.model.Dependency;
class AddGradleExtensionsTest extends AbstractAddExtensionsTest> {
- @Disabled
- void addExtensionTwiceInTwoBatches() throws IOException {
- //FIXME This is currently not working
- }
-
@Override
protected List createProject() throws IOException, QuarkusCommandException {
CreateProjectTest.delete(getProjectPath().toFile());
@@ -53,6 +56,30 @@ private static String getBuildFileDependencyString(final String groupId, final S
}
private QuarkusProject getQuarkusProject() {
- return QuarkusProject.of(getProjectPath(), getPlatformDescriptor(), BuildTool.GRADLE);
+ final Path projectPath = getProjectPath();
+ final QuarkusPlatformDescriptor platformDescriptor = getPlatformDescriptor();
+ return QuarkusProject.of(projectPath, platformDescriptor, new TestingGradleBuildFile(projectPath, platformDescriptor));
+ }
+
+ static class TestingGradleBuildFile extends AbstractGradleBuildFile {
+
+ public TestingGradleBuildFile(Path projectFolderPath, QuarkusPlatformDescriptor platformDescriptor) {
+ super(projectFolderPath, platformDescriptor);
+ }
+
+ @Override
+ protected List getDependencies() throws IOException {
+ final Matcher matcher = Pattern.compile("\\s*implementation\\s+'([^\\v:]+):([^\\v:]+)(:[^:\\v]+)?'")
+ .matcher(getBuildContent());
+ final ImmutableList.Builder builder = ImmutableList.builder();
+ while (matcher.find()) {
+ final Dependency dep = new Dependency();
+ dep.setGroupId(matcher.group(1));
+ dep.setArtifactId(matcher.group(2));
+ dep.setVersion(matcher.group(3));
+ builder.add(dep);
+ }
+ return builder.build();
+ }
}
}
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AddMavenExtensionsTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AddMavenExtensionsTest.java
similarity index 87%
rename from independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AddMavenExtensionsTest.java
rename to independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AddMavenExtensionsTest.java
index 57ee06f705246..904777bf8917e 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AddMavenExtensionsTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/AddMavenExtensionsTest.java
@@ -1,5 +1,7 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
import io.quarkus.devtools.project.BuildTool;
import io.quarkus.devtools.project.QuarkusProject;
import io.quarkus.maven.utilities.MojoUtils;
@@ -46,6 +48,6 @@ protected long countDependencyOccurrences(final Model project, final String grou
}
private QuarkusProject getQuarkusProject() {
- return QuarkusProject.of(getProjectPath(), getPlatformDescriptor(), BuildTool.MAVEN);
+ return QuarkusProject.maven(getProjectPath(), getPlatformDescriptor());
}
}
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/CreateProjectTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/CreateProjectTest.java
new file mode 100644
index 0000000000000..8bc7c11aea806
--- /dev/null
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/CreateProjectTest.java
@@ -0,0 +1,142 @@
+package io.quarkus.devtools.commands;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
+import static org.assertj.core.api.Assertions.contentOf;
+import static org.junit.jupiter.api.Assertions.assertFalse;
+import static org.junit.jupiter.api.Assertions.assertTrue;
+
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
+import io.quarkus.devtools.project.BuildTool;
+import io.quarkus.devtools.project.codegen.writer.FileProjectWriter;
+import io.quarkus.maven.utilities.MojoUtils;
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.Comparator;
+import java.util.List;
+import java.util.concurrent.Callable;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.ExecutorService;
+import java.util.concurrent.Executors;
+import java.util.stream.Collectors;
+import java.util.stream.IntStream;
+import java.util.stream.Stream;
+import org.apache.maven.model.Model;
+import org.junit.jupiter.api.Assertions;
+import org.junit.jupiter.api.DisplayName;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.api.Timeout;
+
+public class CreateProjectTest extends PlatformAwareTestBase {
+ @Test
+ public void create() throws Exception {
+ final File file = new File("target/basic-rest");
+ delete(file);
+ createProject(file, "io.quarkus", "basic-rest", "1.0.0-SNAPSHOT");
+
+ final File gitignore = new File(file, ".gitignore");
+ assertTrue(gitignore.exists());
+ final String gitignoreContent = new String(Files.readAllBytes(gitignore.toPath()), StandardCharsets.UTF_8);
+ assertTrue(gitignoreContent.contains("\ntarget/\n"));
+ }
+
+ @Test
+ public void createGradle() throws Exception {
+ final File file = new File("target/basic-rest-gradle");
+ delete(file);
+ createProject(BuildTool.GRADLE, file, "io.quarkus", "basic-rest", "1.0.0-SNAPSHOT");
+
+ final File gitignore = new File(file, ".gitignore");
+ assertTrue(gitignore.exists());
+ final String gitignoreContent = new String(Files.readAllBytes(gitignore.toPath()), StandardCharsets.UTF_8);
+ Assertions.assertFalse(gitignoreContent.contains("\ntarget/\n"));
+ assertTrue(gitignoreContent.contains("\nbuild/"));
+ assertTrue(gitignoreContent.contains("\n.gradle/\n"));
+
+ assertThat(new File(file, "README.md")).exists();
+ assertThat(contentOf(new File(file, "README.md"), "UTF-8")).contains("./gradlew");
+ }
+
+ @Test
+ public void createOnTopOfExisting() throws Exception {
+ final File testDir = new File("target/existing");
+ delete(testDir);
+ testDir.mkdirs();
+
+ Model model = new Model();
+ model.setModelVersion("4.0.0");
+ model.setGroupId("org.acme");
+ model.setArtifactId("foobar");
+ model.setVersion("10.1.2");
+ final File pom = new File(testDir, "pom.xml");
+ MojoUtils.write(model, pom);
+ assertThatExceptionOfType(QuarkusCommandException.class).isThrownBy(() -> {
+ new CreateProject(testDir.toPath(), getPlatformDescriptor())
+ .groupId("something.is")
+ .artifactId("wrong")
+ .version("1.0.0-SNAPSHOT")
+ .className("org.foo.MyResource")
+ .execute();
+ }).withRootCauseInstanceOf(IOException.class);
+ }
+
+ @Test
+ @Timeout(2)
+ @DisplayName("Should create correctly multiple times in parallel with multiple threads")
+ void createMultipleTimes() throws InterruptedException {
+ final ExecutorService executorService = Executors.newFixedThreadPool(4);
+ final CountDownLatch latch = new CountDownLatch(20);
+
+ List> collect = IntStream.range(0, 20).boxed().map(i -> (Callable) () -> {
+ File tempDir = Files.createTempDirectory("test").toFile();
+ FileProjectWriter write = new FileProjectWriter(tempDir);
+ final QuarkusCommandOutcome result = new CreateProject(tempDir.toPath(), getPlatformDescriptor())
+ .groupId("org.acme")
+ .artifactId("acme")
+ .version("1.0.0-SNAPSHOT")
+ .className("org.acme.MyResource")
+ .execute();
+ assertTrue(result.isSuccess());
+ latch.countDown();
+ write.close();
+ tempDir.delete();
+ return null;
+ }).collect(Collectors.toList());
+ executorService.invokeAll(collect);
+ latch.await();
+ }
+
+ public static void delete(final File file) throws IOException {
+
+ if (file.exists()) {
+ try (Stream stream = Files.walk(file.toPath())) {
+ stream.sorted(Comparator.reverseOrder())
+ .map(Path::toFile)
+ .forEach(File::delete);
+ }
+ }
+
+ Assertions.assertFalse(
+ Files.exists(file.toPath()), "Directory still exists");
+ }
+
+ private void createProject(final File file, String groupId, String artifactId, String version)
+ throws QuarkusCommandException {
+ createProject(BuildTool.MAVEN, file, groupId, artifactId, version);
+ }
+
+ private void createProject(BuildTool buildTool, File file, String groupId, String artifactId, String version)
+ throws QuarkusCommandException {
+ final QuarkusCommandOutcome result = new CreateProject(file.toPath(), getPlatformDescriptor())
+ .buildTool(buildTool)
+ .groupId(groupId)
+ .artifactId(artifactId)
+ .version(version)
+ .execute();
+ assertTrue(result.isSuccess());
+ }
+}
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/ListExtensionsTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/ListExtensionsTest.java
similarity index 86%
rename from independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/ListExtensionsTest.java
rename to independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/ListExtensionsTest.java
index cd039e61c49a6..a0b797e8ac976 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/ListExtensionsTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/ListExtensionsTest.java
@@ -1,11 +1,13 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
import static io.quarkus.maven.utilities.MojoUtils.readPom;
import static java.util.Arrays.asList;
-import static org.assertj.core.api.Assertions.assertThat;
+import static java.util.stream.Collectors.toMap;
+import static org.assertj.core.api.Assertions.assertThatExceptionOfType;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import io.quarkus.devtools.project.BuildTool;
+import io.quarkus.dependencies.Extension;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
import io.quarkus.devtools.project.QuarkusProject;
import io.quarkus.maven.utilities.MojoUtils;
import io.quarkus.maven.utilities.QuarkusDependencyPredicate;
@@ -13,11 +15,13 @@
import java.io.File;
import java.io.IOException;
import java.io.PrintStream;
+import java.io.UncheckedIOException;
import java.nio.file.Files;
+import java.nio.file.NoSuchFileException;
import java.nio.file.Path;
import java.util.HashSet;
import java.util.Map;
-import org.apache.maven.model.Dependency;
+import java.util.function.Function;
import org.apache.maven.model.Model;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
@@ -31,7 +35,7 @@ public void listWithBom() throws Exception {
final ListExtensions listExtensions = new ListExtensions(project);
- final Map installed = listExtensions.findInstalled();
+ final Map installed = readByManagementKey(project);
Assertions.assertNotNull(installed.get(getPluginGroupId() + ":quarkus-agroal"));
}
@@ -49,7 +53,7 @@ public void listWithBomExtensionWithSpaces() throws Exception {
final ListExtensions listExtensions = new ListExtensions(quarkusProject);
- final Map installed = listExtensions.findInstalled();
+ final Map installed = readByManagementKey(quarkusProject);
Assertions.assertNotNull(installed.get(getPluginGroupId() + ":quarkus-resteasy"));
Assertions.assertNotNull(installed.get(getPluginGroupId() + ":quarkus-hibernate-validator"));
@@ -59,10 +63,8 @@ public void listWithBomExtensionWithSpaces() throws Exception {
public void listWithoutBom() throws Exception {
final File pom = new File("target/list-extensions-test", "pom.xml");
final QuarkusProject quarkusProject = createNewProject(pom);
-
Model model = readPom(pom);
- model.setDependencyManagement(null);
model.getDependencies().stream()
.filter(new QuarkusDependencyPredicate())
.forEach(d -> d.setVersion("0.0.1"));
@@ -162,9 +164,9 @@ public void searchRest() throws Exception {
@Test
void testListExtensionsWithoutAPomFile() throws IOException {
final Path tempDirectory = Files.createTempDirectory("proj");
- ListExtensions listExtensions = new ListExtensions(
- QuarkusProject.of(tempDirectory, getPlatformDescriptor(), BuildTool.MAVEN));
- assertThat(listExtensions.findInstalled()).isEmpty();
+ final QuarkusProject project = QuarkusProject.maven(tempDirectory, getPlatformDescriptor());
+ assertThatExceptionOfType(UncheckedIOException.class).isThrownBy(() -> readByManagementKey(project))
+ .withRootCauseInstanceOf(NoSuchFileException.class);
}
private void addExtensions(QuarkusProject quarkusProject, String... extensions) throws Exception {
@@ -181,6 +183,11 @@ private QuarkusProject createNewProject(final File pom) throws IOException, Quar
.artifactId("add-extension-test")
.version("0.0.1-SNAPSHOT")
.execute();
- return QuarkusProject.of(projectFolderPath, getPlatformDescriptor(), BuildTool.MAVEN);
+ return QuarkusProject.maven(projectFolderPath, getPlatformDescriptor());
+ }
+
+ private static Map readByManagementKey(QuarkusProject project) throws IOException {
+ return project.getExtensionsManager().read().stream()
+ .collect(toMap(Extension::managementKey, Function.identity()));
}
}
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/PlatformAwareTestBase.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/PlatformAwareTestBase.java
similarity index 98%
rename from independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/PlatformAwareTestBase.java
rename to independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/PlatformAwareTestBase.java
index d9a9541f65528..33b1278cd484d 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/PlatformAwareTestBase.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/PlatformAwareTestBase.java
@@ -1,4 +1,4 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
import io.quarkus.platform.tools.config.QuarkusPlatformConfig;
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/RemoveGradleExtensionsTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/RemoveGradleExtensionsTest.java
similarity index 80%
rename from independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/RemoveGradleExtensionsTest.java
rename to independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/RemoveGradleExtensionsTest.java
index 2348a72ba3361..963af786163e6 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/RemoveGradleExtensionsTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/RemoveGradleExtensionsTest.java
@@ -1,9 +1,13 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
import io.quarkus.devtools.project.BuildTool;
import io.quarkus.devtools.project.QuarkusProject;
+import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
import java.io.IOException;
import java.nio.file.Files;
+import java.nio.file.Path;
import java.util.HashSet;
import java.util.List;
import org.junit.jupiter.api.Disabled;
@@ -56,7 +60,10 @@ protected long countDependencyOccurrences(final List buildFile, final St
}
private QuarkusProject getQuarkusProject() {
- return QuarkusProject.of(getProjectPath(), getPlatformDescriptor(), BuildTool.GRADLE);
+ final Path projectPath = getProjectPath();
+ final QuarkusPlatformDescriptor platformDescriptor = getPlatformDescriptor();
+ return QuarkusProject.of(projectPath, platformDescriptor,
+ new AddGradleExtensionsTest.TestingGradleBuildFile(projectPath, platformDescriptor));
}
private static String getBuildFileDependencyString(final String groupId, final String artifactId, final String version) {
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/RemoveMavenExtensionsTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/RemoveMavenExtensionsTest.java
similarity index 88%
rename from independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/RemoveMavenExtensionsTest.java
rename to independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/RemoveMavenExtensionsTest.java
index 57971f118a4ed..febaba8565c34 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/RemoveMavenExtensionsTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/RemoveMavenExtensionsTest.java
@@ -1,6 +1,7 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands;
-import io.quarkus.devtools.project.BuildTool;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
import io.quarkus.devtools.project.QuarkusProject;
import io.quarkus.maven.utilities.MojoUtils;
import java.io.File;
@@ -52,6 +53,6 @@ protected long countDependencyOccurrences(final Model project, final String grou
}
private QuarkusProject getQuarkusProject() {
- return QuarkusProject.of(getProjectPath(), getPlatformDescriptor(), BuildTool.MAVEN);
+ return QuarkusProject.maven(getProjectPath(), getPlatformDescriptor());
}
}
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AddExtensionsSelectTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/handlers/QuarkusCommandHandlersTest.java
similarity index 86%
rename from independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AddExtensionsSelectTest.java
rename to independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/handlers/QuarkusCommandHandlersTest.java
index 633d796491b68..e87d46a1e4ef2 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/cli/commands/AddExtensionsSelectTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/commands/handlers/QuarkusCommandHandlersTest.java
@@ -1,14 +1,16 @@
-package io.quarkus.cli.commands;
+package io.quarkus.devtools.commands.handlers;
+import static io.quarkus.devtools.commands.handlers.QuarkusCommandHandlers.select;
import static java.util.Arrays.asList;
import io.quarkus.dependencies.Extension;
+import io.quarkus.devtools.commands.data.SelectionResult;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Assertions;
import org.junit.jupiter.api.Test;
-class AddExtensionsSelectTest {
+class QuarkusCommandHandlersTest {
@Test
void testMultiMatchByLabels() {
@@ -24,11 +26,11 @@ void testMultiMatchByLabels() {
List extensions = asList(e1, e2, e3);
Collections.shuffle(extensions);
- SelectionResult matches = AddExtensionsCommandHandler.select("foo", extensions, true);
+ SelectionResult matches = select(extensions, "foo", true);
Assertions.assertFalse(matches.matches());
Assertions.assertEquals(2, matches.getExtensions().size());
- matches = AddExtensionsCommandHandler.select("foo", extensions, false);
+ matches = select(extensions, "foo", false);
Assertions.assertFalse(matches.matches());
Assertions.assertEquals(0, matches.getExtensions().size());
}
@@ -44,7 +46,7 @@ void testThatSingleLabelMatchIsNotAMatch() {
List extensions = asList(e1, e2);
Collections.shuffle(extensions);
- SelectionResult matches = AddExtensionsCommandHandler.select("foo", extensions, true);
+ SelectionResult matches = select(extensions, "foo", true);
Assertions.assertFalse(matches.matches());
Assertions.assertEquals(1, matches.getExtensions().size());
}
@@ -63,11 +65,11 @@ void testMultiMatchByArtifactIdsAndNames() {
List extensions = asList(e1, e2, e3);
Collections.shuffle(extensions);
- SelectionResult matches = AddExtensionsCommandHandler.select("foo", extensions, false);
+ SelectionResult matches = select(extensions, "foo", false);
Assertions.assertFalse(matches.matches());
Assertions.assertEquals(2, matches.getExtensions().size());
- matches = AddExtensionsCommandHandler.select("foo", extensions, true);
+ matches = select(extensions, "foo", true);
Assertions.assertFalse(matches.matches());
Assertions.assertEquals(3, matches.getExtensions().size());
@@ -88,7 +90,7 @@ void testShortNameSelection() {
List extensions = asList(e1, e2, e3);
Collections.shuffle(extensions);
- SelectionResult matches = AddExtensionsCommandHandler.select("foo", extensions, false);
+ SelectionResult matches = select(extensions, "foo", false);
Assertions.assertTrue(matches.matches());
Assertions.assertEquals(1, matches.getExtensions().size());
Assertions.assertTrue(matches.iterator().hasNext());
@@ -111,7 +113,7 @@ void testArtifactIdSelectionWithQuarkusPrefix() {
List extensions = asList(e1, e2, e3);
Collections.shuffle(extensions);
- SelectionResult matches = AddExtensionsCommandHandler.select("foo", extensions, false);
+ SelectionResult matches = select(extensions, "foo", false);
Assertions.assertEquals(1, matches.getExtensions().size());
Assertions.assertTrue(matches.iterator().hasNext());
Assertions.assertTrue(matches.iterator().next().getArtifactId().equalsIgnoreCase("quarkus-foo"));
@@ -133,12 +135,11 @@ void testListedVsUnlisted() {
List extensions = asList(e1, e2, e3);
Collections.shuffle(extensions);
- SelectionResult matches = AddExtensionsCommandHandler.select("quarkus-foo", extensions, true);
+ SelectionResult matches = select(extensions, "quarkus-foo", true);
Assertions.assertEquals(2, matches.getExtensions().size());
- matches = AddExtensionsCommandHandler.select("quarkus-foo-unlisted", extensions, true);
+ matches = select(extensions, "quarkus-foo-unlisted", true);
Assertions.assertEquals(1, matches.getExtensions().size());
}
-
}
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/generators/rest/BasicRestProjectGeneratorTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/project/codegen/rest/BasicRestProjectGeneratorTest.java
similarity index 84%
rename from independent-projects/tools/common/src/test/java/io/quarkus/generators/rest/BasicRestProjectGeneratorTest.java
rename to independent-projects/tools/common/src/test/java/io/quarkus/devtools/project/codegen/rest/BasicRestProjectGeneratorTest.java
index 1ca8d1441dc64..2e3255c76aff8 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/generators/rest/BasicRestProjectGeneratorTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/project/codegen/rest/BasicRestProjectGeneratorTest.java
@@ -1,13 +1,13 @@
-package io.quarkus.generators.rest;
-
-import static io.quarkus.generators.ProjectGenerator.BOM_VERSION;
-import static io.quarkus.generators.ProjectGenerator.CLASS_NAME;
-import static io.quarkus.generators.ProjectGenerator.IS_SPRING;
-import static io.quarkus.generators.ProjectGenerator.PACKAGE_NAME;
-import static io.quarkus.generators.ProjectGenerator.PROJECT_ARTIFACT_ID;
-import static io.quarkus.generators.ProjectGenerator.PROJECT_GROUP_ID;
-import static io.quarkus.generators.ProjectGenerator.PROJECT_VERSION;
-import static io.quarkus.generators.ProjectGenerator.SOURCE_TYPE;
+package io.quarkus.devtools.project.codegen.rest;
+
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.BOM_VERSION;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.CLASS_NAME;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.IS_SPRING;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.PACKAGE_NAME;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.PROJECT_ARTIFACT_ID;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.PROJECT_GROUP_ID;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.PROJECT_VERSION;
+import static io.quarkus.devtools.project.codegen.ProjectGenerator.SOURCE_TYPE;
import static org.mockito.ArgumentMatchers.anyString;
import static org.mockito.ArgumentMatchers.argThat;
import static org.mockito.ArgumentMatchers.eq;
@@ -19,13 +19,11 @@
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Maps;
import io.quarkus.bootstrap.util.IoUtils;
-import io.quarkus.cli.commands.PlatformAwareTestBase;
-import io.quarkus.cli.commands.QuarkusCommandInvocation;
-import io.quarkus.devtools.project.BuildTool;
+import io.quarkus.devtools.commands.PlatformAwareTestBase;
+import io.quarkus.devtools.commands.data.QuarkusCommandInvocation;
import io.quarkus.devtools.project.QuarkusProject;
-import io.quarkus.devtools.writer.FileProjectWriter;
-import io.quarkus.devtools.writer.ProjectWriter;
-import io.quarkus.generators.SourceType;
+import io.quarkus.devtools.project.codegen.SourceType;
+import io.quarkus.devtools.project.codegen.writer.ProjectWriter;
import io.quarkus.maven.utilities.MojoUtils;
import java.nio.file.Files;
import java.nio.file.Path;
@@ -63,9 +61,8 @@ void generateMultipleTimes() throws InterruptedException {
final BasicRestProjectGenerator basicRestProjectGenerator = new BasicRestProjectGenerator();
List> collect = IntStream.range(0, 20).boxed().map(i -> (Callable) () -> {
final Path path = Files.createTempDirectory("test");
- try (FileProjectWriter writer = new FileProjectWriter(path.toFile())) {
- basicRestProjectGenerator.generate(writer,
- createQuarkusCommandInvocation(path));
+ try {
+ basicRestProjectGenerator.generate(createQuarkusCommandInvocation(path));
} finally {
IoUtils.recursiveDelete(path);
}
@@ -138,7 +135,7 @@ void generateFilesWithSpringControllerResource() throws Exception {
}
private QuarkusCommandInvocation createQuarkusCommandInvocation(Path projectPath) {
- return new QuarkusCommandInvocation(QuarkusProject.of(projectPath, getPlatformDescriptor(), BuildTool.MAVEN),
+ return new QuarkusCommandInvocation(QuarkusProject.maven(projectPath, getPlatformDescriptor()),
BASIC_PROJECT_CONTEXT);
}
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/devtools/project/compress/QuarkusProjectCompressTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/project/compress/QuarkusProjectCompressTest.java
index 33b014420a00c..4b522f93f335f 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/devtools/project/compress/QuarkusProjectCompressTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/devtools/project/compress/QuarkusProjectCompressTest.java
@@ -6,11 +6,11 @@
import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertTrue;
-import io.quarkus.cli.commands.CreateProject;
-import io.quarkus.cli.commands.CreateProjectTest;
-import io.quarkus.cli.commands.PlatformAwareTestBase;
-import io.quarkus.cli.commands.QuarkusCommandException;
-import io.quarkus.cli.commands.QuarkusCommandOutcome;
+import io.quarkus.devtools.commands.CreateProject;
+import io.quarkus.devtools.commands.CreateProjectTest;
+import io.quarkus.devtools.commands.PlatformAwareTestBase;
+import io.quarkus.devtools.commands.data.QuarkusCommandException;
+import io.quarkus.devtools.commands.data.QuarkusCommandOutcome;
import io.quarkus.devtools.project.QuarkusProject;
import java.io.File;
import java.io.FileInputStream;
diff --git a/independent-projects/tools/common/src/test/java/io/quarkus/test/platform/descriptor/CombinedQuarkusPlatformDescriptorTest.java b/independent-projects/tools/common/src/test/java/io/quarkus/test/platform/descriptor/CombinedQuarkusPlatformDescriptorTest.java
index a0c449225fd1e..f9da268b93ccc 100644
--- a/independent-projects/tools/common/src/test/java/io/quarkus/test/platform/descriptor/CombinedQuarkusPlatformDescriptorTest.java
+++ b/independent-projects/tools/common/src/test/java/io/quarkus/test/platform/descriptor/CombinedQuarkusPlatformDescriptorTest.java
@@ -4,9 +4,9 @@
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertNotNull;
-import io.quarkus.cli.commands.PlatformAwareTestBase;
import io.quarkus.dependencies.Category;
import io.quarkus.dependencies.Extension;
+import io.quarkus.devtools.commands.PlatformAwareTestBase;
import io.quarkus.platform.descriptor.CombinedQuarkusPlatformDescriptor;
import io.quarkus.platform.descriptor.QuarkusPlatformDescriptor;
import java.util.List;
diff --git a/independent-projects/tools/platform-descriptor-api/src/main/java/io/quarkus/platform/tools/ConsoleMessageFormat.java b/independent-projects/tools/platform-descriptor-api/src/main/java/io/quarkus/platform/tools/ConsoleMessageFormat.java
new file mode 100644
index 0000000000000..d4dc80af5c314
--- /dev/null
+++ b/independent-projects/tools/platform-descriptor-api/src/main/java/io/quarkus/platform/tools/ConsoleMessageFormat.java
@@ -0,0 +1,23 @@
+package io.quarkus.platform.tools;
+
+public final class ConsoleMessageFormat {
+
+ public static final String OK = "\u2705";
+ public static final String NOK = "\u274c";
+ public static final String NOOP = "\uD83D\uDC4D";
+
+ private ConsoleMessageFormat() {
+ }
+
+ public static String nok(String content) {
+ return NOK + content;
+ }
+
+ public static String ok(String content) {
+ return OK + content;
+ }
+
+ public static String noop(String content) {
+ return NOOP + content;
+ }
+}
diff --git a/integration-tests/maven/src/test/resources/projects/simple-pom-it/pom.xml b/integration-tests/maven/src/test/resources/projects/simple-pom-it/pom.xml
index 1dc185b7a8940..5147ef2652777 100644
--- a/integration-tests/maven/src/test/resources/projects/simple-pom-it/pom.xml
+++ b/integration-tests/maven/src/test/resources/projects/simple-pom-it/pom.xml
@@ -5,4 +5,21 @@
io.acme.it
acme-empty-pom
0.0.1.BUILD-SNAPSHOT
+
+ io.quarkus
+ quarkus-bom
+ @project.version@
+
+
+
+
+
+ ${quarkus.platform.group-id}
+ ${quarkus.platform.artifact-id}
+ ${quarkus.platform.version}
+ pom
+ import
+
+
+