feat(dev-session): Containerize dev session manager
This commit introduces a containerized workflow for the development session manager (dev_session.py). - Dockerization: Added gemini.Dockerfile to create a self-contained environment with all Python dependencies, removing the need for manual host setup. - Start Script: Updated start-gemini.sh to build and run the container, executing dev_session.py as the entrypoint. - Session Management: Implemented --done flag to properly terminate a session, update the Notion task status, and clean up the git hook. - Notion Integration: Created and integrated notion_commit_hook.py which is automatically installed/uninstalled to post commit messages to the active Notion task. - Documentation: Updated README_dev_session.md to reflect the new container-based setup, usage, and features.
This commit is contained in:
@@ -15,43 +15,57 @@
|
||||
|
||||
## Voraussetzungen
|
||||
|
||||
* Python 3.6+
|
||||
* `requests` Bibliothek (`pip install requests`)
|
||||
* Ein Notion Integration Token mit Zugriff auf deine "Projects [UT]"- und "Tasks [UT]"-Datenbanken.
|
||||
* **Docker:** Das gesamte Setup ist containerisiert, um Abhängigkeitskonflikte zu vermeiden.
|
||||
* **Notion Integration Token:** Ein Notion API-Token mit Zugriff auf Ihre "Projects"- und "Tasks"-Datenbanken.
|
||||
|
||||
## Installation und Einrichtung
|
||||
|
||||
1. **Notion API Key:**
|
||||
* Stelle sicher, dass du einen Notion Integration Token hast.
|
||||
* Speichere deinen Token in einer Umgebungsvariablen namens `NOTION_API_KEY`. Alternativ fragt das Skript beim Start danach.
|
||||
* Gewähre der Integration Zugriff auf deine "Projects [UT]"- und "Tasks [UT]"-Datenbanken in Notion.
|
||||
Das Setup ist so konzipiert, dass es mit minimalem Aufwand sofort einsatzbereit ist.
|
||||
|
||||
2. **Abhängigkeiten installieren:**
|
||||
```bash
|
||||
pip install requests
|
||||
```
|
||||
1. **Notion API Key:**
|
||||
* Stellen Sie sicher, dass Sie einen Notion Integration Token haben.
|
||||
* Das Skript fragt beim ersten Start interaktiv nach dem Token. Sie können es auch als Umgebungsvariable `NOTION_API_KEY` in einer `.env`-Datei im Hauptverzeichnis speichern, um diesen Schritt zu überspringen.
|
||||
* Gewähren Sie Ihrer Notion-Integration Zugriff auf die relevanten "Projects"- und "Tasks"-Datenbanken.
|
||||
|
||||
2. **Abhängigkeiten:** Alle notwendigen Abhängigkeiten (Python, `requests`, `python-dotenv`) sind im Dockerfile (`gemini.Dockerfile`) definiert und werden automatisch im Container installiert. Es ist keine manuelle Installation via `pip` erforderlich.
|
||||
|
||||
## Nutzung
|
||||
|
||||
1. **Führe das Skript aus:**
|
||||
```bash
|
||||
python3 dev_session.py
|
||||
```
|
||||
### 1. Sitzung starten
|
||||
|
||||
2. **Notion API Key eingeben:** Wenn `NOTION_API_KEY` nicht als Umgebungsvariable gesetzt ist, wirst du zur Eingabe aufgefordert.
|
||||
Führen Sie das Start-Skript aus. Es baut bei Bedarf das Docker-Image und startet den Session-Manager.
|
||||
|
||||
3. **Projekt auswählen:** Wähle dein gewünschtes Projekt aus der angezeigten Liste der Notion-Projekte.
|
||||
```bash
|
||||
./start-gemini.sh
|
||||
```
|
||||
|
||||
4. **Task auswählen oder erstellen:**
|
||||
* Wenn Tasks für das Projekt vorhanden sind, wähle einen aus.
|
||||
* Wenn keine Tasks vorhanden sind oder du einen neuen erstellen möchtest, wähle die Option zum "Neuen Task für dieses Projekt erstellen". Du wirst dann nach dem Task-Titel gefragt.
|
||||
Das Skript führt Sie dann interaktiv durch die Auswahl eines Projekts und eines Tasks, genau wie in der Beispiel-Interaktion unten beschrieben. Nach der Auswahl startet es eine Gemini-CLI-Sitzung mit dem passenden Kontext.
|
||||
|
||||
5. **Git Branch erstellen (manuell):** Das Skript gibt einen `git checkout -b`-Befehl aus, den du kopieren und in deinem Terminal ausführen solltest, um einen neuen Branch für den Task zu erstellen.
|
||||
### 2. Sitzung abschließen
|
||||
|
||||
6. **Gemini CLI Kontext:** Das Skript gibt einen formatierten Textblock aus, den du direkt in die Gemini CLI kopieren und einfügen kannst, um die KI mit dem relevanten Kontext zu versorgen.
|
||||
Wenn Sie die Arbeit an einem Task beendet haben, können Sie die Sitzung über den folgenden Befehl abschließen. Dieser Befehl muss **im Terminal des Hosts** ausgeführt werden, während der Container (`gemini-session`) noch läuft.
|
||||
|
||||
```bash
|
||||
docker exec -it gemini-session python3 dev_session.py --done
|
||||
```
|
||||
|
||||
Dieser Befehl:
|
||||
* Setzt den Status des Notion-Tasks auf "Done" (oder den finalen Status in Ihrer Konfiguration).
|
||||
* Löscht die lokale Session-Datei (`.session_info.json`).
|
||||
* Deinstalliert den Git-Hook.
|
||||
|
||||
### 3. Automatisches Notion-Feedback (Git-Hook)
|
||||
|
||||
Beim Starten einer Sitzung wird automatisch ein `post-commit`-Git-Hook installiert.
|
||||
|
||||
* **Funktion:** Nach jedem `git commit` wird die Commit-Nachricht automatisch als Kommentar an den verknüpften Notion-Task gesendet.
|
||||
* **Voraussetzung:** Funktioniert nur für Commits, die im `gemini-session`-Container oder auf dem Host-System (mit installiertem `requests`) gemacht werden, während die Session aktiv ist.
|
||||
* **Deinstallation:** Der Hook wird beim Abschluss der Sitzung mit `--done` automatisch wieder entfernt.
|
||||
|
||||
### Beispiel-Interaktion (gekürzt)
|
||||
|
||||
Die interaktive Auswahl von Projekt und Task bleibt unverändert:
|
||||
|
||||
```
|
||||
Starte interaktive Entwicklungs-Session...
|
||||
Bitte gib deinen Notion API Key ein (Eingabe wird nicht angezeigt): ****************
|
||||
@@ -63,45 +77,11 @@ An welchem Projekt möchtest du arbeiten?
|
||||
[2] Sync Engine
|
||||
[...]
|
||||
Bitte wähle eine Nummer: 2
|
||||
|
||||
Projekt 'Sync Engine' ausgewählt.
|
||||
|
||||
--- Lade Tasks für das ausgewählte Projekt... ---
|
||||
Keine offenen Tasks für dieses Projekt gefunden.
|
||||
[1] Neuen Task für dieses Projekt erstellen
|
||||
Bitte wähle eine Nummer: 1
|
||||
|
||||
--- Neuen Task erstellen ---
|
||||
Bitte gib den Titel für den neuen Task ein: Create README.md for dev_session.py
|
||||
✅ Task 'Create README.md for dev_session.py' erfolgreich erstellt.
|
||||
|
||||
Task 'Create README.md for dev_session.py' ausgewählt.
|
||||
|
||||
--- Aktualisiere Status von Task '<TASK_ID>' auf 'Doing'... ---
|
||||
✅ Task-Status erfolgreich auf 'Doing' aktualisiert.
|
||||
|
||||
------------------------------------------------------------------
|
||||
✅ Setup abgeschlossen!
|
||||
|
||||
Du solltest jetzt den Git-Branch manuell erstellen und auschecken:
|
||||
git checkout -b feature/task-2f388f42-create-readmemd-for-devsessionpy
|
||||
|
||||
Der Notion-Task 'Create README.md for dev_session.py' wurde auf 'Doing' gesetzt.
|
||||
---
|
||||
|
||||
Kontext für die Gemini CLI (bitte kopieren und einfügen):
|
||||
|
||||
Ich arbeite jetzt am Projekt 'Sync Engine'. Der Fokus liegt auf dem Task 'Create README.md for dev_session.py'.
|
||||
|
||||
Die relevanten Dateien für dieses Projekt sind wahrscheinlich:
|
||||
- Die primäre Projektdokumentation: @readme.md
|
||||
- Die spezifische Dokumentation für dieses Modul: @readme.md (falls vorhanden)
|
||||
- Der Haupt-Code befindet sich wahrscheinlich in: @dev_session.py
|
||||
|
||||
Mein Ziel ist es, den Task 'Create README.md for dev_session.py' umzusetzen. Alle Commits für diesen Task sollen die Kennung `[2f388f42]` enthalten.
|
||||
------------------------------------------------------------------
|
||||
...
|
||||
```
|
||||
|
||||
Nach der Auswahl wird automatisch die Gemini CLI gestartet.
|
||||
|
||||
## Git Branch Benennungs-Konvention
|
||||
|
||||
Das Skript schlägt automatisch einen Git-Branch-Namen vor, der dem Muster `feature/task-{kurze_task_id}-{task_titel_slug}` folgt.
|
||||
|
||||
247
dev_session.py
247
dev_session.py
@@ -197,6 +197,76 @@ def create_new_notion_task(token: str, project_id: str, tasks_db_id: str) -> Opt
|
||||
print(f"Antwort des Servers: {e.response.text}")
|
||||
return None
|
||||
|
||||
def add_comment_to_notion_task(token: str, task_id: str, comment: str) -> bool:
|
||||
"""Fügt einen Kommentar zu einer Notion-Seite (Task) hinzu."""
|
||||
url = "https://api.notion.com/v1/comments"
|
||||
headers = {
|
||||
"Authorization": f"Bearer {token}",
|
||||
"Content-Type": "application/json",
|
||||
"Notion-Version": "2022-06-28"
|
||||
}
|
||||
payload = {
|
||||
"parent": {"page_id": task_id},
|
||||
"rich_text": [{
|
||||
"text": {
|
||||
"content": comment
|
||||
}
|
||||
}]
|
||||
}
|
||||
try:
|
||||
response = requests.post(url, headers=headers, json=payload)
|
||||
response.raise_for_status()
|
||||
# Kein print, da dies vom Git-Hook im Hintergrund aufgerufen wird
|
||||
return True
|
||||
except requests.exceptions.RequestException:
|
||||
# Fehler unterdrücken, um den Commit-Prozess nicht zu blockieren
|
||||
return False
|
||||
|
||||
# --- Session Management ---
|
||||
|
||||
SESSION_DIR = ".dev_session"
|
||||
SESSION_FILE_PATH = os.path.join(SESSION_DIR, "SESSION_INFO")
|
||||
|
||||
def save_session_info(task_id: str, token: str):
|
||||
"""Speichert die Task-ID und den Token für den Git-Hook."""
|
||||
os.makedirs(SESSION_DIR, exist_ok=True)
|
||||
session_data = {
|
||||
"task_id": task_id,
|
||||
"token": token
|
||||
}
|
||||
with open(SESSION_FILE_PATH, "w") as f:
|
||||
json.dump(session_data, f)
|
||||
|
||||
def install_git_hook():
|
||||
"""Installiert das notion_commit_hook.py Skript als post-commit Git-Hook."""
|
||||
git_hooks_dir = os.path.join(".git", "hooks")
|
||||
post_commit_hook_path = os.path.join(git_hooks_dir, "post-commit")
|
||||
source_hook_script = "notion_commit_hook.py"
|
||||
|
||||
if not os.path.exists(git_hooks_dir):
|
||||
# Wahrscheinlich kein Git-Repository, also nichts tun
|
||||
return
|
||||
|
||||
if not os.path.exists(source_hook_script):
|
||||
print(f"Warnung: Hook-Skript {source_hook_script} nicht gefunden. Hook wird nicht installiert.")
|
||||
return
|
||||
|
||||
try:
|
||||
# Lese den Inhalt des Quellskripts
|
||||
with open(source_hook_script, "r") as f:
|
||||
hook_content = f.read()
|
||||
|
||||
# Schreibe den Inhalt in den post-commit Hook
|
||||
with open(post_commit_hook_path, "w") as f:
|
||||
f.write(hook_content)
|
||||
|
||||
# Mache den Hook ausführbar
|
||||
os.chmod(post_commit_hook_path, 0o755)
|
||||
print("✅ Git-Hook für Notion-Kommentare erfolgreich installiert.")
|
||||
|
||||
except (IOError, OSError) as e:
|
||||
print(f"❌ FEHLER beim Installieren des Git-Hooks: {e}")
|
||||
|
||||
# --- UI Functions ---
|
||||
|
||||
def select_project(token: str) -> Optional[Tuple[Dict, Optional[str]]]:
|
||||
@@ -259,37 +329,141 @@ def select_task(token: str, project_id: str, tasks_db_id: str) -> Optional[Dict]
|
||||
except ValueError:
|
||||
print("Ungültige Eingabe. Bitte eine Zahl eingeben.")
|
||||
|
||||
import subprocess
|
||||
|
||||
# --- Context Generation ---
|
||||
|
||||
def generate_cli_context(project_title: str, task_title: str, task_id: str, suggested_branch_name: str, readme_path: Optional[str]) -> str:
|
||||
"""Erstellt einen formatierten Kontext-String für die Gemini CLI."""
|
||||
def generate_cli_context(project_title: str, task_title: str, task_id: str, readme_path: Optional[str]) -> str:
|
||||
"""Erstellt den reinen Kontext-String für die Gemini CLI."""
|
||||
|
||||
# Fallback, falls kein Pfad in Notion gesetzt ist
|
||||
if not readme_path:
|
||||
readme_path = "readme.md"
|
||||
|
||||
context = (
|
||||
"\n------------------------------------------------------------------"
|
||||
"\n✅ Setup abgeschlossen!"
|
||||
f"\n\nDu solltest jetzt den Git-Branch manuell erstellen und auschecken:"
|
||||
f"\ngit checkout -b {suggested_branch_name}"
|
||||
f"\n\nDer Notion-Task '{task_title}' wurde auf 'Doing' gesetzt."
|
||||
"\n---"
|
||||
"\n\nKontext für die Gemini CLI (bitte kopieren und einfügen):"
|
||||
f"\n\nIch arbeite jetzt am Projekt '{project_title}'. Der Fokus liegt auf dem Task '{task_title}'."
|
||||
"\n\nDie relevanten Dateien für dieses Projekt sind wahrscheinlich:"
|
||||
"\n- Die primäre Projektdokumentation: @readme.md"
|
||||
f"\n- Die spezifische Dokumentation für dieses Modul: @{readme_path}"
|
||||
f"\n- Der Haupt-Code befindet sich wahrscheinlich in: @dev_session.py"
|
||||
f"\n\nMein Ziel ist es, den Task '{task_title}' umzusetzen. Alle Commits für diesen Task sollen die Kennung `[{task_id.split('-')[0]}]` enthalten."
|
||||
"\n------------------------------------------------------------------"
|
||||
f"Ich arbeite jetzt am Projekt '{project_title}'. Der Fokus liegt auf dem Task '{task_title}'.\n\n"
|
||||
"Die relevanten Dateien für dieses Projekt sind wahrscheinlich:\n"
|
||||
"- Die primäre Projektdokumentation: @readme.md\n"
|
||||
f"- Die spezifische Dokumentation für dieses Modul: @{readme_path}\n"
|
||||
f"- Der Haupt-Code befindet sich wahrscheinlich in: @dev_session.py\n\n"
|
||||
f"Mein Ziel ist es, den Task '{task_title}' umzusetzen. Alle Commits für diesen Task sollen die Kennung `[{task_id.split('-')[0]}]` enthalten."
|
||||
)
|
||||
return context
|
||||
|
||||
# --- Main Execution ---
|
||||
# --- CLI Execution ---
|
||||
|
||||
def main():
|
||||
"""Hauptfunktion des Skripts."""
|
||||
def start_gemini_cli(initial_context: str):
|
||||
"""Startet die Gemini CLI als interaktiven Subprozess und übergibt den Startkontext."""
|
||||
print("\n--- Übergebe an Gemini CLI... ---")
|
||||
print("Die Gemini CLI wird jetzt gestartet. Sie können direkt mit der Arbeit beginnen.")
|
||||
|
||||
try:
|
||||
# Der Befehl, um die Gemini CLI zu starten
|
||||
command = ["gemini"]
|
||||
|
||||
# Starte den Prozess
|
||||
# stdin=subprocess.PIPE, um den Kontext zu senden
|
||||
# text=True für String-basierte Ein-/Ausgabe
|
||||
process = subprocess.Popen(command, stdin=subprocess.PIPE, text=True)
|
||||
|
||||
# Schreibe den initialen Kontext in die Standard-Eingabe der CLI
|
||||
# Ein Zeilenumbruch am Ende simuliert das Drücken der Enter-Taste.
|
||||
process.communicate(input=initial_context + '\n')
|
||||
|
||||
except FileNotFoundError:
|
||||
print("\n❌ FEHLER: Der 'gemini'-Befehl wurde nicht gefunden.")
|
||||
print("Stellen Sie sicher, dass die Gemini CLI korrekt im Container installiert und im PATH verfügbar ist.")
|
||||
except Exception as e:
|
||||
print(f"\n❌ Ein unerwarteter Fehler ist beim Starten der Gemini CLI aufgetreten: {e}")
|
||||
|
||||
import shutil
|
||||
import argparse
|
||||
|
||||
# --- Session Management ---
|
||||
|
||||
SESSION_DIR = ".dev_session"
|
||||
SESSION_FILE_PATH = os.path.join(SESSION_DIR, "SESSION_INFO")
|
||||
|
||||
def save_session_info(task_id: str, token: str):
|
||||
"""Speichert die Task-ID und den Token für den Git-Hook."""
|
||||
os.makedirs(SESSION_DIR, exist_ok=True)
|
||||
session_data = {
|
||||
"task_id": task_id,
|
||||
"token": token
|
||||
}
|
||||
with open(SESSION_FILE_PATH, "w") as f:
|
||||
json.dump(session_data, f)
|
||||
|
||||
def install_git_hook():
|
||||
"""Installiert das notion_commit_hook.py Skript als post-commit Git-Hook."""
|
||||
git_hooks_dir = os.path.join(".git", "hooks")
|
||||
post_commit_hook_path = os.path.join(git_hooks_dir, "post-commit")
|
||||
source_hook_script = "notion_commit_hook.py"
|
||||
|
||||
if not os.path.exists(git_hooks_dir):
|
||||
# Wahrscheinlich kein Git-Repository, also nichts tun
|
||||
return
|
||||
|
||||
if not os.path.exists(source_hook_script):
|
||||
print(f"Warnung: Hook-Skript {source_hook_script} nicht gefunden. Hook wird nicht installiert.")
|
||||
return
|
||||
|
||||
try:
|
||||
# Kopiere das Skript und mache es ausführbar
|
||||
shutil.copy(source_hook_script, post_commit_hook_path)
|
||||
os.chmod(post_commit_hook_path, 0o755)
|
||||
print("✅ Git-Hook für Notion-Kommentare erfolgreich installiert.")
|
||||
|
||||
except (IOError, OSError) as e:
|
||||
print(f"❌ FEHLER beim Installieren des Git-Hooks: {e}")
|
||||
|
||||
def cleanup_session():
|
||||
"""Bereinigt die Session-Datei und den Git-Hook."""
|
||||
if os.path.exists(SESSION_FILE_PATH):
|
||||
os.remove(SESSION_FILE_PATH)
|
||||
|
||||
post_commit_hook_path = os.path.join(".git", "hooks", "post-commit")
|
||||
if os.path.exists(post_commit_hook_path):
|
||||
os.remove(post_commit_hook_path)
|
||||
|
||||
print("🧹 Session-Daten und Git-Hook wurden bereinigt.")
|
||||
|
||||
def complete_session():
|
||||
"""Schließt eine aktive Session ab."""
|
||||
print("Schließe aktive Entwicklungs-Session ab...")
|
||||
if not os.path.exists(SESSION_FILE_PATH):
|
||||
print("Keine aktive Session gefunden.")
|
||||
return
|
||||
|
||||
try:
|
||||
with open(SESSION_FILE_PATH, "r") as f:
|
||||
session_data = json.load(f)
|
||||
task_id = session_data.get("task_id")
|
||||
token = session_data.get("token")
|
||||
|
||||
if task_id and token:
|
||||
# Annahme: Der letzte Status in der Liste ist der "Done"-Status
|
||||
tasks_db_id = find_database_by_title(token, "Tasks [UT]")
|
||||
if tasks_db_id:
|
||||
status_options = get_database_status_options(token, tasks_db_id)
|
||||
if status_options:
|
||||
done_status = status_options[-1]
|
||||
update_notion_task_status(token, task_id, done_status)
|
||||
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
print("Fehler beim Lesen der Session-Informationen.")
|
||||
|
||||
finally:
|
||||
cleanup_session()
|
||||
|
||||
user_input = input("\nMöchtest du eine neue Session starten? (j/n): ").lower()
|
||||
if user_input == 'j':
|
||||
main() # Starte den interaktiven Prozess von vorne
|
||||
else:
|
||||
print("Auf Wiedersehen!")
|
||||
|
||||
def start_interactive_session():
|
||||
"""Startet den Prozess zur Auswahl von Projekt/Task und startet Gemini."""
|
||||
print("Starte interaktive Entwicklungs-Session...")
|
||||
|
||||
token = os.environ.get('NOTION_API_KEY')
|
||||
@@ -327,7 +501,13 @@ def main():
|
||||
task_title = get_page_title(selected_task)
|
||||
task_id = selected_task["id"]
|
||||
print(f"\nTask '{task_title}' ausgewählt.")
|
||||
|
||||
# Session-Informationen für den Git-Hook speichern
|
||||
save_session_info(task_id, token)
|
||||
|
||||
# Git-Hook installieren, der die Session-Infos nutzt
|
||||
install_git_hook()
|
||||
|
||||
title_slug = re.sub(r'[^a-z0-9\s-]', '', task_title.lower())
|
||||
title_slug = re.sub(r'\s+', '-', title_slug)
|
||||
title_slug = re.sub(r'-+', '-', title_slug).strip('-')
|
||||
@@ -338,8 +518,33 @@ def main():
|
||||
if not status_updated:
|
||||
print("Warnung: Notion-Task-Status konnte nicht aktualisiert werden.")
|
||||
|
||||
cli_context = generate_cli_context(project_title, task_title, task_id, suggested_branch_name, readme_path)
|
||||
print(cli_context)
|
||||
# Finale Setup-Informationen ausgeben
|
||||
print("\n------------------------------------------------------------------")
|
||||
print("✅ Setup abgeschlossen!")
|
||||
print(f"\nDer Notion-Task '{task_title}' wurde auf 'Doing' gesetzt.")
|
||||
print(f"\nBitte erstellen Sie jetzt manuell den Git-Branch in einem separaten Terminal:")
|
||||
print(f"git checkout -b {suggested_branch_name}")
|
||||
print("------------------------------------------------------------------")
|
||||
|
||||
# CLI-Kontext generieren und die interaktive Session starten
|
||||
cli_context = generate_cli_context(project_title, task_title, task_id, readme_path)
|
||||
start_gemini_cli(cli_context)
|
||||
|
||||
|
||||
# --- Main Execution ---
|
||||
|
||||
def main():
|
||||
"""Hauptfunktion des Skripts."""
|
||||
parser = argparse.ArgumentParser(description="Interaktiver Session-Manager für die Gemini-Entwicklung mit Notion-Integration.")
|
||||
parser.add_argument("--done", action="store_true", help="Schließt die aktuelle Entwicklungs-Session ab.")
|
||||
|
||||
args = parser.parse_args()
|
||||
|
||||
if args.done:
|
||||
complete_session()
|
||||
else:
|
||||
start_interactive_session()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -11,6 +11,9 @@ RUN apt-get update && apt-get install -y --no-install-recommends \
|
||||
&& apt-get clean \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Python-Abhängigkeiten für dev_session.py installieren
|
||||
RUN pip3 install requests python-dotenv --break-system-packages
|
||||
|
||||
# Installieren der von Ihnen gefundenen, korrekten Gemini CLI global
|
||||
RUN npm install -g @google/gemini-cli
|
||||
|
||||
|
||||
61
notion_commit_hook.py
Normal file
61
notion_commit_hook.py
Normal file
@@ -0,0 +1,61 @@
|
||||
#!/usr/bin/env python3
|
||||
import os
|
||||
import sys
|
||||
import json
|
||||
import subprocess
|
||||
|
||||
# Fügen Sie das Hauptverzeichnis zum Python-Pfad hinzu, damit wir dev_session importieren können
|
||||
sys.path.append(os.path.dirname(os.path.abspath(__file__)))
|
||||
|
||||
try:
|
||||
from dev_session import add_comment_to_notion_task
|
||||
except ImportError:
|
||||
print("Fehler: Konnte dev_session.py nicht importieren.", file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
SESSION_DIR = ".dev_session"
|
||||
SESSION_FILE_PATH = os.path.join(SESSION_DIR, "SESSION_INFO")
|
||||
|
||||
def get_last_commit_message() -> str:
|
||||
"""Holt die letzte Commit-Nachricht mit git."""
|
||||
try:
|
||||
# Führt 'git log -1 --pretty=%B' aus, um die vollständige Commit-Nachricht zu erhalten
|
||||
result = subprocess.run(
|
||||
["git", "log", "-1", "--pretty=%B"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
check=True
|
||||
)
|
||||
return result.stdout.strip()
|
||||
except (subprocess.CalledProcessError, FileNotFoundError):
|
||||
return ""
|
||||
|
||||
def main():
|
||||
"""Hauptfunktion des Git-Hooks."""
|
||||
# Führe den Hook nur aus, wenn eine aktive Session existiert
|
||||
if not os.path.exists(SESSION_FILE_PATH):
|
||||
sys.exit(0)
|
||||
|
||||
try:
|
||||
with open(SESSION_FILE_PATH, "r") as f:
|
||||
session_data = json.load(f)
|
||||
|
||||
task_id = session_data.get("task_id")
|
||||
token = session_data.get("token")
|
||||
|
||||
if not task_id or not token:
|
||||
sys.exit(0)
|
||||
|
||||
commit_message = get_last_commit_message()
|
||||
|
||||
if commit_message:
|
||||
# Formatieren der Nachricht für Notion
|
||||
comment = f"✅ New Commit:\n---\n{commit_message}"
|
||||
add_comment_to_notion_task(token, task_id, comment)
|
||||
|
||||
except (FileNotFoundError, json.JSONDecodeError):
|
||||
# Wenn die Datei nicht existiert oder fehlerhaft ist, einfach beenden
|
||||
sys.exit(0)
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -1,3 +1,4 @@
|
||||
|
||||
#!/bin/sh
|
||||
|
||||
# Sicherstellen, dass der Config-Ordner existiert, damit Docker ihn als Ordner und nicht als Datei mountet
|
||||
@@ -14,4 +15,6 @@ sudo docker run -it --rm \
|
||||
-v "$(pwd):/app" \
|
||||
-v "$(pwd)/.gemini-config:/root/.config" \
|
||||
--name gemini-session \
|
||||
gemini-dev-env
|
||||
gemini-dev-env \
|
||||
bash -c "python3 dev_session.py"
|
||||
|
||||
Reference in New Issue
Block a user