155 lines
4.5 KiB
Python
Executable File
155 lines
4.5 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
# Sunday Comics - Version bump script
|
|
# Copyright (c) 2025 Tomasita Cabrera
|
|
# Licensed under the MIT License - see LICENSE file for details
|
|
|
|
"""
|
|
Script to bump the project version number
|
|
|
|
Usage:
|
|
python scripts/bump_version.py # Use today's date
|
|
python scripts/bump_version.py 2025.12.25 # Use specific date
|
|
"""
|
|
import sys
|
|
import os
|
|
import re
|
|
from datetime import datetime
|
|
import argparse
|
|
|
|
|
|
def validate_version(version_str):
|
|
"""Validate version format (YYYY.MM.DD)"""
|
|
pattern = r'^\d{4}\.\d{2}\.\d{2}$'
|
|
if not re.match(pattern, version_str):
|
|
return False
|
|
|
|
# Try to parse as a date to ensure it's valid
|
|
try:
|
|
parts = version_str.split('.')
|
|
year, month, day = int(parts[0]), int(parts[1]), int(parts[2])
|
|
datetime(year, month, day)
|
|
return True
|
|
except ValueError:
|
|
return False
|
|
|
|
|
|
def get_current_version(parent_dir):
|
|
"""Read current version from version.py"""
|
|
version_file = os.path.join(parent_dir, 'version.py')
|
|
try:
|
|
with open(version_file, 'r', encoding='utf-8') as f:
|
|
content = f.read()
|
|
match = re.search(r'__version__\s*=\s*["\']([^"\']+)["\']', content)
|
|
if match:
|
|
return match.group(1)
|
|
except FileNotFoundError:
|
|
pass
|
|
return None
|
|
|
|
|
|
def update_version_py(parent_dir, new_version):
|
|
"""Update version.py with new version"""
|
|
version_file = os.path.join(parent_dir, 'version.py')
|
|
|
|
content = f"""# Sunday Comics Version
|
|
# This file contains the version number for the project
|
|
# Format: YYYY.MM.DD (date-based versioning)
|
|
|
|
__version__ = "{new_version}"
|
|
"""
|
|
|
|
with open(version_file, 'w', encoding='utf-8') as f:
|
|
f.write(content)
|
|
|
|
print(f"✓ Updated {version_file}")
|
|
|
|
|
|
def update_version_file(parent_dir, new_version):
|
|
"""Update VERSION file with new version"""
|
|
version_file = os.path.join(parent_dir, 'VERSION')
|
|
|
|
with open(version_file, 'w', encoding='utf-8') as f:
|
|
f.write(f"{new_version}\n")
|
|
|
|
print(f"✓ Updated {version_file}")
|
|
|
|
|
|
def remind_changelog(parent_dir, new_version, current_version):
|
|
"""Remind user to update CHANGELOG.md"""
|
|
changelog_file = os.path.join(parent_dir, 'CHANGELOG.md')
|
|
|
|
print(f"\n📝 Don't forget to update {changelog_file}!")
|
|
print(f"\nAdd your changes under the new version section:")
|
|
print(f"\n## [{new_version}] - {datetime.now().strftime('%Y-%m-%d')}")
|
|
print(f"\n### Added")
|
|
print(f"### Changed")
|
|
print(f"### Fixed")
|
|
|
|
if os.path.exists(changelog_file):
|
|
print(f"\n💡 Tip: Edit the file now with: nano {changelog_file}")
|
|
|
|
|
|
def main():
|
|
parser = argparse.ArgumentParser(
|
|
description='Bump project version number',
|
|
epilog='Examples:\n %(prog)s\n %(prog)s 2025.12.25',
|
|
formatter_class=argparse.RawDescriptionHelpFormatter
|
|
)
|
|
parser.add_argument(
|
|
'version',
|
|
nargs='?',
|
|
help='Version number in YYYY.MM.DD format (defaults to today\'s date)'
|
|
)
|
|
parser.add_argument(
|
|
'--no-changelog-reminder',
|
|
action='store_true',
|
|
help='Skip the changelog reminder'
|
|
)
|
|
|
|
args = parser.parse_args()
|
|
|
|
# Determine new version
|
|
if args.version:
|
|
new_version = args.version
|
|
if not validate_version(new_version):
|
|
print(f"Error: Invalid version format '{new_version}'")
|
|
print(f"Expected format: YYYY.MM.DD (e.g., 2025.12.25)")
|
|
sys.exit(1)
|
|
else:
|
|
# Use today's date
|
|
new_version = datetime.now().strftime('%Y.%m.%d')
|
|
|
|
# Get parent directory (project root)
|
|
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
|
|
|
# Get current version
|
|
current_version = get_current_version(parent_dir)
|
|
|
|
if current_version:
|
|
print(f"Current version: {current_version}")
|
|
|
|
print(f"New version: {new_version}")
|
|
|
|
# Check if version is the same
|
|
if current_version == new_version:
|
|
print(f"\n⚠️ Version is already {new_version}")
|
|
response = input("Continue anyway? [y/N]: ").lower().strip()
|
|
if response != 'y':
|
|
print("Aborted.")
|
|
sys.exit(0)
|
|
|
|
# Update files
|
|
print(f"\nUpdating version files...")
|
|
update_version_py(parent_dir, new_version)
|
|
update_version_file(parent_dir, new_version)
|
|
|
|
print(f"\n✅ Version bumped to {new_version}")
|
|
|
|
# Remind about changelog
|
|
if not args.no_changelog_reminder:
|
|
remind_changelog(parent_dir, new_version, current_version)
|
|
|
|
|
|
if __name__ == '__main__':
|
|
main()
|