@@ -408,7 +408,7 @@ function extractEnvironmentDirectory(executablePath: string): string | undefined
408408
409409/**
410410 * Gets all extra environment search paths from various configuration sources.
411- * Combines python.venvFolders (for migration), python-env.searchPaths settings, and legacy custom venv dirs .
411+ * Combines legacy python settings (with migration), python-env.searchPaths settings.
412412 * @returns Array of search directory paths
413413 */
414414async function getAllExtraSearchPaths ( ) : Promise < string [ ] > {
@@ -419,8 +419,8 @@ async function getAllExtraSearchPaths(): Promise<string[]> {
419419 searchDirectories . push ( ...customVenvDirs ) ;
420420 traceLog ( 'Added legacy custom venv directories:' , customVenvDirs ) ;
421421
422- // Handle migration from python.venvFolders to python-env.searchPaths
423- await handleVenvFoldersMigration ( ) ;
422+ // Handle migration from legacy python settings to python-env.searchPaths
423+ await handleLegacyPythonSettingsMigration ( ) ;
424424
425425 // Get searchPaths using proper VS Code settings precedence
426426 const searchPaths = getSearchPathsWithPrecedence ( ) ;
@@ -445,19 +445,15 @@ async function getAllExtraSearchPaths(): Promise<string[]> {
445445 traceLog ( 'Processing regex pattern for Python environment discovery:' , trimmedPath ) ;
446446 traceLog ( 'Warning: Using regex patterns in searchPaths may cause performance issues due to file system scanning' ) ;
447447
448- // Modify the regex to search for directories that might contain Python executables
449- // Instead of searching for executables directly, we append python pattern to find parent directories
450- const directoryPattern = trimmedPath . endsWith ( 'python*' ) ? trimmedPath . replace ( / p y t h o n \* $ / , '' ) : trimmedPath ;
451-
452- // Use workspace.findFiles to search for directories or python-related files
453- const foundFiles = await workspace . findFiles ( directoryPattern + '**/python*' , null ) ;
454- traceLog ( 'Regex pattern search found' , foundFiles . length , 'files matching pattern:' , directoryPattern + '**/python*' ) ;
448+ // Use workspace.findFiles to search with the regex pattern as literally as possible
449+ const foundFiles = await workspace . findFiles ( trimmedPath , null ) ;
450+ traceLog ( 'Regex pattern search found' , foundFiles . length , 'files matching pattern:' , trimmedPath ) ;
455451
456452 for ( const file of foundFiles ) {
457453 const filePath = file . fsPath ;
458454 traceLog ( 'Evaluating file from regex search:' , filePath ) ;
459455
460- // Get environment folder (file -> bin -> env -> this)
456+ // Extract environment directory from the found file path
461457 const environmentDir = extractEnvironmentDirectory ( filePath ) ;
462458 if ( environmentDir ) {
463459 searchDirectories . push ( environmentDir ) ;
@@ -473,13 +469,9 @@ async function getAllExtraSearchPaths(): Promise<string[]> {
473469 searchDirectories . push ( trimmedPath ) ;
474470 traceLog ( 'Added directory as search path:' , trimmedPath ) ;
475471 }
476- // If path doesn't exist, add it anyway as it might exist in the future
477- // This handles cases where:
478- // - Virtual environments might be created later
479- // - Network drives that might not be mounted yet
480- // - Symlinks to directories that might be created
472+ // Path doesn't exist yet - might be created later (virtual envs, network drives, symlinks)
481473 else {
482- traceLog ( 'Path does not exist currently, adding for future resolution when environments may be created :' , trimmedPath ) ;
474+ traceLog ( 'Path does not exist currently, adding for future resolution:' , trimmedPath ) ;
483475 searchDirectories . push ( trimmedPath ) ;
484476 }
485477 } catch ( error ) {
@@ -540,51 +532,71 @@ function untildifyArray(paths: string[]): string[] {
540532}
541533
542534/**
543- * Handles migration from python. venvFolders to python-env.searchPaths.
544- * Only migrates if python.venvFolders exists and searchPaths is different.
535+ * Handles migration from legacy python settings (python.venvPath and python. venvFolders) to python-env.searchPaths.
536+ * Only migrates if legacy settings exist and searchPaths is different.
545537 */
546- async function handleVenvFoldersMigration ( ) : Promise < void > {
538+ async function handleLegacyPythonSettingsMigration ( ) : Promise < void > {
547539 try {
548- // Check if we have python.venvFolders set at user level
549540 const pythonConfig = getConfiguration ( 'python' ) ;
541+ const envConfig = getConfiguration ( 'python-env' ) ;
542+
543+ // Get legacy settings
544+ const venvPathInspection = pythonConfig . inspect < string > ( 'venvPath' ) ;
545+ const venvPath = venvPathInspection ?. globalValue ;
546+
550547 const venvFoldersInspection = pythonConfig . inspect < string [ ] > ( 'venvFolders' ) ;
551- const venvFolders = venvFoldersInspection ?. globalValue ;
548+ const venvFolders = venvFoldersInspection ?. globalValue || [ ] ;
549+
550+ // Collect all legacy paths
551+ const legacyPaths : string [ ] = [ ] ;
552+ if ( venvPath ) {
553+ legacyPaths . push ( venvPath ) ;
554+ }
555+ legacyPaths . push ( ...venvFolders ) ;
552556
553- if ( ! venvFolders || venvFolders . length === 0 ) {
557+ if ( legacyPaths . length === 0 ) {
554558 return ;
555559 }
556560
557- traceLog ( 'Found python.venvFolders setting :' , venvFolders ) ;
561+ traceLog ( 'Found legacy python settings - venvPath:' , venvPath , 'venvFolders :', venvFolders ) ;
558562
559563 // Check current searchPaths at user level
560- const envConfig = getConfiguration ( 'python-env' ) ;
561564 const searchPathsInspection = envConfig . inspect < string [ ] > ( 'searchPaths' ) ;
562565 const currentSearchPaths = searchPathsInspection ?. globalValue || [ ] ;
563566
564567 // Check if they are the same (no need to migrate)
565- if ( arraysEqual ( venvFolders , currentSearchPaths ) ) {
566- traceLog ( 'python.venvFolders and searchPaths are identical, no migration needed' ) ;
568+ if ( arraysEqual ( legacyPaths , currentSearchPaths ) ) {
569+ traceLog ( 'Legacy settings and searchPaths are identical, no migration needed' ) ;
567570 return ;
568571 }
569572
570- // Combine venvFolders with existing searchPaths (remove duplicates)
571- const combinedPaths = Array . from ( new Set ( [ ...currentSearchPaths , ...venvFolders ] ) ) ;
573+ // Combine legacy paths with existing searchPaths (remove duplicates)
574+ const combinedPaths = Array . from ( new Set ( [ ...currentSearchPaths , ...legacyPaths ] ) ) ;
572575
573576 // Update searchPaths at user level
574577 await envConfig . update ( 'searchPaths' , combinedPaths , true ) ; // true = global/user level
575578
576- traceLog ( 'Migrated python.venvFolders to searchPaths. Combined paths:' , combinedPaths ) ;
579+ // Delete the old legacy settings
580+ if ( venvPath ) {
581+ await pythonConfig . update ( 'venvPath' , undefined , true ) ;
582+ }
583+ if ( venvFolders . length > 0 ) {
584+ await pythonConfig . update ( 'venvFolders' , undefined , true ) ;
585+ }
586+
587+ traceLog ( 'Migrated legacy python settings to searchPaths and removed old settings. Combined paths:' , combinedPaths ) ;
577588
578589 // Show notification to user about migration
579590 // Note: We should only show this once per session to avoid spam
580591 if ( ! migrationNotificationShown ) {
581592 migrationNotificationShown = true ;
582593 // Note: Actual notification would use VS Code's window.showInformationMessage
583594 // but we'll log it for now since we can't import window APIs here
584- traceLog ( 'User notification: Automatically migrated python.venvFolders setting to python-env.searchPaths' ) ;
595+ const settingsRemoved = [ venvPath ? 'python.venvPath' : '' , venvFolders . length > 0 ? 'python.venvFolders' : '' ] . filter ( Boolean ) . join ( ' and ' ) ;
596+ traceLog ( `User notification: Automatically migrated ${ settingsRemoved } to python-env.searchPaths and removed the old settings.` ) ;
585597 }
586598 } catch ( error ) {
587- traceLog ( 'Error during venvFolders migration:' , error ) ;
599+ traceLog ( 'Error during legacy python settings migration:' , error ) ;
588600 }
589601}
590602
0 commit comments