diff options
| author | Can Celik <ogulcancelik@gmail.com> | 2026-04-04 19:22:04 +0300 |
|---|---|---|
| committer | Can Celik <ogulcancelik@gmail.com> | 2026-04-05 01:23:06 +0300 |
| commit | 41dd733ca7123c9ac4bfc6c781697a660e95b052 (patch) | |
| tree | 3fc91815ca139ef2e0b281bba0abda4ef15175f4 /scripts | |
| parent | 55c138263e190a1e79d4b997bfb9397306c0ec1f (diff) | |
feat: finish ghostty pane backend integration
Diffstat (limited to 'scripts')
| -rwxr-xr-x | scripts/build_vendored_libghostty_vt.sh | 17 | ||||
| -rw-r--r-- | scripts/test_vendor_libghostty_vt.py | 50 | ||||
| -rw-r--r-- | scripts/vendor_libghostty_vt.py | 107 |
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() |
