webdrop-bridge/scripts/sync_version.py

152 lines
4.5 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""Sync version from __init__.py to changelog.
This script reads the version from src/webdrop_bridge/__init__.py and
updates the CHANGELOG.md. Config and pyproject.toml automatically read
from __init__.py, so no manual sync needed for those files.
This script uses shared version utilities (build/scripts/version_utils.py)
to ensure consistent version reading across all build scripts.
Usage:
python scripts/sync_version.py [--version VERSION]
Examples:
python scripts/sync_version.py # Use version from __init__.py
python scripts/sync_version.py --version 2.0.0 # Override with new version
"""
import argparse
import re
import sys
from datetime import datetime
from pathlib import Path
# Import shared version utilities
sys.path.insert(0, str(Path(__file__).parent.parent / "build" / "scripts"))
from version_utils import get_current_version, get_project_root
PROJECT_ROOT = get_project_root()
def get_current_version_from_init() -> str:
"""Get version from __init__.py using shared utility.
Returns:
Current version string from __init__.py
Raises:
ValueError: If __version__ cannot be found
"""
return get_current_version()
def update_init_version(version: str) -> None:
"""Update version in __init__.py.
Args:
version: New version string to set
"""
init_file = PROJECT_ROOT / "src/webdrop_bridge/__init__.py"
content = init_file.read_text()
new_content = re.sub(
r'__version__\s*=\s*["\'][^"\']+["\']',
f'__version__ = "{version}"',
content,
)
init_file.write_text(new_content)
print(f"✓ Updated src/webdrop_bridge/__init__.py to {version}")
def update_env_example(version: str) -> None:
"""Update APP_VERSION in .env.example (optional).
Note: config.py now reads from __init__.py by default.
Only update if .env.example explicitly sets APP_VERSION for testing.
Args:
version: New version string to set
"""
env_file = PROJECT_ROOT / ".env.example"
if env_file.exists():
content = env_file.read_text()
# Only update if APP_VERSION is explicitly set
if 'APP_VERSION=' in content:
new_content = re.sub(
r'APP_VERSION=[^\n]+',
f'APP_VERSION={version}',
content,
)
env_file.write_text(new_content)
print(f"✓ Updated .env.example to {version}")
else:
print(
f" .env.example does not override APP_VERSION "
f"(uses __init__.py)"
)
def update_changelog(version: str) -> None:
"""Add version header to CHANGELOG.md if not present.
Args:
version: New version string to add
"""
changelog = PROJECT_ROOT / "CHANGELOG.md"
if changelog.exists():
content = changelog.read_text()
if f"## [{version}]" not in content and f"## {version}" not in content:
date_str = datetime.now().strftime("%Y-%m-%d")
header = (
f"## [{version}] - {date_str}\n\n"
"### Added\n\n### Changed\n\n### Fixed\n\n"
)
new_content = header + content
changelog.write_text(new_content)
print(f"✓ Added version header to CHANGELOG.md for {version}")
def main() -> int:
"""Sync version across project.
Updates __init__.py (source of truth) and changelog.
Config and pyproject.toml automatically read from __init__.py.
Returns:
0 on success, 1 on error
"""
parser = argparse.ArgumentParser(
description="Sync version from __init__.py to dependent files"
)
parser.add_argument(
"--version",
type=str,
help="Version to set (if not provided, reads from __init__.py)",
)
args = parser.parse_args()
try:
if args.version:
if not re.match(r"^\d+\.\d+\.\d+", args.version):
print(
"❌ Invalid version format. Use semantic versioning"
" (e.g., 1.2.3)"
)
return 1
version = args.version
update_init_version(version)
else:
version = get_current_version_from_init()
print(f"📍 Current version from __init__.py: {version}")
update_env_example(version)
update_changelog(version)
print(f"\n✅ Version sync complete: {version}")
return 0
except Exception as e:
print(f"❌ Error: {e}")
return 1
if __name__ == "__main__":
sys.exit(main())