Activators
Activators control whether options or entire commands are available. Deactivated options are hidden from tab completion and help, and deactivated commands are invisible to the user.
--aesh-complete callbacks, and static shell completion scripts (static scripts honor activators since 3.18). For options that should still parse when typed but never be suggested, use OptionVisibility.HIDDEN instead of an activator.OptionActivator
Enable or disable an option based on conditions. The ParsedCommand gives you access to the current command and the values of other options that have been parsed so far:
public interface OptionActivator {
boolean isActivated(ParsedCommand parsedCommand);
}Example: Conditional Options
SSL-related options should only appear when --secure is used:
import org.aesh.command.activator.OptionActivator;
import org.aesh.command.impl.internal.ParsedCommand;
public class SslOptionActivator implements OptionActivator {
@Override
public boolean isActivated(ParsedCommand parsedCommand) {
// SSL options only active if --secure has been specified
return parsedCommand.findLongOptionNoActivatorCheck("secure")
.getValue() != null;
}
}Usage:
@CommandDefinition(name = "server", description = "Start the server")
public class ServerCommand implements Command<CommandInvocation> {
@Option(name = "secure", hasValue = false, description = "Enable secure mode")
private boolean secureMode = false;
@Option(
name = "cert",
activator = SslOptionActivator.class,
description = "SSL certificate (only in secure mode)"
)
private String certPath;
@Option(
name = "key",
activator = SslOptionActivator.class,
description = "SSL private key (only in secure mode)"
)
private String keyPath;
@Override
public CommandResult execute(CommandInvocation invocation) {
if (secureMode) {
invocation.println("Starting HTTPS with cert=" + certPath);
} else {
invocation.println("Starting HTTP server");
}
return CommandResult.SUCCESS;
}
}When --secure is not set, --cert and --key are hidden from tab completion and --help output.
CommandActivator
Control whether an entire command is visible and available:
public interface CommandActivator {
boolean isActivated(ParsedCommand command);
}Example: Admin-Only Commands
import org.aesh.command.activator.CommandActivator;
import org.aesh.command.impl.internal.ParsedCommand;
public class AdminCommandActivator implements CommandActivator {
@Override
public boolean isActivated(ParsedCommand command) {
return "admin".equals(System.getProperty("user.role", "user"));
}
}@CommandDefinition(
name = "shutdown",
description = "Shutdown the server",
activator = AdminCommandActivator.class
)
public class ShutdownCommand implements Command<CommandInvocation> {
@Override
public CommandResult execute(CommandInvocation invocation) {
invocation.println("Shutting down...");
return CommandResult.SUCCESS;
}
}The shutdown command only appears in tab completion and help when user.role is admin. Users without admin role cannot discover or execute it.
Platform-Conditional Commands
A common use case is a cross-platform CLI where some commands only exist on one platform (e.g. a vm appliance command that is macOS-only because the managed runtime runs natively on Linux). Gate it with a CommandActivator behind a single command tree instead of maintaining one top-level command per platform:
import org.aesh.command.activator.CommandActivator;
import org.aesh.command.impl.internal.ParsedCommand;
public class MacOnly implements CommandActivator {
@Override
public boolean isActivated(ParsedCommand command) {
return Platform.isMacOS();
}
}@CommandDefinition(
name = "vm",
description = "Manage the VM appliance (macOS only)",
activator = MacOnly.class,
groupCommands = { VmStartCommand.class, VmStopCommand.class }
)
public class VmCommand implements Command<CommandInvocation> { }On Linux, isx vm is rejected at execution time and never appears in --help, tab completion, or generated shell completion scripts — no post-filtering of the scripts required.
CompletionFilter to keep generated completions in step.Conditional Required Options
Combine activators with required = true to make options conditionally required:
public class OutputFileActivator implements OptionActivator {
@Override
public boolean isActivated(ParsedCommand parsedCommand) {
// Output file only required when not in verbose mode
return parsedCommand.findLongOptionNoActivatorCheck("verbose")
.getValue() == null;
}
}
@CommandDefinition(name = "process", description = "Process data")
public class ProcessCommand implements Command<CommandInvocation> {
@Option(name = "verbose", hasValue = false, description = "Verbose output to console")
private boolean verbose = false;
@Option(
name = "output",
activator = OutputFileActivator.class,
required = true,
description = "Output file (required unless --verbose)"
)
private String outputFile;
@Override
public CommandResult execute(CommandInvocation invocation) {
if (verbose) {
invocation.println("Processing... (verbose output)");
} else {
invocation.println("Writing output to " + outputFile);
}
return CommandResult.SUCCESS;
}
}When --verbose is used, --output is deactivated and not required. Without --verbose, --output is required.