improve exceptions

This commit is contained in:
2026-01-07 22:00:32 +01:00
parent 921229aa5b
commit 2a9f086c9d
43 changed files with 137 additions and 92 deletions

View File

@@ -7,11 +7,9 @@ import com.infendro.cli.command.context.ContextParser
import com.infendro.cli.command.help.DefaultHelpRenderer
import com.infendro.cli.command.help.HelpRenderer
import com.infendro.cli.command.option.Option
import com.infendro.cli.exception.build.*
import com.infendro.cli.error.build.*
import com.infendro.cli.parser.*
import com.infendro.cli.util.Regex
import com.infendro.cli.util.Regex.ARGUMENT
import com.infendro.cli.util.Regex.OPTION
import kotlin.reflect.KProperty
sealed class Command private constructor(
@@ -205,15 +203,11 @@ sealed class Command private constructor(
argument.required && last.optional -> throw InvalidArgumentOrder()
}
}
if (!argument.name.matches(ARGUMENT)) throw InvalidArgument(argument.name)
}
private fun validateOption(option: Option<*>) {
for (name in option.names) {
when {
!name.matches(OPTION) -> throw InvalidOption(name)
options.any { name in it.names } -> throw DuplicateOption(name)
}
if (options.any { name in it.names }) throw DuplicateOption(name)
}
}
@@ -222,7 +216,7 @@ sealed class Command private constructor(
}
private fun validateRenderer() {
if (_renderer != null) throw Exception() //TODO
if (_renderer != null) throw DuplicateRenderer()
}
private fun validate() {

View File

@@ -1,7 +1,9 @@
package com.infendro.cli.command.argument
import com.infendro.cli.exception.build.InvalidRange
import com.infendro.cli.error.build.InvalidArgument
import com.infendro.cli.error.build.InvalidRange
import com.infendro.cli.parser.Parser
import com.infendro.cli.util.Regex.ARGUMENT
sealed class Argument<T : Any>(
val parser: Parser<T>,
@@ -10,7 +12,10 @@ sealed class Argument<T : Any>(
val max: Int?,
) {
init {
if (min !in 0..count || max == 0) throw InvalidRange()
when {
!name.matches(ARGUMENT) -> throw InvalidArgument(name)
min !in 0..count || max == 0 -> throw InvalidRange()
}
}
val required: Boolean

View File

@@ -1,7 +1,7 @@
package com.infendro.cli.command.context
import com.infendro.cli.command.Command
import com.infendro.cli.exception.run.*
import com.infendro.cli.error.run.*
import com.infendro.cli.parser.Parser
internal class ContextParser(
@@ -19,13 +19,13 @@ internal class ContextParser(
data class Failure(
val command: Command,
val error: RuntimeError,
val error: RunError,
) : Result()
}
private fun success(context: Context) = Result.Success(context)
private fun help(command: Command) = Result.Help(command)
private fun failure(command: Command, exception: RuntimeError) = Result.Failure(command, exception)
private fun failure(command: Command, exception: RunError) = Result.Failure(command, exception)
private var index = 0
private val current: String

View File

@@ -75,7 +75,11 @@ object DefaultHelpRenderer : HelpRenderer {
private fun StringBuilder.commands(commands: List<Command>) {
appendLine("Commands:")
for (command in commands) {
appendLine(" * ${command.name}")
val name = when {
command is Command.Fallback<*> -> "<${command.name}>"
else -> command.name
}
appendLine(" * $name")
}
}

View File

@@ -1,8 +1,10 @@
package com.infendro.cli.command.option
import com.infendro.cli.exception.build.InvalidRange
import com.infendro.cli.exception.build.MissingOptionName
import com.infendro.cli.error.build.InvalidOption
import com.infendro.cli.error.build.InvalidRange
import com.infendro.cli.error.build.MissingOptionName
import com.infendro.cli.parser.Parser
import com.infendro.cli.util.Regex.OPTION
sealed class Option<T : Any>(
val parser: Parser<T>,
@@ -33,6 +35,7 @@ sealed class Option<T : Any>(
init {
when {
names.isEmpty() -> throw MissingOptionName()
names.any { !it.matches(OPTION) } -> throw InvalidOption(name)
min !in 0..count || max == 0 -> throw InvalidRange()
}
}

View File

@@ -8,7 +8,7 @@ object OptionFactory {
fun long(vararg names: String) = option(LongParser, *names)
fun float(vararg names: String) = option(FloatParser, *names)
fun double(vararg names: String) = option(DoubleParser, *names)
fun boolean(vararg names: String) = option(BooleanParser, true, *names)
fun boolean(vararg names: String) = option(BooleanParser, fallback = true, *names)
inline fun <reified T : Enum<T>> enum(vararg names: String) = option(enumParser<T>(), *names)
}