Skip to content

Commit 6285d0e

Browse files
committed
Add support for external server in config.
1 parent 6dbbcde commit 6285d0e

File tree

4 files changed

+76
-42
lines changed

4 files changed

+76
-42
lines changed

package.json

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -153,6 +153,11 @@
153153
"additionalProperties": {
154154
"type": "string"
155155
}
156+
},
157+
"shader-validator.serverPath": {
158+
"description": "Use an external server instead of the bundled ones.",
159+
"type": "string",
160+
"default": ""
156161
}
157162
}
158163
},

src/test/suite/utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
import * as vscode from 'vscode';
2+
import * as path from 'path';
23

34
export function getRootFolder() : string {
45
// Depending on platform, we have different cwd...
56
// https://github.com/microsoft/vscode-test/issues/17
6-
return process.platform === 'win32' ? "../../" : "./";
7+
return path.join(process.cwd(), process.platform === 'win32' ? "../../" : "./");
78
}
89

910
export async function activate(docUri: vscode.Uri, waitServer: boolean) : Promise<[vscode.TextDocument, vscode.TextEditor] | null> {

src/test/suite/version.test.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@ import * as assert from 'assert';
33
// You can import and use all API from the 'vscode' module
44
// as well as import your extension to test it
55
import * as vscode from 'vscode';
6-
import * as path from 'path';
6+
import * as fs from 'fs';
77
import * as cp from 'child_process';
88
import { getRootFolder } from './utils';
9-
import { getPlatformBinaryPath, getServerPlatform } from '../../validator';
9+
import { getPlatformBinaryUri, getServerPlatform } from '../../validator';
1010

1111
suite('Server version Test Suite', () => {
1212
test('Check server version', () => {
1313
let platform = getServerPlatform();
14-
let server = cp.spawn(getRootFolder() + getPlatformBinaryPath(platform), [
14+
let executableUri = getPlatformBinaryUri(vscode.Uri.parse(getRootFolder()), platform);
15+
assert.ok(fs.existsSync(executableUri.fsPath), `Failed to find ${executableUri}`);
16+
let server = cp.spawn(executableUri.fsPath, [
1517
"--version"
1618
]);
1719
const version = vscode.extensions.getExtension('antaalt.shader-validator')!.packageJSON.server_version;

src/validator.ts

Lines changed: 64 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
import * as vscode from "vscode";
22
import * as cp from "child_process";
3+
import fs from 'fs';
4+
import path from 'path';
35

46
import {
57
createStdioOptions,
@@ -34,50 +36,68 @@ export function isRunningOnWeb() : boolean {
3436
// Web environment is detected with no fallback on child process which is not supported there.
3537
return typeof cp.spawn !== 'function' || typeof process === 'undefined';
3638
}
37-
38-
function getPlatformBinaryDirectoryPath(platform: ServerPlatform) : string {
39-
// CI is handling the copy to bin folder to avoid storage of exe on git.
40-
switch (platform) {
41-
case ServerPlatform.windows:
42-
return "bin/windows/";
43-
case ServerPlatform.linux:
44-
return "bin/linux/";
45-
case ServerPlatform.wasi:
46-
return "bin/wasi/";
39+
function getUserServerPath() : string | null {
40+
if (isRunningOnWeb()) {
41+
return null;
42+
} else {
43+
// Check configuration.
44+
let serverPath = vscode.workspace.getConfiguration("shader-validator").get<string>("serverPath");
45+
if (serverPath && serverPath.length > 0) {
46+
if (fs.existsSync(serverPath)) {
47+
console.info(`User server path found: ${serverPath}`);
48+
return serverPath;
49+
} else {
50+
vscode.window.showErrorMessage(`User server path is invalid: ${serverPath}`);
51+
}
52+
}
53+
// Check environment variables
54+
if (process.env.SHADER_LANGUAGE_SERVER_EXECUTABLE_PATH !== undefined) {
55+
let envPath = process.env.SHADER_LANGUAGE_SERVER_EXECUTABLE_PATH;
56+
if (fs.existsSync(envPath)) {
57+
console.info(`SHADER_LANGUAGE_SERVER_EXECUTABLE_PATH found: ${envPath}`);
58+
return envPath;
59+
} else {
60+
vscode.window.showErrorMessage(`SHADER_LANGUAGE_SERVER_EXECUTABLE_PATH is invalid: ${serverPath}`);
61+
}
62+
}
63+
// Use bundled executables.
64+
return null;
4765
}
4866
}
49-
function getPlatformBinaryName(platform: ServerPlatform) : string {
50-
switch (platform) {
67+
function getPlatformBinaryDirectoryPath(extensionUri: vscode.Uri, platform: ServerPlatform) : vscode.Uri {
68+
let serverPath = getUserServerPath();
69+
if (serverPath) {
70+
return vscode.Uri.file(path.dirname(serverPath));
71+
} else {
72+
// CI is handling the copy to bin folder to avoid storage of exe on git.
73+
switch (platform) {
5174
case ServerPlatform.windows:
52-
return "shader-language-server.exe";
75+
return vscode.Uri.joinPath(extensionUri, "bin/windows/");
5376
case ServerPlatform.linux:
54-
return "shader-language-server";
77+
return vscode.Uri.joinPath(extensionUri, "bin/linux/");
5578
case ServerPlatform.wasi:
56-
return "shader-language-server.wasm";
79+
return vscode.Uri.joinPath(extensionUri, "bin/wasi/");
80+
}
5781
}
5882
}
59-
function getPlatformBinaryDirectoryUri(context: vscode.ExtensionContext, platform: ServerPlatform) : vscode.Uri {
60-
// process is undefined on the wasi.
61-
if (platform !== ServerPlatform.wasi && context.extensionMode === vscode.ExtensionMode.Development) {
62-
console.info("Running extension in dev mode. Looking for environment variable SHADER_LANGUAGE_SERVER_EXECUTABLE_PATH targetting server.");
63-
if (process.env.SHADER_LANGUAGE_SERVER_EXECUTABLE_PATH !== undefined) {
64-
console.info(`SHADER_LANGUAGE_SERVER_EXECUTABLE_PATH found: ${process.env.SHADER_LANGUAGE_SERVER_EXECUTABLE_PATH}`);
65-
return vscode.Uri.file(process.env.SHADER_LANGUAGE_SERVER_EXECUTABLE_PATH + '/');
66-
} else {
67-
console.warn('SHADER_LANGUAGE_SERVER_EXECUTABLE_PATH environment variable not found. Trying to launch from bin folder');
68-
return vscode.Uri.joinPath(context.extensionUri, getPlatformBinaryDirectoryPath(platform));
83+
function getPlatformBinaryName(platform: ServerPlatform) : string {
84+
let serverPath = getUserServerPath();
85+
if (serverPath) {
86+
return path.basename(serverPath);
87+
} else {
88+
switch (platform) {
89+
case ServerPlatform.windows:
90+
return "shader-language-server.exe";
91+
case ServerPlatform.linux:
92+
return "shader-language-server";
93+
case ServerPlatform.wasi:
94+
return "shader-language-server.wasm";
6995
}
70-
} else { // Running in production or test mode
71-
return vscode.Uri.joinPath(context.extensionUri, getPlatformBinaryDirectoryPath(platform));
7296
}
7397
}
74-
// Relative path from extension directory
75-
export function getPlatformBinaryPath(platform: ServerPlatform) : string {
76-
return getPlatformBinaryDirectoryPath(platform) + getPlatformBinaryName(platform);
77-
}
7898
// Absolute path as uri
79-
export function getPlatformBinaryUri(context: vscode.ExtensionContext, platform: ServerPlatform) : vscode.Uri {
80-
return vscode.Uri.joinPath(getPlatformBinaryDirectoryUri(context, platform), getPlatformBinaryName(platform));
99+
export function getPlatformBinaryUri(extensionUri: vscode.Uri, platform: ServerPlatform) : vscode.Uri {
100+
return vscode.Uri.joinPath(getPlatformBinaryDirectoryPath(extensionUri, platform), getPlatformBinaryName(platform));
81101
}
82102

83103
export function getServerPlatform() : ServerPlatform {
@@ -99,8 +119,11 @@ export function getServerPlatform() : ServerPlatform {
99119
function notifyConfigurationChange(context: vscode.ExtensionContext, client: LanguageClient) {
100120
context.subscriptions.push(
101121
vscode.workspace.onDidChangeConfiguration(async (event : vscode.ConfigurationChangeEvent) => {
102-
if (event.affectsConfiguration("shader-validator"))
103-
{
122+
if (event.affectsConfiguration("shader-validator")) {
123+
if (event.affectsConfiguration("shader-validator.trace.server") ||
124+
event.affectsConfiguration("shader-validator.serverPath")) {
125+
//restartServer();
126+
}
104127
await client.sendNotification(DidChangeConfigurationNotification.type, {
105128
settings: "",
106129
});
@@ -171,7 +194,9 @@ export async function createLanguageClient(context: vscode.ExtensionContext): Pr
171194
}
172195
}
173196
async function createLanguageClientStandard(context: vscode.ExtensionContext, platform : ServerPlatform) : Promise<LanguageClient | null> {
174-
const executable = getPlatformBinaryUri(context, platform);
197+
const executable = getPlatformBinaryUri(context.extensionUri, platform);
198+
const cwd = getPlatformBinaryDirectoryPath(context.extensionUri, platform);
199+
console.info(`Executing server ${executable} with working directory ${cwd}`);
175200
const trace = vscode.workspace.getConfiguration("shader-validator").get<string>("trace.server");
176201
const defaultEnv = {};
177202
const env = (trace === "verbose") ? {
@@ -187,7 +212,7 @@ async function createLanguageClientStandard(context: vscode.ExtensionContext, pl
187212
command: executable.fsPath,
188213
transport: TransportKind.stdio,
189214
options: {
190-
cwd: getPlatformBinaryDirectoryUri(context, platform).fsPath,
215+
cwd: cwd.fsPath,
191216
env: env
192217
}
193218
};
@@ -234,7 +259,8 @@ async function createLanguageClientWASI(context: vscode.ExtensionContext) : Prom
234259
// Load the WASM module. It is stored alongside the extension's JS code.
235260
// So we can use VS Code's file system API to load it. Makes it
236261
// independent of whether the code runs in the desktop or the web.
237-
const executable = getPlatformBinaryUri(context, ServerPlatform.wasi);
262+
const executable = getPlatformBinaryUri(context.extensionUri, ServerPlatform.wasi);
263+
console.info(`Executing wasi server ${executable}`);
238264
const bits = await vscode.workspace.fs.readFile(executable);
239265
const module = await WebAssembly.compile(bits);
240266

0 commit comments

Comments
 (0)