|
@@ -1,91 +1,106 @@
|
|
|
# Vendoring chattolib
|
|
# Vendoring chattolib
|
|
|
|
|
|
|
|
-This plugin includes a **vendored copy of chattolib** in the `chattolib_vendor/` directory.
|
|
|
|
|
-This means you don't need to install chattolib separately — it's bundled with the plugin.
|
|
|
|
|
|
|
+This plugin ships a **vendored copy of chattolib and all its dependencies** in
|
|
|
|
|
+`vendor/`. Nothing has to be installed separately — the plugin brings its own
|
|
|
|
|
+dependency tree.
|
|
|
|
|
|
|
|
## Why Vendoring?
|
|
## Why Vendoring?
|
|
|
|
|
|
|
|
- **No dependencies to install**: `hermes plugin install` works immediately
|
|
- **No dependencies to install**: `hermes plugin install` works immediately
|
|
|
-- **No lazy-import complexity**: No need for `ensure()` or `lazy_import` mechanisms
|
|
|
|
|
-- **Isolated**: The vendored chattolib won't conflict with any system-installed version
|
|
|
|
|
-- **Offline-friendly**: Works in air-gapped environments
|
|
|
|
|
|
|
+- **No lazy-import complexity**: no `ensure()` or `lazy_import` mechanisms
|
|
|
|
|
+- **Isolated**: the vendored copy cannot conflict with a system-installed one
|
|
|
|
|
+- **Offline-friendly**: works in air-gapped environments
|
|
|
|
|
|
|
|
-## Updating the Vendored chattolib
|
|
|
|
|
|
|
+## Layout
|
|
|
|
|
|
|
|
-To update to a new version of chattolib:
|
|
|
|
|
|
|
+Three of the vendored packages contain compiled extension modules and are
|
|
|
|
|
+therefore platform-specific: `pyqwest` (~15 MB, the HTTP core used by
|
|
|
|
|
+`connectrpc`), `protobuf` and `protobuf-py-ext`. Everything else is pure
|
|
|
|
|
+Python. The tree is split accordingly, so the shared part is stored once:
|
|
|
|
|
|
|
|
-```bash
|
|
|
|
|
-# Run the vendoring script
|
|
|
|
|
-./vendor_chattolib.sh [version]
|
|
|
|
|
-
|
|
|
|
|
-# Example: update to 0.5.0
|
|
|
|
|
-./vendor_chattolib.sh 0.5.0
|
|
|
|
|
-
|
|
|
|
|
-# Or use default (latest known stable)
|
|
|
|
|
-./vendor_chattolib.sh
|
|
|
|
|
|
|
+```
|
|
|
|
|
+vendor/
|
|
|
|
|
+├── __init__.py
|
|
|
|
|
+├── common/ # pure-Python packages (~8 MB), all platforms
|
|
|
|
|
+│ ├── chattolib/
|
|
|
|
|
+│ ├── connectrpc/
|
|
|
|
|
+│ ├── httpx/ httpcore/ h11/ anyio/ idna/ certifi/
|
|
|
|
|
+│ └── opentelemetry/ protobuf/ typing_extensions.py
|
|
|
|
|
+└── platform/ # compiled extensions, ~16 MB per platform
|
|
|
|
|
+ ├── linux-x86_64/ # pyqwest/, protobuf_ext/, google/
|
|
|
|
|
+ ├── linux-aarch64/
|
|
|
|
|
+ └── macos-arm64/
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-The script will:
|
|
|
|
|
-1. Download the chattolib wheel from PyPI
|
|
|
|
|
-2. Extract it to `chattolib_vendor/`
|
|
|
|
|
-3. Also download the `websockets` dependency (needed for realtime features)
|
|
|
|
|
|
|
+`vendor_path.py` derives the platform tag from `platform.system()` /
|
|
|
|
|
+`platform.machine()` at import time and prepends
|
|
|
|
|
+`vendor/platform/<tag>` and `vendor/common` to `sys.path` — platform directory
|
|
|
|
|
+first, so the right binaries win. Both `adapter.py` and `platform_config.py`
|
|
|
|
|
+call `setup_vendor_path()` before importing anything from `chattolib`.
|
|
|
|
|
|
|
|
-## Development without Vendoring
|
|
|
|
|
|
|
+If the current platform was not vendored, the import fails with an explicit
|
|
|
|
|
+message naming the available platforms — rather than a cryptic `dlopen` error
|
|
|
|
|
+about an invalid Mach-O/ELF file.
|
|
|
|
|
|
|
|
-If you're developing and want to use your system-installed chattolib instead:
|
|
|
|
|
|
|
+## Updating or rebuilding
|
|
|
|
|
|
|
|
```bash
|
|
```bash
|
|
|
-pip install chattolib[realtime]
|
|
|
|
|
-```
|
|
|
|
|
|
|
+# Default platform set: linux-x86_64, linux-aarch64, macos-arm64
|
|
|
|
|
+./vendor_chattolib.sh
|
|
|
|
|
|
|
|
-The adapter will automatically fall back to the system-installed version if the vendored copy is not found.
|
|
|
|
|
|
|
+# A single platform
|
|
|
|
|
+PLATFORMS="linux-x86_64" ./vendor_chattolib.sh
|
|
|
|
|
|
|
|
-## Structure
|
|
|
|
|
|
|
+# Add another one (see the table below for valid tags)
|
|
|
|
|
+PLATFORMS="linux-x86_64 linux-aarch64 macos-arm64 windows-amd64" ./vendor_chattolib.sh
|
|
|
|
|
|
|
|
-```
|
|
|
|
|
-chattolib_vendor/
|
|
|
|
|
-├── __init__.py # Marker file
|
|
|
|
|
-├── chattolib/ # The chattolib package
|
|
|
|
|
-│ ├── __init__.py
|
|
|
|
|
-│ ├── src/
|
|
|
|
|
-│ │ └── chattolib/
|
|
|
|
|
-│ │ ├── _pb/ # Protobuf generated files
|
|
|
|
|
-│ │ ├── _transport.py
|
|
|
|
|
-│ │ ├── client.py
|
|
|
|
|
-│ │ ├── realtime.py
|
|
|
|
|
-│ │ ├── types.py
|
|
|
|
|
-│ │ └── ...
|
|
|
|
|
-│ └── ...
|
|
|
|
|
-└── websockets/ # Dependency for realtime features
|
|
|
|
|
- └── ...
|
|
|
|
|
|
|
+# Pin a specific chattolib version
|
|
|
|
|
+CHATTOLIB_SPEC="chattolib==0.4.20" ./vendor_chattolib.sh
|
|
|
```
|
|
```
|
|
|
|
|
|
|
|
-## License
|
|
|
|
|
|
|
+The script wipes `vendor/`, installs the dependency tree once per platform via
|
|
|
|
|
+`uv pip install --python-platform …`, splits the result with `vendor_split.py`,
|
|
|
|
|
+and verifies that `import chattolib` works on the machine you ran it on.
|
|
|
|
|
+Afterwards: `git add vendor/`.
|
|
|
|
|
|
|
|
-The vendored chattolib is licensed under **MPL-2.0 + Apache-2.0** (see `chattolib/LICENSE`).
|
|
|
|
|
-The original source is available at: https://github.com/chattocorp/chatto
|
|
|
|
|
|
|
+### Supported platform tags
|
|
|
|
|
|
|
|
-## Manual Vendoring (Alternative)
|
|
|
|
|
|
|
+| Tag | uv `--python-platform` | vendored by default |
|
|
|
|
|
+| -------------------- | ------------------------------ | ------------------- |
|
|
|
|
|
+| `linux-x86_64` | `x86_64-unknown-linux-gnu` | ✅ |
|
|
|
|
|
+| `linux-aarch64` | `aarch64-unknown-linux-gnu` | ✅ |
|
|
|
|
|
+| `macos-arm64` | `aarch64-apple-darwin` | ✅ |
|
|
|
|
|
+| `linux-x86_64-musl` | `x86_64-unknown-linux-musl` | — |
|
|
|
|
|
+| `linux-aarch64-musl` | `aarch64-unknown-linux-musl` | — |
|
|
|
|
|
+| `macos-x86_64` | `x86_64-apple-darwin` | — |
|
|
|
|
|
+| `windows-amd64` | `x86_64-pc-windows-msvc` | — |
|
|
|
|
|
|
|
|
-If the script doesn't work for your environment:
|
|
|
|
|
|
|
+All seven are available as binary wheels upstream; only the default three are
|
|
|
|
|
+committed, to keep the repository at a reasonable size (~59 MB for `vendor/`).
|
|
|
|
|
+
|
|
|
|
|
+### Python versions
|
|
|
|
|
+
|
|
|
|
|
+The script resolves wheels for **Python 3.11** (`PYTHON_VERSION`), which is the
|
|
|
|
|
+project minimum. At that version the three binary packages still provide
|
|
|
|
|
+`cp310-abi3` wheels, and the stable ABI is forward compatible — so one build
|
|
|
|
|
+covers 3.11 through 3.14. Resolving for 3.12+ would instead pull
|
|
|
|
|
+version-specific wheels (`cp312-…`) that only work on that exact version.
|
|
|
|
|
+
|
|
|
|
|
+**If you raise `PYTHON_VERSION`, check that the resulting `.so` files are still
|
|
|
|
|
+named `*.abi3.so`.** If they are not, the vendored tree silently becomes
|
|
|
|
|
+Python-version-specific.
|
|
|
|
|
+
|
|
|
|
|
+## Development without vendoring
|
|
|
|
|
|
|
|
```bash
|
|
```bash
|
|
|
-# Create directory
|
|
|
|
|
-mkdir -p chattolib_vendor
|
|
|
|
|
-
|
|
|
|
|
-# Download and extract chattolib
|
|
|
|
|
-pip download chattolib==0.4.19 --no-deps -d /tmp
|
|
|
|
|
-cd /tmp
|
|
|
|
|
-unzip chattolib-*.whl -d chattolib_extracted
|
|
|
|
|
-cp -r chattolib_extracted/chattolib* ../chattolib_vendor/
|
|
|
|
|
-
|
|
|
|
|
-# Download websockets
|
|
|
|
|
-pip download websockets -d /tmp
|
|
|
|
|
-cd /tmp
|
|
|
|
|
-unzip websockets-*.whl -d websockets_extracted
|
|
|
|
|
-mkdir -p ../chattolib_vendor/websockets
|
|
|
|
|
-cp -r websockets_extracted/websockets* ../chattolib_vendor/websockets/
|
|
|
|
|
-
|
|
|
|
|
-# Add __init__.py
|
|
|
|
|
-echo "# Vendored chattolib" > chattolib_vendor/__init__.py
|
|
|
|
|
|
|
+pip install chattolib
|
|
|
```
|
|
```
|
|
|
|
|
+
|
|
|
|
|
+A system-installed chattolib is only used if `vendor/` is absent — the vendored
|
|
|
|
|
+copy is deliberately prepended to `sys.path` and therefore wins.
|
|
|
|
|
+
|
|
|
|
|
+## License
|
|
|
|
|
+
|
|
|
|
|
+The vendored chattolib is licensed under **MPL-2.0 + Apache-2.0** (see
|
|
|
|
|
+`vendor/common/chattolib-*.dist-info/`). Upstream source:
|
|
|
|
|
+https://github.com/chattocorp/chatto
|