improve parsing and flag Options

This commit is contained in:
2025-12-31 22:45:43 +01:00
parent 06a2d1bdce
commit 0dc064b8cf
15 changed files with 171 additions and 131 deletions

View File

@@ -1,5 +1,7 @@
package com.infendro.cli.command
import com.infendro.cli.command.context.Context
import com.infendro.cli.command.context.Parser
import com.infendro.cli.exception.build.*
import com.infendro.cli.exception.run.CliException
import com.infendro.cli.util.Regex.COMMAND
@@ -22,7 +24,7 @@ class Command private constructor(
}
class Builder internal constructor(
private val index: Int,
private val level: Int,
private val name: String?,
) {
private val commands = mutableListOf<Command>()
@@ -30,22 +32,19 @@ class Command private constructor(
private val options = mutableListOf<Option<*>>()
private lateinit var _execute: Context.() -> Unit
private val nextIndex: Int
get() = index + 1
private val key: Key
get() = Key(level)
fun command(name: String? = null, block: Builder.(Key) -> Unit) {
// validate
val last = commands.lastOrNull()
when {
last?.fallback == true -> throw CommandOrderException()
name?.matches(COMMAND) == false -> throw IllegalCommandNameException(name)
last != null && last.fallback -> throw CommandOrderException()
name != null && !name.matches(COMMAND) -> throw IllegalCommandNameException(name)
commands.any { it.name == name } -> throw DuplicateCommandException(name)
}
commands += Builder(nextIndex, name).also {
val key = Key(nextIndex)
it.block(key)
}.build()
commands += Builder(level + 1, name).also { it.block(it.key) }.build()
}
fun argument(argument: Argument<*>) {
@@ -53,7 +52,7 @@ class Command private constructor(
val last = arguments.lastOrNull()
when {
last is Argument.Variable -> throw ArgumentOrderException()
argument.required && last?.required == false -> throw ArgumentOrderException()
argument.required && last != null && !last.required -> throw ArgumentOrderException()
}
arguments += argument
@@ -92,7 +91,7 @@ class Command private constructor(
// validate
val last = commands.lastOrNull()
when {
last?.fallback == true && arguments.isNotEmpty() -> throw InvalidFallbackException()
last != null && last.fallback && arguments.isNotEmpty() -> throw InvalidFallbackException()
}
if (!::_execute.isInitialized)
@@ -107,8 +106,5 @@ class Command private constructor(
)
}
fun cli(block: Command.Builder.() -> Unit): Command {
val builder = Command.Builder(-1, null)
builder.block()
return builder.build()
}
fun cli(block: Command.Builder.() -> Unit) =
Command.Builder(-1, null).also(block).build()