184 lines
7.0 KiB
Python
Executable File
184 lines
7.0 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
"""
|
|
Version synchronization script for Text Texture Generator.
|
|
Updates version information from git tags across all template files.
|
|
"""
|
|
|
|
import os
|
|
import sys
|
|
import json
|
|
import re
|
|
import subprocess
|
|
from pathlib import Path
|
|
from typing import Dict, Tuple, Optional
|
|
|
|
def get_project_root() -> Path:
|
|
"""Get the project root directory."""
|
|
return Path(__file__).parent.parent
|
|
|
|
def load_config() -> Dict:
|
|
"""Load build configuration."""
|
|
config_path = get_project_root() / "build" / "config.json"
|
|
with open(config_path, 'r') as f:
|
|
return json.load(f)
|
|
|
|
def get_latest_git_tag() -> Optional[str]:
|
|
"""Get the latest git tag that matches the version pattern."""
|
|
try:
|
|
# Get all tags sorted by version
|
|
result = subprocess.run(['git', 'tag', '-l', '--sort=-version:refname'],
|
|
capture_output=True, text=True, check=True)
|
|
tags = result.stdout.strip().split('\n')
|
|
|
|
config = load_config()
|
|
pattern = config['versions']['git_tag_pattern']
|
|
version_regex = re.compile(pattern)
|
|
|
|
for tag in tags:
|
|
if version_regex.match(tag):
|
|
# Extract version number, removing 'v' prefix if present
|
|
match = version_regex.match(tag)
|
|
return match.group(1) if match else None
|
|
|
|
return None
|
|
except subprocess.CalledProcessError:
|
|
print("Warning: Could not get git tags. Using fallback version.")
|
|
return None
|
|
|
|
def get_version_info(version_string: str) -> Tuple[str, int, int, int]:
|
|
"""Parse version string into components."""
|
|
parts = version_string.split('.')
|
|
if len(parts) != 3:
|
|
raise ValueError(f"Invalid version format: {version_string}")
|
|
|
|
major, minor, patch = map(int, parts)
|
|
return version_string, major, minor, patch
|
|
|
|
def create_template_variables(config: Dict, version: str, version_type: str = "full") -> Dict[str, str]:
|
|
"""Create template variables for file generation."""
|
|
version_str, major, minor, patch = get_version_info(version)
|
|
|
|
# Load exclusions configuration for version limits
|
|
exclusions_path = get_project_root() / "build" / "file_exclusions.json"
|
|
with open(exclusions_path, 'r') as f:
|
|
exclusions_config = json.load(f)
|
|
|
|
# Get version-specific configuration
|
|
version_config = exclusions_config['version_configs'][version_type]
|
|
|
|
# Parse Blender version
|
|
blender_version = config['project']['blender_version_min']
|
|
blender_parts = blender_version.split('.')
|
|
blender_major, blender_minor = int(blender_parts[0]), int(blender_parts[1])
|
|
blender_patch = int(blender_parts[2]) if len(blender_parts) > 2 else 0
|
|
|
|
# Format dependencies for TOML
|
|
deps = []
|
|
for dep, version_spec in config['dependencies'].items():
|
|
deps.append(f'{dep} = "{version_spec}"')
|
|
dependencies_str = '\n'.join(deps)
|
|
|
|
variables = {
|
|
'PROJECT_ID': config['project']['id'],
|
|
'PROJECT_NAME': config['project']['name'],
|
|
'PROJECT_AUTHOR': config['project']['author'],
|
|
'PROJECT_DESCRIPTION': config['project']['description'],
|
|
'PROJECT_CATEGORY': config['project']['category'],
|
|
'PROJECT_LOCATION': config['project']['location'],
|
|
'PROJECT_SUPPORT': config['project']['support'],
|
|
'PROJECT_TAGS': json.dumps(config['project']['tags']),
|
|
'PROJECT_LICENSE': json.dumps(config['project']['license']),
|
|
'VERSION': version_str,
|
|
'VERSION_MAJOR': str(major),
|
|
'VERSION_MINOR': str(minor),
|
|
'VERSION_PATCH': str(patch),
|
|
'VERSION_TYPE': version_type,
|
|
'BLENDER_VERSION_MIN': blender_version,
|
|
'BLENDER_VERSION_MAJOR': str(blender_major),
|
|
'BLENDER_VERSION_MINOR': str(blender_minor),
|
|
'BLENDER_VERSION_PATCH': str(blender_patch),
|
|
'DEPENDENCIES': dependencies_str,
|
|
'MAX_TEXTURE_SIZE': str(version_config['max_texture_size']),
|
|
'MAX_CONCURRENT_OPERATIONS': str(version_config['max_concurrent_operations'])
|
|
}
|
|
|
|
return variables
|
|
|
|
def process_template(template_path: Path, output_path: Path, variables: Dict[str, str]):
|
|
"""Process a template file and write the output."""
|
|
print(f"Processing template: {template_path} -> {output_path}")
|
|
|
|
# Read template
|
|
with open(template_path, 'r') as f:
|
|
content = f.read()
|
|
|
|
# Replace variables
|
|
for key, value in variables.items():
|
|
content = content.replace(f'{{{{{key}}}}}', value)
|
|
|
|
# Ensure output directory exists
|
|
output_path.parent.mkdir(parents=True, exist_ok=True)
|
|
|
|
# Write output
|
|
with open(output_path, 'w') as f:
|
|
f.write(content)
|
|
|
|
print(f"Generated: {output_path}")
|
|
|
|
def sync_version(version: Optional[str] = None, version_type: str = "full"):
|
|
"""Synchronize version across all template files."""
|
|
config = load_config()
|
|
|
|
# Get version from git tag if not provided
|
|
if version is None:
|
|
version = get_latest_git_tag()
|
|
if version is None:
|
|
print("Warning: No valid git tag found. Using version from current blender_manifest.toml")
|
|
# Fallback to current version
|
|
manifest_path = get_project_root() / "src" / "blender_manifest.toml"
|
|
if manifest_path.exists():
|
|
with open(manifest_path, 'r') as f:
|
|
for line in f:
|
|
if line.startswith('version = '):
|
|
version = line.split('=')[1].strip().strip('"')
|
|
break
|
|
if version is None:
|
|
version = "1.0.0" # Ultimate fallback
|
|
|
|
print(f"Synchronizing version: {version} (type: {version_type})")
|
|
|
|
# Create template variables
|
|
variables = create_template_variables(config, version, version_type)
|
|
|
|
# Process each template file
|
|
templates_dir = get_project_root() / "build" / "templates"
|
|
for template_file in templates_dir.glob("*.template"):
|
|
# Determine output path
|
|
relative_name = template_file.stem # Remove .template extension
|
|
if relative_name == "blender_manifest.toml":
|
|
output_path = get_project_root() / "src" / relative_name
|
|
elif relative_name == "constants.py":
|
|
output_path = get_project_root() / "src" / "utils" / relative_name
|
|
else:
|
|
# For other templates, maintain directory structure
|
|
output_path = get_project_root() / "src" / relative_name
|
|
|
|
process_template(template_file, output_path, variables)
|
|
|
|
print(f"Version synchronization complete: {version}")
|
|
|
|
if __name__ == "__main__":
|
|
import argparse
|
|
|
|
parser = argparse.ArgumentParser(description="Synchronize version information")
|
|
parser.add_argument("--version", help="Version to set (defaults to latest git tag)")
|
|
parser.add_argument("--type", choices=["free", "full"], default="full",
|
|
help="Version type (free or full)")
|
|
|
|
args = parser.parse_args()
|
|
|
|
try:
|
|
sync_version(args.version, args.type)
|
|
except Exception as e:
|
|
print(f"Error: {e}")
|
|
sys.exit(1) |