aboutsummaryrefslogtreecommitdiff
path: root/scripts
diff options
context:
space:
mode:
authorCan Celik <ogulcancelik@gmail.com>2026-04-04 19:22:04 +0300
committerCan Celik <ogulcancelik@gmail.com>2026-04-05 01:23:06 +0300
commit41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch)
tree3fc91815ca139ef2e0b281bba0abda4ef15175f4 /scripts
parent55c138263e190a1e79d4b997bfb9397306c0ec1f (diff)
feat: finish ghostty pane backend integration
Diffstat (limited to 'scripts')
-rwxr-xr-xscripts/build_vendored_libghostty_vt.sh17
-rw-r--r--scripts/test_vendor_libghostty_vt.py50
-rw-r--r--scripts/vendor_libghostty_vt.py107
3 files changed, 174 insertions, 0 deletions
diff --git a/scripts/build_vendored_libghostty_vt.sh b/scripts/build_vendored_libghostty_vt.sh
new file mode 100755
index 00000000..1d051810
--- /dev/null
+++ b/scripts/build_vendored_libghostty_vt.sh
@@ -0,0 +1,17 @@
+#!/usr/bin/env bash
+set -euo pipefail
+
+ROOT_DIR=$(cd -- "$(dirname -- "${BASH_SOURCE[0]}")/.." && pwd)
+VENDORED_DIR=${VENDORED_GHOSTTY_DIR:-"$ROOT_DIR/vendor/libghostty-vt"}
+OPTIMIZE=${LIBGHOSTTY_VT_OPTIMIZE:-ReleaseFast}
+
+if [[ ! -f "$VENDORED_DIR/build.zig" ]]; then
+ echo "error: vendored libghostty-vt source not found at $VENDORED_DIR" >&2
+ exit 1
+fi
+
+cd "$VENDORED_DIR"
+zig build -Demit-lib-vt -Doptimize="$OPTIMIZE" "$@"
+
+echo
+printf 'built libghostty-vt in %s/zig-out\n' "$VENDORED_DIR"
diff --git a/scripts/test_vendor_libghostty_vt.py b/scripts/test_vendor_libghostty_vt.py
new file mode 100644
index 00000000..9a9806b3
--- /dev/null
+++ b/scripts/test_vendor_libghostty_vt.py
@@ -0,0 +1,50 @@
+from __future__ import annotations
+
+import io
+import tarfile
+import tempfile
+import unittest
+from pathlib import Path
+
+from scripts.vendor_libghostty_vt import parse_archive_root
+
+
+class VendorLibghosttyVtTests(unittest.TestCase):
+ def test_parse_archive_root_returns_single_top_level_directory(self) -> None:
+ with tempfile.TemporaryDirectory() as temp_dir:
+ archive = Path(temp_dir) / "libghostty-vt.tar.gz"
+ with tarfile.open(archive, "w:gz") as tar:
+ data = b"hello"
+ info = tarfile.TarInfo("libghostty-vt-1.0.0/README.md")
+ info.size = len(data)
+ tar.addfile(info, io.BytesIO(data))
+
+ self.assertEqual(parse_archive_root(archive), "libghostty-vt-1.0.0")
+
+ def test_vendored_tree_contains_required_upstream_files(self) -> None:
+ root = Path(__file__).resolve().parent.parent / "vendor" / "libghostty-vt"
+ required = [
+ root / "build.zig",
+ root / "build.zig.zon",
+ root / "CMakeLists.txt",
+ root / "dist" / "cmake" / "ghostty-vt-config.cmake.in",
+ root / "include" / "ghostty" / "vt.h",
+ root / "include" / "ghostty" / "vt" / "render.h",
+ root / "src" / "lib_vt.zig",
+ ]
+
+ missing = [str(path.relative_to(root)) for path in required if not path.exists()]
+ self.assertEqual(missing, [])
+
+ def test_vendor_metadata_exists_and_points_at_vendored_tree(self) -> None:
+ project_root = Path(__file__).resolve().parent.parent
+ metadata = project_root / "vendor" / "libghostty-vt.vendor.json"
+ self.assertTrue(metadata.exists())
+ text = metadata.read_text()
+ self.assertIn('"source_commit"', text)
+ self.assertIn('"dist_archive"', text)
+ self.assertIn('"extracted_dir"', text)
+
+
+if __name__ == "__main__":
+ unittest.main()
diff --git a/scripts/vendor_libghostty_vt.py b/scripts/vendor_libghostty_vt.py
new file mode 100644
index 00000000..f53e809b
--- /dev/null
+++ b/scripts/vendor_libghostty_vt.py
@@ -0,0 +1,107 @@
+from __future__ import annotations
+
+import argparse
+import json
+import shutil
+import subprocess
+import tarfile
+import tempfile
+from dataclasses import asdict, dataclass
+from pathlib import Path
+
+
+@dataclass
+class VendorMetadata:
+ source_repo: str
+ source_commit: str
+ dist_archive: str
+ extracted_dir: str
+
+
+def parse_archive_root(archive: Path) -> str:
+ with tarfile.open(archive, "r:gz") as tar:
+ roots = {
+ member.name.split("/", 1)[0]
+ for member in tar.getmembers()
+ if member.name and member.name != "."
+ }
+ if len(roots) != 1:
+ raise ValueError(f"expected exactly one archive root in {archive}, found {sorted(roots)}")
+ return next(iter(roots))
+
+
+def git_head(repo: Path) -> str:
+ return subprocess.check_output(["git", "rev-parse", "HEAD"], cwd=repo, text=True).strip()
+
+
+def ensure_dist_archive(source_repo: Path) -> Path:
+ subprocess.run(
+ ["zig", "build", "dist", "-Demit-lib-vt", "-Doptimize=ReleaseFast"],
+ cwd=source_repo,
+ check=True,
+ )
+ dist_dir = source_repo / "zig-out" / "dist"
+ archives = sorted(dist_dir.glob("libghostty-vt-*.tar.gz"))
+ if not archives:
+ raise FileNotFoundError(f"no libghostty-vt dist archive found in {dist_dir}")
+ return archives[-1]
+
+
+def vendor_libghostty_vt(source_repo: Path, destination: Path) -> VendorMetadata:
+ archive = ensure_dist_archive(source_repo)
+ root = parse_archive_root(archive)
+
+ with tempfile.TemporaryDirectory() as temp_dir:
+ temp_dir_path = Path(temp_dir)
+ with tarfile.open(archive, "r:gz") as tar:
+ tar.extractall(temp_dir_path)
+
+ extracted = temp_dir_path / root
+ if not extracted.exists():
+ raise FileNotFoundError(f"expected extracted root {extracted}")
+
+ if destination.exists():
+ shutil.rmtree(destination)
+ destination.parent.mkdir(parents=True, exist_ok=True)
+ shutil.copytree(extracted, destination)
+
+ return VendorMetadata(
+ source_repo=str(source_repo),
+ source_commit=git_head(source_repo),
+ dist_archive=archive.name,
+ extracted_dir=root,
+ )
+
+
+def main() -> None:
+ parser = argparse.ArgumentParser(description="Vendor the pinned libghostty-vt source dist into herdr")
+ parser.add_argument(
+ "--source-repo",
+ default="/home/can/Projects/ghostty",
+ help="Path to a local ghostty checkout",
+ )
+ parser.add_argument(
+ "--destination",
+ default="vendor/libghostty-vt",
+ help="Destination directory for the extracted libghostty-vt source dist",
+ )
+ parser.add_argument(
+ "--metadata",
+ default="vendor/libghostty-vt.vendor.json",
+ help="Path to write vendoring metadata JSON",
+ )
+ args = parser.parse_args()
+
+ repo = Path(args.source_repo).resolve()
+ destination = Path(args.destination).resolve()
+ metadata_path = Path(args.metadata).resolve()
+
+ metadata = vendor_libghostty_vt(repo, destination)
+ metadata_path.parent.mkdir(parents=True, exist_ok=True)
+ metadata_path.write_text(json.dumps(asdict(metadata), indent=2) + "\n")
+
+ print(f"vendored {metadata.extracted_dir} from {metadata.source_commit} into {destination}")
+
+
+if __name__ == "__main__":
+ main()