> getValues() {
}
/**
- * @param nameOrAlias the potential {@link Property#getName() name} or {@link Property#getAlias() alias} of the
- * requested {@link Property}.
+ * @param nameOrAlias the potential {@link Property#getName() name} or {@link Property#getAlias() alias} of the requested {@link Property}.
* @return the requested {@link Property property} or {@code null} if not found.
*/
public Property> getOption(String nameOrAlias) {
@@ -108,8 +107,7 @@ protected void addKeyword(Property> property) {
protected > P add(P property) {
if (this.multiValued != null) {
- throw new IllegalStateException(
- "The multi-valued property " + this.multiValued + " can not be followed by " + property);
+ throw new IllegalStateException("The multi-valued property " + this.multiValued + " can not be followed by " + property);
}
this.propertiesList.add(property);
if (property.isOption()) {
@@ -147,8 +145,7 @@ private void add(String name, Property> property, boolean alias) {
public abstract String getName();
/**
- * @return the first keyword of this {@link Commandlet}. Typically the same as {@link #getName() name} but may also
- * differ (e.g. "set" vs. "set-version").
+ * @return the first keyword of this {@link Commandlet}. Typically the same as {@link #getName() name} but may also differ (e.g. "set" vs. "set-version").
*/
public String getKeyword() {
@@ -167,8 +164,7 @@ protected C getCommandlet(Class commandletType) {
}
/**
- * @return {@code true} if {@link IdeContext#getIdeHome() IDE_HOME} is required for this commandlet, {@code false}
- * otherwise.
+ * @return {@code true} if {@link IdeContext#getIdeHome() IDE_HOME} is required for this commandlet, {@code false} otherwise.
*/
public boolean isIdeHomeRequired() {
@@ -176,8 +172,7 @@ public boolean isIdeHomeRequired() {
}
/**
- * @return {@code true} to suppress the {@link com.devonfw.tools.ide.step.StepImpl#logSummary(boolean) step summary
- * success message}.
+ * @return {@code true} to suppress the {@link com.devonfw.tools.ide.step.StepImpl#logSummary(boolean) step summary success message}.
*/
public boolean isSuppressStepSuccess() {
@@ -190,8 +185,7 @@ public boolean isSuppressStepSuccess() {
public abstract void run();
/**
- * @return {@code true} if this {@link Commandlet} is the valid candidate to be {@link #run()}, {@code false}
- * otherwise.
+ * @return {@code true} if this {@link Commandlet} is the valid candidate to be {@link #run()}, {@code false} otherwise.
* @see Property#validate()
*/
public boolean validate() {
@@ -217,8 +211,8 @@ public String toString() {
}
/**
- * @return the {@link ToolCommandlet} set in a {@link Property} of this commandlet used for auto-completion of a
- * {@link VersionIdentifier} or {@code null} if not exists or not configured.
+ * @return the {@link ToolCommandlet} set in a {@link Property} of this commandlet used for auto-completion of a {@link VersionIdentifier} or {@code null} if
+ * not exists or not configured.
*/
public ToolCommandlet getToolForVersionCompletion() {
diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CompleteCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CompleteCommandlet.java
index a9d856a98..10edb2faf 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/CompleteCommandlet.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/CompleteCommandlet.java
@@ -1,20 +1,20 @@
package com.devonfw.tools.ide.commandlet;
-import java.util.List;
-
import com.devonfw.tools.ide.cli.CliArguments;
import com.devonfw.tools.ide.completion.CompletionCandidate;
import com.devonfw.tools.ide.context.AbstractIdeContext;
import com.devonfw.tools.ide.context.IdeContext;
-import com.devonfw.tools.ide.property.StringListProperty;
+import com.devonfw.tools.ide.property.StringProperty;
+
+import java.util.List;
/**
* {@link Commandlet} for auto-completion.
*/
public final class CompleteCommandlet extends Commandlet {
- /** {@link StringListProperty} with the current CLI arguments to complete. */
- public final StringListProperty args;
+ /** {@link StringProperty} with the current CLI arguments to complete. */
+ public final StringProperty args;
/**
* The constructor.
@@ -25,7 +25,7 @@ public CompleteCommandlet(IdeContext context) {
super(context);
addKeyword(getName());
- this.args = add(new StringListProperty("", false, "args"));
+ this.args = add(new StringProperty("", false, true, "args"));
}
@Override
diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/RepositoryCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/RepositoryCommandlet.java
index f216099a4..6781f70c7 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/RepositoryCommandlet.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/RepositoryCommandlet.java
@@ -1,18 +1,12 @@
package com.devonfw.tools.ide.commandlet;
import com.devonfw.tools.ide.context.IdeContext;
-import com.devonfw.tools.ide.property.PathProperty;
import com.devonfw.tools.ide.property.RepositoryProperty;
import com.devonfw.tools.ide.tool.ToolCommandlet;
-import java.io.FileInputStream;
-import java.io.IOException;
-import java.io.InputStream;
import java.nio.file.Files;
import java.nio.file.Path;
-import java.util.ArrayList;
import java.util.List;
-import java.util.Properties;
import static com.devonfw.tools.ide.commandlet.RepositoryConfig.loadProperties;
@@ -65,8 +59,7 @@ public void run() {
return;
}
- List propertiesFiles = this.context.getFileAccess().listChildren(repositories,
- path -> path.getFileName().toString().endsWith(".properties"));
+ List propertiesFiles = this.context.getFileAccess().listChildren(repositories, path -> path.getFileName().toString().endsWith(".properties"));
boolean forceMode = this.context.isForceMode();
for (Path propertiesFile : propertiesFiles) {
@@ -93,8 +86,7 @@ private void doImportRepository(Path repositoryFile, boolean forceMode) {
String repository = repositoryConfig.path();
String gitUrl = repositoryConfig.gitUrl();
if (repository == null || "".equals(repository) || gitUrl == null || "".equals(gitUrl)) {
- this.context.warning("Invalid repository configuration {} - both 'path' and 'git-url' have to be defined."
- , repositoryFile.getFileName().toString());
+ this.context.warning("Invalid repository configuration {} - both 'path' and 'git-url' have to be defined.", repositoryFile.getFileName().toString());
return;
}
@@ -112,11 +104,10 @@ private void doImportRepository(Path repositoryFile, boolean forceMode) {
if (buildCmd != null && !buildCmd.isEmpty()) {
String[] command = buildCmd.split("\\s+");
ToolCommandlet commandlet = this.context.getCommandletManager().getToolCommandlet(command[0]);
- List args = new ArrayList<>(command.length - 1);
+
for (int i = 1; i < command.length; i++) {
- args.add(command[i]);
+ commandlet.arguments.addValue(command[i]);
}
- commandlet.arguments.setValue(args);
commandlet.run();
} else {
this.context.info("Build command not set. Skipping build for repository.");
diff --git a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java
index 00002b23c..0fb940066 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/commandlet/UninstallCommandlet.java
@@ -1,11 +1,11 @@
package com.devonfw.tools.ide.commandlet;
-import java.nio.file.Files;
-import java.nio.file.Path;
-
import com.devonfw.tools.ide.context.IdeContext;
-import com.devonfw.tools.ide.io.FileAccess;
import com.devonfw.tools.ide.property.ToolProperty;
+import com.devonfw.tools.ide.tool.ToolCommandlet;
+
+import java.nio.file.Files;
+import java.nio.file.Path;
/**
* An internal {@link Commandlet} to uninstall a tool.
@@ -13,7 +13,7 @@
public class UninstallCommandlet extends Commandlet {
/** The tool to uninstall. */
- public final ToolProperty tool;
+ public final ToolProperty tools;
/**
* The constructor.
@@ -24,7 +24,7 @@ public UninstallCommandlet(IdeContext context) {
super(context);
addKeyword(getName());
- this.tool = add(new ToolProperty("", true, "tool"));
+ this.tools = add(new ToolProperty("", true, true, "tool"));
}
@Override
@@ -36,18 +36,25 @@ public String getName() {
@Override
public void run() {
- String commandletName = this.tool.getValue().getName();
- Path softwarePath = context.getSoftwarePath().resolve(commandletName);
- if (Files.exists(softwarePath)) {
- FileAccess fileAccess = context.getFileAccess();
+ for (int i = 0; i < this.tools.getValueCount(); i++) {
+ ToolCommandlet toolCommandlet = this.tools.getValue(i);
+
try {
- fileAccess.delete(softwarePath);
- this.context.success("Successfully uninstalled " + commandletName);
+ String commandletName = toolCommandlet.getName();
+ Path softwarePath = context.getSoftwarePath().resolve(commandletName);
+ if (Files.exists(softwarePath)) {
+ try {
+ context.getFileAccess().delete(softwarePath);
+ this.context.success("Successfully uninstalled " + commandletName);
+ } catch (Exception e) {
+ this.context.error("Couldn't uninstall " + commandletName);
+ }
+ } else {
+ this.context.warning("An installed version of " + commandletName + " does not exist");
+ }
} catch (Exception e) {
- throw new IllegalStateException("Couldn't uninstall " + commandletName, e);
+ this.context.error(e.getMessage());
}
- } else {
- this.context.info("An installed version of " + commandletName + " does not exist");
}
}
}
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/BooleanProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/BooleanProperty.java
index 3f9cf0de2..680b62b1f 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/BooleanProperty.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/BooleanProperty.java
@@ -19,7 +19,7 @@ public class BooleanProperty extends Property {
*/
public BooleanProperty(String name, boolean required, String alias) {
- super(name, required, alias, null);
+ super(name, required, alias);
}
@Override
@@ -82,8 +82,8 @@ public void setValueAsString(String valueAsString, IdeContext context) {
}
@Override
- protected boolean applyValue(String argValue, boolean lookahead, CliArguments args, IdeContext context,
- Commandlet commandlet, CompletionCandidateCollector collector) {
+ protected boolean applyValue(String argValue, boolean lookahead, CliArguments args, IdeContext context, Commandlet commandlet,
+ CompletionCandidateCollector collector) {
if (lookahead) {
Boolean b = parse(argValue);
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/CommandletProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/CommandletProperty.java
index a0854d6bc..0baad0ca1 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/CommandletProperty.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/CommandletProperty.java
@@ -1,11 +1,11 @@
package com.devonfw.tools.ide.property;
-import java.util.function.Consumer;
-
import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
import com.devonfw.tools.ide.context.IdeContext;
+import java.util.function.Consumer;
+
/**
* {@link Property} with {@link #getValueType() value type} {@link Commandlet}.
*/
@@ -33,7 +33,7 @@ public CommandletProperty(String name, boolean required, String alias) {
*/
public CommandletProperty(String name, boolean required, String alias, Consumer validator) {
- super(name, required, alias, validator);
+ super(name, required, alias, false, validator);
}
@Override
@@ -49,8 +49,7 @@ protected String format(Commandlet valueToFormat) {
}
@Override
- protected void completeValue(String arg, IdeContext context, Commandlet commandlet,
- CompletionCandidateCollector collector) {
+ protected void completeValue(String arg, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {
for (Commandlet cmd : context.getCommandletManager().getCommandlets()) {
String cmdName = cmd.getName();
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/EditionProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/EditionProperty.java
index f2226254b..cf17227a3 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/EditionProperty.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/EditionProperty.java
@@ -28,7 +28,7 @@ public EditionProperty(String name, boolean required, String alias) {
*/
public EditionProperty(String name, boolean required, String alias, Consumer validator) {
- super(name, required, alias, validator);
+ super(name, required, alias, false, validator);
}
@Override
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/EnumProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/EnumProperty.java
index d1db549e0..86dfb0b68 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/EnumProperty.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/EnumProperty.java
@@ -1,11 +1,11 @@
package com.devonfw.tools.ide.property;
-import java.util.Locale;
-
import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
import com.devonfw.tools.ide.context.IdeContext;
+import java.util.Locale;
+
/**
* {@link Property} with {@link #getValueType() value type} {@link Boolean}.
*/
@@ -22,7 +22,7 @@ public class EnumProperty> extends Property {
*/
public EnumProperty(String name, boolean required, String alias, Class valueType) {
- super(name, required, alias, null);
+ super(name, required, alias);
this.valueType = valueType;
}
@@ -46,8 +46,7 @@ public V parse(String valueAsString, IdeContext context) {
}
@Override
- protected void completeValue(String arg, IdeContext context, Commandlet commandlet,
- CompletionCandidateCollector collector) {
+ protected void completeValue(String arg, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {
for (V enumConstant : this.valueType.getEnumConstants()) {
String name = enumConstant.name().toLowerCase(Locale.ROOT);
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/LocaleProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/LocaleProperty.java
index 0db5e9750..b28a9ffc1 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/LocaleProperty.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/LocaleProperty.java
@@ -1,13 +1,13 @@
package com.devonfw.tools.ide.property;
-import java.util.Arrays;
-import java.util.Locale;
-import java.util.function.Consumer;
-
import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
import com.devonfw.tools.ide.context.IdeContext;
+import java.util.Arrays;
+import java.util.Locale;
+import java.util.function.Consumer;
+
/**
* {@link Property} with {@link Locale} as {@link #getValueType() value type}.
*/
@@ -37,7 +37,7 @@ public LocaleProperty(String name, boolean required, String alias) {
*/
public LocaleProperty(String name, boolean required, String alias, Consumer validator) {
- super(name, required, alias, validator);
+ super(name, required, alias, false, validator);
}
@Override
@@ -53,8 +53,7 @@ public Locale parse(String valueAsString, IdeContext context) {
}
@Override
- protected void completeValue(String arg, IdeContext context, Commandlet commandlet,
- CompletionCandidateCollector collector) {
+ protected void completeValue(String arg, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {
collector.addAllMatches(arg, getAvailableLocales(), this, commandlet);
}
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/NumberProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/NumberProperty.java
index ccc6b7ddc..0b947f623 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/NumberProperty.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/NumberProperty.java
@@ -1,9 +1,9 @@
package com.devonfw.tools.ide.property;
-import java.util.function.Consumer;
-
import com.devonfw.tools.ide.context.IdeContext;
+import java.util.function.Consumer;
+
/**
* {@link Property} with {@link #getValueType() value type} {@link Long}.
*/
@@ -31,7 +31,7 @@ public NumberProperty(String name, boolean required, String alias) {
*/
public NumberProperty(String name, boolean required, String alias, Consumer validator) {
- super(name, required, alias, validator);
+ super(name, required, alias, false, validator);
}
@Override
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/PathProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/PathProperty.java
index 92c86155a..2e7a56603 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/PathProperty.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/PathProperty.java
@@ -1,15 +1,15 @@
package com.devonfw.tools.ide.property;
+import com.devonfw.tools.ide.commandlet.Commandlet;
+import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
+import com.devonfw.tools.ide.context.IdeContext;
+
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.function.Consumer;
import java.util.stream.Stream;
-import com.devonfw.tools.ide.commandlet.Commandlet;
-import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
-import com.devonfw.tools.ide.context.IdeContext;
-
/**
* {@link Property} with {@link Path} as {@link #getValueType() value type}.
*/
@@ -41,7 +41,7 @@ public PathProperty(String name, boolean required, String alias, boolean mustExi
*/
public PathProperty(String name, boolean required, String alias, boolean mustExist, Consumer validator) {
- super(name, required, alias, validator);
+ super(name, required, alias, false, validator);
this.mustExist = mustExist;
}
@@ -61,10 +61,10 @@ public Path parse(String valueAsString, IdeContext context) {
public boolean validate() {
if (this.value != null) {
- if (Files.exists(this.value)) {
- if (isPathRequiredToBeFile() && !Files.isRegularFile(this.value)) {
+ if (Files.exists(getValue())) {
+ if (isPathRequiredToBeFile() && !Files.isRegularFile(getValue())) {
throw new IllegalStateException("Path " + this.value + " is not a file.");
- } else if (isPathRequiredToBeFolder() && !Files.isDirectory(this.value)) {
+ } else if (isPathRequiredToBeFolder() && !Files.isDirectory(getValue())) {
throw new IllegalStateException("Path " + this.value + " is not a folder.");
}
} else if (isPathRequiredToExist()) {
@@ -76,8 +76,8 @@ public boolean validate() {
}
/**
- * @return {@code true} if the {@link Path} {@link #getValue() value} must
- * {@link Files#exists(Path, java.nio.file.LinkOption...) exist} if set, {@code false} otherwise.
+ * @return {@code true} if the {@link Path} {@link #getValue() value} must {@link Files#exists(Path, java.nio.file.LinkOption...) exist} if set, {@code false}
+ * otherwise.
*/
protected boolean isPathRequiredToExist() {
@@ -85,8 +85,8 @@ protected boolean isPathRequiredToExist() {
}
/**
- * @return {@code true} if the {@link Path} {@link #getValue() value} must be a
- * {@link Files#isDirectory(Path, java.nio.file.LinkOption...) folder} if it exists, {@code false} otherwise.
+ * @return {@code true} if the {@link Path} {@link #getValue() value} must be a {@link Files#isDirectory(Path, java.nio.file.LinkOption...) folder} if it
+ * exists, {@code false} otherwise.
*/
protected boolean isPathRequiredToBeFolder() {
@@ -94,8 +94,8 @@ protected boolean isPathRequiredToBeFolder() {
}
/**
- * @return {@code true} if the {@link Path} {@link #getValue() value} must be a
- * {@link Files#isRegularFile(Path, java.nio.file.LinkOption...) file} if it exists, {@code false} otherwise.
+ * @return {@code true} if the {@link Path} {@link #getValue() value} must be a {@link Files#isRegularFile(Path, java.nio.file.LinkOption...) file} if it
+ * exists, {@code false} otherwise.
*/
protected boolean isPathRequiredToBeFile() {
@@ -103,16 +103,14 @@ protected boolean isPathRequiredToBeFile() {
}
@Override
- protected void completeValue(String arg, IdeContext context, Commandlet commandlet,
- CompletionCandidateCollector collector) {
+ protected void completeValue(String arg, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {
Path path = Path.of(arg);
Path parent = path.getParent();
String filename = path.getFileName().toString();
if (Files.isDirectory(parent)) {
try (Stream children = Files.list(parent)) {
- children.filter(child -> isValidPath(path, filename))
- .forEach(child -> collector.add(child.toString(), null, this, commandlet));
+ children.filter(child -> isValidPath(path, filename)).forEach(child -> collector.add(child.toString(), null, this, commandlet));
} catch (IOException e) {
throw new IllegalStateException(e);
}
@@ -121,9 +119,9 @@ protected void completeValue(String arg, IdeContext context, Commandlet commandl
private boolean isValidPath(Path path, String filename) {
- if (isPathRequiredToBeFile() && !Files.isRegularFile(this.value)) {
+ if (isPathRequiredToBeFile() && !Files.isRegularFile(getValue())) {
return false;
- } else if (isPathRequiredToBeFolder() && !Files.isDirectory(this.value)) {
+ } else if (isPathRequiredToBeFolder() && !Files.isDirectory(getValue())) {
return false;
}
return path.getFileName().toString().startsWith(filename);
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/Property.java b/cli/src/main/java/com/devonfw/tools/ide/property/Property.java
index 5f79211bc..a936f7b7f 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/Property.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/Property.java
@@ -1,8 +1,5 @@
package com.devonfw.tools.ide.property;
-import java.util.Objects;
-import java.util.function.Consumer;
-
import com.devonfw.tools.ide.cli.CliArgument;
import com.devonfw.tools.ide.cli.CliArguments;
import com.devonfw.tools.ide.commandlet.Commandlet;
@@ -10,14 +7,17 @@
import com.devonfw.tools.ide.completion.CompletionCandidateCollectorAdapter;
import com.devonfw.tools.ide.context.IdeContext;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Objects;
+import java.util.function.Consumer;
+
/**
- * A {@link Property} is a simple container for a {@link #getValue() value} with a fixed {@link #getName() name} and
- * {@link #getValueType() type}. Further we use a {@link Property} as {@link CliArgument CLI argument} so it is either
- * an {@link #isOption() option} or a {@link #isValue() value}.
- * In classic Java Beans a property only exists implicit as a combination of a getter and a setter. This class makes it
- * an explicit construct that allows to {@link #getValue() get} and {@link #setValue(Object) set} the value of a
- * property easily in a generic way including to retrieve its {@link #getName() name} and {@link #getValueType() type}.
- * Besides simplification this also prevents the use of reflection for generic CLI parsing with assigning and validating
+ * A {@link Property} is a simple container for a {@link #getValue() value} with a fixed {@link #getName() name} and {@link #getValueType() type}. Further we
+ * use a {@link Property} as {@link CliArgument CLI argument} so it is either an {@link #isOption() option} or a {@link #isValue() value}.
In classic Java
+ * Beans a property only exists implicit as a combination of a getter and a setter. This class makes it an explicit construct that allows to
+ * {@link #getValue() get} and {@link #setValue(Object) set} the value of a property easily in a generic way including to retrieve its {@link #getName() name}
+ * and {@link #getValueType() type}. Besides simplification this also prevents the use of reflection for generic CLI parsing with assigning and validating
* arguments what is beneficial for compiling the Java code to a native image using GraalVM.
*
* @param the {@link #getValueType() value type}.
@@ -39,8 +39,11 @@ public abstract class Property {
private final Consumer validator;
+ /** @see #isMultiValued() */
+ private final boolean multivalued;
+
/** @see #getValue() */
- protected V value;
+ protected final List value = new ArrayList<>();
/**
* The constructor.
@@ -48,15 +51,34 @@ public abstract class Property {
* @param name the {@link #getName() property name}.
* @param required the {@link #isRequired() required flag}.
* @param alias the {@link #getAlias() property alias}.
+ */
+ public Property(String name, boolean required, String alias) {
+
+ super();
+ this.name = name;
+ this.required = required;
+ this.alias = alias;
+ this.multivalued = false;
+ this.validator = null;
+ }
+
+ /**
+ * The constructor.
+ *
+ * @param name the {@link #getName() property name}.
+ * @param required the {@link #isRequired() required flag}.
+ * @param alias the {@link #getAlias() property alias}.
+ * @param multivalued the boolean flag about multiple arguments
* @param validator the {@link Consumer} used to {@link #validate() validate} the {@link #getValue() value}.
*/
- public Property(String name, boolean required, String alias, Consumer validator) {
+ public Property(String name, boolean required, String alias, boolean multivalued, Consumer validator) {
super();
this.name = name;
this.required = required;
this.alias = alias;
this.validator = validator;
+ this.multivalued = multivalued;
}
/**
@@ -77,8 +99,7 @@ public String getAlias() {
}
/**
- * @return the {@link #getName() name} or the {@link #getAlias() alias} if {@link #getName() name} is
- * {@link String#isEmpty() empty}.
+ * @return the {@link #getName() name} or the {@link #getAlias() alias} if {@link #getName() name} is {@link String#isEmpty() empty}.
*/
public String getNameOrAlias() {
@@ -89,8 +110,8 @@ public String getNameOrAlias() {
}
/**
- * @return {@code true} if this property is required (if argument is not present the {@link Commandlet} cannot be
- * invoked), {@code false} otherwise (if optional).
+ * @return {@code true} if this property is required (if argument is not present the {@link Commandlet} cannot be invoked), {@code false} otherwise (if
+ * optional).
*/
public boolean isRequired() {
@@ -106,8 +127,8 @@ public boolean isExpectValue() {
}
/**
- * Determines if this {@link Property} is an option. Canonical options have a long-option {@link #getName() name}
- * (e.g. "--force") and a short-option {@link #getAlias() alias} (e.g. "-f").
+ * Determines if this {@link Property} is an option. Canonical options have a long-option {@link #getName() name} (e.g. "--force") and a short-option
+ * {@link #getAlias() alias} (e.g. "-f").
*
* @return {@code true} if this {@link Property} is an option, {@code false} otherwise (if a positional argument).
*/
@@ -117,8 +138,8 @@ public boolean isOption() {
}
/**
- * @return {@code true} if this {@link Property} forces an implicit {@link CliArgument#isEndOptions() end-options} as
- * if "--" was provided before its first {@link CliArgument argument}.
+ * @return {@code true} if this {@link Property} forces an implicit {@link CliArgument#isEndOptions() end-options} as if "--" was provided before its first
+ * {@link CliArgument argument}.
*/
public boolean isEndOptions() {
@@ -126,21 +147,20 @@ public boolean isEndOptions() {
}
/**
- * Determines if this {@link Property} is multi-valued and accepts any number of values. A multi-valued
- * {@link Property} needs to be the last {@link Property} of a {@link Commandlet}.
+ * Determines if this {@link Property} is multi-valued and accepts any number of values. A multi-valued {@link Property} needs to be the last {@link Property}
+ * of a {@link Commandlet}.
*
* @return {@code true} if multi-valued, {@code false} otherwise.
*/
public boolean isMultiValued() {
- return false;
+ return multivalued;
}
/**
- * Determines if this a value {@link Property}. Such value is either a {@link KeywordProperty} with the keyword as
- * {@link #getName() name} or a raw indexed value argument. In the latter case the command-line argument at this index
- * will be the immediate value of the {@link Property}, the {@link #getName() name} is {@link String#isEmpty() empty}
- * and the {@link #getAlias() alias} is a logical name of the value to display to users.
+ * Determines if this a value {@link Property}. Such value is either a {@link KeywordProperty} with the keyword as {@link #getName() name} or a raw indexed
+ * value argument. In the latter case the command-line argument at this index will be the immediate value of the {@link Property}, the {@link #getName() name}
+ * is {@link String#isEmpty() empty} and the {@link #getAlias() alias} is a logical name of the value to display to users.
*
* @return {@code true} if value, {@code false} otherwise.
*/
@@ -160,7 +180,28 @@ public boolean isValue() {
*/
public V getValue() {
- return this.value;
+ if (this.value.isEmpty()) {
+ return null;
+ } else {
+ return this.value.get(0);
+ }
+ }
+
+ /**
+ * @param i the position to get.
+ * @return the value of this property.
+ */
+ public V getValue(int i) {
+
+ return this.value.get(i);
+ }
+
+ /**
+ * @return amount of values.
+ */
+ public int getValueCount() {
+
+ return this.value.size();
}
/**
@@ -169,10 +210,10 @@ public V getValue() {
*/
public String getValueAsString() {
- if (this.value == null) {
+ if (getValue() == null) {
return null;
}
- return format(this.value);
+ return format(getValue());
}
/**
@@ -190,7 +231,27 @@ protected String format(V valueToFormat) {
*/
public void setValue(V value) {
- this.value = value;
+ if (!this.multivalued) {
+ this.value.clear();
+ }
+ this.value.add(value);
+ }
+
+ public void addValue(V value) {
+
+ if (!this.multivalued) {
+ throw new IllegalStateException("not multivalued");
+ }
+ this.value.add(value);
+ }
+
+ /**
+ * @param value the new {@link #getValue() value} to set.
+ * @param i the position to set.
+ */
+ public void setValue(V value, int i) {
+
+ this.value.set(i, value);
}
/**
@@ -201,9 +262,9 @@ public void setValue(V value) {
public void setValueAsString(String valueAsString, IdeContext context) {
if (valueAsString == null) {
- this.value = getNullValue();
+ setValue(getNullValue());
} else {
- this.value = parse(valueAsString, context);
+ setValue(parse(valueAsString, context));
}
}
@@ -246,15 +307,13 @@ protected V getNullValue() {
public abstract V parse(String valueAsString, IdeContext context);
/**
- * @param args the {@link CliArguments} already {@link CliArguments#current() pointing} the {@link CliArgument} to
- * apply.
+ * @param args the {@link CliArguments} already {@link CliArguments#current() pointing} the {@link CliArgument} to apply.
* @param context the {@link IdeContext}.
* @param commandlet the {@link Commandlet} owning this property.
* @param collector the {@link CompletionCandidateCollector}.
* @return {@code true} if it matches, {@code false} otherwise.
*/
- public boolean apply(CliArguments args, IdeContext context, Commandlet commandlet,
- CompletionCandidateCollector collector) {
+ public boolean apply(CliArguments args, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {
CliArgument argument = args.current();
if (argument.isCompletion()) {
@@ -295,19 +354,26 @@ public boolean apply(CliArguments args, IdeContext context, Commandlet commandle
/**
* @param argValue the value to set as {@link String}.
- * @param lookahead - {@code true} if the given {@code argValue} is taken as lookahead from the next value,
- * {@code false} otherwise.
+ * @param lookahead - {@code true} if the given {@code argValue} is taken as lookahead from the next value, {@code false} otherwise.
* @param args the {@link CliArguments}.
* @param context the {@link IdeContext}.
* @param commandlet the {@link Commandlet} owning this {@link Property}.
* @param collector the {@link CompletionCandidateCollector}.
* @return {@code true} if it matches, {@code false} otherwise.
*/
- protected boolean applyValue(String argValue, boolean lookahead, CliArguments args, IdeContext context,
- Commandlet commandlet, CompletionCandidateCollector collector) {
+ protected boolean applyValue(String argValue, boolean lookahead, CliArguments args, IdeContext context, Commandlet commandlet,
+ CompletionCandidateCollector collector) {
boolean success = assignValueAsString(argValue, context, commandlet);
+
if (success) {
+ if (multivalued) {
+
+ while (success && args.hasNext()) {
+ CliArgument arg = args.next();
+ success = assignValueAsString(arg.get(), context, commandlet);
+ }
+ }
args.next();
}
return success;
@@ -322,8 +388,7 @@ protected boolean applyValue(String argValue, boolean lookahead, CliArguments ar
* @param commandlet the {@link Commandlet} owning this {@link Property}.
* @param collector the {@link CompletionCandidateCollector}.
*/
- protected void complete(CliArgument argument, CliArguments args, IdeContext context, Commandlet commandlet,
- CompletionCandidateCollector collector) {
+ protected void complete(CliArgument argument, CliArguments args, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {
String arg = argument.get();
if (this.name.isEmpty()) {
@@ -351,7 +416,7 @@ protected void complete(CliArgument argument, CliArguments args, IdeContext cont
if (value != null) {
String key = argument.getKey();
if (this.name.equals(key) || Objects.equals(this.alias, key)) {
- completeValue(value, context, commandlet, new CompletionCandidateCollectorAdapter(key+"=", collector));
+ completeValue(value, context, commandlet, new CompletionCandidateCollectorAdapter(key + "=", collector));
}
}
}
@@ -364,15 +429,13 @@ protected void complete(CliArgument argument, CliArguments args, IdeContext cont
* @param commandlet the {@link Commandlet} owning this {@link Property}.
* @param collector the {@link CompletionCandidateCollector}.
*/
- protected void completeValue(String arg, IdeContext context, Commandlet commandlet,
- CompletionCandidateCollector collector) {
+ protected void completeValue(String arg, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {
}
/**
* @param nameOrAlias the potential {@link #getName() name} or {@link #getAlias() alias} to match.
- * @return {@code true} if the given {@code nameOrAlias} is equal to {@link #getName() name} or {@link #getAlias()
- * alias}, {@code false} otherwise.
+ * @return {@code true} if the given {@code nameOrAlias} is equal to {@link #getName() name} or {@link #getAlias() alias}, {@code false} otherwise.
*/
public boolean matches(String nameOrAlias) {
@@ -380,18 +443,18 @@ public boolean matches(String nameOrAlias) {
}
/**
- * @return {@code true} if this {@link Property} is valid, {@code false} if it is {@link #isRequired() required} but
- * no {@link #getValue() value} has been set.
- * @throws RuntimeException if the {@link #getValue() value} is violating given constraints. This is checked by the
- * optional {@link Consumer} function given at construction time.
+ * @return {@code true} if this {@link Property} is valid, {@code false} if it is {@link #isRequired() required} but no {@link #getValue() value} has been
+ * set.
+ * @throws RuntimeException if the {@link #getValue() value} is violating given constraints. This is checked by the optional {@link Consumer} function given
+ * at construction time.
*/
public boolean validate() {
- if (this.required && (this.value == null)) {
+ if (this.required && (getValue() == null)) {
return false;
}
if (this.validator != null) {
- this.validator.accept(this.value);
+ this.validator.accept(getValue());
}
return true;
}
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/StringListProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/StringListProperty.java
deleted file mode 100644
index 1a393d077..000000000
--- a/cli/src/main/java/com/devonfw/tools/ide/property/StringListProperty.java
+++ /dev/null
@@ -1,107 +0,0 @@
-package com.devonfw.tools.ide.property;
-
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.List;
-import java.util.Objects;
-import java.util.function.Consumer;
-
-import com.devonfw.tools.ide.cli.CliArgument;
-import com.devonfw.tools.ide.cli.CliArguments;
-import com.devonfw.tools.ide.commandlet.Commandlet;
-import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
-import com.devonfw.tools.ide.context.IdeContext;
-
-/**
- * {@link Property} with {@link #getValueType() value type} {@link String}.
- */
-public class StringListProperty extends Property> {
-
- private static final String[] NO_ARGS = new String[0];
-
- /**
- * The constructor.
- *
- * @param name the {@link #getName() property name}.
- * @param required the {@link #isRequired() required flag}.
- * @param alias the {@link #getAlias() property alias}.
- */
- public StringListProperty(String name, boolean required, String alias) {
-
- this(name, required, alias, null);
- }
-
- /**
- * The constructor.
- *
- * @param name the {@link #getName() property name}.
- * @param required the {@link #isRequired() required flag}.
- * @param alias the {@link #getAlias() property alias}.
- * @param validator the {@link Consumer} used to {@link #validate() validate} the {@link #getValue() value}.
- */
- public StringListProperty(String name, boolean required, String alias, Consumer> validator) {
-
- super(name, required, alias, validator);
- }
-
- @SuppressWarnings({ "unchecked", "rawtypes" })
- @Override
- public Class> getValueType() {
-
- return (Class) List.class;
- }
-
- @Override
- public boolean isMultiValued() {
-
- return true;
- }
-
- @Override
- public void setValueAsString(String valueAsString, IdeContext context) {
-
- Objects.requireNonNull(valueAsString);
- // pragmatic solution this implementation does not set the list value to the given string
- // instead it adds the given value to the list
- List list = getValue();
- if (list == null) {
- list = new ArrayList<>();
- setValue(list);
- }
- list.add(valueAsString);
- }
-
- @Override
- public List parse(String valueAsString, IdeContext context) {
-
- String[] items = valueAsString.split(" ");
- return Arrays.asList(items);
- }
-
- /**
- * @return the {@link #getValue() value} as null-safe {@link String} array.
- */
- public String[] asArray() {
-
- List list = getValue();
- if ((list == null) || list.isEmpty()) {
- return NO_ARGS;
- }
- return list.toArray(new String[list.size()]);
- }
-
- @Override
- protected boolean applyValue(String argValue, boolean lookahead, CliArguments args, IdeContext context,
- Commandlet commandlet, CompletionCandidateCollector collector) {
-
- this.value = new ArrayList<>();
- this.value.add(argValue);
- while (args.hasNext()) {
- CliArgument arg = args.next();
- this.value.add(arg.get());
- }
- args.next();
- return true;
- }
-
-}
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/StringProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/StringProperty.java
index 1ae5cff13..55a46c9dc 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/StringProperty.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/StringProperty.java
@@ -1,9 +1,9 @@
package com.devonfw.tools.ide.property;
-import java.util.function.Consumer;
-
import com.devonfw.tools.ide.context.IdeContext;
+import java.util.function.Consumer;
+
/**
* {@link Property} with {@link #getValueType() value type} {@link String}.
*/
@@ -18,7 +18,20 @@ public class StringProperty extends Property {
*/
public StringProperty(String name, boolean required, String alias) {
- this(name, required, alias, null);
+ this(name, required, alias, false, null);
+ }
+
+ /**
+ * The constructor.
+ *
+ * @param name the {@link #getName() property name}.
+ * @param required the {@link #isRequired() required flag}.
+ * @param alias the {@link #getAlias() property alias}.
+ * @param multivalued the boolean flag about multiple arguments.
+ */
+ public StringProperty(String name, boolean required, boolean multivalued, String alias) {
+
+ this(name, required, alias, multivalued, null);
}
/**
@@ -28,10 +41,11 @@ public StringProperty(String name, boolean required, String alias) {
* @param required the {@link #isRequired() required flag}.
* @param alias the {@link #getAlias() property alias}.
* @param validator the {@link Consumer} used to {@link #validate() validate} the {@link #getValue() value}.
+ * @param multivalued the boolean flag about multiple arguments
*/
- public StringProperty(String name, boolean required, String alias, Consumer validator) {
+ public StringProperty(String name, boolean required, String alias, boolean multivalued, Consumer validator) {
- super(name, required, alias, validator);
+ super(name, required, alias, multivalued, validator);
}
@Override
@@ -46,4 +60,12 @@ public String parse(String valueAsString, IdeContext context) {
return valueAsString;
}
+ /**
+ * @return the {@link #getValue() value} as null-safe {@link String} array.
+ */
+ public String[] asArray() {
+
+ return this.value.toArray(new String[this.value.size()]);
+ }
+
}
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/ToolProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/ToolProperty.java
index 6b3d71e5c..31e1c7233 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/ToolProperty.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/ToolProperty.java
@@ -1,12 +1,12 @@
package com.devonfw.tools.ide.property;
-import java.util.function.Consumer;
-
import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.tool.ToolCommandlet;
+import java.util.function.Consumer;
+
/**
* {@link Property} with {@link #getValueType() value type} {@link ToolCommandlet}.
*/
@@ -21,7 +21,20 @@ public class ToolProperty extends Property {
*/
public ToolProperty(String name, boolean required, String alias) {
- this(name, required, alias, null);
+ this(name, required, alias, false, null);
+ }
+
+ /**
+ * The constructor.
+ *
+ * @param name the {@link #getName() property name}.
+ * @param required the {@link #isRequired() required flag}.
+ * @param multivalued the boolean flag about multiple arguments
+ * @param alias the {@link #getAlias() property alias}.
+ */
+ public ToolProperty(String name, boolean required, boolean multivalued, String alias) {
+
+ this(name, required, alias, multivalued, null);
}
/**
@@ -30,11 +43,12 @@ public ToolProperty(String name, boolean required, String alias) {
* @param name the {@link #getName() property name}.
* @param required the {@link #isRequired() required flag}.
* @param alias the {@link #getAlias() property alias}.
+ * @param multivalued the boolean flag about multiple arguments
* @param validator the {@link Consumer} used to {@link #validate() validate} the {@link #getValue() value}.
*/
- public ToolProperty(String name, boolean required, String alias, Consumer validator) {
+ public ToolProperty(String name, boolean required, String alias, boolean multivalued, Consumer validator) {
- super(name, required, alias, validator);
+ super(name, required, alias, multivalued, validator);
}
@Override
@@ -56,8 +70,7 @@ public ToolCommandlet parse(String valueAsString, IdeContext context) {
}
@Override
- protected void completeValue(String arg, IdeContext context, Commandlet commandlet,
- CompletionCandidateCollector collector) {
+ protected void completeValue(String arg, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {
for (Commandlet cmd : context.getCommandletManager().getCommandlets()) {
if (cmd instanceof ToolCommandlet) {
diff --git a/cli/src/main/java/com/devonfw/tools/ide/property/VersionProperty.java b/cli/src/main/java/com/devonfw/tools/ide/property/VersionProperty.java
index 72364ee31..7db0b535a 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/property/VersionProperty.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/property/VersionProperty.java
@@ -1,10 +1,5 @@
package com.devonfw.tools.ide.property;
-import java.util.Collections;
-import java.util.List;
-import java.util.function.Consumer;
-import java.util.stream.IntStream;
-
import com.devonfw.tools.ide.commandlet.Commandlet;
import com.devonfw.tools.ide.completion.CompletionCandidate;
import com.devonfw.tools.ide.completion.CompletionCandidateCollector;
@@ -13,6 +8,11 @@
import com.devonfw.tools.ide.version.VersionIdentifier;
import com.devonfw.tools.ide.version.VersionSegment;
+import java.util.Collections;
+import java.util.List;
+import java.util.function.Consumer;
+import java.util.stream.IntStream;
+
/**
* {@link Property} for {@link VersionIdentifier} as {@link #getValueType() value type}.
*/
@@ -40,7 +40,7 @@ public VersionProperty(String name, boolean required, String alias) {
*/
public VersionProperty(String name, boolean required, String alias, Consumer validator) {
- super(name, required, alias, validator);
+ super(name, required, alias, false, validator);
}
@Override
@@ -56,15 +56,16 @@ public VersionIdentifier parse(String valueAsString, IdeContext context) {
}
@Override
- protected void completeValue(String arg, IdeContext context, Commandlet commandlet,
- CompletionCandidateCollector collector) {
+ protected void completeValue(String arg, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {
ToolCommandlet tool = commandlet.getToolForVersionCompletion();
if (tool != null) {
completeVersion(VersionIdentifier.of(arg), tool, context, commandlet, collector);
}
}
- private void completeVersion(VersionIdentifier version2complete, ToolCommandlet tool, IdeContext context, Commandlet commandlet, CompletionCandidateCollector collector) {
+
+ private void completeVersion(VersionIdentifier version2complete, ToolCommandlet tool, IdeContext context, Commandlet commandlet,
+ CompletionCandidateCollector collector) {
collector.disableSorting();
if (tool != null) {
@@ -80,13 +81,12 @@ private void completeVersion(VersionIdentifier version2complete, ToolCommandlet
}
List versions = context.getUrls().getSortedVersions(tool.getName(), tool.getEdition());
int size = versions.size();
- String[] sortedCandidates = IntStream.rangeClosed(1, size).mapToObj(i -> versions.get(size - i).toString())
- .toArray(String[]::new);
+ String[] sortedCandidates = IntStream.rangeClosed(1, size).mapToObj(i -> versions.get(size - i).toString()).toArray(String[]::new);
collector.addAllMatches(text, sortedCandidates, this, commandlet);
List candidates = collector.getCandidates();
Collections.reverse(candidates);
- CompletionCandidate latest = collector.createCandidate(text + VersionSegment.PATTERN_MATCH_ANY_STABLE_VERSION,
- "Latest stable matching version", this, commandlet);
+ CompletionCandidate latest = collector.createCandidate(text + VersionSegment.PATTERN_MATCH_ANY_STABLE_VERSION, "Latest stable matching version", this,
+ commandlet);
if (candidates.isEmpty()) {
candidates.add(latest);
} else {
diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java
index f433093df..0787bd2bb 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/tool/GlobalToolCommandlet.java
@@ -25,8 +25,7 @@ public abstract class GlobalToolCommandlet extends ToolCommandlet {
*
* @param context the {@link IdeContext}.
* @param tool the {@link #getName() tool name}.
- * @param tags the {@link #getTags() tags} classifying the tool. Should be created via {@link Set#of(Object) Set.of}
- * method.
+ * @param tags the {@link #getTags() tags} classifying the tool. Should be created via {@link Set#of(Object) Set.of} method.
*/
public GlobalToolCommandlet(IdeContext context, String tool, Set tags) {
diff --git a/cli/src/main/java/com/devonfw/tools/ide/tool/ToolCommandlet.java b/cli/src/main/java/com/devonfw/tools/ide/tool/ToolCommandlet.java
index 9260188d0..8a4916054 100644
--- a/cli/src/main/java/com/devonfw/tools/ide/tool/ToolCommandlet.java
+++ b/cli/src/main/java/com/devonfw/tools/ide/tool/ToolCommandlet.java
@@ -10,7 +10,7 @@
import com.devonfw.tools.ide.process.ProcessContext;
import com.devonfw.tools.ide.process.ProcessErrorHandling;
import com.devonfw.tools.ide.process.ProcessMode;
-import com.devonfw.tools.ide.property.StringListProperty;
+import com.devonfw.tools.ide.property.StringProperty;
import com.devonfw.tools.ide.version.VersionIdentifier;
import java.io.IOException;
@@ -30,7 +30,7 @@ public abstract class ToolCommandlet extends Commandlet implements Tags {
private final Set tags;
/** The commandline arguments to pass to the tool. */
- public final StringListProperty arguments;
+ public final StringProperty arguments;
private MacOsHelper macOsHelper;
@@ -47,7 +47,7 @@ public ToolCommandlet(IdeContext context, String tool, Set tags) {
this.tool = tool;
this.tags = tags;
addKeyword(tool);
- this.arguments = new StringListProperty("", false, "args");
+ this.arguments = new StringProperty("", false, true, "args");
initProperties();
}
diff --git a/cli/src/test/java/com/devonfw/tools/ide/commandlet/UninstallCommandletTest.java b/cli/src/test/java/com/devonfw/tools/ide/commandlet/UninstallCommandletTest.java
index bd86e2b0c..1aeece501 100644
--- a/cli/src/test/java/com/devonfw/tools/ide/commandlet/UninstallCommandletTest.java
+++ b/cli/src/test/java/com/devonfw/tools/ide/commandlet/UninstallCommandletTest.java
@@ -1,18 +1,23 @@
package com.devonfw.tools.ide.commandlet;
-import static org.mockito.ArgumentMatchers.any;
-import static org.mockito.Mockito.doThrow;
-import static org.mockito.Mockito.mock;
+import com.devonfw.tools.ide.context.AbstractIdeContextTest;
+import com.devonfw.tools.ide.context.IdeTestContext;
+import com.devonfw.tools.ide.io.FileAccessImpl;
+import com.devonfw.tools.ide.log.IdeLogLevel;
+import com.devonfw.tools.ide.property.ToolProperty;
+import com.devonfw.tools.ide.tool.dotnet.DotNet;
+import com.devonfw.tools.ide.tool.eclipse.Eclipse;
+import com.devonfw.tools.ide.tool.npm.Npm;
+import org.junit.jupiter.api.Test;
import java.nio.file.Files;
import java.nio.file.Path;
-import org.junit.jupiter.api.Test;
-
-import com.devonfw.tools.ide.context.AbstractIdeContextTest;
-import com.devonfw.tools.ide.context.IdeTestContext;
-import com.devonfw.tools.ide.io.FileAccess;
-import com.devonfw.tools.ide.log.IdeLogLevel;
+import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.Mockito.doThrow;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
/**
* Integration test of {@link UninstallCommandlet}.
@@ -21,57 +26,77 @@ public class UninstallCommandletTest extends AbstractIdeContextTest {
/**
* Test of {@link UninstallCommandlet} run.
- *
*/
@Test
public void testUninstallCommandletRun_WithExistingCommandlet() {
// arrange
- String toolName = "npm";
+ String npm = "npm";
+ String dotnet = "dotnet";
IdeTestContext context = newContext(PROJECT_BASIC);
- UninstallCommandlet uninstallCommandlet = context.getCommandletManager().getCommandlet(UninstallCommandlet.class);
- uninstallCommandlet.tool.setValueAsString(toolName, context);
+ CommandletManager commandletManager = getCommandletManager(context);
+ UninstallCommandlet uninstallCommandlet = commandletManager.getCommandlet(UninstallCommandlet.class);
+ Npm npmCommandlet = commandletManager.getCommandlet(Npm.class);
+ DotNet dotnetCommandlet = commandletManager.getCommandlet(DotNet.class);
+
+ ToolProperty tools = uninstallCommandlet.tools;
+ tools.addValue(npmCommandlet);
+ tools.addValue(dotnetCommandlet);
+
// act
uninstallCommandlet.run();
// assert
- assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully uninstalled " + toolName);
- assertThat(Files.notExists(context.getSoftwarePath().resolve(toolName)));
+ assertLogMessage(context, IdeLogLevel.SUCCESS, "Successfully uninstalled " + npm);
+ assertLogMessage(context, IdeLogLevel.WARNING, "An installed version of " + dotnet + " does not exist");
+ assertThat(Files.notExists(context.getSoftwarePath().resolve(npm)));
}
@Test
public void testUninstallCommandletRun_WithNonExistingCommandlet() {
// arrange
- String toolName = "eclipse";
+ String eclipse = "eclipse";
IdeTestContext context = newContext(PROJECT_BASIC);
- UninstallCommandlet uninstallCommandlet = context.getCommandletManager().getCommandlet(UninstallCommandlet.class);
- uninstallCommandlet.tool.setValueAsString(toolName, context);
+ CommandletManager commandletManager = getCommandletManager(context);
+ UninstallCommandlet uninstallCommandlet = commandletManager.getCommandlet(UninstallCommandlet.class);
+ Eclipse eclipseCommandlet = commandletManager.getCommandlet(Eclipse.class);
+ uninstallCommandlet.tools.addValue(eclipseCommandlet);
// act
uninstallCommandlet.run();
// assert
- assertLogMessage(context, IdeLogLevel.INFO, "An installed version of " + toolName + " does not exist");
- assertThat(Files.notExists(context.getSoftwarePath().resolve(toolName)));
+ assertLogMessage(context, IdeLogLevel.WARNING, "An installed version of " + eclipse + " does not exist");
+ assertThat(Files.notExists(context.getSoftwarePath().resolve(eclipse)));
}
@Test
public void testUninstallCommandletRun_ThrowsException() {
// arrange
- String toolName = "npm";
+ FileAccessImpl mockFileAccess = mock(FileAccessImpl.class);
+ IdeTestContext mockContext = mock(IdeTestContext.class);
IdeTestContext context = newContext(PROJECT_BASIC);
+ Path softwarePath = context.getSoftwarePath();
+
+ when(mockContext.getFileAccess()).thenReturn(mockFileAccess);
- FileAccess mockFileAccess = mock(FileAccess.class);
- doThrow(new IllegalStateException()).when(mockFileAccess).delete(any(Path.class));
- context.setMockFileAccess(mockFileAccess);
+ when(mockContext.getCommandletManager()).thenReturn(new CommandletManagerImpl(mockContext));
+ when(mockContext.getSoftwarePath()).thenReturn(softwarePath);
+
+ doThrow(new IllegalStateException("Couldn't uninstall")).when(mockFileAccess).delete(any());
+ CommandletManager commandletManager = getCommandletManager(mockContext);
+ UninstallCommandlet uninstallCommandlet = commandletManager.getCommandlet(UninstallCommandlet.class);
+ Npm npmCommandlet = commandletManager.getCommandlet(Npm.class);
+ uninstallCommandlet.tools.addValue(npmCommandlet);
- UninstallCommandlet uninstallCommandlet = context.getCommandletManager().getCommandlet(UninstallCommandlet.class);
- uninstallCommandlet.tool.setValueAsString(toolName, context);
// act
- try {
- uninstallCommandlet.run();
- } catch (IllegalStateException e) {
- // assert
- assertThat(e).hasMessageContaining("Couldn't uninstall " + toolName);
- }
+ uninstallCommandlet.run();
+
+ //assert
+ verify(mockContext).error("Couldn't uninstall npm");
+ }
+
+ private CommandletManager getCommandletManager(IdeTestContext context) {
+
+ return context.getCommandletManager();
}
-}
+}
\ No newline at end of file
diff --git a/cli/src/test/java/com/devonfw/tools/ide/tool/jmc/JmcTest.java b/cli/src/test/java/com/devonfw/tools/ide/tool/jmc/JmcTest.java
index 5de3c5b93..58cf5df13 100644
--- a/cli/src/test/java/com/devonfw/tools/ide/tool/jmc/JmcTest.java
+++ b/cli/src/test/java/com/devonfw/tools/ide/tool/jmc/JmcTest.java
@@ -1,18 +1,16 @@
package com.devonfw.tools.ide.tool.jmc;
-import java.io.IOException;
-import java.util.List;
-
-import org.junit.jupiter.api.Test;
-import org.junit.jupiter.params.ParameterizedTest;
-import org.junit.jupiter.params.provider.ValueSource;
-
import com.devonfw.tools.ide.commandlet.InstallCommandlet;
import com.devonfw.tools.ide.context.AbstractIdeContextTest;
import com.devonfw.tools.ide.context.IdeTestContext;
import com.devonfw.tools.ide.log.IdeLogLevel;
import com.devonfw.tools.ide.os.SystemInfo;
import com.devonfw.tools.ide.os.SystemInfoMock;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedTest;
+import org.junit.jupiter.params.provider.ValueSource;
+
+import java.io.IOException;
/**
* Integration test of {@link Jmc}.
@@ -59,7 +57,9 @@ public void testJmcRun(String os) {
SystemInfo systemInfo = SystemInfoMock.of(os);
context.setSystemInfo(systemInfo);
Jmc commandlet = new Jmc(context);
- commandlet.arguments.setValue(List.of("foo", "bar"));
+
+ commandlet.arguments.addValue("foo");
+ commandlet.arguments.addValue("bar");
// act
commandlet.run();