1
+ import threading
2
+
1
3
from watchdog .observers import Observer
2
4
from watchdog .events import FileSystemEventHandler
3
5
import subprocess
4
6
import os
5
7
import time
6
8
import signal
9
+ from pathlib import Path
10
+ from rich .console import Console
11
+ from rich .panel import Panel
7
12
8
13
# parse arg
9
14
import argparse
12
17
parser .add_argument ("package_path" , type = str , help = "Path to the package to watch." )
13
18
parser .add_argument ("mkdocs_path" , type = str , help = "Path to the MkDocs folder." )
14
19
args = parser .parse_args ()
15
- package_path = args .package_path
16
- mkdocs_path = args .mkdocs_path
20
+ package_path = Path (args .package_path )
21
+ mkdocs_path = Path (args .mkdocs_path )
22
+ console = Console ()
17
23
18
24
19
25
class PackageWatchHandler (FileSystemEventHandler ) :
20
26
def __init__ (self , package_path , mkdocs_path ) :
21
27
self .package_path = package_path
22
28
self .mkdocs_path = mkdocs_path
23
29
self .mkdocs_process = None
30
+ self .mkdocs_process = None
31
+ self .log_thread = None
32
+ self .stop_logging = False
33
+
34
+ def log_output (self , process ) :
35
+ """Thread for logging MkDocs output with Rich."""
36
+ while process .poll () is None : # Check if process is still running
37
+ line = process .stdout .readline ()
38
+ if line :
39
+ # Utilise Rich pour afficher les logs stylisés
40
+ if "ERROR" in line :
41
+ console .log (f"[bold red][MkDocs ERROR][/bold red]: { line .strip ()} " )
42
+ elif "WARNING" in line :
43
+ console .log (f"[bold yellow][MkDocs WARNING][/bold yellow]: { line .strip ()} " )
44
+ else :
45
+ console .log (f"[bold green][MkDocs][/bold green]: { line .strip ()} " )
24
46
25
47
def start_mkdocs (self ) :
26
48
"""Démarre le serveur MkDocs avec python -m mkdocs."""
27
- print ("Starting MkDocs server..." )
49
+ console . print (Panel ( f "Starting MkDocs server for { self . mkdocs_path } ..." , style = "bold blue" ) )
28
50
self .mkdocs_process = subprocess .Popen (
29
- ["python " , "-m " , "mkdocs" , "serve" ],
51
+ ["uv " , "run " , "mkdocs" , "--color " , "serve" ],
30
52
cwd = self .mkdocs_path ,
31
53
stdout = subprocess .PIPE ,
32
- stderr = subprocess .PIPE ,
33
- text = True ,
54
+ stderr = subprocess .STDOUT ,
55
+ universal_newlines = True ,
56
+ bufsize = 1 ,
57
+ )
58
+ self .stop_logging = False
59
+ self .log_thread = threading .Thread (target = self .log_output , args = (self .mkdocs_process ,))
60
+ self .log_thread .start ()
61
+ console .print (
62
+ Panel ("MkDocs server started at [bold blue]https://127.0.0.1:8000[/bold blue]." , style = "bold green" )
34
63
)
35
- print ("MkDocs server started." )
36
64
37
65
def stop_mkdocs (self ) :
38
- """Arrête le serveur MkDocs proprement ."""
66
+ """Stop the MkDocs server ."""
39
67
if self .mkdocs_process :
40
- print ("Stopping MkDocs server..." )
68
+ console .print (Panel ("Stopping MkDocs server..." , style = "bold red" ))
69
+ self .stop_logging = True
41
70
self .mkdocs_process .terminate ()
42
71
try :
43
72
self .mkdocs_process .wait (timeout = 5 )
44
73
except subprocess .TimeoutExpired :
45
74
os .kill (self .mkdocs_process .pid , signal .SIGKILL )
46
- print ("MkDocs server stopped." )
75
+ if self .log_thread :
76
+ self .log_thread .join ()
47
77
self .mkdocs_process = None
78
+ console .print (Panel ("MkDocs server stopped." , style = "bold red" ))
48
79
49
80
def restart_mkdocs (self ) :
50
- """Redémarre le serveur MkDocs."""
81
+ """Restart the MkDocs server ."""
51
82
self .stop_mkdocs ()
52
83
self .start_mkdocs ()
53
84
54
85
def on_any_event (self , event ) :
55
- """Réagit aux modifications de fichiers ."""
86
+ """React to file changes ."""
56
87
if event .is_directory or not event .src_path .endswith (".py" ) :
57
88
return
58
- print (f"Change detected in { event .src_path } . Reinstalling package..." )
59
- subprocess .run (["pip" , "install" , "-e" , self .package_path ], check = True )
89
+ console . print (Panel ( f"Change detected in { event .src_path } . Reinstalling package..." , style = "bold yellow" ) )
90
+ subprocess .run (["uv" , " pip" , "install" , "-e" , self .package_path ], check = True )
60
91
self .restart_mkdocs ()
61
92
62
93
@@ -66,27 +97,22 @@ def on_any_event(self, event) :
66
97
67
98
# Vérifie si le dossier MkDocs existe
68
99
if not os .path .isdir (mkdocs_path ) :
69
- print (f"Error: MkDocs path '{ mkdocs_path } ' does not exist." )
100
+ console . print (f"[bold red] Error:[/bold red] MkDocs path '{ mkdocs_path } ' does not exist." )
70
101
exit (1 )
71
102
72
103
event_handler = PackageWatchHandler (package_path , mkdocs_path )
73
104
observer = Observer ()
74
105
observer .schedule (event_handler , package_path , recursive = True )
75
106
76
- print (f"Watching for changes in { package_path } ..." )
77
- event_handler .start_mkdocs () # Lancer MkDocs au début
107
+ console . print (f"[bold green] Watching for changes in { package_path } ...[/bold green] " )
108
+ event_handler .start_mkdocs ()
78
109
observer .start ()
79
110
80
111
try :
81
112
while True :
82
- # Lire les logs de MkDocs pendant que le script tourne
83
- if event_handler .mkdocs_process :
84
- output = event_handler .mkdocs_process .stdout .readline ()
85
- if output :
86
- print (f"[MkDocs]: { output .strip ()} " )
87
113
time .sleep (1 )
88
114
except KeyboardInterrupt :
89
- print ("Shutting down..." )
115
+ console . print ("[bold red] Shutting down...[/bold red] " )
90
116
observer .stop ()
91
117
event_handler .stop_mkdocs ()
92
- observer .join ()
118
+ observer .join ()
0 commit comments