Compare commits

..

No commits in common. "38646c625713844ab6ed3ae31a31d76dc43f6c47" and "9bee0aed5b7a12bbea11011491926ada16f32fa6" have entirely different histories.

6 changed files with 6 additions and 195 deletions

View File

@ -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

View File

@ -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]))

View File

@ -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" }

View File

@ -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"))

View File

@ -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)
} }
} }

View File

@ -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)
}
}
}