Files
microdao-daarion/scripts/update_repos_info.py
Apple 3de3c8cb36 feat: Add presence heartbeat for Matrix online status
- matrix-gateway: POST /internal/matrix/presence/online endpoint
- usePresenceHeartbeat hook with activity tracking
- Auto away after 5 min inactivity
- Offline on page close/visibility change
- Integrated in MatrixChatRoom component
2025-11-27 00:19:40 -08:00

379 lines
16 KiB
Python
Executable File
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env python3
"""
Скрипт для автоматичного оновлення інформації про GitHub репозиторії
в INFRASTRUCTURE.md та docs/infrastructure_quick_ref.ipynb
Використання:
python scripts/update_repos_info.py
# або
./scripts/update_repos_info.py
"""
import subprocess
import re
import json
from pathlib import Path
from datetime import datetime
from typing import Dict, List, Optional
# Шляхи до файлів
PROJECT_ROOT = Path(__file__).parent.parent
INFRASTRUCTURE_MD = PROJECT_ROOT / "INFRASTRUCTURE.md"
INFRASTRUCTURE_NOTEBOOK = PROJECT_ROOT / "docs" / "infrastructure_quick_ref.ipynb"
def get_known_repositories() -> Dict[str, Dict[str, str]]:
"""Повертає список відомих репозиторіїв проєкту (навіть якщо remote не додано)"""
return {
"microdao-daarion": {
"name": "MicroDAO",
"ssh_url": "git@github.com:IvanTytar/microdao-daarion.git",
"https_url": "https://github.com/IvanTytar/microdao-daarion.git",
"remote_name": "origin",
"main_branch": "main",
"owner": "IvanTytar",
"repo": "microdao-daarion",
"is_current": True
},
"daarion-ai-city": {
"name": "DAARION.city",
"ssh_url": "git@github.com:DAARION-DAO/daarion-ai-city.git",
"https_url": "https://github.com/DAARION-DAO/daarion-ai-city.git",
"remote_name": "daarion-city",
"main_branch": "main",
"owner": "DAARION-DAO",
"repo": "daarion-ai-city",
"is_current": False
}
}
def get_git_remotes() -> Dict[str, Dict[str, str]]:
"""Витягує інформацію про git remotes з поточного репозиторію"""
known_repos = get_known_repositories()
remotes = {}
try:
result = subprocess.run(
["git", "remote", "-v"],
capture_output=True,
text=True,
cwd=PROJECT_ROOT,
check=True
)
remotes = {}
for line in result.stdout.strip().split('\n'):
if not line:
continue
parts = line.split()
if len(parts) >= 2:
remote_name = parts[0]
url = parts[1]
# Очистити URL від токенів та конвертувати
# Видалити токени з HTTPS URL (ghp_xxx@ або token@)
clean_url = re.sub(r'https://[^@]+@', 'https://', url)
clean_url = re.sub(r'ghp_[^@]+@', '', clean_url)
# Визначити тип URL (SSH або HTTPS)
if url.startswith('git@') or 'git@' in clean_url:
# Якщо це SSH URL
ssh_match = re.search(r'git@github\.com:[^/]+/[^/\s]+', url)
if ssh_match:
ssh_url = ssh_match.group(0)
else:
ssh_url = clean_url.replace('https://github.com/', 'git@github.com:')
# Конвертувати SSH URL в HTTPS
https_url = ssh_url.replace('git@github.com:', 'https://github.com/')
elif url.startswith('https://') or 'github.com' in clean_url:
# Якщо це HTTPS URL
https_match = re.search(r'https://github\.com/[^/]+/[^/\s]+', clean_url)
if https_match:
https_url = https_match.group(0)
else:
https_url = clean_url
# Конвертувати HTTPS URL в SSH
ssh_url = https_url.replace('https://github.com/', 'git@github.com:')
else:
continue
# Витягнути owner/repo з URL
match = re.search(r'github\.com[:/]([^/]+)/([^/]+)', url)
if match:
owner = match.group(1)
repo_name = match.group(2).replace('.git', '')
# Визначити main branch
try:
branch_result = subprocess.run(
["git", "remote", "show", remote_name],
capture_output=True,
text=True,
cwd=PROJECT_ROOT,
check=True
)
branch_match = re.search(r'HEAD branch:\s+(\S+)', branch_result.stdout)
main_branch = branch_match.group(1) if branch_match else "main"
except:
main_branch = "main"
# Перевірити чи це відомий репозиторій
repo_key = None
for key, known_repo in known_repos.items():
if known_repo["repo"] == repo_name:
repo_key = key
break
if repo_key:
# Використати дані з відомих репозиторіїв
remotes[remote_name] = known_repos[repo_key].copy()
remotes[remote_name]["remote_name"] = remote_name
remotes[remote_name]["main_branch"] = main_branch
remotes[remote_name]["ssh_url"] = ssh_url
remotes[remote_name]["https_url"] = https_url
else:
# Невідомий репозиторій - створити новий запис
remotes[remote_name] = {
"name": repo_name.replace('-', ' ').title(),
"ssh_url": ssh_url,
"https_url": https_url,
"remote_name": remote_name,
"main_branch": main_branch,
"owner": owner,
"repo": repo_name
}
# Додати відомі репозиторії які не мають remote
for repo_key, known_repo in known_repos.items():
if not any(r.get("repo") == known_repo["repo"] for r in remotes.values()):
# Якщо це поточний репозиторій, додати як origin
if known_repo.get("is_current") and "origin" not in remotes:
remotes["origin"] = known_repo.copy()
# Інакше додати з remote_name як ключ
elif not known_repo.get("is_current"):
remotes[known_repo["remote_name"]] = known_repo.copy()
return remotes
except subprocess.CalledProcessError as e:
print(f"Помилка при виконанні git команди: {e}")
return {}
except Exception as e:
print(f"Неочікувана помилка: {e}")
return {}
def get_repo_purpose(repo_name: str) -> str:
"""Визначає призначення репозиторію на основі назви"""
purposes = {
"microdao-daarion": "MicroDAO core code, DAGI Stack, documentation",
"daarion-ai-city": "Official DAARION.city website and integrations"
}
return purposes.get(repo_name, "Project repository")
def update_infrastructure_md(remotes: Dict[str, Dict[str, str]]) -> bool:
"""Оновлює розділ про репозиторії в INFRASTRUCTURE.md"""
if not INFRASTRUCTURE_MD.exists():
print(f"Файл {INFRASTRUCTURE_MD} не знайдено")
return False
content = INFRASTRUCTURE_MD.read_text(encoding='utf-8')
# Знайти розділ про репозиторії
repo_section_start = content.find("## 🐙 GitHub Repositories")
if repo_section_start == -1:
print("Розділ про репозиторії не знайдено в INFRASTRUCTURE.md")
return False
# Знайти кінець розділу (наступний ##)
repo_section_end = content.find("\n## ", repo_section_start + 1)
if repo_section_end == -1:
repo_section_end = len(content)
# Створити новий розділ
new_section = "## 🐙 GitHub Repositories\n\n"
repo_num = 1
for remote_name, repo_info in remotes.items():
purpose = get_repo_purpose(repo_info["repo"])
new_section += f"### {repo_num}. {repo_info['name']}"
if remote_name == "origin":
new_section += " (Current Project)"
new_section += "\n"
new_section += f"- **Repository:** `{repo_info['ssh_url']}`\n"
new_section += f"- **HTTPS:** `{repo_info['https_url']}`\n"
new_section += f"- **Remote Name:** `{repo_info['remote_name']}`\n"
new_section += f"- **Main Branch:** `{repo_info['main_branch']}`\n"
new_section += f"- **Purpose:** {purpose}\n\n"
new_section += "**Quick Clone:**\n"
new_section += "```bash\n"
new_section += f"git clone {repo_info['ssh_url']}\n"
new_section += f"cd {repo_info['repo']}\n"
new_section += "```\n\n"
repo_num += 1
# Додати інструкції для додавання remote (якщо є більше одного)
if len(remotes) > 1:
other_remotes = [r for r in remotes.items() if r[0] != "origin"]
if other_remotes:
new_section += "**Add as remote to MicroDAO:**\n"
new_section += "```bash\n"
new_section += "cd microdao-daarion\n"
for remote_name, repo_info in other_remotes:
new_section += f"git remote add {repo_info['remote_name']} {repo_info['ssh_url']}\n"
new_section += f"git fetch {repo_info['remote_name']}\n"
new_section += "```\n\n"
new_section += "---\n\n"
# Замінити старий розділ
updated_content = (
content[:repo_section_start] +
new_section +
content[repo_section_end:]
)
INFRASTRUCTURE_MD.write_text(updated_content, encoding='utf-8')
print(f"✅ Оновлено {INFRASTRUCTURE_MD}")
return True
def update_notebook(remotes: Dict[str, Dict[str, str]]) -> bool:
"""Оновлює розділ про репозиторії в infrastructure_quick_ref.ipynb"""
if not INFRASTRUCTURE_NOTEBOOK.exists():
print(f"Файл {INFRASTRUCTURE_NOTEBOOK} не знайдено")
return False
try:
notebook = json.loads(INFRASTRUCTURE_NOTEBOOK.read_text(encoding='utf-8'))
except json.JSONDecodeError as e:
print(f"Помилка при читанні notebook: {e}")
return False
# Знайти комірки з репозиторіями
repo_markdown_idx = None
repo_code_idx = None
for i, cell in enumerate(notebook.get("cells", [])):
if cell.get("cell_type") == "markdown":
source = "".join(cell.get("source", []))
if "## 🐙 GitHub Repositories" in source:
repo_markdown_idx = i
elif cell.get("cell_type") == "code":
source = "".join(cell.get("source", []))
if "REPOSITORIES = {" in source:
repo_code_idx = i
# Оновити markdown комірку
if repo_markdown_idx is not None:
new_markdown = "## 🐙 GitHub Repositories\n\n"
repo_num = 1
for remote_name, repo_info in remotes.items():
purpose = get_repo_purpose(repo_info["repo"])
new_markdown += f"### {repo_num}. {repo_info['name']}"
if remote_name == "origin":
new_markdown += " (Current Project)"
new_markdown += "\n"
new_markdown += f"- **Repository:** `{repo_info['ssh_url']}`\n"
new_markdown += f"- **HTTPS:** `{repo_info['https_url']}`\n"
new_markdown += f"- **Remote Name:** `{repo_info['remote_name']}`\n"
new_markdown += f"- **Main Branch:** `{repo_info['main_branch']}`\n"
new_markdown += f"- **Purpose:** {purpose}\n\n"
repo_num += 1
new_markdown += "---\n"
notebook["cells"][repo_markdown_idx]["source"] = new_markdown.split("\n")
# Оновити code комірку
if repo_code_idx is not None:
repos_dict = {}
for remote_name, repo_info in remotes.items():
purpose = get_repo_purpose(repo_info["repo"])
repos_dict[repo_info["repo"]] = {
"name": repo_info["name"],
"ssh_url": repo_info["ssh_url"],
"https_url": repo_info["https_url"],
"remote_name": repo_info["remote_name"],
"main_branch": repo_info["main_branch"],
"purpose": purpose,
"clone_cmd": f"git clone {repo_info['ssh_url']}"
}
new_code = "# GitHub Repositories Configuration\n"
new_code += "REPOSITORIES = " + json.dumps(repos_dict, indent=4, ensure_ascii=False) + "\n\n"
new_code += 'print("GitHub Repositories:")\n'
new_code += 'print("="*80)\n'
new_code += "for repo_id, repo in REPOSITORIES.items():\n"
new_code += ' print(f"\\n{repo[\'name\']} ({repo_id})")\n'
new_code += ' print(f" SSH URL: {repo[\'ssh_url\']}")\n'
new_code += ' print(f" HTTPS URL: {repo[\'https_url\']}")\n'
new_code += ' print(f" Remote: {repo[\'remote_name\']}")\n'
new_code += ' print(f" Branch: {repo[\'main_branch\']}")\n'
new_code += ' print(f" Purpose: {repo[\'purpose\']}")\n'
new_code += ' print(f" Clone: {repo[\'clone_cmd\']}")\n\n'
new_code += 'print("\\n" + "="*80)\n'
new_code += 'print("\\nQuick Commands:")\n'
new_code += 'print("\\n# Clone MicroDAO:")\n'
new_code += 'print("git clone git@github.com:IvanTytar/microdao-daarion.git")\n'
new_code += 'print("\\n# Clone DAARION.city:")\n'
new_code += 'print("git clone git@github.com:DAARION-DAO/daarion-ai-city.git")\n'
if len(remotes) > 1:
other_remotes = [r for r in remotes.items() if r[0] != "origin"]
if other_remotes:
new_code += 'print("\\n# Add DAARION.city as remote to MicroDAO:")\n'
new_code += 'print("cd microdao-daarion")\n'
for remote_name, repo_info in other_remotes:
remote_name_val = repo_info['remote_name']
ssh_url_val = repo_info['ssh_url']
new_code += f'print("git remote add {remote_name_val} {ssh_url_val}")\n'
new_code += f'print("git fetch {remote_name_val}")\n'
notebook["cells"][repo_code_idx]["source"] = new_code.split("\n")
# Зберегти notebook
INFRASTRUCTURE_NOTEBOOK.write_text(
json.dumps(notebook, indent=1, ensure_ascii=False),
encoding='utf-8'
)
print(f"✅ Оновлено {INFRASTRUCTURE_NOTEBOOK}")
return True
def main():
"""Головна функція"""
print("🔄 Оновлення інформації про GitHub репозиторії...\n")
# Витягнути інформацію про remotes
remotes = get_git_remotes()
if not remotes:
print("⚠️ Не знайдено жодного git remote")
return 1
print(f"Знайдено {len(remotes)} remote(s):")
for remote_name, repo_info in remotes.items():
print(f" - {remote_name}: {repo_info['repo']}")
print()
# Оновити файли
success_md = update_infrastructure_md(remotes)
success_nb = update_notebook(remotes)
if success_md and success_nb:
print("\nВсі файли успішно оновлено!")
return 0
else:
print("\n⚠️ Деякі файли не вдалося оновити")
return 1
if __name__ == "__main__":
exit(main())