from typing import Optional, Dict, Union import re from datetime import datetime from sqlalchemy.orm import Session from models.version import Version from schemas.version import VersionCreate, VersionUpdate def validate_version_number(version_number: str) -> bool: """ Validate version number format (e.g., 1.0.0, 2.1.3) Args: version_number: Version number string to validate Returns: bool: True if version format is valid, False otherwise """ pattern = r'^\d+\.\d+\.\d+$' return bool(re.match(pattern, version_number)) def parse_version_components(version_number: str) -> Dict[str, int]: """ Parse version number into major, minor and patch components Args: version_number: Version number string (e.g. '1.2.3') Returns: Dict containing major, minor and patch numbers """ major, minor, patch = version_number.split('.') return { 'major': int(major), 'minor': int(minor), 'patch': int(patch) } def compare_versions(version1: str, version2: str) -> int: """ Compare two version numbers Args: version1: First version number version2: Second version number Returns: 1 if version1 > version2 -1 if version1 < version2 0 if version1 == version2 """ v1_components = parse_version_components(version1) v2_components = parse_version_components(version2) for component in ['major', 'minor', 'patch']: if v1_components[component] > v2_components[component]: return 1 elif v1_components[component] < v2_components[component]: return -1 return 0 def get_latest_version(db: Session) -> Optional[Version]: """ Get the latest version from database Args: db: Database session Returns: Latest Version object if exists, None otherwise """ return db.query(Version).order_by(Version.version_number.desc()).first() def create_version_safely(db: Session, version_data: VersionCreate) -> Union[Version, Dict[str, str]]: """ Create a new version with validation and error handling Args: db: Database session version_data: Version data for creation Returns: Version object if created successfully, error dict otherwise """ if not validate_version_number(version_data.version_number): return {"error": "Invalid version number format"} existing_version = db.query(Version).filter( Version.version_number == version_data.version_number ).first() if existing_version: return {"error": "Version already exists"} db_version = Version( version_number=version_data.version_number, description=version_data.description ) db.add(db_version) db.commit() db.refresh(db_version) return db_version def increment_version(current_version: str, increment_type: str = 'patch') -> str: """ Increment version number based on semantic versioning Args: current_version: Current version number increment_type: Type of increment ('major', 'minor', or 'patch') Returns: New version number """ components = parse_version_components(current_version) if increment_type == 'major': components['major'] += 1 components['minor'] = 0 components['patch'] = 0 elif increment_type == 'minor': components['minor'] += 1 components['patch'] = 0 else: # patch components['patch'] += 1 return f"{components['major']}.{components['minor']}.{components['patch']}"