#!/usr/bin/env python # -*- coding: utf-8 -*- """ 配置迁移脚本 将现有的 JSON 配置文件迁移到 .env 环境变量文件 """ import os import sys import json import shutil from pathlib import Path # 添加项目根目录到 sys.path project_root = Path(__file__).parent.parent sys.path.insert(0, str(project_root)) from config.schema import AppConfig def migrate_json_to_env( json_file: str = "config/user_settings.json", env_file: str = ".env", backup: bool = True, ) -> bool: """ 迁移 JSON 配置到 .env 文件 Args: json_file: JSON 配置文件路径 env_file: .env 文件路径 backup: 是否备份原 JSON 文件 Returns: 迁移是否成功 """ json_path = project_root / json_file env_path = project_root / env_file # 检查 JSON 文件是否存在 if not json_path.exists(): print(f"❌ JSON 配置文件不存在: {json_path}") print(f"💡 提示: 如果这是首次运行,请复制 .env.example 到 .env 并填入配置") return False # 检查 .env 文件是否已存在 if env_path.exists(): response = input(f"⚠️ .env 文件已存在: {env_path}\n是否覆盖? (y/N): ") if response.lower() != "y": print("❌ 迁移已取消") return False # 备份现有的 .env 文件 backup_path = env_path.with_suffix(".env.backup") shutil.copy(env_path, backup_path) print(f"✅ 已备份现有 .env 文件到: {backup_path}") try: # 读取 JSON 配置 print(f"📖 读取 JSON 配置: {json_path}") with open(json_path, "r", encoding="utf-8") as f: json_data = json.load(f) # 使用 ConfigLoader 将字典转换为配置对象 from config.loader import ConfigLoader config = ConfigLoader._dict_to_config(json_data) # 保存到 .env 文件 print(f"💾 保存配置到 .env 文件: {env_path}") success = ConfigLoader.save_to_env(config, env_file) if not success: print("❌ 保存 .env 文件失败") return False # 备份原 JSON 文件 if backup: backup_path = json_path.with_suffix(".json.backup") shutil.copy(json_path, backup_path) print(f"✅ 已备份 JSON 配置到: {backup_path}") print("\n✅ 配置迁移成功!") print(f"\n📝 新配置文件: {env_path}") print(f"📦 备份文件: {backup_path if backup else '无'}") print("\n💡 提示:") print(" 1. 请检查 .env 文件中的配置是否正确") print(" 2. 确保 .env 文件不会被提交到版本控制") print(" 3. 可以删除原 JSON 配置文件: " + str(json_path)) return True except json.JSONDecodeError as e: print(f"❌ JSON 解析失败: {e}") return False except Exception as e: print(f"❌ 迁移失败: {e}") import traceback traceback.print_exc() return False def create_env_from_example( example_file: str = ".env.example", env_file: str = ".env" ) -> bool: """ 从 .env.example 创建 .env 文件 Args: example_file: .env.example 文件路径 env_file: .env 文件路径 Returns: 创建是否成功 """ example_path = project_root / example_file env_path = project_root / env_file if not example_path.exists(): print(f"❌ .env.example 文件不存在: {example_path}") return False if env_path.exists(): response = input(f"⚠️ .env 文件已存在: {env_path}\n是否覆盖? (y/N): ") if response.lower() != "y": print("❌ 操作已取消") return False try: shutil.copy(example_path, env_path) print(f"✅ 已从 {example_file} 创建 {env_file}") print("\n💡 提示:") print(" 1. 请编辑 .env 文件,填入实际的配置值") print(" 2. 特别注意敏感信息(密码、密钥等)") print(" 3. 确保 .env 文件不会被提交到版本控制") return True except Exception as e: print(f"❌ 创建失败: {e}") return False def main(): """主函数""" print("=" * 60) print("🔄 配置迁移工具 - JSON → .env") print("=" * 60) # 检查命令行参数 if len(sys.argv) > 1: command = sys.argv[1].lower() if command == "from-example": # 从 .env.example 创建 print("\n📋 模式: 从 .env.example 创建配置文件") example_file = sys.argv[2] if len(sys.argv) > 2 else ".env.example" env_file = sys.argv[3] if len(sys.argv) > 3 else ".env" create_env_from_example(example_file, env_file) return elif command == "migrate": # 从 JSON 迁移 print("\n📋 模式: 从 JSON 配置迁移") json_file = ( sys.argv[2] if len(sys.argv) > 2 else "config/user_settings.json" ) env_file = sys.argv[3] if len(sys.argv) > 3 else ".env" migrate_json_to_env(json_file, env_file) return elif command == "help": print(""" 用法: python scripts/migrate_to_env.py <命令> [参数] 命令: migrate [json_file] [env_file] 从 JSON 配置迁移到 .env from-example [example] [env_file] 从 .env.example 创建配置文件 help 显示此帮助信息 示例: python scripts/migrate_to_env.py migrate python scripts/migrate_to_env.py migrate config/user_settings.json .env python scripts/migrate_to_env.py from-example python scripts/migrate_to_env.py from-example .env.example .env.local """) return # 交互模式 print("\n请选择操作:") print(" 1. 从 JSON 配置迁移到 .env") print(" 2. 从 .env.example 创建配置文件") print(" 3. 退出") choice = input("\n请输入选项 (1-3): ").strip() if choice == "1": json_file = input( "JSON 配置文件路径 (默认: config/user_settings.json): " ).strip() if not json_file: json_file = "config/user_settings.json" env_file = input(".env 文件路径 (默认: .env): ").strip() if not env_file: env_file = ".env" backup_choice = input("是否备份原 JSON 文件? (Y/n): ").strip().lower() backup = backup_choice != "n" migrate_json_to_env(json_file, env_file, backup) elif choice == "2": example_file = input(".env.example 文件路径 (默认: .env.example): ").strip() if not example_file: example_file = ".env.example" env_file = input(".env 文件路径 (默认: .env): ").strip() if not env_file: env_file = ".env" create_env_from_example(example_file, env_file) elif choice == "3": print("👋 再见!") else: print("❌ 无效的选项") if __name__ == "__main__": main()