Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/features/terminal/shells/bash/bashStartup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,14 +27,14 @@ async function isGitBashInstalled(): Promise<boolean> {
return false;
}

async function getBashProfiles(): Promise<string> {
export async function getBashProfiles(): Promise<string> {
const homeDir = os.homedir();
const profile: string = path.join(homeDir, '.bashrc');

return profile;
}

async function getZshProfiles(): Promise<string> {
export async function getZshProfiles(): Promise<string> {
const homeDir = os.homedir();
const profile: string = path.join(homeDir, '.zshrc');

Expand Down
6 changes: 5 additions & 1 deletion src/features/terminal/shells/fish/fishStartup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ async function isFishInstalled(): Promise<boolean> {
}
}

async function getFishProfile(): Promise<string> {
export async function getFishProfile(): Promise<string> {
const homeDir = os.homedir();
// Fish configuration is typically at ~/.config/fish/config.fish
const profilePath = path.join(homeDir, '.config', 'fish', 'config.fish');
Expand Down Expand Up @@ -155,4 +155,8 @@ export class FishStartupProvider implements ShellStartupScriptProvider {
clearCache(): Promise<void> {
return Promise.resolve();
}

getProfilePath(): Promise<string | undefined> {
return getFishProfile();
}
}
2 changes: 1 addition & 1 deletion src/features/terminal/shells/pwsh/pwshStartup.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,7 +52,7 @@ async function isPowerShellInstalled(shell: string): Promise<boolean> {
}
}

async function getProfileForShell(shell: 'powershell' | 'pwsh'): Promise<string> {
export async function getProfileForShell(shell: 'powershell' | 'pwsh'): Promise<string> {
const cachedPath = getProfilePathCache(shell);
if (cachedPath) {
traceInfo(`SHELL: ${shell} profile path from cache: ${cachedPath}`);
Expand Down
10 changes: 10 additions & 0 deletions src/features/terminal/shells/sh/shStartup.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import * as os from 'os';
import * as path from 'path';

/**
* Returns an array of possible sh profile paths in order of preference.
*/
export async function getShProfiles(): Promise<string> {
const home = os.homedir();
return path.join(home, '.profile');
}
86 changes: 65 additions & 21 deletions src/managers/conda/condaUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,9 @@ import {
import { getConfiguration } from '../../common/workspace.apis';
import { ShellConstants } from '../../features/common/shellConstants';
import { quoteArgs } from '../../features/execution/execUtils';
import { getBashProfiles, getZshProfiles } from '../../features/terminal/shells/bash/bashStartup';
import { getProfileForShell } from '../../features/terminal/shells/pwsh/pwshStartup';
import { getShProfiles } from '../../features/terminal/shells/sh/shStartup';
import {
isNativeEnvInfo,
NativeEnvInfo,
Expand Down Expand Up @@ -293,41 +296,51 @@ async function getNamedCondaPythonInfo(

if (conda.includes('/') || conda.includes('\\')) {
const shActivate = path.join(path.dirname(path.dirname(conda)), 'etc', 'profile.d', 'conda.sh');
const profileInit = await checkProfileForCondaInitialization();

if (isWindows()) {
shellActivation.set(ShellConstants.GITBASH, [
{ executable: '.', args: [pathForGitBash(shActivate)] },
{ executable: 'conda', args: ['activate', name] },
]);
// didn't find gitbash
const rcGitBash: PythonCommandRunConfiguration[] = [{ executable: 'conda', args: ['activate', name] }];
if (!profileInit.get(ShellConstants.GITBASH)) {
rcGitBash.unshift({ executable: '.', args: [pathForGitBash(shActivate)] });
}
shellActivation.set(ShellConstants.GITBASH, rcGitBash);
shellDeactivation.set(ShellConstants.GITBASH, [{ executable: 'conda', args: ['deactivate'] }]);

// not sure about cmd and how to find profile
const cmdActivate = path.join(path.dirname(conda), 'activate.bat');
shellActivation.set(ShellConstants.CMD, [{ executable: cmdActivate, args: [name] }]);
shellDeactivation.set(ShellConstants.CMD, [{ executable: 'conda', args: ['deactivate'] }]);
} else {
shellActivation.set(ShellConstants.BASH, [
{ executable: '.', args: [shActivate] },
{ executable: 'conda', args: ['activate', name] },
]);
// bash
const rc: PythonCommandRunConfiguration[] = [{ executable: 'conda', args: ['activate', name] }];
if (!profileInit.get(ShellConstants.BASH)) {
rc.unshift({ executable: '.', args: [shActivate] });
}
shellActivation.set(ShellConstants.BASH, rc);
shellDeactivation.set(ShellConstants.BASH, [{ executable: 'conda', args: ['deactivate'] }]);

shellActivation.set(ShellConstants.SH, [
{ executable: '.', args: [shActivate] },
{ executable: 'conda', args: ['activate', name] },
]);
const rcSh: PythonCommandRunConfiguration[] = [{ executable: 'conda', args: ['activate', name] }];
if (!profileInit.get(ShellConstants.SH)) {
rcSh.unshift({ executable: '.', args: [shActivate] });
}
shellActivation.set(ShellConstants.SH, rcSh);
shellDeactivation.set(ShellConstants.SH, [{ executable: 'conda', args: ['deactivate'] }]);

shellActivation.set(ShellConstants.ZSH, [
{ executable: '.', args: [shActivate] },
{ executable: 'conda', args: ['activate', name] },
]);
// zsh
const rcZsh: PythonCommandRunConfiguration[] = [{ executable: 'conda', args: ['activate', name] }];
if (!profileInit.get(ShellConstants.ZSH)) {
rcZsh.unshift({ executable: '.', args: [shActivate] });
}
shellActivation.set(ShellConstants.ZSH, rcZsh);
shellDeactivation.set(ShellConstants.ZSH, [{ executable: 'conda', args: ['deactivate'] }]);
}
const psActivate = await getCondaHookPs1Path(conda);
shellActivation.set(ShellConstants.PWSH, [
{ executable: '&', args: [psActivate] },
{ executable: 'conda', args: ['activate', name] },
]);
const rcPwsh: PythonCommandRunConfiguration[] = [{ executable: 'conda', args: ['activate', name] }];
if (!profileInit.get(ShellConstants.PWSH)) {
const psActivate = await getCondaHookPs1Path(conda);
rcPwsh.unshift({ executable: '.', args: [psActivate] });
}
shellActivation.set(ShellConstants.PWSH, rcPwsh);
shellDeactivation.set(ShellConstants.PWSH, [{ executable: 'conda', args: ['deactivate'] }]);
} else {
shellActivation.set(ShellConstants.GITBASH, [{ executable: 'conda', args: ['activate', name] }]);
Expand Down Expand Up @@ -374,6 +387,37 @@ async function getNamedCondaPythonInfo(
};
}

async function checkProfileForCondaInitialization(): Promise<Map<string, boolean>> {
const profileStatusMap = new Map<string, boolean>();

// bash
const bashProfiles = await getBashProfiles();
const containsInitBash = await readProfile(bashProfiles);
profileStatusMap.set(ShellConstants.BASH, containsInitBash);
// zsh
const zshProfiles = await getZshProfiles();
const containsInitZsh = await readProfile(zshProfiles);
profileStatusMap.set(ShellConstants.ZSH, containsInitZsh);

// sh
const shProfiles = await getShProfiles();
const containsInitSh = await readProfile(shProfiles);
profileStatusMap.set(ShellConstants.SH, containsInitSh);

const pwshProfiles = await getProfileForShell('pwsh');
const containsInitPwsh = await readProfile(pwshProfiles);
profileStatusMap.set(ShellConstants.PWSH, containsInitPwsh);

return profileStatusMap;
}
async function readProfile(profilePath: string): Promise<boolean> {
if (await fse.pathExists(profilePath)) {
const content = await fse.readFile(profilePath, 'utf8');
return content.includes('# >>> conda initialize >>>#');
}
return false;
}

async function getPrefixesCondaPythonInfo(
prefix: string,
executable: string,
Expand Down