diff --git a/editors/vscode/client/ConfigService.ts b/editors/vscode/client/ConfigService.ts index 799c8305cf301..5a03d9a7e1225 100644 --- a/editors/vscode/client/ConfigService.ts +++ b/editors/vscode/client/ConfigService.ts @@ -1,3 +1,4 @@ +import * as path from 'node:path'; import { ConfigurationChangeEvent, Uri, workspace, WorkspaceFolder } from 'vscode'; import { IDisposable } from './types'; import { VSCodeConfig } from './VSCodeConfig'; @@ -59,6 +60,24 @@ export class ConfigService implements IDisposable { return false; } + public getUserServerBinPath(): string | undefined { + let bin = this.vsCodeConfig.binPath; + if (!bin) { + return; + } + + if (!path.isAbsolute(bin)) { + // if the path is not absolute, resolve it to the first workspace folder + let cwd = this.workspaceConfigs.keys().next().value; + if (!cwd) { + return; + } + bin = path.normalize(path.join(cwd, bin)); + } + + return bin; + } + private async onVscodeConfigChange(event: ConfigurationChangeEvent): Promise { let isConfigChanged = false; diff --git a/editors/vscode/client/extension.ts b/editors/vscode/client/extension.ts index 685555f73ca74..a0766fe9ad4f4 100644 --- a/editors/vscode/client/extension.ts +++ b/editors/vscode/client/extension.ts @@ -138,7 +138,7 @@ export async function activate(context: ExtensionContext) { ); async function findBinary(): Promise { - let bin = configService.vsCodeConfig.binPath; + let bin = configService.getUserServerBinPath(); if (bin) { try { await fsPromises.access(bin); diff --git a/editors/vscode/tests/ConfigService.spec.ts b/editors/vscode/tests/ConfigService.spec.ts new file mode 100644 index 0000000000000..4ae0f87c46fdf --- /dev/null +++ b/editors/vscode/tests/ConfigService.spec.ts @@ -0,0 +1,37 @@ +import { strictEqual } from 'assert'; +import { workspace } from 'vscode'; +import { ConfigService } from '../client/ConfigService.js'; +import { testSingleFolderMode, WORKSPACE_FOLDER } from './test-helpers.js'; + +const conf = workspace.getConfiguration('oxc'); + +suite('ConfigService', () => { + setup(async () => { + const keys = ['path.server']; + + await Promise.all(keys.map(key => conf.update(key, undefined))); + }); + + teardown(async () => { + const keys = ['path.server']; + + await Promise.all(keys.map(key => conf.update(key, undefined))); + }); + + testSingleFolderMode('resolves relative server path with workspace folder', async () => { + const service = new ConfigService(); + const nonDefinedServerPath = service.getUserServerBinPath(); + + strictEqual(nonDefinedServerPath, undefined); + + await conf.update('path.server', '/absolute/binary'); + const absoluteServerPath = service.getUserServerBinPath(); + + strictEqual(absoluteServerPath, '/absolute/binary'); + + await conf.update('path.server', './relative/binary'); + const relativeServerPath = service.getUserServerBinPath(); + + strictEqual(relativeServerPath, WORKSPACE_FOLDER.uri.path + '/relative/binary'); + }); +});