Refactor commands and enhance UI with mordant widgets

Updated various commands to use mordant widgets for improved output formatting, including tables and panels. Replaced `error` calls with `UsageError` for better exception handling consistency. Added a basic test for replay argument parsing and included project-specific settings for GitToolBox.
This commit is contained in:
2025-03-07 00:02:42 +01:00
parent 7803e05431
commit fb639312f4
6 changed files with 65 additions and 24 deletions

15
.idea/git_toolbox_prj.xml generated Normal file
View File

@ -0,0 +1,15 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="GitToolBoxProjectSettings">
<option name="commitMessageIssueKeyValidationOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
<option name="commitMessageValidationEnabledOverride">
<BoolValueOverride>
<option name="enabled" value="true" />
</BoolValueOverride>
</option>
</component>
</project>

View File

@ -14,7 +14,7 @@ object ReplayUtils : CliktCommand() {
override val printHelpOnEmptyArgs = true override val printHelpOnEmptyArgs = true
private val config by findOrSetObject { RunConfig() } private val config by findOrSetObject { RunConfig() }
private val replay by argument(help = "Replay ID or Path").optional() val replay by argument(help = "Replay ID or Path").optional()
private val path by option("-p", "--path", help = "Replay is a Path").flag() private val path by option("-p", "--path", help = "Replay is a Path").flag()
override fun run() { override fun run() {

View File

@ -1,7 +1,6 @@
package de.chaoscaot.replay.commands package de.chaoscaot.replay.commands
import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.*
import com.github.ajalt.clikt.core.requireObject
import de.chaoscaot.replay.RunConfig import de.chaoscaot.replay.RunConfig
import de.chaoscaot.replay.parser.BlueEmbeddedSchemPacket import de.chaoscaot.replay.parser.BlueEmbeddedSchemPacket
import de.chaoscaot.replay.parser.RedEmbeddedSchemPacket import de.chaoscaot.replay.parser.RedEmbeddedSchemPacket
@ -17,7 +16,7 @@ object ExtractSchematics: CliktCommand() {
override fun run() { override fun run() {
if (config.replay == null) { if (config.replay == null) {
error("No Replay specified") throw UsageError("No Replay specified")
} }
val nbt by lazy { Nbt() } val nbt by lazy { Nbt() }

View File

@ -1,11 +1,17 @@
package de.chaoscaot.replay.commands package de.chaoscaot.replay.commands
import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.clikt.core.UsageError
import com.github.ajalt.clikt.core.requireObject import com.github.ajalt.clikt.core.requireObject
import com.github.ajalt.clikt.parameters.options.flag import com.github.ajalt.clikt.parameters.options.flag
import com.github.ajalt.clikt.parameters.options.multiple import com.github.ajalt.clikt.parameters.options.multiple
import com.github.ajalt.clikt.parameters.options.option import com.github.ajalt.clikt.parameters.options.option
import com.github.ajalt.mordant.rendering.BorderType
import com.github.ajalt.mordant.table.Borders
import com.github.ajalt.mordant.table.table import com.github.ajalt.mordant.table.table
import com.github.ajalt.mordant.widgets.Panel
import com.github.ajalt.mordant.widgets.Text
import com.github.ajalt.mordant.widgets.UnorderedList
import de.chaoscaot.replay.RunConfig import de.chaoscaot.replay.RunConfig
import de.chaoscaot.replay.parser.ReplayParser import de.chaoscaot.replay.parser.ReplayParser
import de.chaoscaot.replay.parser.UserJoinPacket import de.chaoscaot.replay.parser.UserJoinPacket
@ -18,36 +24,42 @@ object Info : CliktCommand() {
override fun run() { override fun run() {
if (config.replay == null) { if (config.replay == null) {
error("No Replay specified") throw UsageError("No Replay specified")
} }
val packets = ReplayParser.read(config.replay!!).toList() val packets = ReplayParser.read(config.replay!!).toList()
if (players) { if (players) {
echo("Players:") echo(Panel(
packets.filterIsInstance<UserJoinPacket>().map { it.userId }.forEach { echo("\t$it") } UnorderedList(packets.filterIsInstance<UserJoinPacket>().map { Text(it.userId.toString()) }),
echo() Text("Players")
))
} }
if (toCount.isNotEmpty()) { if (toCount.isNotEmpty()) {
echo(table { echo(Panel(
header { table {
row("PacketType", "Count") borderType = BorderType.SQUARE_DOUBLE_SECTION_SEPARATOR
} tableBorders = Borders.NONE
header {
row("PacketType", "Count")
}
body { body {
toCount.forEach { name -> toCount.forEach { name ->
val klass = packets.firstOrNull { it.javaClass.simpleName.lowercase() == "${name}packet".lowercase() }?.javaClass val klass = packets.firstOrNull { it.javaClass.simpleName.lowercase() == "${name}packet".lowercase() }?.javaClass
if (klass == null) { if (klass == null) {
row(name, 0) row(name, 0)
} else { } else {
row(klass.simpleName, packets.count { it.javaClass == klass }) row(klass.simpleName, packets.count { it.javaClass == klass })
}
} }
} }
}
}) },
Text("Packets")
))
} }
} }
} }

View File

@ -1,11 +1,16 @@
package de.chaoscaot.replay.commands package de.chaoscaot.replay.commands
import com.github.ajalt.clikt.core.CliktCommand import com.github.ajalt.clikt.core.CliktCommand
import com.github.ajalt.mordant.table.table
import de.chaoscaot.replay.parser.PacketType import de.chaoscaot.replay.parser.PacketType
object ListPackets : CliktCommand() { object ListPackets : CliktCommand(name = "packets") {
override fun run() { override fun run() {
echo("Packets:") echo(table {
PacketType.entries.forEach { echo("\t${it.name.lowercase().replace("_packet", "").replace("_", "").padEnd(25, ' ')}: 0x${it.id.toString(16).padStart(2, '0')}") } header { row("Packet", "ID") }
body {
PacketType.entries.forEach { row(it.name.lowercase().replace("_packet", "").replace("_", ""), "0x${it.id.toString(16).padStart(2, '0')}") }
}
})
} }
} }

View File

@ -0,0 +1,10 @@
import com.github.ajalt.clikt.testing.test
import de.chaoscaot.replay.ReplayUtils
import kotlin.test.Test
object Tests {
@Test
fun `Test Parsing Replay Id`() {
val result = ReplayUtils.test("123")
}
}