Skip to content

Commit

Permalink
#344: add generic list support to property (#355)
Browse files Browse the repository at this point in the history
  • Loading branch information
ndemirca authored May 28, 2024
1 parent 1e650d7 commit 2554339
Show file tree
Hide file tree
Showing 22 changed files with 349 additions and 345 deletions.
7 changes: 7 additions & 0 deletions cli/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@
<artifactId>jansi</artifactId>
<version>${jansi.version}</version>
</dependency>
<dependency>
<!-- required for advanced mocking -->
<groupId>net.bytebuddy</groupId>
<artifactId>byte-buddy</artifactId>
<version>1.14.15</version>
<scope>test</scope>
</dependency>
</dependencies>

<build>
Expand Down
25 changes: 10 additions & 15 deletions cli/src/main/java/com/devonfw/tools/ide/cli/CliArgument.java
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,16 @@
import java.util.Objects;

/**
* Represents an argument for a command-line-interface (CLI) and a chain to all its {@link #getNext(boolean)
* successors}.
* Represents an argument for a command-line-interface (CLI) and a chain to all its {@link #getNext(boolean) successors}.
*
* @since 1.0.0
* @see #getNext(boolean)
* @since 1.0.0
*/
public class CliArgument {

/**
* The {@link #get() argument} to indicate the end of the options. If this string is given as argument, any further
* arguments are treated as values. This allows to provide values (e.g. a filename) starting with a hyphen ('-').
* The {@link #get() argument} to indicate the end of the options. If this string is given as argument, any further arguments are treated as values. This
* allows to provide values (e.g. a filename) starting with a hyphen ('-').
*/
public static final String END_OPTIONS = "--";

Expand Down Expand Up @@ -144,8 +143,7 @@ public boolean isStart() {

/**
* @param successors the number of {@link #getNext() successors} expected.
* @return {@code true} if at least the given number of {@link #getNext() successors} are available, {@code false}
* otherwise.
* @return {@code true} if at least the given number of {@link #getNext() successors} are available, {@code false} otherwise.
*/
public boolean hasMoreSuccessorsThan(int successors) {

Expand Down Expand Up @@ -173,8 +171,7 @@ public CliArgument getNext() {
}

/**
* @param splitShortOpts - if {@code true} then combined short options will be split (so instead of "-fbd" you will
* get "-f", "-b", "-d").
* @param splitShortOpts - if {@code true} then combined short options will be split (so instead of "-fbd" you will get "-f", "-b", "-d").
* @return the next {@link CliArgument} or {@code null} if this is the {@link #isEnd() end}.
*/
public CliArgument getNext(boolean splitShortOpts) {
Expand All @@ -194,8 +191,7 @@ public CliArgument getNext(boolean splitShortOpts) {
}

/**
* @return the {@code «key»} part if the {@link #get() argument} has the has the form {@code «key»=«value»}. Otherwise
* the {@link #get() argument} itself.
* @return the {@code «key»} part if the {@link #get() argument} has the has the form {@code «key»=«value»}. Otherwise the {@link #get() argument} itself.
*/
public String getKey() {

Expand All @@ -204,8 +200,7 @@ public String getKey() {
}

/**
* @return the {@code «value»} part if the {@link #get() argument} has the has the form {@code «key»=«value»}.
* Otherwise {@code null}.
* @return the {@code «value»} part if the {@link #get() argument} has the has the form {@code «key»=«value»}. Otherwise {@code null}.
*/
public String getValue() {

Expand All @@ -228,8 +223,8 @@ private void initKeyValue() {
}

/**
* @return a {@link String} representing all arguments from this {@link CliArgument} recursively along is
* {@link #getNext(boolean) next} arguments to the {@link #isEnd() end}.
* @return a {@link String} representing all arguments from this {@link CliArgument} recursively along is {@link #getNext(boolean) next} arguments to the
* {@link #isEnd() end}.
*/
public String getArgs() {

Expand Down
34 changes: 14 additions & 20 deletions cli/src/main/java/com/devonfw/tools/ide/commandlet/Commandlet.java
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
package com.devonfw.tools.ide.commandlet;

import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.property.KeywordProperty;
import com.devonfw.tools.ide.property.Property;
import com.devonfw.tools.ide.tool.ToolCommandlet;
import com.devonfw.tools.ide.version.VersionIdentifier;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;

import com.devonfw.tools.ide.context.IdeContext;
import com.devonfw.tools.ide.property.KeywordProperty;
import com.devonfw.tools.ide.property.Property;
import com.devonfw.tools.ide.tool.ToolCommandlet;
import com.devonfw.tools.ide.version.VersionIdentifier;

/**
* A {@link Commandlet} is a sub-command of the IDE CLI.
*/
Expand Down Expand Up @@ -68,8 +68,7 @@ public List<Property<?>> 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) {
Expand Down Expand Up @@ -108,8 +107,7 @@ protected void addKeyword(Property<?> property) {
protected <P extends Property<?>> 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()) {
Expand Down Expand Up @@ -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() {

Expand All @@ -167,17 +164,15 @@ protected <C extends Commandlet> C getCommandlet(Class<C> 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() {

return true;
}

/**
* @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() {

Expand All @@ -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() {
Expand All @@ -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() {

Expand Down
Original file line number Diff line number Diff line change
@@ -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.
Expand All @@ -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
Expand Down
Original file line number Diff line number Diff line change
@@ -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;

Expand Down Expand Up @@ -65,8 +59,7 @@ public void run() {
return;
}

List <Path> propertiesFiles = this.context.getFileAccess().listChildren(repositories,
path -> path.getFileName().toString().endsWith(".properties"));
List<Path> propertiesFiles = this.context.getFileAccess().listChildren(repositories, path -> path.getFileName().toString().endsWith(".properties"));

boolean forceMode = this.context.isForceMode();
for (Path propertiesFile : propertiesFiles) {
Expand All @@ -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;
}

Expand All @@ -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<String> 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.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
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.
*/
public class UninstallCommandlet extends Commandlet {

/** The tool to uninstall. */
public final ToolProperty tool;
public final ToolProperty tools;

/**
* The constructor.
Expand All @@ -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
Expand All @@ -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");
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public class BooleanProperty extends Property<Boolean> {
*/
public BooleanProperty(String name, boolean required, String alias) {

super(name, required, alias, null);
super(name, required, alias);
}

@Override
Expand Down Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
@@ -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}.
*/
Expand Down Expand Up @@ -33,7 +33,7 @@ public CommandletProperty(String name, boolean required, String alias) {
*/
public CommandletProperty(String name, boolean required, String alias, Consumer<Commandlet> validator) {

super(name, required, alias, validator);
super(name, required, alias, false, validator);
}

@Override
Expand All @@ -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();
Expand Down
Loading

0 comments on commit 2554339

Please sign in to comment.