@@ -171,11 +171,181 @@ def should_modify_pyproject_toml() -> bool:
171171 if "tests_root" not in config or config ["tests_root" ] is None or not Path (config ["tests_root" ]).is_dir ():
172172 return True
173173
174- return Confirm .ask (
174+ should_reconfigure = Confirm .ask (
175175 "✅ A valid Codeflash config already exists in this project. Do you want to re-configure it?" ,
176176 default = False ,
177177 show_default = True ,
178178 )
179+
180+ if not should_reconfigure :
181+ display_current_config (config , config_file_path )
182+
183+ return should_reconfigure
184+
185+
186+ def browse_and_select_directory (start_dir : Path , message : str , title : str ) -> Path | None :
187+ """Interactive directory browser with tab-completion-like functionality."""
188+ current_dir = start_dir
189+
190+ while True :
191+ # Get all subdirectories in current directory
192+ try :
193+ subdirs = []
194+ for item in current_dir .iterdir ():
195+ if item .is_dir () and not item .name .startswith ('.' ):
196+ subdirs .append (item .name )
197+ subdirs .sort ()
198+ except PermissionError :
199+ console .print (f"❌ Permission denied accessing { current_dir } " )
200+ return None
201+
202+ # Build choices list
203+ choices = []
204+
205+ # Add parent directory option if not at start_dir
206+ if current_dir != start_dir and current_dir .parent != current_dir :
207+ choices .append (("📁 .. (parent directory)" , ".." ))
208+
209+ # Add current directory selection option
210+ choices .append (("✅ Select this directory" , "SELECT" ))
211+
212+ # Add subdirectories
213+ for subdir in subdirs :
214+ choices .append ((f"📂 { subdir } /" , subdir ))
215+
216+ # Add option to type custom path
217+ choices .append (("⌨️ Type custom path" , "CUSTOM" ))
218+ choices .append (("❌ Cancel" , "CANCEL" ))
219+
220+ # Show current directory in panel
221+ browse_panel = Panel (
222+ Text (f"📍 Current directory: { current_dir } \n \n { message } " , style = "cyan" ),
223+ title = title ,
224+ border_style = "bright_blue" ,
225+ )
226+ console .print (browse_panel )
227+ console .print ()
228+
229+ # Prompt for selection
230+ questions = [
231+ inquirer .List (
232+ "selection" ,
233+ message = "Navigate or select directory:" ,
234+ choices = choices ,
235+ carousel = True ,
236+ )
237+ ]
238+
239+ answers = inquirer .prompt (questions , theme = CodeflashTheme ())
240+ if not answers :
241+ return None
242+
243+ selection = answers ["selection" ]
244+
245+ if selection == "SELECT" :
246+ return current_dir
247+ elif selection == "CANCEL" :
248+ return None
249+ elif selection == ".." :
250+ current_dir = current_dir .parent
251+ elif selection == "CUSTOM" :
252+ # Allow custom path input
253+ custom_panel = Panel (
254+ Text ("Enter a directory path (relative to current directory or absolute):" , style = "yellow" ),
255+ title = "🔧 Custom Path" ,
256+ border_style = "bright_yellow" ,
257+ )
258+ console .print (custom_panel )
259+ console .print ()
260+
261+ custom_path = click .prompt ("Directory path" , type = str ).strip ()
262+ if custom_path :
263+ try :
264+ if Path (custom_path ).is_absolute ():
265+ new_dir = Path (custom_path )
266+ else :
267+ new_dir = current_dir / custom_path
268+
269+ new_dir = new_dir .resolve ()
270+ if new_dir .exists () and new_dir .is_dir ():
271+ current_dir = new_dir
272+ else :
273+ console .print (f"❌ Directory does not exist: { new_dir } " )
274+ click .pause ()
275+ except Exception as e :
276+ console .print (f"❌ Invalid path: { e } " )
277+ click .pause ()
278+ else :
279+ # Navigate to subdirectory
280+ try :
281+ new_dir = current_dir / selection
282+ if new_dir .exists () and new_dir .is_dir ():
283+ current_dir = new_dir
284+ else :
285+ console .print (f"❌ Directory not accessible: { new_dir } " )
286+ click .pause ()
287+ except Exception as e :
288+ console .print (f"❌ Error accessing directory: { e } " )
289+ click .pause ()
290+
291+
292+ def display_current_config (config : dict [str , Any ], config_file_path : Path ) -> None :
293+ """Display the current codeflash configuration in a nice format."""
294+ # Create a table for the configuration
295+ config_table = Table (show_header = True , header_style = "bold cyan" )
296+ config_table .add_column ("Setting" , style = "blue" , width = 20 )
297+ config_table .add_column ("Value" , style = "green" )
298+
299+ # Add configuration rows
300+ config_table .add_row ("Module Root" , str (config .get ("module_root" , "Not set" )))
301+
302+ # Handle tests_root - it could be a string or list
303+ tests_root = config .get ("tests_root" , "Not set" )
304+ if isinstance (tests_root , list ):
305+ tests_root_display = ", " .join (tests_root ) if tests_root else "Not set"
306+ else :
307+ tests_root_display = str (tests_root )
308+ config_table .add_row ("Tests Root" , tests_root_display )
309+
310+ config_table .add_row ("Test Framework" , str (config .get ("test_framework" , "Not set" )))
311+ config_table .add_row ("Benchmarks Root" , str (config .get ("benchmarks_root" , "Not set" )))
312+ config_table .add_row ("Git Remote" , str (config .get ("git_remote" , "origin" )))
313+
314+ # Handle formatter commands
315+ formatter_cmds = config .get ("formatter_cmds" , [])
316+ if isinstance (formatter_cmds , list ):
317+ formatter_display = ", " .join (formatter_cmds ) if formatter_cmds else "Not set"
318+ else :
319+ formatter_display = str (formatter_cmds )
320+ config_table .add_row ("Formatter Commands" , formatter_display )
321+
322+ # Handle ignore paths
323+ ignore_paths = config .get ("ignore_paths" , [])
324+ if isinstance (ignore_paths , list ):
325+ ignore_display = ", " .join (ignore_paths ) if ignore_paths else "None"
326+ else :
327+ ignore_display = str (ignore_paths )
328+ config_table .add_row ("Ignore Paths" , ignore_display )
329+
330+ # Display telemetry setting
331+ telemetry_disabled = config .get ("disable_telemetry" , False )
332+ telemetry_status = "Disabled" if telemetry_disabled else "Enabled"
333+ config_table .add_row ("Telemetry" , telemetry_status )
334+
335+ # Create the panel
336+ config_panel = Panel (
337+ Group (
338+ Text ("📋 Current Codeflash Configuration\n " , style = "bold cyan" , justify = "center" ),
339+ Text (f"Configuration file: { config_file_path } \n " , style = "dim" ),
340+ config_table
341+ ),
342+ title = "📋 Current Configuration" ,
343+ border_style = "bright_blue" ,
344+ padding = (1 , 2 ),
345+ )
346+
347+ console .print (config_panel )
348+ console .print ()
179349
180350
181351# Custom theme for better UX
@@ -336,16 +506,13 @@ def collect_setup_info() -> SetupInfo:
336506 console .print (custom_tests_panel )
337507 console .print ()
338508
339- custom_tests_questions = [
340- inquirer .Path (
341- "custom_tests_path" , message = "Enter the path to your tests directory" , path_type = inquirer .Path .DIRECTORY
342- )
343- ]
344-
345- custom_tests_answers = inquirer .prompt (custom_tests_questions , theme = CodeflashTheme ())
346- if custom_tests_answers :
347- tests_root = Path (curdir ) / Path (custom_tests_answers ["custom_tests_path" ])
348- else :
509+ # Use interactive directory browser instead of simple path input
510+ tests_root = browse_and_select_directory (
511+ curdir ,
512+ "Select your tests directory:" ,
513+ "🧪 Browse for Tests Directory"
514+ )
515+ if not tests_root :
349516 apologize_and_exit ()
350517 else :
351518 tests_root = Path (curdir ) / Path (cast ("str" , tests_root_answer ))
0 commit comments