Add version synchronization script
This script helps keep version numbers in sync between pyproject.toml and _version.py. It can check sync status, update _version.py to match pyproject.toml, or set both files to a new version. Usage: - python sync_version.py # Check sync status - python sync_version.py --update # Update _version.py to match pyproject.toml - python sync_version.py --set 1.0.2 # Set both versions to 1.0.2
This commit is contained in:
parent
3518a5afdf
commit
ac3c04e8d1
160
sync_version.py
Normal file
160
sync_version.py
Normal file
@ -0,0 +1,160 @@
|
||||
#!/usr/bin/env python3
|
||||
"""
|
||||
Version synchronization script for vultr-dns-mcp.
|
||||
|
||||
This script ensures that the version number in pyproject.toml
|
||||
and src/vultr_dns_mcp/_version.py are kept in sync.
|
||||
|
||||
Usage:
|
||||
python sync_version.py # Check if versions are in sync
|
||||
python sync_version.py --update # Update _version.py to match pyproject.toml
|
||||
python sync_version.py --set 1.0.2 # Set both versions to 1.0.2
|
||||
"""
|
||||
|
||||
import argparse
|
||||
import re
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
try:
|
||||
import tomllib
|
||||
except ImportError:
|
||||
try:
|
||||
import tomli as tomllib
|
||||
except ImportError:
|
||||
print("Error: tomllib or tomli not available. Install with: pip install tomli")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def get_version_from_pyproject() -> str:
|
||||
"""Get version from pyproject.toml."""
|
||||
pyproject_path = Path("pyproject.toml")
|
||||
if not pyproject_path.exists():
|
||||
raise FileNotFoundError("pyproject.toml not found")
|
||||
|
||||
with open(pyproject_path, "rb") as f:
|
||||
data = tomllib.load(f)
|
||||
|
||||
return data["project"]["version"]
|
||||
|
||||
|
||||
def get_version_from_version_py() -> str:
|
||||
"""Get version from _version.py."""
|
||||
version_path = Path("src/vultr_dns_mcp/_version.py")
|
||||
if not version_path.exists():
|
||||
raise FileNotFoundError("src/vultr_dns_mcp/_version.py not found")
|
||||
|
||||
with open(version_path, "r") as f:
|
||||
content = f.read()
|
||||
|
||||
match = re.search(r'__version__\s*=\s*["\']([^"\']+)["\']', content)
|
||||
if not match:
|
||||
raise ValueError("Could not find __version__ in _version.py")
|
||||
|
||||
return match.group(1)
|
||||
|
||||
|
||||
def update_version_py(new_version: str) -> None:
|
||||
"""Update version in _version.py."""
|
||||
version_path = Path("src/vultr_dns_mcp/_version.py")
|
||||
|
||||
content = f'''"""Version information for vultr-dns-mcp package."""
|
||||
|
||||
__version__ = "{new_version}"
|
||||
__version_info__ = tuple(int(i) for i in __version__.split(".") if i.isdigit())
|
||||
'''
|
||||
|
||||
with open(version_path, "w") as f:
|
||||
f.write(content)
|
||||
|
||||
print(f"✅ Updated _version.py to {new_version}")
|
||||
|
||||
|
||||
def update_pyproject_toml(new_version: str) -> None:
|
||||
"""Update version in pyproject.toml."""
|
||||
pyproject_path = Path("pyproject.toml")
|
||||
|
||||
with open(pyproject_path, "r") as f:
|
||||
content = f.read()
|
||||
|
||||
# Replace version line
|
||||
pattern = r'(version\s*=\s*)["\'][^"\']+["\']'
|
||||
replacement = f'\\1"{new_version}"'
|
||||
new_content = re.sub(pattern, replacement, content)
|
||||
|
||||
with open(pyproject_path, "w") as f:
|
||||
f.write(new_content)
|
||||
|
||||
print(f"✅ Updated pyproject.toml to {new_version}")
|
||||
|
||||
|
||||
def check_versions() -> tuple[str, str, bool]:
|
||||
"""Check if versions are in sync."""
|
||||
try:
|
||||
pyproject_version = get_version_from_pyproject()
|
||||
version_py_version = get_version_from_version_py()
|
||||
|
||||
in_sync = pyproject_version == version_py_version
|
||||
|
||||
return pyproject_version, version_py_version, in_sync
|
||||
|
||||
except Exception as e:
|
||||
print(f"❌ Error reading versions: {e}")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
def validate_version(version: str) -> bool:
|
||||
"""Validate version format (basic semver check)."""
|
||||
pattern = r'^\d+\.\d+\.\d+(?:-[a-zA-Z0-9]+(?:\.\d+)?)?$'
|
||||
return bool(re.match(pattern, version))
|
||||
|
||||
|
||||
def main():
|
||||
parser = argparse.ArgumentParser(description="Sync version numbers between files")
|
||||
group = parser.add_mutually_exclusive_group()
|
||||
group.add_argument("--update", action="store_true",
|
||||
help="Update _version.py to match pyproject.toml")
|
||||
group.add_argument("--set", metavar="VERSION",
|
||||
help="Set both files to the specified version")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.set:
|
||||
if not validate_version(args.set):
|
||||
print(f"❌ Invalid version format: {args.set}")
|
||||
print("Expected format: X.Y.Z or X.Y.Z-suffix")
|
||||
sys.exit(1)
|
||||
|
||||
update_pyproject_toml(args.set)
|
||||
update_version_py(args.set)
|
||||
print(f"✅ Set both versions to {args.set}")
|
||||
|
||||
elif args.update:
|
||||
pyproject_version, version_py_version, in_sync = check_versions()
|
||||
|
||||
if in_sync:
|
||||
print(f"✅ Versions already in sync: {pyproject_version}")
|
||||
else:
|
||||
update_version_py(pyproject_version)
|
||||
print(f"✅ Updated _version.py from {version_py_version} to {pyproject_version}")
|
||||
|
||||
else:
|
||||
# Default: check status
|
||||
pyproject_version, version_py_version, in_sync = check_versions()
|
||||
|
||||
print("📋 Version Status:")
|
||||
print(f" pyproject.toml: {pyproject_version}")
|
||||
print(f" _version.py: {version_py_version}")
|
||||
|
||||
if in_sync:
|
||||
print("✅ Versions are in sync!")
|
||||
else:
|
||||
print("❌ Versions are out of sync!")
|
||||
print("\nTo fix:")
|
||||
print(" python sync_version.py --update # Update _version.py to match pyproject.toml")
|
||||
print(" python sync_version.py --set X.Y.Z # Set both to version X.Y.Z")
|
||||
sys.exit(1)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
Loading…
x
Reference in New Issue
Block a user