import os import yaml import shutil from typing import Dict, Any def merge_yaml_files(root_dir: str) -> Dict[str, Any]: """合并所有 docker-compose 相关 YAML 文件内容""" # 初始化合并后的结构 merged = { 'services': {}, 'networks': {}, 'volumes': {} } yaml_files = [] # 1. 收集根目录下的 docker-compose.*.yaml(排除目标输出文件) for file in os.listdir(root_dir): if (file.startswith('docker-compose.') and file.endswith('.yaml') and file != 'docker-compose.yaml'): yaml_files.append(os.path.join(root_dir, file)) # 2. 收集 deploy/api 目录下的所有 docker-compose.*.yaml api_root = os.path.join(root_dir, 'deploy', 'api') if os.path.exists(api_root): for dir_name in os.listdir(api_root): dir_path = os.path.join(api_root, dir_name) if os.path.isdir(dir_path): for file in os.listdir(dir_path): if file.startswith('docker-compose.') and file.endswith('.yaml'): yaml_files.append(os.path.join(dir_path, file)) # 合并所有 YAML 文件内容 for file_path in yaml_files: print(f"合并文件: {file_path}") with open(file_path, 'r', encoding='utf-8') as f: try: data = yaml.safe_load(f) if not data: continue # 合并 services 配置 if 'services' in data: merged['services'].update(data['services']) # 合并 networks 配置 if 'networks' in data: merged['networks'].update(data['networks']) # 合并 volumes 配置 if 'volumes' in data: merged['volumes'].update(data['volumes']) except yaml.YAMLError as e: print(f"解析 {file_path} 失败: {e}") continue return merged def process_yaml(root_dir: str): """处理 YAML 文件的主函数:合并并输出到目标路径""" # 合并 YAML 文件 merged_data = merge_yaml_files(root_dir) # 输出到临时文件 temp_output = os.path.join(root_dir, 'docker-compose.temp.yaml') with open(temp_output, 'w', encoding='utf-8') as f: yaml.dump( merged_data, f, sort_keys=False, # 保持键的顺序 allow_unicode=True, # 支持中文 default_flow_style=False # 使用块样式而非流式样式 ) print(f"已生成合并后的临时文件: {temp_output}") # 复制到部署目录并替换目标文件 deploy_dir = os.path.join(root_dir, 'deploy') target_output = os.path.join(deploy_dir, 'docker-compose.yaml') shutil.move(temp_output, target_output) print(f"已将合并后的文件复制到: {target_output}") if __name__ == "__main__": # 示例:从当前脚本所在目录作为根目录处理 root_dir = os.path.dirname(os.path.abspath(__file__)) process_yaml(root_dir)