bump_version.py
1 #!/usr/bin/env python3 2 """ 3 Automatic version bumping for Kamaji. 4 5 Usage: 6 python bump_version.py patch # 0.1.0 -> 0.1.1 7 python bump_version.py minor # 0.1.0 -> 0.2.0 8 python bump_version.py major # 0.1.0 -> 1.0.0 9 """ 10 11 import re 12 import sys 13 from pathlib import Path 14 15 16 def get_current_version(): 17 """Read current version from setup.py.""" 18 setup_file = Path(__file__).parent / "setup.py" 19 20 with open(setup_file, 'r') as f: 21 content = f.read() 22 23 match = re.search(r'version=["\']([^"\']+)["\']', content) 24 if match: 25 return match.group(1) 26 27 raise ValueError("Could not find version in setup.py") 28 29 30 def parse_version(version_str): 31 """Parse version string into (major, minor, patch).""" 32 parts = version_str.split('.') 33 if len(parts) != 3: 34 raise ValueError(f"Invalid version format: {version_str}") 35 36 return tuple(int(p) for p in parts) 37 38 39 def bump_version(current, bump_type): 40 """Bump version based on type (major, minor, patch).""" 41 major, minor, patch = parse_version(current) 42 43 if bump_type == "major": 44 return f"{major + 1}.0.0" 45 elif bump_type == "minor": 46 return f"{major}.{minor + 1}.0" 47 elif bump_type == "patch": 48 return f"{major}.{minor}.{patch + 1}" 49 else: 50 raise ValueError(f"Invalid bump type: {bump_type}") 51 52 53 def update_version_in_file(file_path, old_version, new_version): 54 """Update version in a file.""" 55 with open(file_path, 'r') as f: 56 content = f.read() 57 58 # Replace version string 59 updated = content.replace( 60 f'version="{old_version}"', 61 f'version="{new_version}"' 62 ).replace( 63 f"version='{old_version}'", 64 f"version='{new_version}'" 65 ).replace( 66 f'__version__ = "{old_version}"', 67 f'__version__ = "{new_version}"' 68 ).replace( 69 f"__version__ = '{old_version}'", 70 f"__version__ = '{new_version}'" 71 ) 72 73 with open(file_path, 'w') as f: 74 f.write(updated) 75 76 print(f"ā Updated {file_path.name}: {old_version} ā {new_version}") 77 78 79 def main(): 80 if len(sys.argv) != 2: 81 print("Usage: python bump_version.py [major|minor|patch]") 82 sys.exit(1) 83 84 bump_type = sys.argv[1].lower() 85 if bump_type not in ["major", "minor", "patch"]: 86 print("Error: bump type must be major, minor, or patch") 87 sys.exit(1) 88 89 # Get current version 90 current_version = get_current_version() 91 print(f"š¦ Current version: {current_version}") 92 93 # Calculate new version 94 new_version = bump_version(current_version, bump_type) 95 print(f"š New version: {new_version}") 96 97 # Update files 98 project_root = Path(__file__).parent 99 100 files_to_update = [ 101 project_root / "setup.py", 102 project_root / "kamaji" / "__init__.py", 103 ] 104 105 for file_path in files_to_update: 106 if file_path.exists(): 107 update_version_in_file(file_path, current_version, new_version) 108 else: 109 print(f"ā ļø File not found: {file_path}") 110 111 print(f"\n⨠Version bumped from {current_version} to {new_version}") 112 print("\nš Next steps:") 113 print(f" git add -A") 114 print(f' git commit -m "Bump version to {new_version}"') 115 print(f" git tag v{new_version}") 116 print(f" git push && git push --tags") 117 118 119 if __name__ == "__main__": 120 main()