Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
06c3f00
updated get method to correctly display an error
Apr 25, 2025
dfa9856
init shell in base
Nic-KL Oct 9, 2025
5a7495d
connected Shellcommand and ACommand
Nic-KL Oct 13, 2025
31a3032
moved classes to base
Nic-KL Oct 13, 2025
c28cb0b
fix: deleting not necessary result return
Nic-KL Oct 14, 2025
583ae37
feat: added error handling
Nic-KL Oct 14, 2025
5642f76
fix: use message instead of info
Nic-KL Oct 14, 2025
e776cd5
feat: advanced key handling for raw terminal
Nic-KL Oct 23, 2025
f90305f
refactor: extracted methods from readShellCommand
Nic-KL Oct 23, 2025
f0a6c6a
style: separated messages
Nic-KL Oct 24, 2025
3904f26
style: removed empty lines
Nic-KL Oct 24, 2025
0626eae
feat: possibility to alter options
Nic-KL Oct 24, 2025
86249bf
feat: proper implemented a method to get shell options
Nic-KL Oct 24, 2025
e8d488a
reafactor: improved readability, feat: added auto tab completion
Nic-KL Oct 24, 2025
edc3d09
fix: serval auto tabulator and cursor fixes
Nic-KL Oct 30, 2025
a8aa8dd
feat: ability to manipulate option lists and run normal commands in t…
Nic-KL Oct 30, 2025
f5c8633
feat: added shell colors for three log error levels
Nic-KL Oct 30, 2025
759f5ab
fix: added the three new error colors to the configuration
Nic-KL Oct 30, 2025
f96d1eb
feat: small help info improvements
Nic-KL Oct 30, 2025
ca59a9f
fix: align descriptions of shellcommands
Nic-KL Oct 31, 2025
642ef58
fix: replaced iterator of command history with normal index
Nic-KL Nov 1, 2025
a38ca19
fix: historyIndex
Nic-KL Nov 2, 2025
a3e32e6
refactor: changed index name
Nic-KL Nov 2, 2025
5d798fb
fix: final fix for iterator replacement
Nic-KL Nov 2, 2025
f50745f
docs: added descriptions for all shell classes
Nic-KL Nov 7, 2025
84de8c7
refactor-docs: splitted methods for better redability, added descript…
Nic-KL Nov 7, 2025
97c9e6f
docs: added descriptions for shell related class
Nic-KL Nov 7, 2025
83c8eea
refactor-feat-docs: switched from optional to result, added helper me…
Nic-KL Nov 11, 2025
c4ea0d9
docs: fixed typos
Nic-KL Nov 11, 2025
b0197e8
refactor: clearer naming of some methods
Nic-KL Nov 17, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/main/java/de/featjar/base/FeatJAR.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
import de.featjar.base.io.IO;
import de.featjar.base.log.BufferedLog;
import de.featjar.base.log.CallerFormatter;
import de.featjar.base.log.ColorFormatter;
import de.featjar.base.log.ConfigurableLog;
import de.featjar.base.log.EmptyProgressBar;
import de.featjar.base.log.IProgressBar;
Expand Down Expand Up @@ -204,6 +205,20 @@ public static Configuration testConfiguration() {
return configuration;
}

/**
* {@return a new FeatJAR configuration with values intended for shell settings}
*/
public static Configuration shellConfiguration() {
final Configuration configuration = new Configuration();
configuration
.logConfig
.logToSystemOut(Log.Verbosity.MESSAGE, Log.Verbosity.INFO, Log.Verbosity.PROGRESS)
.logToSystemErr(Log.Verbosity.ERROR, Log.Verbosity.WARNING)
.addFormatter(new ColorFormatter());
configuration.cacheConfig.setCachePolicy(Cache.CachePolicy.CACHE_NONE);
return configuration;
}

/**
* {@return the current FeatJAR instance}
*
Expand Down
24 changes: 24 additions & 0 deletions src/main/java/de/featjar/base/cli/ACommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@
*/
package de.featjar.base.cli;

import de.featjar.base.data.Result;
import de.featjar.base.shell.ShellSession;
import java.nio.file.Path;
import java.util.List;

Expand Down Expand Up @@ -49,4 +51,26 @@ public abstract class ACommand implements ICommand {
public final List<Option<?>> getOptions() {
return Option.getAllOptions(getClass());
}

/**
* {@return an option list with all parsed arguments and properties including a path variable from the session}
*/
public OptionList getShellOptions(ShellSession session, List<String> cmdParams) {
OptionList optionList = new OptionList();

if (cmdParams.isEmpty()) {
throw new IllegalArgumentException("No path object specified");
}

Result<Path> path = session.get(cmdParams.get(0), Path.class);

if (path.isEmpty()) {
throw new IllegalArgumentException(String.format("'%s' is not a session object", cmdParams.get(0)));
}

optionList.parseArguments();
optionList.parseProperties(INPUT_OPTION, String.valueOf(path.get()));

return optionList;
}
}
4 changes: 4 additions & 0 deletions src/main/java/de/featjar/base/cli/Commands.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,10 @@ public class Commands extends AExtensionPoint<ICommand> {
*/
public static final Pattern STANDARD_INPUT_PATTERN = Pattern.compile(STANDARD_INPUT + "(\\.(.+))?");

public static Commands getInstance() {
return FeatJAR.extensionPoint(Commands.class);
}

/**
* Runs a given function in a new thread, aborting it when it is not done after a timeout expires.
* If the entire process should be stopped afterwards, {@link System#exit(int)} must be called explicitly.
Expand Down
16 changes: 16 additions & 0 deletions src/main/java/de/featjar/base/cli/ICommand.java
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
package de.featjar.base.cli;

import de.featjar.base.extension.IExtension;
import de.featjar.base.shell.ShellSession;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
Expand Down Expand Up @@ -62,4 +63,19 @@ default Optional<String> getShortName() {
* @return exit code
*/
int run(OptionList optionParser);

/**
* Parses arguments into an option list.
*
* @param session the shell session
* @param cmdParams the given arguments for the command
* @return an option list containing parsed arguments
*/
default OptionList getShellOptions(ShellSession session, List<String> cmdParams) {
OptionList optionList = new OptionList();

optionList.parseArguments();

return optionList;
}
}
10 changes: 10 additions & 0 deletions src/main/java/de/featjar/base/cli/OptionList.java
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,16 @@ private void parseConfigurationFiles(List<Problem> problemList) {
}
}
}
/**
* Adds a option with custom value to properties.
*
* @param option the option
* @param optionValue the command
*/
public void parseProperties(Option<?> option, String optionValue) {
Result<?> parse = option.parse(optionValue);
properties.put(option.getName(), parse.get());
}

private void parseRemainingArguments(List<Problem> problemList) {
ListIterator<String> listIterator = arguments.listIterator();
Expand Down
17 changes: 15 additions & 2 deletions src/main/java/de/featjar/base/env/Process.java
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

import de.featjar.base.FeatJAR;
import de.featjar.base.data.Problem;
import de.featjar.base.data.Problem.Severity;
import de.featjar.base.data.Result;
import de.featjar.base.data.Void;
import java.io.BufferedReader;
Expand All @@ -39,6 +40,7 @@
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;
import java.util.function.Supplier;
import java.util.stream.Collectors;

/**
* Executes an external executable in a process.
Expand Down Expand Up @@ -134,8 +136,19 @@ public java.lang.Process start() throws IOException {
@Override
public Result<List<String>> get() {
List<String> output = new ArrayList<>();
Result<Void> result = run(output::add, output::add);
return result.map(r -> output);
List<String> error = new ArrayList<>();
Result<Void> result = run(output::add, error::add);

if (result.isPresent()) {
output.addAll(error);
return result.map(r -> output);
} else {
if (error.isEmpty()) {
return result.map(r -> null);
} else {
return Result.empty(new Problem(error.stream().collect(Collectors.joining("\n")), Severity.ERROR));
}
}
}

/**
Expand Down
60 changes: 60 additions & 0 deletions src/main/java/de/featjar/base/log/ColorFormatter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
/*
* Copyright (C) 2025 FeatJAR-Development-Team
*
* This file is part of FeatJAR-base.
*
* base is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License,
* or (at your option) any later version.
*
* base is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with base. If not, see <https://www.gnu.org/licenses/>.
*
* See <https://github.com/FeatureIDE/FeatJAR-base> for further information.
*/
package de.featjar.base.log;

import de.featjar.base.log.Log.Verbosity;

/**
* Prepends different colors to logs and appends a reset of the colors as suffix.
*
* @author Niclas Kleinert
*/
public class ColorFormatter implements IFormatter {

private static final String TERMINAL_COLOR_LIGHT_BLUE = "\033[38;2;173;236;255m";
private static final String TERMINAL_COLOR_YELLOW = "\033[38;2;255;255;0m";
private static final String TERMINAL_COLOR_RED = "\033[38;2;255;0;0m";
private static final String TERMINAL_COLOR_RESET = "\033[0m";

@Override
public String getPrefix(String message, Verbosity verbosity) {
switch (verbosity) {
case INFO:
return TERMINAL_COLOR_LIGHT_BLUE;
case WARNING:
return TERMINAL_COLOR_YELLOW;
case ERROR:
return TERMINAL_COLOR_RED;
case MESSAGE:
case PROGRESS:
case DEBUG:
break;
default:
throw new IllegalStateException(String.valueOf(verbosity));
}
return "";
}

@Override
public String getSuffix(String message, Verbosity verbosity) {
return TERMINAL_COLOR_RESET;
}
}
12 changes: 12 additions & 0 deletions src/main/java/de/featjar/base/log/Log.java
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,18 @@ default void plainMessage(Object messageObject) {
plainMessage(() -> String.valueOf(messageObject));
}

default void noLineBreakMessage(Supplier<String> message) {
print(message, Verbosity.MESSAGE, false);
}

default void noLineBreakMessage(String formatMessage, Object... elements) {
noLineBreakMessage(() -> String.format(formatMessage, elements));
}

default void noLineBreakMessage(Object messageObject) {
noLineBreakMessage(() -> String.valueOf(messageObject));
}

/**
* Logs a debug message.
*
Expand Down
59 changes: 59 additions & 0 deletions src/main/java/de/featjar/base/shell/ClearShellCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright (C) 2025 FeatJAR-Development-Team
*
* This file is part of FeatJAR-base.
*
* base is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License,
* or (at your option) any later version.
*
* base is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with base. If not, see <https://www.gnu.org/licenses/>.
*
* See <https://github.com/FeatureIDE/FeatJAR-base> for further information.
*/
package de.featjar.base.shell;

import de.featjar.base.FeatJAR;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

/**
* Deletes all variables from the entire shell session.
*
* @author Niclas Kleinert
*/
public class ClearShellCommand implements IShellCommand {

@Override
public void execute(ShellSession session, List<String> cmdParams) {
String choice = Shell.readCommand("Clearing the entire session. Proceed ? (y)es (n)o")
.orElse("")
.toLowerCase()
.trim();

if (Objects.equals("y", choice)) {
session.clear();
FeatJAR.log().message("Clearing successful");
} else if (Objects.equals("n", choice)) {
FeatJAR.log().message("Clearing aborted");
}
}

@Override
public Optional<String> getShortName() {
return Optional.of("clear");
}

@Override
public Optional<String> getDescription() {
return Optional.of("- delete the entire session");
}
}
64 changes: 64 additions & 0 deletions src/main/java/de/featjar/base/shell/DeleteShellCommand.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
/*
* Copyright (C) 2025 FeatJAR-Development-Team
*
* This file is part of FeatJAR-base.
*
* base is free software: you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3.0 of the License,
* or (at your option) any later version.
*
* base is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with base. If not, see <https://www.gnu.org/licenses/>.
*
* See <https://github.com/FeatureIDE/FeatJAR-base> for further information.
*/
package de.featjar.base.shell;

import de.featjar.base.FeatJAR;
import de.featjar.base.log.Log.Verbosity;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

/**
* Deletes a given list of variables from the shell session.
*
* @author Niclas Kleinert
*/
public class DeleteShellCommand implements IShellCommand {

@Override
public void execute(ShellSession session, List<String> cmdParams) {

if (cmdParams.isEmpty()) {
session.printAll();
cmdParams = Shell.readCommand("Enter the variable names you want to delete or leave blank to abort:")
.map(c -> Arrays.stream(c.split("\\s+")).collect(Collectors.toList()))
.orElse(Collections.emptyList());
}

cmdParams.forEach(e -> {
session.remove(e)
.ifPresent(a -> FeatJAR.log().message("Removing of " + e + " successful"))
.orElseLog(Verbosity.ERROR);
});
}

@Override
public Optional<String> getShortName() {
return Optional.of("delete");
}

@Override
public Optional<String> getDescription() {
return Optional.of("- <var>... - delete session variables");
}
}
Loading