Compare commits
No commits in common. "38646c625713844ab6ed3ae31a31d76dc43f6c47" and "9bee0aed5b7a12bbea11011491926ada16f32fa6" have entirely different histories.
38646c6257
...
9bee0aed5b
@ -112,16 +112,9 @@ For more details, see the specific module documentation:
|
|||||||
|
|
||||||
| Platform | lyng.io.fs | lyng.io.process | lyng.io.console | lyng.io.http | lyng.io.ws | lyng.io.net |
|
| Platform | lyng.io.fs | lyng.io.process | lyng.io.console | lyng.io.http | lyng.io.ws | lyng.io.net |
|
||||||
| :--- | :---: | :---: | :---: | :---: | :---: | :---: |
|
| :--- | :---: | :---: | :---: | :---: | :---: | :---: |
|
||||||
| **JVM** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| **JVM** | ✅ | ✅ | ✅ (baseline) | ✅ | ✅ | ✅ |
|
||||||
| **Linux Native** | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
|
| **Native (Linux/macOS)** | ✅ | ✅ | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||||
| **Apple Native** | ✅ | ✅ | ✅ | ✅ | ✅ | ⚠️ |
|
| **Native (Windows)** | ✅ | 🚧 (Planned) | 🚧 | 🚧 | 🚧 | 🚧 |
|
||||||
| **Windows Native** | ✅ | ❌ | ✅ | ✅ | ✅ | ❌ |
|
| **Android** | ✅ | ❌ | ❌ | 🚧 | 🚧 | 🚧 |
|
||||||
| **Android** | ✅ | ❌ | ⚠️ | ✅ | ✅ | ✅ |
|
| **NodeJS** | ✅ | ❌ | ❌ | 🚧 | 🚧 | 🚧 |
|
||||||
| **JS / Node** | ✅ | ❌ | ⚠️ | ✅ | ✅ | ✅ |
|
| **Browser / Wasm** | ✅ (In-memory) | ❌ | ❌ | 🚧 | 🚧 | 🚧 |
|
||||||
| **JS / Browser** | ✅ (in-memory) | ❌ | ⚠️ | ✅ | ✅ | ❌ |
|
|
||||||
| **Wasm** | ✅ (in-memory) | ❌ | ⚠️ | ❌ | ❌ | ❌ |
|
|
||||||
|
|
||||||
Legend:
|
|
||||||
- `✅` supported
|
|
||||||
- `⚠️` available but environment-dependent or not fully host-verified yet
|
|
||||||
- `❌` unsupported
|
|
||||||
|
|||||||
@ -1,23 +0,0 @@
|
|||||||
#!/env/bin lyng
|
|
||||||
|
|
||||||
import lyng.io.http
|
|
||||||
|
|
||||||
// Step 1: download the main lynglang.com page.
|
|
||||||
val home = Http.get("https://lynglang.com").text()
|
|
||||||
|
|
||||||
// Step 2: find the version-script reference in the page HTML.
|
|
||||||
val jsRef = "src=\"([^\"]*lyng-version\\.js)\"".re.find(home)
|
|
||||||
require(jsRef != null, "lyng-version.js reference not found on the homepage")
|
|
||||||
|
|
||||||
// Step 3: extract the referenced script path from the first regex capture.
|
|
||||||
val versionJsPath = jsRef[1]
|
|
||||||
|
|
||||||
// Step 4: download the script that exposes `window.LYNG_VERSION`.
|
|
||||||
val versionJs = Http.get("https://lynglang.com/" + versionJsPath).text()
|
|
||||||
|
|
||||||
// Step 5: pull the actual version string from the JavaScript source.
|
|
||||||
val versionMatch = "LYNG_VERSION\\s*=\\s*\"([^\"]+)\"".re.find(versionJs)
|
|
||||||
require(versionMatch != null, "LYNG_VERSION assignment not found")
|
|
||||||
|
|
||||||
// Step 6: print the discovered version for the user.
|
|
||||||
println("Lynglang.com version: " + ((versionMatch as RegexMatch)[1]))
|
|
||||||
@ -14,7 +14,6 @@ firebaseCrashlyticsBuildtools = "3.0.3"
|
|||||||
okioVersion = "3.10.2"
|
okioVersion = "3.10.2"
|
||||||
compiler = "3.2.0-alpha11"
|
compiler = "3.2.0-alpha11"
|
||||||
ktor = "3.3.1"
|
ktor = "3.3.1"
|
||||||
slf4j = "2.0.17"
|
|
||||||
|
|
||||||
[libraries]
|
[libraries]
|
||||||
clikt = { module = "com.github.ajalt.clikt:clikt", version.ref = "clikt" }
|
clikt = { module = "com.github.ajalt.clikt:clikt", version.ref = "clikt" }
|
||||||
@ -41,7 +40,6 @@ ktor-client-js = { module = "io.ktor:ktor-client-js", version.ref = "ktor" }
|
|||||||
ktor-client-winhttp = { module = "io.ktor:ktor-client-winhttp", version.ref = "ktor" }
|
ktor-client-winhttp = { module = "io.ktor:ktor-client-winhttp", version.ref = "ktor" }
|
||||||
ktor-client-websockets = { module = "io.ktor:ktor-client-websockets", version.ref = "ktor" }
|
ktor-client-websockets = { module = "io.ktor:ktor-client-websockets", version.ref = "ktor" }
|
||||||
ktor-network = { module = "io.ktor:ktor-network", version.ref = "ktor" }
|
ktor-network = { module = "io.ktor:ktor-network", version.ref = "ktor" }
|
||||||
slf4j-nop = { module = "org.slf4j:slf4j-nop", version.ref = "slf4j" }
|
|
||||||
|
|
||||||
[plugins]
|
[plugins]
|
||||||
androidLibrary = { id = "com.android.library", version.ref = "agp" }
|
androidLibrary = { id = "com.android.library", version.ref = "agp" }
|
||||||
|
|||||||
@ -80,11 +80,6 @@ kotlin {
|
|||||||
val nativeMain by creating {
|
val nativeMain by creating {
|
||||||
dependsOn(commonMain)
|
dependsOn(commonMain)
|
||||||
}
|
}
|
||||||
val jvmMain by getting {
|
|
||||||
dependencies {
|
|
||||||
implementation(libs.slf4j.nop)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val jvmTest by getting {
|
val jvmTest by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(kotlin("test"))
|
implementation(kotlin("test"))
|
||||||
|
|||||||
@ -34,15 +34,9 @@ import net.sergeych.lyng.ScriptError
|
|||||||
import net.sergeych.lyng.Source
|
import net.sergeych.lyng.Source
|
||||||
import net.sergeych.lyng.io.console.createConsoleModule
|
import net.sergeych.lyng.io.console.createConsoleModule
|
||||||
import net.sergeych.lyng.io.fs.createFs
|
import net.sergeych.lyng.io.fs.createFs
|
||||||
import net.sergeych.lyng.io.http.createHttpModule
|
|
||||||
import net.sergeych.lyng.io.net.createNetModule
|
|
||||||
import net.sergeych.lyng.io.ws.createWsModule
|
|
||||||
import net.sergeych.lyng.obj.*
|
import net.sergeych.lyng.obj.*
|
||||||
import net.sergeych.lyngio.console.security.PermitAllConsoleAccessPolicy
|
import net.sergeych.lyngio.console.security.PermitAllConsoleAccessPolicy
|
||||||
import net.sergeych.lyngio.fs.security.PermitAllAccessPolicy
|
import net.sergeych.lyngio.fs.security.PermitAllAccessPolicy
|
||||||
import net.sergeych.lyngio.http.security.PermitAllHttpAccessPolicy
|
|
||||||
import net.sergeych.lyngio.net.security.PermitAllNetAccessPolicy
|
|
||||||
import net.sergeych.lyngio.ws.security.PermitAllWsAccessPolicy
|
|
||||||
import net.sergeych.mp_tools.globalDefer
|
import net.sergeych.mp_tools.globalDefer
|
||||||
import okio.FileSystem
|
import okio.FileSystem
|
||||||
import okio.Path.Companion.toPath
|
import okio.Path.Companion.toPath
|
||||||
@ -80,11 +74,6 @@ val baseScopeDefer = globalDefer {
|
|||||||
// Install console access by default for interactive CLI scripts.
|
// Install console access by default for interactive CLI scripts.
|
||||||
// Scripts still need to `import lyng.io.console` to use it.
|
// Scripts still need to `import lyng.io.console` to use it.
|
||||||
createConsoleModule(PermitAllConsoleAccessPolicy, this)
|
createConsoleModule(PermitAllConsoleAccessPolicy, this)
|
||||||
// Install network-oriented lyngio modules for CLI scripts.
|
|
||||||
// Scripts still need to import the modules they use explicitly.
|
|
||||||
createHttpModule(PermitAllHttpAccessPolicy, this)
|
|
||||||
createWsModule(PermitAllWsAccessPolicy, this)
|
|
||||||
createNetModule(PermitAllNetAccessPolicy, this)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,141 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2026 Sergey S. Chernov real.sergeych@gmail.com
|
|
||||||
*
|
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
||||||
* you may not use this file except in compliance with the License.
|
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
|
||||||
*
|
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
||||||
* See the License for the specific language governing permissions and
|
|
||||||
* limitations under the License.
|
|
||||||
*
|
|
||||||
*/
|
|
||||||
package net.sergeych.lyng_cli
|
|
||||||
|
|
||||||
import com.sun.net.httpserver.HttpExchange
|
|
||||||
import com.sun.net.httpserver.HttpServer
|
|
||||||
import net.sergeych.jvmExitImpl
|
|
||||||
import net.sergeych.runMain
|
|
||||||
import org.junit.After
|
|
||||||
import org.junit.Assert.assertNull
|
|
||||||
import org.junit.Assert.assertTrue
|
|
||||||
import org.junit.Before
|
|
||||||
import org.junit.Test
|
|
||||||
import java.io.ByteArrayOutputStream
|
|
||||||
import java.io.PrintStream
|
|
||||||
import java.net.InetSocketAddress
|
|
||||||
|
|
||||||
class CliNetworkJvmTest {
|
|
||||||
private val originalOut: PrintStream = System.out
|
|
||||||
private val originalErr: PrintStream = System.err
|
|
||||||
|
|
||||||
private class TestExit(val code: Int) : RuntimeException()
|
|
||||||
|
|
||||||
@Before
|
|
||||||
fun setUp() {
|
|
||||||
jvmExitImpl = { code -> throw TestExit(code) }
|
|
||||||
}
|
|
||||||
|
|
||||||
@After
|
|
||||||
fun tearDown() {
|
|
||||||
System.setOut(originalOut)
|
|
||||||
System.setErr(originalErr)
|
|
||||||
jvmExitImpl = { code -> kotlin.system.exitProcess(code) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private data class CliResult(val out: String, val err: String, val exitCode: Int?)
|
|
||||||
|
|
||||||
private fun runCli(vararg args: String): CliResult {
|
|
||||||
val outBuf = ByteArrayOutputStream()
|
|
||||||
val errBuf = ByteArrayOutputStream()
|
|
||||||
System.setOut(PrintStream(outBuf, true, Charsets.UTF_8))
|
|
||||||
System.setErr(PrintStream(errBuf, true, Charsets.UTF_8))
|
|
||||||
|
|
||||||
var exitCode: Int? = null
|
|
||||||
try {
|
|
||||||
runMain(arrayOf(*args))
|
|
||||||
} catch (e: TestExit) {
|
|
||||||
exitCode = e.code
|
|
||||||
} finally {
|
|
||||||
System.out.flush()
|
|
||||||
System.err.flush()
|
|
||||||
}
|
|
||||||
return CliResult(outBuf.toString("UTF-8"), errBuf.toString("UTF-8"), exitCode)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
fun cliHasAllNetworkingModulesInstalled() {
|
|
||||||
val server = newServer()
|
|
||||||
try {
|
|
||||||
val script = """
|
|
||||||
import lyng.io.http
|
|
||||||
import lyng.io.ws
|
|
||||||
import lyng.io.net
|
|
||||||
|
|
||||||
assert(Http.isSupported())
|
|
||||||
println("ws=" + Ws.isSupported())
|
|
||||||
println("net=" + Net.isSupported())
|
|
||||||
|
|
||||||
val home = Http.get("http://127.0.0.1:${server.address.port}/").text()
|
|
||||||
val jsRef = "src=\"([^\"]*lyng-version\\.js)\"".re.find(home)
|
|
||||||
require(jsRef != null, "lyng-version.js reference not found")
|
|
||||||
|
|
||||||
val versionJsPath = (jsRef as RegexMatch)[1]
|
|
||||||
val versionJs = Http.get("http://127.0.0.1:${server.address.port}/" + versionJsPath).text()
|
|
||||||
val versionMatch = "LYNG_VERSION\\s*=\\s*\"([^\"]+)\"".re.find(versionJs)
|
|
||||||
require(versionMatch != null, "LYNG_VERSION assignment not found")
|
|
||||||
|
|
||||||
println("version=" + ((versionMatch as RegexMatch)[1]))
|
|
||||||
""".trimIndent()
|
|
||||||
|
|
||||||
val result = runCli("-x", script)
|
|
||||||
assertNull(result.exitCode)
|
|
||||||
assertTrue(result.err, result.err.isBlank())
|
|
||||||
assertTrue(result.out, result.out.contains("ws="))
|
|
||||||
assertTrue(result.out, result.out.contains("net="))
|
|
||||||
assertTrue(result.out, result.out.contains("version=9.9.9-test"))
|
|
||||||
} finally {
|
|
||||||
server.stop(0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun newServer(): HttpServer {
|
|
||||||
val server = HttpServer.create(InetSocketAddress("127.0.0.1", 0), 0)
|
|
||||||
server.createContext("/") { exchange ->
|
|
||||||
when (exchange.requestURI.path) {
|
|
||||||
"/" -> writeResponse(
|
|
||||||
exchange,
|
|
||||||
200,
|
|
||||||
"""
|
|
||||||
<!doctype html>
|
|
||||||
<html>
|
|
||||||
<head>
|
|
||||||
<script src="lyng-version.js"></script>
|
|
||||||
</head>
|
|
||||||
<body>
|
|
||||||
<span id="lyng-version-ribbon"></span>
|
|
||||||
</body>
|
|
||||||
</html>
|
|
||||||
""".trimIndent()
|
|
||||||
)
|
|
||||||
|
|
||||||
"/lyng-version.js" -> writeResponse(exchange, 200, """window.LYNG_VERSION = "9.9.9-test";""")
|
|
||||||
else -> writeResponse(exchange, 404, "missing")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
server.start()
|
|
||||||
return server
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun writeResponse(exchange: HttpExchange, status: Int, body: String) {
|
|
||||||
val bytes = body.toByteArray()
|
|
||||||
exchange.sendResponseHeaders(status, bytes.size.toLong())
|
|
||||||
exchange.responseBody.use { out ->
|
|
||||||
out.write(bytes)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user