From a5890a7812271bc6efa095b7597d816878f6e7e7 Mon Sep 17 00:00:00 2001 From: chun-awa <110163919+chun-awa@users.noreply.github.com> Date: Wed, 21 Aug 2024 13:54:03 +0800 Subject: [PATCH] feat: Refactor, Change build info, Command Completion, pwd, whoami, chdir --- README.md | 4 +- build.gradle.kts | 27 +++-- src/main/kotlin/io/github/lmfs/box/LMFSBox.kt | 99 +++++++++++++++---- .../io/github/lmfs/box/command/CdCommand.kt | 22 +++++ .../io/github/lmfs/box/command/Commands.kt | 40 ++++++++ .../lmfs/box/command/CopyrightCommand.kt | 12 +++ .../io/github/lmfs/box/command/EchoCommand.kt | 15 +++ .../io/github/lmfs/box/command/ExitCommand.kt | 17 ++++ .../io/github/lmfs/box/command/HelpCommand.kt | 22 +++++ .../github/lmfs/box/command/LicenseCommand.kt | 12 +++ .../io/github/lmfs/box/command/LsCommand.kt | 95 ++++++++++++++++++ .../io/github/lmfs/box/command/PwdCommand.kt | 12 +++ .../io/github/lmfs/box/command/TimeCommand.kt | 25 +++++ .../github/lmfs/box/command/WhoAmICommand.kt | 11 +++ .../io/github/lmfs/box/util/CommandUtil.kt | 45 +++++++++ .../resources/META-INF/lmfsbox.properties | 2 + 16 files changed, 432 insertions(+), 28 deletions(-) create mode 100644 src/main/kotlin/io/github/lmfs/box/command/CdCommand.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/command/Commands.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/command/CopyrightCommand.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/command/EchoCommand.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/command/ExitCommand.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/command/HelpCommand.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/command/LicenseCommand.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/command/LsCommand.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/command/PwdCommand.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/command/TimeCommand.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/command/WhoAmICommand.kt create mode 100644 src/main/kotlin/io/github/lmfs/box/util/CommandUtil.kt diff --git a/README.md b/README.md index bcea4c2..25768ad 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # LMFSBox -> Better replacement of HOJVBOX +> A simple toolbox ### How to build? ```bash -./gradlew shadowJar +./gradlew build ``` \ No newline at end of file diff --git a/build.gradle.kts b/build.gradle.kts index 2561ceb..3428103 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,8 +1,10 @@ +import com.palantir.gradle.gitversion.VersionDetails import java.util.Date plugins { kotlin("jvm") version "2.0.20-RC2" id("com.github.johnrengelman.shadow") version "8.1.1" + id("com.palantir.git-version") version "3.1.0" application } @@ -15,8 +17,10 @@ repositories { dependencies { testImplementation(kotlin("test")) + implementation(kotlin("reflect")) implementation("org.fusesource.jansi:jansi:2.4.1") implementation("com.github.ajalt.clikt:clikt:4.4.0") + implementation("org.jline:jline:3.26.3") } tasks.test { @@ -27,15 +31,22 @@ kotlin { jvmToolchain(21) } +val versionDetails: groovy.lang.Closure by extra + tasks.withType { - val resourceTargets = listOf("META-INF/lmfsbox.properties", "META-INF/lmfsbox.license.txt", "META-INF/lmfsbox.copyright.txt") - val replaceProperties = mapOf( - Pair("gradle", gradle), - Pair("project", project), - Pair("date", Date()), - Pair("building", "Gradle v${gradle.gradleVersion} (JavaToolchain ${java.toolchain.languageVersion.get()}) on ${System.getProperty("os.arch")}"), - Pair("licenseText", rootProject.file("LICENSE").readText()), - Pair("copyrightText", rootProject.file("COPYRIGHT").readText()) + val resourceTargets = listOf( + "META-INF/lmfsbox.properties", + "META-INF/lmfsbox.license.txt", + "META-INF/lmfsbox.copyright.txt" + ) + val replaceProperties = mapOf( + "gradle" to gradle, + "project" to project, + "date" to Date(), + "building" to "Gradle v${gradle.gradleVersion} (JavaToolchain ${java.toolchain.languageVersion.get()}) ${System.getProperty("os.arch").uppercase()}", + "licenseText" to rootProject.file("LICENSE").readText(), + "copyrightText" to rootProject.file("COPYRIGHT").readText(), + "gitVersion" to versionDetails() ) filesMatching(resourceTargets) { expand(replaceProperties) diff --git a/src/main/kotlin/io/github/lmfs/box/LMFSBox.kt b/src/main/kotlin/io/github/lmfs/box/LMFSBox.kt index 17b6f05..4973231 100644 --- a/src/main/kotlin/io/github/lmfs/box/LMFSBox.kt +++ b/src/main/kotlin/io/github/lmfs/box/LMFSBox.kt @@ -1,40 +1,91 @@ package io.github.lmfs.box import com.github.ajalt.clikt.testing.test -import io.github.lmfs.box.commands.Commands +import com.github.ajalt.mordant.rendering.AnsiLevel +import io.github.lmfs.box.command.Commands +import io.github.lmfs.box.util.makeJLineTreeCompleter import io.github.lmfs.box.util.space import org.fusesource.jansi.Ansi import org.fusesource.jansi.Ansi.ansi +import org.jline.reader.EndOfFileException +import org.jline.reader.LineReaderBuilder +import org.jline.reader.UserInterruptException +import org.jline.terminal.TerminalBuilder import java.util.* + object LMFSBox { - val license = this@LMFSBox::class.java.classLoader.getResourceAsStream("META-INF/lmfsbox.license.txt")?.readAllBytes()?.toString(Charsets.UTF_8) ?: "" - val copyright = this@LMFSBox::class.java.classLoader.getResourceAsStream("META-INF/lmfsbox.copyright.txt")?.readAllBytes()?.toString(Charsets.UTF_8) ?: "" + @JvmStatic + val LICENSE = this.javaClass.classLoader + .getResourceAsStream("META-INF/lmfsbox.license.txt") + ?.readAllBytes() + ?.toString(Charsets.UTF_8) + ?: "" + @JvmStatic + val COPYRIGHT = this.javaClass.classLoader + .getResourceAsStream("META-INF/lmfsbox.copyright.txt") + ?.readAllBytes() + ?.toString(Charsets.UTF_8) + ?: "" - val properties = Properties().apply { - load(this@LMFSBox::class.java.classLoader.getResourceAsStream("META-INF/lmfsbox.properties")) + @JvmStatic + val PROPERTIES = Properties().also { + it.load( + this.javaClass.classLoader.getResourceAsStream("META-INF/lmfsbox.properties") + ) } - val version = properties["lmfsbox.version"] - val build = properties["lmfsbox.build"] - val buildDate = properties["lmfsbox.build.date"] + @JvmStatic + val VERSION = PROPERTIES["lmfsbox.version"] + + @JvmStatic + val BUILD = PROPERTIES["lmfsbox.build"] + + @JvmStatic + val BUILD_DATE = PROPERTIES["lmfsbox.build.date"] + + @JvmStatic + val GIT_HASH = PROPERTIES["lmfsbox.git.hash"] + + @JvmStatic + val GIT_BRANCH = PROPERTIES["lmfsbox.git.branch"] + fun main(args: Array) { - if (args.isNotEmpty()) return runCommand(args.toList()) + if (args.isNotEmpty()) + return runCommand(args.toList()) + println( ansi() .fgBrightBlue().bold().a("LMFSBox").reset().space(1) - .fgBrightMagenta().a("$version").reset().space(1) - .fgYellow().a("($buildDate)").reset().space(1) - .fgBrightYellow().a("[$build]").reset() + .fgBrightMagenta().a("$VERSION").reset().space(1) + .fgYellow().a("(commits/$GIT_BRANCH:$GIT_HASH, $BUILD_DATE)").reset().space(1) + .fgBrightYellow().a("[$BUILD]").reset() + ) + + println( + ansi().a(Ansi.Attribute.ITALIC) + .a("Type \"help\", \"copyright\" or \"license\" for more information.") ) - println(ansi().a(Ansi.Attribute.ITALIC).a("Type \"help\", \"copyright\", \"credits\" or \"license\" for more information.")) + val builder = LineReaderBuilder.builder() + .terminal( + TerminalBuilder.builder() + .system(true) + .jansi(true) + .dumb(true) + .build() + ) + .completer(Commands.makeJLineTreeCompleter()) + .build() while (true) { - print(ansi().fgGreen().a(">>>").space(1).reset()) - val input = readln() try { + val input = builder.readLine(ansi().fgGreen().a(">>>").space(1).reset().toString()) runCommand(input) + } catch (exception: EndOfFileException) { + break + } catch (exception: UserInterruptException) { + break } catch (throwable: Throwable) { throwable.printStackTrace(System.err) } @@ -42,15 +93,27 @@ object LMFSBox { } fun runCommand(input: String) { - val result = Commands.test(input, includeSystemEnvvars = true) + val result = Commands.test( + input, + includeSystemEnvvars = true, + ansiLevel = AnsiLevel.TRUECOLOR, + height = Int.MAX_VALUE, + width = Int.MAX_VALUE + ) print(result.output) } fun runCommand(input: List) { - val result = Commands.test(input, includeSystemEnvvars = true) + val result = Commands.test( + input, + includeSystemEnvvars = true, + ansiLevel = AnsiLevel.TRUECOLOR, + height = Int.MAX_VALUE, + width = Int.MAX_VALUE + ) print(result.output) } } -fun main(args: Array) = LMFSBox.main(args) \ No newline at end of file +fun main(args: Array) = LMFSBox.main(args) diff --git a/src/main/kotlin/io/github/lmfs/box/command/CdCommand.kt b/src/main/kotlin/io/github/lmfs/box/command/CdCommand.kt new file mode 100644 index 0000000..0d770c4 --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/CdCommand.kt @@ -0,0 +1,22 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.ProgramResult +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.types.path +import kotlin.io.path.Path + + +object CdCommand : CliktCommand("Change the working directory", name = "cd") { + + private val to by argument("to").path(mustExist = false, canBeSymlink = true, canBeDir = true, canBeFile = false) + + override fun run() { + val current = Path(System.getProperty("user.dir")) + val changed = current.resolve(to).toFile() + if (!changed.isDirectory) throw ProgramResult(1) + System.setProperty("user.dir", changed.toString()) + throw ProgramResult(0) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/command/Commands.kt b/src/main/kotlin/io/github/lmfs/box/command/Commands.kt new file mode 100644 index 0000000..d4712d4 --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/Commands.kt @@ -0,0 +1,40 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.core.Context +import com.github.ajalt.clikt.core.subcommands +import com.github.ajalt.clikt.output.HelpFormatter + +object Commands : CliktCommand("LMFSBox", name = ">>>", hidden = true, printHelpOnEmptyArgs = false) { + + init { + Commands.subcommands( + HelpCommand, CopyrightCommand, LicenseCommand, LsCommand, ExitCommand, + TimeCommand, WhoAmICommand, PwdCommand, CdCommand, EchoCommand + ) + } + + @JvmStatic + val COMMAND_ALIASES = mutableMapOf>() + + @JvmStatic + fun createRootContext(parent: Context? = null): Context = + CliktCommand::class.java.getDeclaredMethod( + "createContext", + List::class.java, + Context::class.java, + List::class.java + ).apply { + isAccessible = true + }.invoke(this, emptyList(), parent, emptyList()) as Context + + + override fun allHelpParams(): List { + return super.allHelpParams().filterNot { it is HelpFormatter.ParameterHelp.Option && "--help" in it.names } + } + + override fun aliases() = COMMAND_ALIASES + + override fun run() = Unit + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/command/CopyrightCommand.kt b/src/main/kotlin/io/github/lmfs/box/command/CopyrightCommand.kt new file mode 100644 index 0000000..2137fd0 --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/CopyrightCommand.kt @@ -0,0 +1,12 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand +import io.github.lmfs.box.LMFSBox + +object CopyrightCommand : CliktCommand("Show copyright information", name = "copyright") { + + override fun run() { + echo(LMFSBox.COPYRIGHT) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/command/EchoCommand.kt b/src/main/kotlin/io/github/lmfs/box/command/EchoCommand.kt new file mode 100644 index 0000000..9165f7d --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/EchoCommand.kt @@ -0,0 +1,15 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.options.default +import com.github.ajalt.clikt.parameters.options.option + +object EchoCommand : CliktCommand("Write content to the standard output.", name = "echo") { + + private val text by option("--text", "-T").default("") + + override fun run() { + echo(text) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/command/ExitCommand.kt b/src/main/kotlin/io/github/lmfs/box/command/ExitCommand.kt new file mode 100644 index 0000000..2e8f2a4 --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/ExitCommand.kt @@ -0,0 +1,17 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.arguments.default +import com.github.ajalt.clikt.parameters.types.int +import kotlin.system.exitProcess + +object ExitCommand : CliktCommand("Exit the program", name = "exit") { + + private val code by argument("code", help = "Status code").int().default(0) + + override fun run() { + exitProcess(code) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/command/HelpCommand.kt b/src/main/kotlin/io/github/lmfs/box/command/HelpCommand.kt new file mode 100644 index 0000000..269f79d --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/HelpCommand.kt @@ -0,0 +1,22 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.arguments.optional + +object HelpCommand : CliktCommand("Show this help message", name = "help") { + + private val argument by argument("command").optional() + + override fun run() { + if (argument != null) { + val subCommand = Commands.registeredSubcommands() + .firstOrNull { it.commandName == argument } + ?: HelpCommand + subCommand.echoFormattedHelp() + } else { + Commands.echoFormattedHelp() + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/command/LicenseCommand.kt b/src/main/kotlin/io/github/lmfs/box/command/LicenseCommand.kt new file mode 100644 index 0000000..2cceadf --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/LicenseCommand.kt @@ -0,0 +1,12 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand +import io.github.lmfs.box.LMFSBox + +object LicenseCommand : CliktCommand("Show license information", name = "license") { + + override fun run() { + echo(LMFSBox.LICENSE) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/command/LsCommand.kt b/src/main/kotlin/io/github/lmfs/box/command/LsCommand.kt new file mode 100644 index 0000000..d84d838 --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/LsCommand.kt @@ -0,0 +1,95 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.arguments.argument +import com.github.ajalt.clikt.parameters.arguments.defaultLazy +import com.github.ajalt.clikt.parameters.options.default +import com.github.ajalt.clikt.parameters.options.option +import com.github.ajalt.clikt.parameters.types.boolean +import com.github.ajalt.clikt.parameters.types.file +import org.fusesource.jansi.Ansi +import org.fusesource.jansi.Ansi.ansi +import java.io.File +import java.nio.file.Files +import java.text.SimpleDateFormat +import java.util.* + +object LsCommand : + CliktCommand("List information about the files (the current directory by default)", name = "ls") { + + @JvmStatic + var DATE_FORMAT = SimpleDateFormat("yyyy-MM-dd HH:mm:ss") + + private val directory by argument("directory") + .file(canBeFile = false, canBeDir = true, mustExist = true, mustBeReadable = true) + .defaultLazy { File(System.getProperty("user.dir")) } + + private val showDate by option("--date", "-D", help = "Display the last modification date of the file") + .boolean() + .default(true) + + private val showSize by option("--size", "-S", help = "Display the size of the file") + .boolean() + .default(true) + + @JvmStatic + fun processStyle(file: File, isSymbolicLink: Boolean, ansi: Ansi = ansi()) = ansi.also { + if (file.isDirectory) + it.fgBlue().bold() + if (file.isHidden) + it.a(Ansi.Attribute.ITALIC) + if (isSymbolicLink) + it.fgBrightCyan().boldOff() + } + + @JvmStatic + fun formatFileSize(bytes: Long): String { + if (bytes < 1024) return "${bytes}B" + val units = arrayOf("KiB", "MiB", "GiB", "TiB", "PiB", "EiB", "ZiB", "YiB") + var value = bytes.toDouble() + var i = -1 + while (value >= 1024 && i < units.size - 1) { + value /= 1024 + i++ + if (i == units.size - 1) break + } + return String.format("%.2f%s", value, units[i]) + } + + override fun run() { + val files = directory.listFiles()?.toList() ?: emptyList() + + val sizePlaceholder = if (showSize) files.maxOf { formatFileSize(it.length()).length } else 0 + val lastModifiedPlaceholder = + if (showDate) files.maxOf { DATE_FORMAT.format(Date(it.lastModified())).length } else 0 + + for (file in files) { + val style = ansi() + val prefix = buildString { + if (showDate) append( + "${DATE_FORMAT.format(Date(file.lastModified()))}${ + " ".repeat( + lastModifiedPlaceholder + ) + }".subSequence(0..lastModifiedPlaceholder) + ) + if (showSize) append("${formatFileSize(file.length())}${" ".repeat(sizePlaceholder)}".subSequence(0..sizePlaceholder)) + } + style.a(prefix) + val isSymbolicLink = Files.isSymbolicLink(file.toPath()) + processStyle(file, isSymbolicLink, style) + if (isSymbolicLink) { + val target = Files.readSymbolicLink(file.toPath()) + style.fgBrightBlue() + .a(file.name) + .reset() + .a(" -> ") + .reset() + val relativize = runCatching { directory.toPath().relativize(target) }.getOrDefault(target) + style.a(relativize) + } else style.a(file.name) + echo(style.reset()) + } + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/command/PwdCommand.kt b/src/main/kotlin/io/github/lmfs/box/command/PwdCommand.kt new file mode 100644 index 0000000..ffd3020 --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/PwdCommand.kt @@ -0,0 +1,12 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand +import java.io.File + +object PwdCommand : CliktCommand("Print the name of the current working directory", name = "pwd") { + + override fun run() { + echo(File(System.getProperty("user.dir")).absoluteFile.toPath().normalize()) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/command/TimeCommand.kt b/src/main/kotlin/io/github/lmfs/box/command/TimeCommand.kt new file mode 100644 index 0000000..41074bb --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/TimeCommand.kt @@ -0,0 +1,25 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.options.option +import com.github.ajalt.clikt.parameters.types.long +import java.time.Instant +import java.time.LocalDateTime +import java.time.ZoneId +import java.time.format.DateTimeFormatter + +object TimeCommand : CliktCommand("Display the current time in the given format", name = "time") { + + private val format by option("--format", "-F", help = "Set the date format for output") + private val time by option("--time", "-T", help = "Set the time stamp for output").long() + + override fun run() { + val dateFormat = format?.let { DateTimeFormatter.ofPattern(it) } + val date = if (time == null) LocalDateTime.now() else LocalDateTime.ofInstant( + Instant.ofEpochMilli(time!!), + ZoneId.systemDefault() + ) + echo(if (format == null) date else dateFormat!!.format(date)) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/command/WhoAmICommand.kt b/src/main/kotlin/io/github/lmfs/box/command/WhoAmICommand.kt new file mode 100644 index 0000000..96556d5 --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/command/WhoAmICommand.kt @@ -0,0 +1,11 @@ +package io.github.lmfs.box.command + +import com.github.ajalt.clikt.core.CliktCommand + +object WhoAmICommand : CliktCommand("Print the user name", name = "whoami") { + + override fun run() { + echo(System.getProperty("user.name")) + } + +} \ No newline at end of file diff --git a/src/main/kotlin/io/github/lmfs/box/util/CommandUtil.kt b/src/main/kotlin/io/github/lmfs/box/util/CommandUtil.kt new file mode 100644 index 0000000..04f5080 --- /dev/null +++ b/src/main/kotlin/io/github/lmfs/box/util/CommandUtil.kt @@ -0,0 +1,45 @@ +package io.github.lmfs.box.util + +import com.github.ajalt.clikt.completion.CompletionCandidates +import com.github.ajalt.clikt.core.CliktCommand +import com.github.ajalt.clikt.parameters.arguments.Argument +import com.github.ajalt.clikt.parameters.options.Option +import io.github.lmfs.box.command.Commands +import org.jline.builtins.Completers +import org.jline.reader.Completer +import org.jline.reader.impl.completer.AggregateCompleter +import org.jline.reader.impl.completer.ArgumentCompleter +import org.jline.reader.impl.completer.NullCompleter +import org.jline.reader.impl.completer.StringsCompleter + +fun CliktCommand.makeJLineTreeCompleter(): Completer = + AggregateCompleter(registeredSubcommands().map { it.makeJLineTreeCompleter(emptyList()) }) + +fun CliktCommand.makeJLineTreeCompleter(parentCommandPath: List): Completer = + registeredSubcommands().let { subcommands -> + val commandPath = parentCommandPath + this + if (subcommands.isEmpty()) ArgumentCompleter( + commandPath.map { StringsCompleter(it.commandName) } + + Completers.OptionCompleter( + registeredArguments().map { it.makeJLineTreeCompleter() }, + registeredOptions().flatMap { it.makeJLineDescription() }, + commandPath.size + ) + ) + else AggregateCompleter(subcommands.map { it.makeJLineTreeCompleter(commandPath) }) + } + +fun CompletionCandidates.makeJLineCompleter(): Completer = when (this) { + is CompletionCandidates.Fixed -> StringsCompleter(candidates) + is CompletionCandidates.Path -> Completers.FileNameCompleter() + is CompletionCandidates.None -> NullCompleter.INSTANCE + else -> NullCompleter.INSTANCE +} + +fun Option.makeJLineDescription(): List { + val valueCompleter = completionCandidates.makeJLineCompleter() + return names.map { Completers.OptDesc(it, it, this.optionHelp(Commands.createRootContext()), valueCompleter) } + + secondaryNames.map { Completers.OptDesc(it, it) } +} + +fun Argument.makeJLineTreeCompleter() = completionCandidates.makeJLineCompleter() diff --git a/src/main/resources/META-INF/lmfsbox.properties b/src/main/resources/META-INF/lmfsbox.properties index c4b712b..d8ff133 100644 --- a/src/main/resources/META-INF/lmfsbox.properties +++ b/src/main/resources/META-INF/lmfsbox.properties @@ -1,3 +1,5 @@ lmfsbox.version=${project.getVersion()} lmfsbox.build=${building} lmfsbox.build.date=${date} +lmfsbox.git.hash=${gitVersion.gitHash} +lmfsbox.git.branch=${gitVersion.branchName} \ No newline at end of file