working CLI tool, versioning support, etc
This commit is contained in:
1 parent
7b76b7d80f
commit
953e0e696b
17 files changed
+234
-46
No files matched your search
+21
-1
@@ -7,10 +7,20 @@ version = "unspecified"
|
||||
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://maven.universablockchain.com/")
|
||||
maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven")
|
||||
mavenLocal()
|
||||
maven("https://gitea.sergeych.net/api/packages/SergeychWorks/maven")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
jvm {
|
||||
binaries {
|
||||
executable {
|
||||
mainClass.set("net.sergeych.lyng_cli.MainKt")
|
||||
}
|
||||
}
|
||||
}
|
||||
linuxX64 {
|
||||
binaries {
|
||||
executable()
|
||||
@@ -18,11 +28,21 @@ kotlin {
|
||||
}
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation(project(":library"))
|
||||
implementation(libs.okio)
|
||||
|
||||
implementation(libs.clikt)
|
||||
|
||||
// optional support for rendering markdown in help messages
|
||||
// implementation(libs.clikt.markdown)
|
||||
}
|
||||
}
|
||||
val commonTest by getting {
|
||||
dependencies {
|
||||
implementation(kotlin("test-common"))
|
||||
implementation(kotlin("test-annotations-common"))
|
||||
implementation(libs.okio.fakefilesystem)
|
||||
}
|
||||
}
|
||||
val linuxX64Main by getting {
|
||||
|
||||
@@ -1,7 +1,110 @@
|
||||
package net.sergeych
|
||||
|
||||
import com.github.ajalt.clikt.core.CliktCommand
|
||||
import com.github.ajalt.clikt.parameters.arguments.argument
|
||||
import com.github.ajalt.clikt.parameters.arguments.multiple
|
||||
import com.github.ajalt.clikt.parameters.arguments.optional
|
||||
import com.github.ajalt.clikt.parameters.options.flag
|
||||
import com.github.ajalt.clikt.parameters.options.option
|
||||
import net.sergeych.lyng.*
|
||||
import okio.FileSystem
|
||||
import okio.Path.Companion.toPath
|
||||
import okio.SYSTEM
|
||||
import okio.buffer
|
||||
import okio.use
|
||||
|
||||
// common code
|
||||
|
||||
fun commonCode() {
|
||||
println("Common code")
|
||||
}
|
||||
expect fun exit(code: Int)
|
||||
|
||||
val baseContext = Context().apply {
|
||||
addFn("exit") {
|
||||
exit(requireOnlyArg<ObjInt>().toInt())
|
||||
ObjVoid
|
||||
}
|
||||
}
|
||||
|
||||
class LyngCLI(val launcher: (suspend () -> Unit) -> Unit) : CliktCommand() {
|
||||
|
||||
override val printHelpOnEmptyArgs = true
|
||||
|
||||
val version by option("-v", "--version", help = "Print version and exit").flag()
|
||||
val script by argument(help = "one or more scripts to execute").optional()
|
||||
val execute: String? by option(
|
||||
"-x", "--execute", help = """
|
||||
execute string <text>, the rest of command line is passed to Lyng as ARGV
|
||||
""".trimIndent()
|
||||
)
|
||||
|
||||
val args by argument(help = "arguments for script").multiple()
|
||||
|
||||
override fun help(context: com.github.ajalt.clikt.core.Context): String =
|
||||
"""
|
||||
The Lyng script language interpreter, language version is $LyngVersion.
|
||||
|
||||
Please refer form more information to the project site:
|
||||
https://gitea.sergeych.net/SergeychWorks/lyng
|
||||
|
||||
""".trimIndent()
|
||||
|
||||
override fun run() {
|
||||
when {
|
||||
version -> {
|
||||
println("Lyng language version ${LyngVersion}")
|
||||
}
|
||||
|
||||
execute != null -> {
|
||||
val objargs = mutableListOf<String>()
|
||||
script?.let { objargs += it }
|
||||
objargs += args
|
||||
baseContext.addConst(
|
||||
"ARGV", ObjList(
|
||||
objargs.map { ObjString(it) }.toMutableList()
|
||||
)
|
||||
)
|
||||
launcher {
|
||||
// there is no script name, it is a first argument instead:
|
||||
processErrors {
|
||||
baseContext.eval(execute!!)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
else -> {
|
||||
if (script == null) {
|
||||
println(
|
||||
"""
|
||||
|
||||
Error: no script specified.
|
||||
|
||||
""".trimIndent()
|
||||
)
|
||||
echoFormattedHelp()
|
||||
} else {
|
||||
baseContext.addConst("ARGV", ObjList(args.map { ObjString(it) }.toMutableList()))
|
||||
launcher { executeFile(script!!) }
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun executeFile(fileName: String) {
|
||||
val text = FileSystem.SYSTEM.source(fileName.toPath()).use { fileSource ->
|
||||
fileSource.buffer().use { bs ->
|
||||
bs.readUtf8()
|
||||
}
|
||||
}
|
||||
processErrors {
|
||||
Compiler().compile(Source(fileName, text)).execute(baseContext)
|
||||
}
|
||||
}
|
||||
|
||||
suspend fun processErrors(block: suspend () -> Unit) {
|
||||
try {
|
||||
block()
|
||||
}
|
||||
catch (e: ScriptError) {
|
||||
println("\nError executing the script:\n$e\n")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package net.sergeych
|
||||
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
actual fun exit(code: Int) {
|
||||
exitProcess(code)
|
||||
}
|
||||
@@ -1,18 +0,0 @@
|
||||
import net.sergeych.commonCode
|
||||
|
||||
//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
|
||||
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
|
||||
fun main() {
|
||||
val name = "Kotlin"
|
||||
//TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text
|
||||
// to see how GIGA IDE suggests fixing it.
|
||||
println("Hello, native " + name + "!")
|
||||
|
||||
commonCode()
|
||||
|
||||
for (i in 1..5) {
|
||||
//TIP Press <shortcut actionId="Debug"/> to start debugging your code. We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
|
||||
// for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.
|
||||
println("i = $i")
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
package net.sergeych.lyng_cli
|
||||
|
||||
import com.github.ajalt.clikt.core.main
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.sergeych.LyngCLI
|
||||
|
||||
fun main(args: Array<String>) {
|
||||
LyngCLI({ runBlocking { it() } }).main(args)
|
||||
}
|
||||
@@ -1,18 +1,7 @@
|
||||
import net.sergeych.commonCode
|
||||
import com.github.ajalt.clikt.core.main
|
||||
import kotlinx.coroutines.runBlocking
|
||||
import net.sergeych.LyngCLI
|
||||
|
||||
//TIP To <b>Run</b> code, press <shortcut actionId="Run"/> or
|
||||
// click the <icon src="AllIcons.Actions.Execute"/> icon in the gutter.
|
||||
fun main() {
|
||||
val name = "Kotlin"
|
||||
//TIP Press <shortcut actionId="ShowIntentionActions"/> with your caret at the highlighted text
|
||||
// to see how GIGA IDE suggests fixing it.
|
||||
println("Hello, native " + name + "!")
|
||||
|
||||
commonCode()
|
||||
|
||||
for (i in 1..5) {
|
||||
//TIP Press <shortcut actionId="Debug"/> to start debugging your code. We have set one <icon src="AllIcons.Debugger.Db_set_breakpoint"/> breakpoint
|
||||
// for you, but you can always add more by pressing <shortcut actionId="ToggleLineBreakpoint"/>.
|
||||
println("i = $i")
|
||||
}
|
||||
fun main(args: Array<String>) {
|
||||
LyngCLI( { runBlocking { it() } }).main(args)
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
package net.sergeych
|
||||
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
actual fun exit(code: Int) {
|
||||
exitProcess(code)
|
||||
}
|
||||
Reference in new issue
Block a user