Compare commits

...

2 Commits

Author SHA1 Message Date
ba1cf1ea25 Maj git_updater pour l'auto maj 2026-03-24 13:08:33 +01:00
3ecae321e7 Ajout de la version 2026-03-24 13:01:06 +01:00
3 changed files with 70 additions and 10 deletions

2
.gitignore vendored
View File

@@ -3,3 +3,5 @@ dist/
build/
__pycache__/
*.spec
*.exe.old
_update.bat

BIN
GitUpdateChecker.exe Normal file

Binary file not shown.

View File

@@ -5,6 +5,8 @@ Accès lecture seule uniquement (fetch/pull/checkout, jamais de push).
Tous les chemins sont relatifs à l'emplacement de l'exécutable.
"""
VERSION = "0.1"
import subprocess
import sys
import os
@@ -139,25 +141,80 @@ def check_self_update():
def do_self_update():
"""Pull les mises à jour du programme lui-même. Retourne (ok, message)."""
"""
Met à jour le programme lui-même.
Sur Windows, un .exe en cours d'exécution ne peut pas être écrasé.
Stratégie : renommer l'exe actuel en .old, puis git pull le nouveau.
Retourne (ok, message).
"""
exe_dir = str(get_exe_dir())
is_frozen = getattr(sys, "frozen", False)
code, branch, _ = run_git(["rev-parse", "--abbrev-ref", "HEAD"], cwd=exe_dir)
if code != 0:
return False, "Impossible de lire la branche"
# Restaurer les fichiers locaux modifiés d'abord
run_git(["checkout", "--", "."], cwd=exe_dir)
# Si on tourne en .exe, renommer l'exe actuel pour libérer le fichier
exe_old_path = None
if is_frozen:
exe_path = Path(sys.executable)
exe_old_path = exe_path.with_suffix(".exe.old")
try:
# Supprimer un ancien .old s'il existe
if exe_old_path.exists():
exe_old_path.unlink()
# Windows permet de renommer un exe en cours d'exécution
exe_path.rename(exe_old_path)
log.info(f"Auto-update: exe renomme {exe_path.name} -> {exe_old_path.name}")
except OSError as e:
log.error(f"Auto-update: impossible de renommer l'exe: {e}")
return False, f"Impossible de renommer l'exe: {e}"
# Restaurer les fichiers locaux modifiés puis pull
run_git(["checkout", "--", "."], cwd=exe_dir)
code, _, err = run_git(["pull", "origin", branch], cwd=exe_dir)
code, out, err = run_git(["pull", "origin", branch], cwd=exe_dir)
if code == 0:
log.info(f"Auto-update: pull OK")
return True, "Mise a jour du programme reussie !\nRedemarre le programme pour appliquer."
log.info("Auto-update: pull OK")
return True, "Mise a jour reussie !\nLe programme va redemarrer."
else:
# En cas d'échec, restaurer l'ancien exe
if is_frozen and exe_old_path and exe_old_path.exists():
try:
exe_old_path.rename(Path(sys.executable))
log.info("Auto-update: exe restaure apres echec")
except OSError:
pass
log.error(f"Auto-update: pull echoue: {err}")
return False, f"Erreur pull: {err}"
def relaunch_program():
"""Relance le programme (nouvel exe) et quitte le processus actuel."""
if getattr(sys, "frozen", False):
exe_path = str(Path(sys.executable))
log.info(f"Auto-update: relance de {exe_path}")
# Lancer un batch qui attend 1s puis lance le nouvel exe et supprime l'ancien .old
bat_path = str(get_exe_dir() / "_update.bat")
bat_content = (
f'@echo off\n'
f'timeout /t 1 /nobreak >nul\n'
f'start "" "{exe_path}"\n'
f'del "{exe_path}.old" 2>nul\n'
f'del "%~f0"\n'
)
with open(bat_path, "w") as f:
f.write(bat_content)
subprocess.Popen(
["cmd", "/c", bat_path],
creationflags=subprocess.CREATE_NO_WINDOW,
)
else:
# Mode script : relancer python
log.info("Auto-update: relance du script")
subprocess.Popen([sys.executable, __file__])
# ── Configuration ────────────────────────────────────────────────────────────
def get_config_path():
@@ -359,7 +416,7 @@ def do_restore(local_path):
class App(tk.Tk):
def __init__(self):
super().__init__()
self.title("Git Update Checker")
self.title(f"Git Update Checker v{VERSION}")
self.geometry("820x600")
self.minsize(700, 450)
self.configure(bg="#1e1e2e")
@@ -367,7 +424,7 @@ class App(tk.Tk):
self.repos_config = load_repos()
self.repo_results = []
log.info("=== Demarrage Git Update Checker ===")
log.info(f"=== Demarrage Git Update Checker v{VERSION} ===")
self._build_ui()
self.after(100, self._check_self_update_then_repos)
@@ -395,7 +452,7 @@ class App(tk.Tk):
# Header
header = ttk.Frame(self)
header.pack(fill="x", padx=15, pady=(15, 5))
ttk.Label(header, text="Git Update Checker", style="Title.TLabel").pack(side="left")
ttk.Label(header, text=f"Git Update Checker v{VERSION}", style="Title.TLabel").pack(side="left")
self.status_label = ttk.Label(header, text="Verification en cours...", style="Status.TLabel")
self.status_label.pack(side="right")
@@ -470,7 +527,8 @@ class App(tk.Tk):
"""Callback après auto-update."""
if ok:
messagebox.showinfo("Auto-update", msg)
log.info("Auto-update appliquee, fermeture")
log.info("Auto-update appliquee, relance...")
relaunch_program()
self.destroy()
return
else: