166 lines
5.2 KiB
Python
166 lines
5.2 KiB
Python
#!/usr/bin/env python3
|
|
import os
|
|
import re
|
|
import shutil
|
|
import sys
|
|
import yaml
|
|
|
|
def extract_version_from_string(input_string) -> dict:
|
|
"""
|
|
从字符串中提取版本号,支持镜像名和文件夹名
|
|
|
|
Args:
|
|
input_string (str): 可以是Docker镜像名或文件夹名
|
|
|
|
Returns:
|
|
dict: 包含提取结果的字典 {success: bool, version: str}
|
|
"""
|
|
if ':' in input_string:
|
|
parts = input_string.split(':')
|
|
candidate = parts[-1]
|
|
else:
|
|
candidate = os.path.basename(input_string)
|
|
|
|
# 保存原始候选字符串用于失败时返回
|
|
original_candidate = candidate
|
|
|
|
# 从复杂标签中提取包含数字和分隔符的版本号部分
|
|
pattern = r'(\d+(?:[\.\-]\d+)+)'
|
|
matches = re.findall(pattern, candidate)
|
|
if matches:
|
|
# 选择最长的匹配项,并统一分隔符为点号
|
|
best_match = max(matches, key=len)
|
|
normalized_version = re.sub(r'[\.\-]', '.', best_match)
|
|
return {"success": True, "version": normalized_version}
|
|
|
|
return {"success": False, "version": original_candidate}
|
|
|
|
def replace_version_in_dirname(old_ver_dir : str, new_version : str) -> str:
|
|
"""
|
|
将旧版本文件夹名中的版本号替换为新版本号
|
|
|
|
Args:
|
|
old_ver_dir (str): 旧版本文件夹名
|
|
new_version (str): 新版本号
|
|
|
|
Returns:
|
|
str: 新版本文件夹名
|
|
"""
|
|
version_info = extract_version_from_string(old_ver_dir)
|
|
|
|
if version_info["success"]:
|
|
old_version = version_info["version"]
|
|
new_ver_dir = old_ver_dir.replace(old_version, new_version)
|
|
return new_ver_dir
|
|
else:
|
|
return new_version
|
|
|
|
def check_directory_contents(check_dir):
|
|
print(f"{check_dir} 目录内容:")
|
|
for item in os.listdir(check_dir):
|
|
print(f" - {item}")
|
|
|
|
def safe_rename_directory(old_path: str, new_path: str) -> bool:
|
|
"""
|
|
安全地重命名目录,包含错误处理
|
|
|
|
Args:
|
|
old_path (str): 原目录路径
|
|
new_path (str): 新目录路径
|
|
|
|
Returns:
|
|
bool: 重命名是否成功
|
|
"""
|
|
try:
|
|
if not os.path.exists(old_path):
|
|
print(f"错误: 原目录不存在: {old_path}")
|
|
return False
|
|
|
|
if os.path.exists(new_path):
|
|
print(f"错误: 目标目录已存在: {new_path}")
|
|
return False
|
|
|
|
print(f"将 {old_path} 重命名为 {new_path}")
|
|
shutil.move(old_path, new_path)
|
|
|
|
# 验证重命名是否成功
|
|
if os.path.exists(new_path) and not os.path.exists(old_path):
|
|
check_directory_contents(new_path)
|
|
print(f"✓ 重命名成功")
|
|
return True
|
|
else:
|
|
print(f"✗ 重命名后验证失败")
|
|
return False
|
|
|
|
except PermissionError as e:
|
|
print(f"✗ 权限错误: {e}")
|
|
return False
|
|
except OSError as e:
|
|
print(f"✗ 系统错误: {e}")
|
|
return False
|
|
except Exception as e:
|
|
print(f"✗ 未知错误: {e}")
|
|
return False
|
|
|
|
def write_version_file(file_path: str, version: str) -> bool:
|
|
"""
|
|
写入版本标记文件
|
|
|
|
Args:
|
|
file_path (str): 版本标记文件路径
|
|
version (str): 版本号
|
|
|
|
Returns:
|
|
bool: 写入是否成功
|
|
"""
|
|
try:
|
|
os.makedirs(os.path.dirname(file_path), exist_ok=True)
|
|
with open(file_path, 'w') as f:
|
|
f.write(version)
|
|
print(f"✓ 版本标记文件已更新: {file_path}")
|
|
return True
|
|
except Exception as e:
|
|
print(f"✗ 写入版本标记文件失败: {e}")
|
|
return False
|
|
|
|
def main():
|
|
app_name = sys.argv[1]
|
|
old_ver_dir = sys.argv[2]
|
|
|
|
docker_compose_file = f"apps/{app_name}/{old_ver_dir}/docker-compose.yml"
|
|
|
|
if not os.path.exists(docker_compose_file):
|
|
print(f"错误: 文件 {docker_compose_file} 不存在")
|
|
sys.exit(1)
|
|
|
|
with open(docker_compose_file, 'r') as f:
|
|
compose_data = yaml.safe_load(f)
|
|
|
|
services = compose_data.get('services', {})
|
|
|
|
first_service = list(services.keys())[0]
|
|
print(f"第一个服务是: {first_service}")
|
|
|
|
image = services[first_service].get('image', '')
|
|
print(f"该服务的镜像: {image}")
|
|
|
|
new_version : str = extract_version_from_string(image).get("version", "latest")
|
|
old_version : str = extract_version_from_string(old_ver_dir).get("version", "latest")
|
|
print(f"旧版本号: {old_version}")
|
|
print(f"新版本号: {new_version}")
|
|
new_ver_dir = replace_version_in_dirname(old_ver_dir, new_version)
|
|
if old_version != new_version:
|
|
old_path = f"apps/{app_name}/{old_ver_dir}"
|
|
new_path = f"apps/{app_name}/{new_ver_dir}"
|
|
|
|
if safe_rename_directory(old_path, new_path):
|
|
# 更新版本标记文件
|
|
version_file = f"apps/{app_name}/{old_ver_dir}.version"
|
|
if not write_version_file(version_file, new_ver_dir):
|
|
print("版本标记文件更新失败,但目录重命名成功")
|
|
else:
|
|
print("错误: 目录重命名失败")
|
|
sys.exit(1)
|
|
|
|
if __name__ == "__main__":
|
|
main() |