Skip to content

Commit a0af050

Browse files
committed
chore: more refactoring
1 parent b7e63c5 commit a0af050

File tree

14 files changed

+657
-660
lines changed

14 files changed

+657
-660
lines changed

.vscode/settings.json

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,17 @@
1212
"typescript.tsc.autoDetect": "off",
1313
"editor.formatOnSave": true,
1414
"[typescript]": {
15-
"editor.defaultFormatter": "esbenp.prettier-vscode"
15+
"editor.defaultFormatter": "esbenp.prettier-vscode",
16+
"editor.codeActionsOnSave": {
17+
"source.organizeImports": "explicit"
18+
}
1619
},
1720
"[python]": {
1821
"editor.defaultFormatter": "charliermarsh.ruff",
19-
"diffEditor.ignoreTrimWhitespace": false
22+
"diffEditor.ignoreTrimWhitespace": false,
23+
"editor.codeActionsOnSave": {
24+
"source.organizeImports": "explicit"
25+
}
2026
},
2127
"prettier.tabWidth": 4,
2228
"python-envs.defaultEnvManager": "ms-python.python:venv",

src/extension.ts

Lines changed: 42 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -1,71 +1,64 @@
11
import { commands, ExtensionContext, LogOutputChannel, Terminal, Uri } from 'vscode';
22

3-
import { PythonEnvironmentManagers } from './features/envManagers';
3+
import { PythonEnvironment, PythonEnvironmentApi } from './api';
4+
import { ensureCorrectVersion } from './common/extVersion';
5+
import { registerTools } from './common/lm.apis';
46
import { registerLogger, traceInfo } from './common/logging';
5-
import { EnvManagerView } from './features/views/envManagersView';
7+
import { setPersistentState } from './common/persistentState';
8+
import { StopWatch } from './common/stopWatch';
9+
import { EventNames } from './common/telemetry/constants';
10+
import { sendTelemetryEvent } from './common/telemetry/sender';
11+
import {
12+
activeTerminal,
13+
createLogOutputChannel,
14+
onDidChangeActiveTerminal,
15+
onDidChangeActiveTextEditor,
16+
onDidChangeTerminalShellIntegration,
17+
} from './common/window.apis';
18+
import { GetEnvironmentInfoTool, InstallPackageTool } from './features/copilotTools';
19+
import { AutoFindProjects } from './features/creators/autoFindProjects';
20+
import { ExistingProjects } from './features/creators/existingProjects';
21+
import { ProjectCreatorsImpl } from './features/creators/projectCreators';
622
import {
723
addPythonProject,
24+
copyPathToClipboard,
25+
createAnyEnvironmentCommand,
826
createEnvironmentCommand,
927
createTerminalCommand,
1028
getPackageCommandOptions,
29+
handlePackageUninstall,
1130
refreshManagerCommand,
31+
refreshPackagesCommand,
1232
removeEnvironmentCommand,
1333
removePythonProject,
34+
resetEnvironmentCommand,
1435
runAsTaskCommand,
36+
runInDedicatedTerminalCommand,
1537
runInTerminalCommand,
16-
setEnvManagerCommand,
1738
setEnvironmentCommand,
39+
setEnvManagerCommand,
1840
setPackageManagerCommand,
19-
resetEnvironmentCommand,
20-
refreshPackagesCommand,
21-
createAnyEnvironmentCommand,
22-
runInDedicatedTerminalCommand,
23-
handlePackageUninstall,
24-
copyPathToClipboard,
2541
} from './features/envCommands';
26-
import { registerCondaFeatures } from './managers/conda/main';
27-
import { registerSystemPythonFeatures } from './managers/builtin/main';
42+
import { PythonEnvironmentManagers } from './features/envManagers';
43+
import { EnvVarManager, PythonEnvVariableManager } from './features/execution/envVariableManager';
2844
import { PythonProjectManagerImpl } from './features/projectManager';
29-
import { EnvironmentManagers, ProjectCreators, PythonProjectManager } from './internal.api';
3045
import { getPythonApi, setPythonApi } from './features/pythonApi';
31-
import { setPersistentState } from './common/persistentState';
32-
import { createNativePythonFinder, NativePythonFinder } from './managers/common/nativePythonFinder';
33-
import { PythonEnvironment, PythonEnvironmentApi } from './api';
34-
import { ProjectCreatorsImpl } from './features/creators/projectCreators';
35-
import { ProjectView } from './features/views/projectView';
3646
import { registerCompletionProvider } from './features/settings/settingCompletions';
37-
import { TerminalManager, TerminalManagerImpl } from './features/terminal/terminalManager';
38-
import {
39-
activeTerminal,
40-
createLogOutputChannel,
41-
onDidChangeActiveTerminal,
42-
onDidChangeActiveTextEditor,
43-
onDidChangeTerminalShellIntegration,
44-
} from './common/window.apis';
4547
import { setActivateMenuButtonContext } from './features/terminal/activateMenuButton';
48+
import { ShellStartupActivationManagerImpl } from './features/terminal/shells/activateUsingShellStartup';
49+
import { normalizeShellPath } from './features/terminal/shells/common/shellUtils';
50+
import { createShellEnvProviders, createShellStartupProviders } from './features/terminal/shells/providers';
51+
import { TerminalActivationImpl } from './features/terminal/terminalActivationState';
52+
import { TerminalManager, TerminalManagerImpl } from './features/terminal/terminalManager';
53+
import { getEnvironmentForTerminal } from './features/terminal/utils';
54+
import { EnvManagerView } from './features/views/envManagersView';
55+
import { ProjectView } from './features/views/projectView';
4656
import { PythonStatusBarImpl } from './features/views/pythonStatusBar';
4757
import { updateViewsAndStatus } from './features/views/revealHandler';
48-
import { EnvVarManager, PythonEnvVariableManager } from './features/execution/envVariableManager';
49-
import { StopWatch } from './common/stopWatch';
50-
import { sendTelemetryEvent } from './common/telemetry/sender';
51-
import { EventNames } from './common/telemetry/constants';
52-
import { ensureCorrectVersion } from './common/extVersion';
53-
import { ExistingProjects } from './features/creators/existingProjects';
54-
import { AutoFindProjects } from './features/creators/autoFindProjects';
55-
import { registerTools } from './common/lm.apis';
56-
import { GetEnvironmentInfoTool, InstallPackageTool } from './features/copilotTools';
57-
import { TerminalActivationImpl } from './features/terminal/terminalActivationState';
58-
import { getEnvironmentForTerminal, normalizeShellPath } from './features/terminal/utils';
59-
import { PwshStartupProvider } from './features/terminal/shells/pwsh/pwshStartup';
60-
import { ShellStartupActivationManagerImpl } from './features/terminal/shells/activateUsingShellStartup';
61-
import {
62-
BashStartupProvider,
63-
GitBashStartupProvider,
64-
ZshStartupProvider,
65-
} from './features/terminal/shells/bash/bashStartup';
66-
import { FishStartupProvider } from './features/terminal/shells/fishStartup';
67-
import { isWindows } from './common/utils/platformUtils';
68-
import { CmdStartupProvider } from './features/terminal/shells/cmdStartup';
58+
import { EnvironmentManagers, ProjectCreators, PythonProjectManager } from './internal.api';
59+
import { registerSystemPythonFeatures } from './managers/builtin/main';
60+
import { createNativePythonFinder, NativePythonFinder } from './managers/common/nativePythonFinder';
61+
import { registerCondaFeatures } from './managers/conda/main';
6962

7063
export async function activate(context: ExtensionContext): Promise<PythonEnvironmentApi> {
7164
const start = new StopWatch();
@@ -92,15 +85,14 @@ export async function activate(context: ExtensionContext): Promise<PythonEnviron
9285
context.subscriptions.push(envManagers);
9386

9487
const terminalActivation = new TerminalActivationImpl();
95-
const shellStartupProviders = isWindows()
96-
? [new PwshStartupProvider(), new GitBashStartupProvider(), new CmdStartupProvider()]
97-
: [new PwshStartupProvider(), new BashStartupProvider(), new ZshStartupProvider(), new FishStartupProvider()];
88+
const shellEnvsProviders = createShellEnvProviders();
89+
const shellStartupProviders = createShellStartupProviders();
9890
const shellStartupActivationManager = new ShellStartupActivationManagerImpl(
9991
context.environmentVariableCollection,
10092
shellStartupProviders,
10193
envManagers,
10294
);
103-
const terminalManager: TerminalManager = new TerminalManagerImpl(terminalActivation, shellStartupProviders);
95+
const terminalManager: TerminalManager = new TerminalManagerImpl(terminalActivation, shellEnvsProviders);
10496
context.subscriptions.push(terminalActivation, terminalManager, shellStartupActivationManager);
10597

10698
const projectCreators: ProjectCreators = new ProjectCreatorsImpl();

src/features/terminal/shells/bash/bashStartup.ts

Lines changed: 9 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -5,19 +5,15 @@ import { ShellScriptEditState, ShellSetupState, ShellStartupScriptProvider } fro
55
import { traceError, traceInfo, traceVerbose } from '../../../../common/logging';
66
import which from 'which';
77
import { BASH_ENV_KEY, ZSH_ENV_KEY } from './bashConstants';
8-
import { ShellConstants } from '../../../common/shellConstants';
98
import { hasStartupCode, insertStartupCode, removeStartupCode } from '../common/editUtils';
109

1110
async function isBashLikeInstalled(): Promise<boolean> {
12-
const result = await Promise.all([
13-
which(ShellConstants.BASH, { nothrow: true }),
14-
which(ShellConstants.SH, { nothrow: true }),
15-
]);
11+
const result = await Promise.all([which('bash', { nothrow: true }), which('sh', { nothrow: true })]);
1612
return result.some((r) => r !== null);
1713
}
1814

1915
async function isZshInstalled(): Promise<boolean> {
20-
const result = await which(ShellConstants.ZSH, { nothrow: true });
16+
const result = await which('zsh', { nothrow: true });
2117
return result !== null;
2218
}
2319

@@ -67,20 +63,20 @@ async function setupStartup(profile: string, key: string, name: string): Promise
6763
const activationContent = getActivationContent(key);
6864

6965
try {
70-
await fs.mkdirp(path.dirname(profile));
71-
72-
if (!(await fs.pathExists(profile))) {
73-
await fs.writeFile(profile, activationContent);
74-
traceInfo(`SHELL: Created new ${name} profile at: ${profile}\n${activationContent}`);
75-
} else {
66+
if (await fs.pathExists(profile)) {
7667
const content = await fs.readFile(profile, 'utf8');
7768
if (hasStartupCode(content, regionStart, regionEnd, [key])) {
7869
traceInfo(`SHELL: ${name} profile already contains activation code at: ${profile}`);
7970
} else {
80-
await fs.appendFile(profile, insertStartupCode(content, regionStart, regionEnd, activationContent));
71+
await fs.writeFile(profile, insertStartupCode(content, regionStart, regionEnd, activationContent));
8172
traceInfo(`SHELL: Updated existing ${name} profile at: ${profile}\n${activationContent}`);
8273
}
74+
} else {
75+
await fs.mkdirp(path.dirname(profile));
76+
await fs.writeFile(profile, insertStartupCode('', regionStart, regionEnd, activationContent));
77+
traceInfo(`SHELL: Created new ${name} profile at: ${profile}\n${activationContent}`);
8378
}
79+
8480
return true;
8581
} catch (err) {
8682
traceError(`SHELL: Failed to setup startup for profile at: ${profile}`, err);
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
export const CMD_ENV_KEY = 'VSCODE_CMD_ACTIVATE';
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
import { EnvironmentVariableCollection } from 'vscode';
2+
import { PythonEnvironment } from '../../../../api';
3+
import { traceError } from '../../../../common/logging';
4+
import { ShellConstants } from '../../../common/shellConstants';
5+
import { getShellActivationCommand, getShellCommandAsString } from '../common/shellUtils';
6+
import { ShellEnvsProvider } from '../startupProvider';
7+
import { CMD_ENV_KEY } from './cmdConstants';
8+
9+
export class CmdEnvsProvider implements ShellEnvsProvider {
10+
readonly shellType: string = ShellConstants.CMD;
11+
async updateEnvVariables(collection: EnvironmentVariableCollection, env: PythonEnvironment): Promise<void> {
12+
try {
13+
const cmdActivation = getShellActivationCommand(this.shellType, env);
14+
if (cmdActivation) {
15+
const command = getShellCommandAsString(this.shellType, cmdActivation);
16+
collection.replace(CMD_ENV_KEY, command);
17+
} else {
18+
collection.delete(CMD_ENV_KEY);
19+
}
20+
} catch (err) {
21+
traceError('Failed to update CMD environment variables', err);
22+
collection.delete(CMD_ENV_KEY);
23+
}
24+
}
25+
26+
async removeEnvVariables(envCollection: EnvironmentVariableCollection): Promise<void> {
27+
envCollection.delete(CMD_ENV_KEY);
28+
}
29+
30+
async getEnvVariables(env?: PythonEnvironment): Promise<Map<string, string | undefined> | undefined> {
31+
if (!env) {
32+
return new Map([[CMD_ENV_KEY, undefined]]);
33+
}
34+
35+
try {
36+
const cmdActivation = getShellActivationCommand(this.shellType, env);
37+
if (cmdActivation) {
38+
return new Map([[CMD_ENV_KEY, getShellCommandAsString(this.shellType, cmdActivation)]]);
39+
}
40+
return undefined;
41+
} catch (err) {
42+
traceError('Failed to get CMD environment variables', err);
43+
return undefined;
44+
}
45+
}
46+
}

0 commit comments

Comments
 (0)