import os import os import argparse # ========================================== # 設定區 # ========================================== # ⚠️ 嚴格排除的資料夾 (完全不掃描這些目錄) EXCLUDE_DIRS = { "__pycache__", ".git", ".vscode", # VS Code 設定檔 ".continue", # Continue.dev 設定檔 "cmts_api_env", # 🚨 Python 虛擬環境 "venv", ".venv", "node_modules", "dist", "build" } # ⚠️ 排除的檔案副檔名 (不讀取這些格式) EXCLUDE_EXTENSIONS = { ".png", ".jpg", ".jpeg", ".gif", ".ico", ".svg", ".pyc", ".pyo", ".pyd", ".exe", ".dll", ".so", ".dylib", ".zip", ".tar", ".gz", ".rar", ".pdf", ".doc", ".docx", ".sqlite3", ".db" } # ⚠️ 排除的特定檔案名稱 EXCLUDE_FILES = { "merge_code.py", # 排除這支腳本自己 "all_code.txt", # 排除全域輸出的檔案 "target_code.txt", # 排除指定輸出的檔案 (新增) ".DS_Store", ".clineignore", ".clinerules", ".gitignore", "requirements.txt" } def should_process_file(filename): """判斷該檔案是否應該被處理 (用於全域掃描)""" if filename in EXCLUDE_FILES: return False ext = os.path.splitext(filename)[1].lower() if ext in EXCLUDE_EXTENSIONS: return False return True def merge_all_files(): """模式一:全域掃描 (無參數時觸發)""" output_file = "all_code.txt" root_dir = os.path.dirname(os.path.abspath(__file__)) with open(output_file, "w", encoding="utf-8") as outfile: outfile.write("=" * 80 + "\n") outfile.write("PROJECT SOURCE CODE EXPORT (FULL)\n") outfile.write("=" * 80 + "\n\n") for dirpath, dirnames, filenames in os.walk(root_dir): dirnames[:] = [d for d in dirnames if d not in EXCLUDE_DIRS] for filename in filenames: if should_process_file(filename): file_path = os.path.join(dirpath, filename) rel_path = os.path.relpath(file_path, root_dir) try: with open(file_path, "r", encoding="utf-8") as infile: content = infile.read() outfile.write("\n" + "=" * 80 + "\n") outfile.write(f"FILE: {rel_path}\n") outfile.write("=" * 80 + "\n") outfile.write(content) outfile.write("\n") print(f"✅ 已合併: {rel_path}") except Exception as e: print(f"❌ 讀取失敗 {rel_path}: {e}") print(f"\n🎉 全域合併完成!所有程式碼已儲存至: {output_file}") def merge_target_files(file_list): """模式二:指定檔案合併 (-t 參數觸發)""" output_file = "target_code.txt" root_dir = os.path.dirname(os.path.abspath(__file__)) with open(output_file, "w", encoding="utf-8") as outfile: outfile.write("=" * 80 + "\n") outfile.write("TARGET SOURCE CODE EXPORT (SPECIFIC)\n") outfile.write("=" * 80 + "\n\n") for rel_path in file_list: file_path = os.path.join(root_dir, rel_path) if not os.path.exists(file_path): print(f"❌ 找不到檔案 (已跳過): {rel_path}") continue if not os.path.isfile(file_path): print(f"❌ 不是有效檔案 (已跳過): {rel_path}") continue try: with open(file_path, "r", encoding="utf-8") as infile: content = infile.read() outfile.write("\n" + "=" * 80 + "\n") outfile.write(f"FILE: {rel_path}\n") outfile.write("=" * 80 + "\n") outfile.write(content) outfile.write("\n") print(f"✅ 已合併: {rel_path}") except Exception as e: print(f"❌ 讀取失敗 {rel_path}: {e}") print(f"\n🎯 指定合併完成!選定的程式碼已儲存至: {output_file}") if __name__ == "__main__": # 使用 argparse 來解析終端機指令 parser = argparse.ArgumentParser(description="合併專案程式碼供 AI 讀取") parser.add_argument( '-t', '--target', nargs='+', # 允許接收一個或多個參數 help="指定要合併的檔案路徑 (例如: -t main.py routers/api.py)" ) args = parser.parse_args() # 根據是否有傳入 -t 參數,決定執行哪一種模式 if args.target: print("🔍 啟動 [指定模式]...") merge_target_files(args.target) else: print("🔍 啟動 [全域模式]...") merge_all_files()