Initial commit.

This commit is contained in:
Storm Dragon committed 2026-10-13 13:00:48 -04:00
commit 6a02494ac8
14 files changed
+843

No files matched your search

+95
View File
@@ -0,0 +1,95 @@
# Copyright (c) 2026 Storm Dragon
# SPDX-License-Identifier: GPL-3.0-or-later
"""Check the repository and the built Tentacle without running a reader."""
import json
import os
from pathlib import Path
import select
import subprocess
import tomllib
def require(condition, message):
if not condition:
raise RuntimeError(message)
def read_toml(path):
with path.open("rb") as source:
return tomllib.load(source)
def check_metadata(repoRoot):
repository = read_toml(repoRoot / "repository.toml")
catalog = read_toml(repoRoot / "catalog.toml")
require(repository["format-version"] == catalog["format-version"] == 1,
"Unsupported metadata format")
require(repository["id"] == "storm.cthulhu-tentacles" and repository["name"],
"Repository identity is missing")
require(catalog["tentacles"] == [{"id": "hello-world", "manifest": "hello-world/tentacle.toml"}],
"Catalog must list exactly Hello World")
manifest = read_toml(repoRoot / catalog["tentacles"][0]["manifest"])
require(manifest["format-version"] == 1 and manifest["id"] == "hello-world"
and manifest["name"] and manifest["version"] == "0.1.0",
"Invalid Hello World metadata")
require(manifest["entry-point"] == ["bin/hello-world"]
and manifest["capabilities"] == ["presentation"], "Unexpected launch or grants")
require((repoRoot / "LICENSE").is_file() and (repoRoot / "hello-world/LICENSE").is_file(),
"Repository and Tentacle licenses are required")
def check_registration(programPath):
with subprocess.Popen([str(programPath)], stdin=subprocess.PIPE,
stdout=subprocess.PIPE, stderr=subprocess.PIPE) as process:
try:
initialization = {
"jsonrpc": "2.0", "id": "1", "method": "initialize",
"params": {"protocol": {"major": 1, "minor": 0}, "session": "check",
"apis": ["commands", "presentation"],
"capabilities": ["commands", "presentation"]},
}
process.stdin.write((json.dumps(initialization) + "\n").encode())
process.stdin.flush()
require(select.select([process.stdout], [], [], 5)[0], "Registration timed out")
registration = json.loads(process.stdout.readline())
require(registration["id"] == "1" and registration["result"]["session"] == "check",
"Invalid registration response")
commands = registration["result"]["commands"]
require(len(commands) == 1 and commands[0]["id"] == "hello-world"
and commands[0]["presentation"] is True, "Unexpected commands or grant")
require(commands[0]["bindings"] == [
{"layout": layout, "scope": "global", "key": "Cthulhu+Alt+Shift+H"}
for layout in ("desktop", "laptop")], "Wrong suggested shortcut")
process.stdin.close()
require(process.wait(timeout=5) == 0, "Tentacle did not stop cleanly on EOF")
finally:
if process.poll() is None:
process.kill()
process.wait(timeout=5)
def check_host(repoRoot, programPath):
readerRoot = repoRoot.parent / "cthulhu-go"
environment = os.environ.copy()
environment.setdefault("GOCACHE", "/tmp/cthulhu-go-cache")
result = subprocess.run([
"go", "run", "./examples/tentacles/host", "-presentation",
"-command", "hello-world", str(programPath),
], cwd=readerRoot, env=environment, capture_output=True, text=True, timeout=60, check=True)
require(json.loads(result.stdout) == {
"speech": "Hello world!", "braille": "Hello world!", "uninterruptible": True,
}, "The actual host returned an unexpected greeting")
def main():
repoRoot = Path(__file__).resolve().parents[1]
programPath = repoRoot / "hello-world/bin/hello-world"
check_metadata(repoRoot)
check_registration(programPath)
check_host(repoRoot, programPath)
print("Repository metadata, shortcut registration and actual-host greeting passed.")
if __name__ == "__main__":
main()