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
Original file line number Diff line number Diff line change
Expand Up @@ -209,21 +209,16 @@ export function activate(context: vscode.ExtensionContext): void {
if (vscode.env.remoteName) {
const markerPrefix: string = '<<<HOMEDIR_START>>>';
const markerSuffix: string = '<<<HOMEDIR_END>>>';
const output: string = await runWorkspaceCommandAsync({
homeDir = await runWorkspaceCommandAsync({
terminalOptions: { name: 'debug-certificate-manager', hideFromUser: true },
// Wrapping the desired node output in markers to trim uninteresting shell output.
commandLine: `node -p "'${markerPrefix}' + require('os').homedir() + '${markerSuffix}'"`,
terminal
terminal,
outputMarker: {
prefix: markerPrefix,
suffix: markerSuffix
}
});
terminal.writeLine(`Running command to resolve home directory: ${output}`);

const startIndex: number = output.lastIndexOf(markerPrefix);
const endIndex: number = output.lastIndexOf(markerSuffix);
if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
homeDir = output.substring(startIndex + markerPrefix.length, endIndex).trim();
} else {
throw new Error('Failed to parse home directory from command output');
}
terminal.writeLine(`Running command to resolve home directory: ${homeDir}`);
} else {
homeDir = require('os').homedir();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,20 +47,16 @@ async function writeExtensionInstalledFileAsync(terminal: ITerminal): Promise<vo
if (vscode.env.remoteName) {
const markerPrefix: string = '<<<TEMPDIR_START>>>';
const markerSuffix: string = '<<<TEMPDIR_END>>>';
const output: string = await runWorkspaceCommandAsync({
tempDir = await runWorkspaceCommandAsync({
terminalOptions: { name: 'playwright-local-browser-server', hideFromUser: true },
commandLine: `node -p "'${markerPrefix}' + require('node:os').tmpdir() + '${markerSuffix}'"`,
terminal
terminal,
outputMarker: {
prefix: markerPrefix,
suffix: markerSuffix
}
});

const startIndex: number = output.indexOf(markerPrefix);
const endIndex: number = output.indexOf(markerSuffix);
if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
tempDir = output.substring(startIndex + markerPrefix.length, endIndex).trim();
} else {
throw new Error('Failed to parse temp directory from command output');
}

// For remote environments, use the vscode-remote scheme
// The workspace folder should have the correct scheme already
const workspaceFolder: vscode.WorkspaceFolder | undefined = vscode.workspace.workspaceFolders?.[0];
Expand Down
41 changes: 39 additions & 2 deletions vscode-extensions/vscode-shared/src/runWorkspaceCommandAsync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,37 @@ import { ITerminal } from '@rushstack/terminal';
import * as vscode from 'vscode';
import { stripVTControlCharacters } from 'node:util';

/**
* Options for extracting a specific value from the command output using markers.
* When provided, the function will search for the markers in the command output and
* return only the content between them. This is useful for extracting specific
* values from shell output that may contain additional noise.
Comment on lines +9 to +12

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Need to explicitly define the behavior when the markers appear multiple times.

*/
export interface IOutputMarkerOptions {
/**
* The prefix marker used to identify the start of the desired output.
*/
prefix: string;
/**
* The suffix marker used to identify the end of the desired output.
*/
suffix: string;
}

export async function runWorkspaceCommandAsync({
terminalOptions,
commandLine,
terminal
terminal,
outputMarker
}: {
terminalOptions: vscode.TerminalOptions;
commandLine: string;
terminal: ITerminal;
/**
* Optional marker options for extracting specific output from the command result.
* When provided, the returned output will be only the content between the markers.
*/
outputMarker?: IOutputMarkerOptions;
}): Promise<string> {
const vsTerminal: vscode.Terminal = vscode.window.createTerminal(terminalOptions);

Expand Down Expand Up @@ -66,7 +89,21 @@ export async function runWorkspaceCommandAsync({
startExecutionDisposable.dispose();

if (event.exitCode === 0) {
resolve(outputStream);
// If outputMarker was provided, extract the content between markers
if (outputMarker) {
const startIndex: number = outputStream.indexOf(outputMarker.prefix);
const endIndex: number = outputStream.indexOf(outputMarker.suffix);
Comment on lines +94 to +95

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per prior conversation regarding the debug certificate manager, to deal with some shells that echo the command to be run, we should be using lastIndexOf instead of indexOf, and also should anchor one from the other.

if (startIndex !== -1 && endIndex !== -1 && endIndex > startIndex) {
const extractedOutput: string = outputStream
.substring(startIndex + outputMarker.prefix.length, endIndex)
.trim();
resolve(extractedOutput);
} else {
reject(new Error('Failed to parse output from command: markers not found'));
}
} else {
resolve(outputStream);
}
} else {
reject(outputStream);
}
Expand Down