22
33import asyncio
44import os
5+ from typing import Any
56from urllib import parse
67
78import click
@@ -96,7 +97,109 @@ def github_server_to_context(
9697)
9798
9899
99- @stack .command (help = "Configure the required git commit-msg hooks" ) # type: ignore[untyped-decorator]
100+ def _print_hooks_status (status : dict [str , Any ]) -> None :
101+ """Print hooks status in a formatted table."""
102+ needs_setup = False
103+ needs_force = False
104+
105+ # Git hooks section
106+ console .print ("\n Git Hooks Status:\n " )
107+ git_hooks = status ["git_hooks" ]
108+
109+ for hook_name , info in git_hooks .items ():
110+ console .print (f" { hook_name } :" )
111+
112+ wrapper_status = info ["wrapper_status" ]
113+ wrapper_path = info ["wrapper_path" ]
114+
115+ if wrapper_status == stack_setup_mod .WrapperStatus .INSTALLED :
116+ console .print (f" Wrapper: [green]installed[/] ({ wrapper_path } )" )
117+ elif wrapper_status == stack_setup_mod .WrapperStatus .LEGACY :
118+ console .print (
119+ " Wrapper: [yellow]legacy[/] (needs --force to migrate)" ,
120+ )
121+ needs_force = True
122+ else : # MISSING
123+ console .print (" Wrapper: [red]not installed[/]" )
124+ needs_setup = True
125+
126+ script_path = info ["script_path" ]
127+ if info ["script_installed" ]:
128+ if info ["script_needs_update" ]:
129+ console .print (f" Script: [yellow]needs update[/] ({ script_path } )" )
130+ needs_setup = True
131+ else :
132+ console .print (f" Script: [green]up to date[/] ({ script_path } )" )
133+ else :
134+ console .print (" Script: [red]not installed[/]" )
135+ needs_setup = True
136+
137+ console .print ()
138+
139+ # Claude hooks section
140+ console .print ("Claude Hooks Status:\n " )
141+ claude_hooks = status ["claude_hooks" ]
142+
143+ for script_name , script_info in claude_hooks ["scripts" ].items ():
144+ console .print (f" { script_name } :" )
145+ if script_info ["installed" ]:
146+ if script_info ["needs_update" ]:
147+ console .print (
148+ f" Script: [yellow]needs update[/] ({ script_info ['path' ]} )" ,
149+ )
150+ needs_setup = True
151+ else :
152+ console .print (
153+ f" Script: [green]up to date[/] ({ script_info ['path' ]} )" ,
154+ )
155+ else :
156+ console .print (" Script: [red]not installed[/]" )
157+ needs_setup = True
158+ console .print ()
159+
160+ console .print (" settings.json:" )
161+ if claude_hooks ["settings_installed" ]:
162+ console .print (
163+ f" Hook: [green]configured[/] ({ claude_hooks ['settings_path' ]} )" ,
164+ )
165+ else :
166+ console .print (" Hook: [red]not configured[/]" )
167+ needs_setup = True
168+ console .print ()
169+
170+ if needs_setup or needs_force :
171+ console .print ("Run 'mergify stack hooks --setup' to install/upgrade hooks." )
172+ if needs_force :
173+ console .print (
174+ "Run 'mergify stack hooks --setup --force' to force reinstall wrappers." ,
175+ )
176+ else :
177+ console .print ("[green]All hooks are up to date.[/]" )
178+
179+
180+ @stack .command (help = "Show git hooks status and manage installation" ) # type: ignore[untyped-decorator]
181+ @click .option (
182+ "--setup" ,
183+ "do_setup" ,
184+ is_flag = True ,
185+ help = "Install or upgrade hooks" ,
186+ )
187+ @click .option (
188+ "--force" ,
189+ "-f" ,
190+ is_flag = True ,
191+ help = "Force reinstall wrappers (use with --setup)" ,
192+ )
193+ @utils .run_with_asyncio
194+ async def hooks (* , do_setup : bool , force : bool ) -> None :
195+ if do_setup :
196+ await stack_setup_mod .stack_setup (force = force )
197+ else :
198+ status = await stack_setup_mod .get_hooks_status ()
199+ _print_hooks_status (status )
200+
201+
202+ @stack .command (help = "Configure git hooks (alias for 'stack hooks --setup')" ) # type: ignore[untyped-decorator]
100203@click .option (
101204 "--force" ,
102205 "-f" ,
@@ -106,11 +209,15 @@ def github_server_to_context(
106209@click .option (
107210 "--check" ,
108211 is_flag = True ,
109- help = "Only check hook status without making changes " ,
212+ help = "Check status only (use 'stack hooks' instead) " ,
110213)
111214@utils .run_with_asyncio
112215async def setup (* , force : bool , check : bool ) -> None :
113- await stack_setup_mod .stack_setup (force = force , check_only = check )
216+ if check :
217+ status = await stack_setup_mod .get_hooks_status ()
218+ _print_hooks_status (status )
219+ else :
220+ await stack_setup_mod .stack_setup (force = force )
114221
115222
116223@stack .command (help = "Edit the stack history" ) # type: ignore[untyped-decorator]
0 commit comments