package net.keinekekse.args.annotation /** * Annotation to define metadata for a command-line argument. * * This annotation can be applied to properties to specify their representation * as command-line arguments. It provides options for defining the argument's * name, shortened single-character alias, description, and whether it is mandatory. * * The property must be declared as mutable and nullable. * * @property name The full name of the command-line argument. Defaults to the name of the property. * @property shortName The single-character alias for the argument. Defaults to [Char.MIN_VALUE], * indicating no short name is defined. * @property description A brief description of the argument's purpose. Defaults to an empty string. * @property isMandatory Specifies if the argument is mandatory. Defaults to `false`. */ @Target(AnnotationTarget.PROPERTY) annotation class CmdLineArgument( val name: String = "", val shortName: Char = Char.MIN_VALUE, val description: String = "", val isMandatory: Boolean = false, ) /** * Annotation to define a subcommand for a command-line interface. * * This annotation can be applied to objects to designate them as subcommands * for a command-line tool. It specifies the subcommand's name, a brief description, * and optional aliases that can be used to invoke the subcommand. * * @property name The primary identifier for the subcommand. Defaults to the simple name of the class. * @property description A short description of the subcommand's purpose. Defaults to an empty string. * @property aliases Alternative names that can be used to invoke the subcommand. Defaults to an * empty array. */ @Target(AnnotationTarget.CLASS) annotation class CmdLineSubCommand( val name: String = "", val description: String = "", val aliases: Array = [], ) /** * Represents a set of parameters associated globally with the program. * This class adds additional properties and customization options to manage * the behavior of the command line interpretation, such as allowing additional parameters, * handling case sensitivity, and keeping track of command execution status. * * The parameters have to be annotated with the [CmdLineArgument] annotation. * Subcommands can be defined using the [CmdLineSubCommand] annotation on objects, * derived from the [SubCommand] class. * * @property programDescription A description of the program's purpose or functionality. * @property additionalParametersAllowed Indicates whether the program allows additional, * unspecified parameters during execution. * @property ignoreCase Determines if parameter matching should be case-insensitive. */ abstract class Parameters( val programDescription: String = "", val additionalParametersAllowed: Boolean = true, val ignoreCase: Boolean = false, var didRun: Boolean = false, ) : SubCommand() /** * Represents an abstract subcommand that can be executed with specific behavior and validation logic. * * Subclasses of this class are expected to provide implementation for validating their parameters * and defining the execution logic of the subcommand. Each subcommand can also handle additional * parameters. * * @property additionalParameters A list of additional command line parameters associated with this * subcommand. */ abstract class SubCommand { var additionalParameters: List = emptyList() abstract fun verifyParameters(): Boolean abstract fun run(globals: Parameters) } /** * Executes the program logic using the specified command-line arguments. * This method internally invokes the `run` method of the `Parameters` class * to parse, validate, and execute the input arguments. * * @param args A list of command-line arguments to be processed by the program. */ fun Parameters.runProgramWith(args: List) { run(args) } /** * Exception thrown to indicate that there is an error related to verifying * the validity of command-line parameters provided to the application. * * This exception is thrown by the [SubCommand.verifyParameters] method to indicate * that the parameters provided to the subcommand are invalid. * * The exception is caught by the [Parameters.runProgramWith] method and the program * execution will be terminated with an error message and the usage information. * * @constructor * Constructs a new [VerifyParameterException] with the specified detail message. * * @param message The detail message describing the parameter verification error. */ class VerifyParameterException(message: String) : RuntimeException(message)