working CLI tool, versioning support, etc
This commit is contained in:
parent
7b76b7d80f
commit
953e0e696b
10
bin/local_release
Executable file
10
bin/local_release
Executable file
@ -0,0 +1,10 @@
|
||||
#!/bin/bash
|
||||
|
||||
set -e
|
||||
|
||||
file=./lyng/build/bin/linuxX64/releaseExecutable/lyng.kexe
|
||||
|
||||
./gradlew :lyng:linkReleaseExecutableLinuxX64
|
||||
strip $file
|
||||
upx $file
|
||||
cp $file ~/bin/lyng
|
@ -16,4 +16,6 @@ fun naiveCountHappyNumbers() {
|
||||
count
|
||||
}
|
||||
|
||||
assert( naiveCountHappyNumbers() == 55252 )
|
||||
val found = naiveCountHappyNumbers()
|
||||
println("Found happy numbers: "+found)
|
||||
assert( found == 55252 )
|
||||
|
2
docs/samples/helloworld.lyng
Normal file
2
docs/samples/helloworld.lyng
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
println("Hello, world!");
|
@ -4,9 +4,11 @@ org.gradle.caching=true
|
||||
org.gradle.configuration-cache=true
|
||||
#Kotlin
|
||||
kotlin.code.style=official
|
||||
kotlin.js.compiler=ir
|
||||
#MPP
|
||||
kotlin.mpp.enableCInteropCommonization=true
|
||||
#Android
|
||||
android.useAndroidX=true
|
||||
android.nonTransitiveRClass=true
|
||||
|
||||
# other
|
||||
kotlin.native.cacheKind.linuxX64=none
|
@ -1,18 +1,24 @@
|
||||
[versions]
|
||||
agp = "8.5.2"
|
||||
clikt = "5.0.3"
|
||||
kotlin = "2.1.21"
|
||||
android-minSdk = "24"
|
||||
android-compileSdk = "34"
|
||||
kotlinx-coroutines = "1.10.1"
|
||||
mp_bintools = "0.1.12"
|
||||
firebaseCrashlyticsBuildtools = "3.0.3"
|
||||
okioVersion = "3.10.2"
|
||||
|
||||
[libraries]
|
||||
clikt = { module = "com.github.ajalt.clikt:clikt", version.ref = "clikt" }
|
||||
clikt-markdown = { module = "com.github.ajalt.clikt:clikt-markdown", version.ref = "clikt" }
|
||||
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
|
||||
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "kotlinx-coroutines" }
|
||||
kotlinx-coroutines-core = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-core", version.ref = "kotlinx-coroutines" }
|
||||
mp_bintools = { module = "net.sergeych:mp_bintools", version.ref = "mp_bintools" }
|
||||
firebase-crashlytics-buildtools = { group = "com.google.firebase", name = "firebase-crashlytics-buildtools", version.ref = "firebaseCrashlyticsBuildtools" }
|
||||
okio = { module = "com.squareup.okio:okio", version.ref = "okioVersion" }
|
||||
okio-fakefilesystem = { module = "com.squareup.okio:okio-fakefilesystem", version.ref = "okioVersion" }
|
||||
|
||||
[plugins]
|
||||
androidLibrary = { id = "com.android.library", version.ref = "agp" }
|
||||
|
@ -11,7 +11,7 @@ plugins {
|
||||
}
|
||||
|
||||
group = "net.sergeych"
|
||||
version = "0.0.1-SNAPSHOT"
|
||||
version = "0.0.5-SNAPSHOT"
|
||||
|
||||
kotlin {
|
||||
jvm()
|
||||
@ -26,7 +26,7 @@ kotlin {
|
||||
// iosArm64()
|
||||
// iosSimulatorArm64()
|
||||
linuxX64()
|
||||
js(IR) {
|
||||
js {
|
||||
browser()
|
||||
nodejs()
|
||||
}
|
||||
@ -44,12 +44,13 @@ kotlin {
|
||||
}
|
||||
|
||||
val commonMain by getting {
|
||||
kotlin.srcDir("$buildDir/generated/buildConfig/commonMain/kotlin")
|
||||
dependencies {
|
||||
implementation("org.jetbrains.kotlinx:kotlinx-serialization-json:1.8.1")
|
||||
//put your multiplatform dependencies here
|
||||
implementation(libs.kotlinx.coroutines.core)
|
||||
implementation(libs.mp.bintools)
|
||||
implementation("net.sergeych:mp_stools:1.5.2")
|
||||
api(libs.kotlinx.coroutines.core)
|
||||
api(libs.mp.bintools)
|
||||
api("net.sergeych:mp_stools:1.5.2")
|
||||
}
|
||||
}
|
||||
val commonTest by getting {
|
||||
@ -109,3 +110,40 @@ mavenPublishing {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val projectVersion by project.extra(provider {
|
||||
// Compute value lazily
|
||||
(version as String)
|
||||
})
|
||||
|
||||
val generateBuildConfig by tasks.registering {
|
||||
// Declare outputs safely
|
||||
val outputDir = layout.buildDirectory.dir("generated/buildConfig/commonMain/kotlin")
|
||||
outputs.dir(outputDir)
|
||||
|
||||
val version = projectVersion.get()
|
||||
|
||||
// Inputs: Version is tracked as an input
|
||||
inputs.property("version", version)
|
||||
|
||||
doLast {
|
||||
val packageName = "net.sergeych.lyng.buildconfig"
|
||||
val packagePath = packageName.replace('.', '/')
|
||||
val buildConfigFile = outputDir.get().file("$packagePath/BuildConfig.kt").asFile
|
||||
|
||||
buildConfigFile.parentFile?.mkdirs()
|
||||
buildConfigFile.writeText(
|
||||
"""
|
||||
|package $packageName
|
||||
|
|
||||
|object BuildConfig {
|
||||
| const val VERSION = "$version"
|
||||
|}
|
||||
""".trimMargin()
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile>().configureEach {
|
||||
dependsOn(generateBuildConfig)
|
||||
}
|
||||
|
@ -21,7 +21,6 @@ class Script(
|
||||
companion object {
|
||||
val defaultContext: Context = Context().apply {
|
||||
addFn("println") {
|
||||
print("yn: ")
|
||||
for ((i, a) in args.withIndex()) {
|
||||
if (i > 0) print(' ' + a.asStr.value)
|
||||
else print(a.asStr.value)
|
||||
|
@ -5,6 +5,7 @@ package net.sergeych.lyng
|
||||
open class ScriptError(val pos: Pos, val errorMessage: String,cause: Throwable?=null) : Exception(
|
||||
"""
|
||||
$pos: Error: $errorMessage
|
||||
|
||||
${pos.currentLine}
|
||||
${"-".repeat(pos.column)}^
|
||||
""".trimIndent(),
|
||||
|
@ -0,0 +1,5 @@
|
||||
package net.sergeych.lyng
|
||||
|
||||
import net.sergeych.lyng.buildconfig.BuildConfig
|
||||
|
||||
val LyngVersion = BuildConfig.VERSION
|
@ -6,6 +6,12 @@ import kotlin.test.*
|
||||
|
||||
class ScriptTest {
|
||||
|
||||
@Test
|
||||
fun testVersion() {
|
||||
println("--------------------------------------------")
|
||||
println("version = ${LyngVersion}")
|
||||
}
|
||||
|
||||
@Test
|
||||
fun parseNewlines() {
|
||||
fun check(expected: String, type: Token.Type, row: Int, col: Int, src: String, offset: Int = 0) {
|
||||
|
@ -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")
|
||||
}
|
||||
}
|
7
lyng/src/jvmMain/kotlin/Common.jvm.kt
Normal file
7
lyng/src/jvmMain/kotlin/Common.jvm.kt
Normal file
@ -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")
|
||||
}
|
||||
}
|
9
lyng/src/jvmMain/kotlin/net/sergeych/lyng_cli/Main.kt
Normal file
9
lyng/src/jvmMain/kotlin/net/sergeych/lyng_cli/Main.kt
Normal file
@ -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)
|
||||
}
|
7
lyng/src/nativeMain/kotlin/Common.native.kt
Normal file
7
lyng/src/nativeMain/kotlin/Common.native.kt
Normal file
@ -0,0 +1,7 @@
|
||||
package net.sergeych
|
||||
|
||||
import kotlin.system.exitProcess
|
||||
|
||||
actual fun exit(code: Int) {
|
||||
exitProcess(code)
|
||||
}
|
Loading…
x
Reference in New Issue
Block a user