0.1.0
This commit is contained in:
9
scripts/build-backend.js
Executable file
9
scripts/build-backend.js
Executable file
@@ -0,0 +1,9 @@
|
||||
#!/usr/bin/env node
|
||||
|
||||
const { execSync } = require("child_process");
|
||||
try {
|
||||
execSync(`poetry run python cx_setup.py build`, { stdio: "inherit" });
|
||||
} catch (error) {
|
||||
console.error("Build failed:", error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
13
scripts/move_wheels.py
Normal file
13
scripts/move_wheels.py
Normal file
@@ -0,0 +1,13 @@
|
||||
"""Move Poetry-built wheels from dist/ to python-dist/ to avoid conflicts
|
||||
with Electron build artifacts.
|
||||
"""
|
||||
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
dist = Path("dist")
|
||||
target = Path("python-dist")
|
||||
target.mkdir(parents=True, exist_ok=True)
|
||||
|
||||
for wheel in dist.glob("*.whl"):
|
||||
shutil.move(str(wheel), target / wheel.name)
|
||||
16
scripts/prepare_frontend_dir.py
Normal file
16
scripts/prepare_frontend_dir.py
Normal file
@@ -0,0 +1,16 @@
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
TARGET = Path("meshchatx") / "public"
|
||||
|
||||
if not Path("pyproject.toml").exists():
|
||||
msg = "Must run from project root"
|
||||
raise RuntimeError(msg)
|
||||
|
||||
if TARGET.exists():
|
||||
if TARGET.is_symlink():
|
||||
msg = f"{TARGET} is a symlink, refusing to remove"
|
||||
raise RuntimeError(msg)
|
||||
shutil.rmtree(TARGET)
|
||||
|
||||
TARGET.mkdir(parents=True, exist_ok=True)
|
||||
21
scripts/rename_legacy_artifacts.sh
Executable file
21
scripts/rename_legacy_artifacts.sh
Executable file
@@ -0,0 +1,21 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
shopt -s nullglob
|
||||
|
||||
patterns=(
|
||||
"dist/*-win-installer.exe"
|
||||
"dist/*-win-portable.exe"
|
||||
"dist/*-linux.AppImage"
|
||||
"dist/*-linux.deb"
|
||||
)
|
||||
|
||||
for pattern in "${patterns[@]}"; do
|
||||
for f in $pattern; do
|
||||
dir=$(dirname "$f")
|
||||
base=$(basename "$f")
|
||||
ext="${base##*.}"
|
||||
name="${base%.$ext}"
|
||||
mv "$f" "$dir/${name}-legacy.${ext}"
|
||||
done
|
||||
done
|
||||
65
scripts/sync_version.py
Normal file
65
scripts/sync_version.py
Normal file
@@ -0,0 +1,65 @@
|
||||
"""Update project version references to stay aligned with the Electron build.
|
||||
|
||||
Reads `package.json`, writes the same version into `src/version.py`, and
|
||||
updates the `[tool.poetry] version` field inside `pyproject.toml`. Run this
|
||||
before any Python packaging commands so the wheel version matches the
|
||||
Electron artifacts.
|
||||
"""
|
||||
|
||||
import json
|
||||
import re
|
||||
from pathlib import Path
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[1]
|
||||
PACKAGE_JSON = ROOT / "package.json"
|
||||
VERSION_PY = ROOT / "meshchatx" / "src" / "version.py"
|
||||
PYPROJECT_TOML = ROOT / "pyproject.toml"
|
||||
|
||||
|
||||
def read_package_version() -> str:
|
||||
with PACKAGE_JSON.open() as handle:
|
||||
return json.load(handle)["version"]
|
||||
|
||||
|
||||
def write_version_module(version: str) -> None:
|
||||
content = (
|
||||
'"""\n'
|
||||
"Auto-generated helper so Python tooling and the Electron build\n"
|
||||
"share the same version string.\n"
|
||||
'"""\n\n'
|
||||
f"__version__ = {version!r}\n"
|
||||
)
|
||||
if VERSION_PY.exists() and VERSION_PY.read_text() == content:
|
||||
return
|
||||
VERSION_PY.write_text(content)
|
||||
|
||||
|
||||
def update_poetry_version(version: str) -> None:
|
||||
if not PYPROJECT_TOML.exists():
|
||||
return
|
||||
content = PYPROJECT_TOML.read_text()
|
||||
|
||||
def replacer(match):
|
||||
return f"{match.group(1)}{version}{match.group(2)}"
|
||||
|
||||
new_content, replaced = re.subn(
|
||||
r'(?m)^(version\s*=\s*")[^"]*(")',
|
||||
replacer,
|
||||
content,
|
||||
count=1,
|
||||
)
|
||||
if replaced == 0:
|
||||
msg = "failed to update version in pyproject.toml"
|
||||
raise RuntimeError(msg)
|
||||
if new_content != content:
|
||||
PYPROJECT_TOML.write_text(new_content)
|
||||
|
||||
|
||||
def main() -> None:
|
||||
version = read_package_version()
|
||||
write_version_module(version)
|
||||
update_poetry_version(version)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
74
scripts/test_wheel.sh
Executable file
74
scripts/test_wheel.sh
Executable file
@@ -0,0 +1,74 @@
|
||||
#!/bin/bash
|
||||
set -e
|
||||
|
||||
# Find wheel file dynamically
|
||||
WHEEL_PATTERN="python-dist/reticulum_meshchatx-*-py3-none-any.whl"
|
||||
WHEEL_FILES=($WHEEL_PATTERN)
|
||||
|
||||
if [ ${#WHEEL_FILES[@]} -eq 0 ]; then
|
||||
echo "Error: No wheel files found matching pattern: $WHEEL_PATTERN"
|
||||
echo "Make sure to run 'poetry build' or similar to create the wheel first."
|
||||
exit 1
|
||||
elif [ ${#WHEEL_FILES[@]} -gt 1 ]; then
|
||||
echo "Error: Multiple wheel files found:"
|
||||
printf ' %s\n' "${WHEEL_FILES[@]}"
|
||||
echo "Please clean up old wheels or specify which one to use."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
WHEEL_PATH="${WHEEL_FILES[0]}"
|
||||
|
||||
if [ ! -f "$WHEEL_PATH" ]; then
|
||||
echo "Error: Wheel not found at $WHEEL_PATH"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo "Found wheel: $WHEEL_PATH"
|
||||
|
||||
echo "Creating test virtual environment..."
|
||||
TEST_VENV=$(mktemp -d)/test-venv
|
||||
python3 -m venv "$TEST_VENV"
|
||||
|
||||
echo "Installing wheel..."
|
||||
"$TEST_VENV/bin/pip" install --upgrade pip
|
||||
"$TEST_VENV/bin/pip" install "$WHEEL_PATH"
|
||||
|
||||
echo ""
|
||||
echo "Checking installation..."
|
||||
"$TEST_VENV/bin/python" << 'PYTHON_SCRIPT'
|
||||
import meshchatx.meshchat as meshchat
|
||||
import os
|
||||
from pathlib import Path
|
||||
|
||||
# Check if meshchat module is importable
|
||||
print(f'meshchat module location: {meshchat.__file__}')
|
||||
|
||||
# Check if public directory exists
|
||||
meshchat_dir = os.path.dirname(meshchat.__file__)
|
||||
public_path = os.path.join(meshchat_dir, 'public')
|
||||
print(f'Checking for public at: {public_path}')
|
||||
print(f'Exists: {os.path.exists(public_path)}')
|
||||
|
||||
# Try get_file_path
|
||||
from meshchatx.meshchat import get_file_path
|
||||
test_path = get_file_path('public')
|
||||
print(f'get_file_path("public"): {test_path}')
|
||||
print(f'Exists: {os.path.exists(test_path)}')
|
||||
|
||||
if os.path.exists(test_path):
|
||||
index_html = os.path.join(test_path, 'index.html')
|
||||
print(f'index.html exists: {os.path.exists(index_html)}')
|
||||
else:
|
||||
print('WARNING: public directory not found!')
|
||||
print('Checking parent directories...')
|
||||
current = meshchat_dir
|
||||
for i in range(3):
|
||||
test = os.path.join(current, 'public')
|
||||
print(f' {test}: {os.path.exists(test)}')
|
||||
current = os.path.dirname(current)
|
||||
PYTHON_SCRIPT
|
||||
|
||||
echo ""
|
||||
echo "Test complete. Virtual environment at: $TEST_VENV"
|
||||
echo "To test running meshchat: $TEST_VENV/bin/meshchat --help"
|
||||
|
||||
Reference in New Issue
Block a user