1- import { commands , ExtensionContext , extensions , LogOutputChannel , Terminal , Uri , window , workspace } from 'vscode' ;
1+ import { commands , ExtensionContext , LogOutputChannel , Terminal , Uri , window } from 'vscode' ;
2+ import { version as extensionVersion } from '../package.json' ;
23import { PythonEnvironment , PythonEnvironmentApi , PythonProjectCreator } from './api' ;
34import { ensureCorrectVersion } from './common/extVersion' ;
4- import { registerLogger , traceError , traceInfo , traceWarn } from './common/logging' ;
5+ import { registerLogger , traceError , traceInfo , traceVerbose , traceWarn } from './common/logging' ;
56import { clearPersistentState , setPersistentState } from './common/persistentState' ;
67import { newProjectSelection } from './common/pickers/managers' ;
78import { StopWatch } from './common/stopWatch' ;
89import { EventNames } from './common/telemetry/constants' ;
910import { sendManagerSelectionTelemetry } from './common/telemetry/helpers' ;
1011import { sendTelemetryEvent } from './common/telemetry/sender' ;
1112import { createDeferred } from './common/utils/deferred' ;
12- import { normalizePath } from './common/utils/pathUtils' ;
1313import { isWindows } from './common/utils/platformUtils' ;
1414import {
1515 activeTerminal ,
@@ -61,19 +61,23 @@ import { cleanupStartupScripts } from './features/terminal/shellStartupSetupHand
6161import { TerminalActivationImpl } from './features/terminal/terminalActivationState' ;
6262import { TerminalEnvVarInjector } from './features/terminal/terminalEnvVarInjector' ;
6363import { TerminalManager , TerminalManagerImpl } from './features/terminal/terminalManager' ;
64- import { getAutoActivationType , getEnvironmentForTerminal } from './features/terminal/utils' ;
64+ import { getEnvironmentForTerminal } from './features/terminal/utils' ;
6565import { EnvManagerView } from './features/views/envManagersView' ;
6666import { ProjectView } from './features/views/projectView' ;
6767import { PythonStatusBarImpl } from './features/views/pythonStatusBar' ;
6868import { updateViewsAndStatus } from './features/views/revealHandler' ;
6969import { ProjectItem } from './features/views/treeViewItems' ;
70+ import {
71+ collectEnvironmentInfo ,
72+ getEnvManagerAndPackageManagerConfigLevels ,
73+ resolveDefaultInterpreter ,
74+ } from './helpers' ;
7075import { EnvironmentManagers , ProjectCreators , PythonProjectManager } from './internal.api' ;
7176import { registerSystemPythonFeatures } from './managers/builtin/main' ;
7277import { SysPythonManager } from './managers/builtin/sysPythonManager' ;
7378import {
7479 createNativePythonFinder ,
7580 getNativePythonToolsPath ,
76- NativeEnvInfo ,
7781 NativePythonFinder ,
7882} from './managers/common/nativePythonFinder' ;
7983import { IDisposable } from './managers/common/types' ;
@@ -82,89 +86,6 @@ import { registerPipenvFeatures } from './managers/pipenv/main';
8286import { registerPoetryFeatures } from './managers/poetry/main' ;
8387import { registerPyenvFeatures } from './managers/pyenv/main' ;
8488
85- /**
86- * Collects relevant Python environment information for issue reporting
87- */
88- async function collectEnvironmentInfo (
89- context : ExtensionContext ,
90- envManagers : EnvironmentManagers ,
91- projectManager : PythonProjectManager ,
92- ) : Promise < string > {
93- const info : string [ ] = [ ] ;
94-
95- try {
96- // Extension version
97- const extensionVersion = context . extension ?. packageJSON ?. version || 'unknown' ;
98- info . push ( `Extension Version: ${ extensionVersion } ` ) ;
99-
100- // Python extension version
101- const pythonExtension = extensions . getExtension ( 'ms-python.python' ) ;
102- const pythonVersion = pythonExtension ?. packageJSON ?. version || 'not installed' ;
103- info . push ( `Python Extension Version: ${ pythonVersion } ` ) ;
104-
105- // Environment managers
106- const managers = envManagers . managers ;
107- info . push ( `\nRegistered Environment Managers (${ managers . length } ):` ) ;
108- managers . forEach ( ( manager ) => {
109- info . push ( ` - ${ manager . id } (${ manager . displayName } )` ) ;
110- } ) ;
111-
112- // Available environments
113- const allEnvironments : PythonEnvironment [ ] = [ ] ;
114- for ( const manager of managers ) {
115- try {
116- const envs = await manager . getEnvironments ( 'all' ) ;
117- allEnvironments . push ( ...envs ) ;
118- } catch ( err ) {
119- info . push ( ` Error getting environments from ${ manager . id } : ${ err } ` ) ;
120- }
121- }
122-
123- info . push ( `\nTotal Available Environments: ${ allEnvironments . length } ` ) ;
124- if ( allEnvironments . length > 0 ) {
125- info . push ( 'Environment Details:' ) ;
126- allEnvironments . slice ( 0 , 10 ) . forEach ( ( env , index ) => {
127- info . push ( ` ${ index + 1 } . ${ env . displayName } (${ env . version } ) - ${ env . displayPath } ` ) ;
128- } ) ;
129- if ( allEnvironments . length > 10 ) {
130- info . push ( ` ... and ${ allEnvironments . length - 10 } more environments` ) ;
131- }
132- }
133-
134- // Python projects
135- const projects = projectManager . getProjects ( ) ;
136- info . push ( `\nPython Projects (${ projects . length } ):` ) ;
137- for ( let index = 0 ; index < projects . length ; index ++ ) {
138- const project = projects [ index ] ;
139- info . push ( ` ${ index + 1 } . ${ project . uri . fsPath } ` ) ;
140- try {
141- const env = await envManagers . getEnvironment ( project . uri ) ;
142- if ( env ) {
143- info . push ( ` Environment: ${ env . displayName } ` ) ;
144- }
145- } catch ( err ) {
146- info . push ( ` Error getting environment: ${ err } ` ) ;
147- }
148- }
149-
150- // Current settings (non-sensitive)
151- const config = workspace . getConfiguration ( 'python-envs' ) ;
152- const pyConfig = workspace . getConfiguration ( 'python' ) ;
153- info . push ( '\nExtension Settings:' ) ;
154- info . push ( ` Default Environment Manager: ${ config . get ( 'defaultEnvManager' ) } ` ) ;
155- info . push ( ` Default Package Manager: ${ config . get ( 'defaultPackageManager' ) } ` ) ;
156- const pyenvAct = config . get ( 'terminal.autoActivationType' , undefined ) ;
157- const pythonAct = pyConfig . get ( 'terminal.activateEnvironment' , undefined ) ;
158- info . push (
159- `Auto-activation is "${ getAutoActivationType ( ) } ". Activation based on first 'py-env.terminal.autoActivationType' setting which is '${ pyenvAct } ' and 'python.terminal.activateEnvironment' if the first is undefined which is '${ pythonAct } '.\n` ,
160- ) ;
161- } catch ( err ) {
162- info . push ( `\nError collecting environment information: ${ err } ` ) ;
163- }
164-
165- return info . join ( '\n' ) ;
166- }
167-
16889export async function activate ( context : ExtensionContext ) : Promise < PythonEnvironmentApi | undefined > {
16990 const useEnvironmentsExtension = getConfiguration ( 'python' ) . get < boolean > ( 'useEnvironmentsExtension' , true ) ;
17091 traceInfo ( `Experiment Status: useEnvironmentsExtension setting set to ${ useEnvironmentsExtension } ` ) ;
@@ -183,6 +104,13 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
183104
184105 ensureCorrectVersion ( ) ;
185106
107+ // log extension version
108+ traceVerbose ( `Python-envs extension version: ${ extensionVersion } ` ) ;
109+ // log settings
110+ const configLevels = getEnvManagerAndPackageManagerConfigLevels ( ) ;
111+ traceInfo ( `\n=== ${ configLevels . section } ===` ) ;
112+ traceInfo ( JSON . stringify ( configLevels , null , 2 ) ) ;
113+
186114 // Setup the persistent state for the extension.
187115 setPersistentState ( context ) ;
188116
@@ -570,7 +498,7 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
570498 shellStartupVarsMgr . initialize ( ) ,
571499 ] ) ;
572500
573- resolveDefaultInterpreter ( nativeFinder , envManagers , api ) ;
501+ await resolveDefaultInterpreter ( nativeFinder , envManagers , api ) ;
574502
575503 sendTelemetryEvent ( EventNames . EXTENSION_MANAGER_REGISTRATION_DURATION , start . elapsedTime ) ;
576504 await terminalManager . initialize ( api ) ;
@@ -595,78 +523,6 @@ export async function disposeAll(disposables: IDisposable[]): Promise<void> {
595523 ) ;
596524}
597525
598- /**
599- * Sets the default Python interpreter for the workspace if the user has not explicitly set 'defaultEnvManager' or it is set to venv.
600- * @param nativeFinder - used to resolve interpreter paths.
601- * @param envManagers - contains all registered managers.
602- * @param api - The PythonEnvironmentApi for environment resolution and setting.
603- */
604- async function resolveDefaultInterpreter (
605- nativeFinder : NativePythonFinder ,
606- envManagers : EnvironmentManagers ,
607- api : PythonEnvironmentApi ,
608- ) {
609- const defaultInterpreterPath = getConfiguration ( 'python' ) . get < string > ( 'defaultInterpreterPath' ) ;
610-
611- if ( defaultInterpreterPath ) {
612- const config = getConfiguration ( 'python-envs' ) ;
613- const inspect = config . inspect < string > ( 'defaultEnvManager' ) ;
614- const userDefinedDefaultManager =
615- inspect ?. workspaceFolderValue !== undefined ||
616- inspect ?. workspaceValue !== undefined ||
617- inspect ?. globalValue !== undefined ;
618- if ( ! userDefinedDefaultManager ) {
619- try {
620- const resolved : NativeEnvInfo = await nativeFinder . resolve ( defaultInterpreterPath ) ;
621- if ( resolved && resolved . executable ) {
622- if ( normalizePath ( resolved . executable ) === normalizePath ( defaultInterpreterPath ) ) {
623- // no action required, the path is already correct
624- return ;
625- }
626- const resolvedEnv = await api . resolveEnvironment ( Uri . file ( resolved . executable ) ) ;
627- traceInfo ( `[resolveDefaultInterpreter] API resolved environment: ${ JSON . stringify ( resolvedEnv ) } ` ) ;
628-
629- let findEnvManager = envManagers . managers . find ( ( m ) => m . id === resolvedEnv ?. envId . managerId ) ;
630- if ( ! findEnvManager ) {
631- findEnvManager = envManagers . managers . find ( ( m ) => m . id === 'ms-python.python:system' ) ;
632- }
633- if ( resolvedEnv ) {
634- const newEnv : PythonEnvironment = {
635- envId : {
636- id : resolvedEnv ?. envId . id ,
637- managerId : resolvedEnv ?. envId . managerId ?? '' ,
638- } ,
639- name : 'defaultInterpreterPath: ' + ( resolved . version ?? '' ) ,
640- displayName : 'defaultInterpreterPath: ' + ( resolved . version ?? '' ) ,
641- version : resolved . version ?? '' ,
642- displayPath : defaultInterpreterPath ?? '' ,
643- environmentPath : defaultInterpreterPath ? Uri . file ( defaultInterpreterPath ) : Uri . file ( '' ) ,
644- sysPrefix : resolved . arch ?? '' ,
645- execInfo : {
646- run : {
647- executable : defaultInterpreterPath ?? '' ,
648- } ,
649- } ,
650- } ;
651- if ( workspace . workspaceFolders ?. [ 0 ] && findEnvManager ) {
652- traceInfo (
653- `[resolveDefaultInterpreter] Setting environment for workspace: ${ workspace . workspaceFolders [ 0 ] . uri . fsPath } ` ,
654- ) ;
655- await api . setEnvironment ( workspace . workspaceFolders [ 0 ] . uri , newEnv ) ;
656- }
657- }
658- } else {
659- traceWarn (
660- `[resolveDefaultInterpreter] NativeFinder did not resolve an executable for path: ${ defaultInterpreterPath } ` ,
661- ) ;
662- }
663- } catch ( err ) {
664- traceError ( `[resolveDefaultInterpreter] Error resolving default interpreter: ${ err } ` ) ;
665- }
666- }
667- }
668- }
669-
670526export async function deactivate ( context : ExtensionContext ) {
671527 await disposeAll ( context . subscriptions ) ;
672528 context . subscriptions . length = 0 ; // Clear subscriptions to prevent memory leaks
0 commit comments