Skip to content
This repository has been archived by the owner on Jan 6, 2025. It is now read-only.

Commit

Permalink
Fix errors with string extensions
Browse files Browse the repository at this point in the history
  • Loading branch information
DonJayamanne committed Sep 15, 2023
1 parent b2220d2 commit 521db1a
Show file tree
Hide file tree
Showing 13 changed files with 37 additions and 53 deletions.
4 changes: 2 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
"name": "python-environment-manager",
"displayName": "Python Environment Manager",
"description": "View and manage Python environments & packages.",
"version": "1.2.3",
"version": "1.2.4",
"capabilities": {
"untrustedWorkspaces": {
"supported": false,
Expand Down
21 changes: 10 additions & 11 deletions src/client/common/extensions.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,11 +56,11 @@ String.prototype.fileToCommandArgumentForPythonMgrExt = function (this: string):
* String.trimQuotes implementation
* Removes leading and trailing quotes from a string
*/
String.prototype.trimQuotes = function (this: string): string {
if (!this) {
return this;
export function trimQuotes(value: string): string {
if (!value) {
return value;
}
return this.replace(/(^['"])|(['"]$)/g, '');
return value.replace(/(^['"])|(['"]$)/g, '');
};

declare interface Promise<T> {
Expand All @@ -74,12 +74,11 @@ declare interface Promise<T> {
* Explicitly tells that promise should be run asynchonously.
*/
Promise.prototype.ignoreErrors = function <T>(this: Promise<T>) {
return this.catch(() => {});
// @ts-ignore
return this.catch(() => { });
};

if (!String.prototype.format) {
String.prototype.format = function (this: string) {
const args = arguments;
return this.replace(/{(\d+)}/g, (match, number) => (args[number] === undefined ? match : args[number]));
};
}
export function format(value: string) {
const args = arguments;
return value.replace(/{(\d+)}/g, (match, number) => (args[number] === undefined ? match : args[number]));
};
3 changes: 2 additions & 1 deletion src/client/common/process/logger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { IProcessLogger, SpawnOptions } from './types';
import { escapeRegExp } from 'lodash';
import { replaceAll } from '../stringUtils';
import { identifyShellFromShellPath } from '../terminal/shellDetectors/baseShellDetector';
import { trimQuotes } from '../extensions';

@injectable()
export class ProcessLogger implements IProcessLogger {
Expand All @@ -24,7 +25,7 @@ export class ProcessLogger implements IProcessLogger {
return;
}
let command = args
? [fileOrCommand, ...args].map((e) => e.trimQuotes().toCommandArgumentForPythonEnvMgrExt()).join(' ')
? [fileOrCommand, ...args].map((e) => trimQuotes(e).toCommandArgumentForPythonMgrExt()).join(' ')
: fileOrCommand;
const info = [`> ${this.getDisplayCommands(command)}`];
if (options?.cwd) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman
targetShell !== TerminalShellType.bash &&
targetShell !== TerminalShellType.gitbash
) {
return [activatePath.path, `conda activate ${condaEnv.toCommandArgumentForPythonEnvMgrExt()}`];
return [activatePath.path, `conda activate ${condaEnv.toCommandArgumentForPythonMgrExt()}`];
}

const condaInfo = await this.condaService.getCondaInfo();
Expand All @@ -86,12 +86,12 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman
if (activatePath.path === 'activate') {
return [
`source ${activatePath.path}`,
`conda activate ${condaEnv.toCommandArgumentForPythonEnvMgrExt()}`,
`conda activate ${condaEnv.toCommandArgumentForPythonMgrExt()}`,
];
}
return [`source ${activatePath.path} ${condaEnv.toCommandArgumentForPythonEnvMgrExt()}`];
return [`source ${activatePath.path} ${condaEnv.toCommandArgumentForPythonMgrExt()}`];
}
return [`conda activate ${condaEnv.toCommandArgumentForPythonEnvMgrExt()}`];
return [`conda activate ${condaEnv.toCommandArgumentForPythonMgrExt()}`];
}

switch (targetShell) {
Expand Down Expand Up @@ -120,15 +120,15 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman
const condaScriptsPath: string = path.dirname(condaExePath);
// prefix the cmd with the found path, and ensure it's quoted properly
activateCmd = path.join(condaScriptsPath, activateCmd);
activateCmd = activateCmd.toCommandArgumentForPythonEnvMgrExt();
activateCmd = activateCmd.toCommandArgumentForPythonMgrExt();
}

return activateCmd;
}

public async getWindowsCommands(condaEnv: string): Promise<string[] | undefined> {
const activate = await this.getWindowsActivateCommand();
return [`${activate} ${condaEnv.toCommandArgumentForPythonEnvMgrExt()}`];
return [`${activate} ${condaEnv.toCommandArgumentForPythonMgrExt()}`];
}
}

Expand All @@ -139,16 +139,16 @@ export class CondaActivationCommandProvider implements ITerminalActivationComman
* Extension will not attempt to work around issues by trying to setup shell for user.
*/
export async function _getPowershellCommands(condaEnv: string): Promise<string[] | undefined> {
return [`conda activate ${condaEnv.toCommandArgumentForPythonEnvMgrExt()}`];
return [`conda activate ${condaEnv.toCommandArgumentForPythonMgrExt()}`];
}

async function getFishCommands(condaEnv: string, condaFile: string): Promise<string[] | undefined> {
// https://github.com/conda/conda/blob/be8c08c083f4d5e05b06bd2689d2cd0d410c2ffe/shell/etc/fish/conf.d/conda.fish#L18-L28
return [`${condaFile.fileToCommandArgumentForPythonMgrExt()} activate ${condaEnv.toCommandArgumentForPythonEnvMgrExt()}`];
return [`${condaFile.fileToCommandArgumentForPythonMgrExt()} activate ${condaEnv.toCommandArgumentForPythonMgrExt()}`];
}

async function getUnixCommands(condaEnv: string, condaFile: string): Promise<string[] | undefined> {
const condaDir = path.dirname(condaFile);
const activateFile = path.join(condaDir, 'activate');
return [`source ${activateFile.fileToCommandArgumentForPythonMgrExt()} ${condaEnv.toCommandArgumentForPythonEnvMgrExt()}`];
return [`source ${activateFile.fileToCommandArgumentForPythonMgrExt()} ${condaEnv.toCommandArgumentForPythonMgrExt()}`];
}
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ export class PyEnvActivationCommandProvider implements ITerminalActivationComman
return undefined;
}

return [`pyenv shell ${interpreter.envName.toCommandArgumentForPythonEnvMgrExt()}`];
return [`pyenv shell ${interpreter.envName.toCommandArgumentForPythonMgrExt()}`];
}

public async getActivationCommandsForInterpreter(
Expand All @@ -41,6 +41,6 @@ export class PyEnvActivationCommandProvider implements ITerminalActivationComman
return undefined;
}

return [`pyenv shell ${interpreter.envName.toCommandArgumentForPythonEnvMgrExt()}`];
return [`pyenv shell ${interpreter.envName.toCommandArgumentForPythonMgrExt()}`];
}
}
2 changes: 1 addition & 1 deletion src/client/common/terminal/helper.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export class TerminalHelper implements ITerminalHelper {
terminalShellType === TerminalShellType.powershell ||
terminalShellType === TerminalShellType.powershellCore;
const commandPrefix = isPowershell ? '& ' : '';
const formattedArgs = args.map((a) => a.toCommandArgumentForPythonEnvMgrExt());
const formattedArgs = args.map((a) => a.toCommandArgumentForPythonMgrExt());

return `${commandPrefix}${command.fileToCommandArgumentForPythonMgrExt()} ${formattedArgs.join(' ')}`.trim();
}
Expand Down
6 changes: 3 additions & 3 deletions src/client/interpreter/activation/service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -189,7 +189,7 @@ export class EnvironmentActivationService implements IEnvironmentActivationServi
try {
const [args, parse] = internalScripts.printEnvVariables();
args.forEach((arg, i) => {
args[i] = arg.toCommandArgumentForPythonEnvMgrExt();
args[i] = arg.toCommandArgumentForPythonMgrExt();
});
const command = `${interpreterPath} ${args.join(' ')}`;
const processService = await this.processServiceFactory.create(resource, { doNotUseCustomEnvs: true });
Expand Down Expand Up @@ -240,7 +240,7 @@ export class EnvironmentActivationService implements IEnvironmentActivationServi
let command: string | undefined;
const [args, parse] = internalScripts.printEnvVariables();
args.forEach((arg, i) => {
args[i] = arg.toCommandArgumentForPythonEnvMgrExt();
args[i] = arg.toCommandArgumentForPythonMgrExt();
});
if (interpreter?.envType === EnvironmentType.Conda) {
const conda = await Conda.getConda(shell);
Expand All @@ -250,7 +250,7 @@ export class EnvironmentActivationService implements IEnvironmentActivationServi
});
if (pythonArgv) {
// Using environment prefix isn't needed as the marker script already takes care of it.
command = [...pythonArgv, ...args].map((arg) => arg.toCommandArgumentForPythonEnvMgrExt()).join(' ');
command = [...pythonArgv, ...args].map((arg) => arg.toCommandArgumentForPythonMgrExt()).join(' ');
}
}
if (!command) {
Expand Down
2 changes: 1 addition & 1 deletion src/client/pythonEnvironments/base/info/interpreter.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ export async function getInterpreterInfo(

// Concat these together to make a set of quoted strings
const quoted = argv.reduce(
(p, c) => (p ? `${p} ${c.toCommandArgumentForPythonEnvMgrExt()}` : `${c.toCommandArgumentForPythonEnvMgrExt()}`),
(p, c) => (p ? `${p} ${c.toCommandArgumentForPythonMgrExt()}` : `${c.toCommandArgumentForPythonMgrExt()}`),
'',
);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ function generateCommandArgs(version?: string, options?: CreateEnvironmentOption
command.push('--git-ignore');
}
if (name && (name || '').trim().length) {
command.push('--name', name.toCommandArgumentForPythonEnvMgrExt());
command.push('--name', name.toCommandArgumentForPythonMgrExt());
}

if (installPackages) {
Expand Down
2 changes: 1 addition & 1 deletion src/client/pythonEnvironments/info/executable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ export async function getExecutablePath(python: PythonExecInfo, shellExec: Shell
const argv = [info.command, ...info.args];
// Concat these together to make a set of quoted strings
const quoted = argv.reduce(
(p, c) => (p ? `${p} ${c.toCommandArgumentForPythonEnvMgrExt()}` : `${c.toCommandArgumentForPythonEnvMgrExt()}`),
(p, c) => (p ? `${p} ${c.toCommandArgumentForPythonMgrExt()}` : `${c.toCommandArgumentForPythonMgrExt()}`),
'',
);
const result = await shellExec(quoted, { timeout: 15000 });
Expand Down
6 changes: 3 additions & 3 deletions src/environments/tools/pyenv.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import { createDeferred } from '../../client/common/utils/async';
import { registerCreateEnvironmentProvider } from '../../client/pythonEnvironments/creation/createEnvApi';
import { EnvironmentType } from '../../client/pythonEnvironments/info';
import { CreateEnvironmentResult } from '../../client/pythonEnvironments/creation/proposed.createEnvApis';
import { splitLines } from '../../client/common/stringUtils';


const pyEnvEnvVars = createDeferred<NodeJS.ProcessEnv>();
Expand Down Expand Up @@ -59,9 +60,8 @@ export async function getPyEnvVersion(iocContainer: IServiceContainer) {
}

const start = versionStart + '## Release '.length;
const verionLines = textFile
.substring(start, start + 20)
.splitLines()
const verionLines = splitLines(textFile
.substring(start, start + 20))
.map((line) => line.trim())
.filter((line) => line.length);

Expand Down
18 changes: 1 addition & 17 deletions typings/extensions.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,32 +10,16 @@
// https://stackoverflow.com/questions/39877156/how-to-extend-string-prototype-and-use-it-next-in-typescript

declare interface String {
/**
* Split a string using the cr and lf characters and return them as an array.
* By default lines are trimmed and empty lines are removed.
* @param {SplitLinesOptions=} splitOptions - Options used for splitting the string.
*/
splitLines(splitOptions?: { trim: boolean; removeEmptyEntries?: boolean }): string[];
/**
* Appropriately formats a string so it can be used as an argument for a command in a shell.
* E.g. if an argument contains a space, then it will be enclosed within double quotes.
*/
toCommandArgumentForPythonEnvMgrExt(): string;
toCommandArgumentForPythonMgrExt(): string;
/**
* Appropriately formats a a file path so it can be used as an argument for a command in a shell.
* E.g. if an argument contains a space, then it will be enclosed within double quotes.
*/
fileToCommandArgumentForPythonMgrExt(): string;
/**
* String.format() implementation.
* Tokens such as {0}, {1} will be replaced with corresponding positional arguments.
*/
format(...args: string[]): string;
/**
* String.trimQuotes implementation
* Removes leading and trailing quotes from a string
*/
trimQuotes(): string;
}

declare interface Promise<T> {
Expand Down

0 comments on commit 521db1a

Please sign in to comment.