]> git.lizzy.rs Git - rust.git/commitdiff
VSCode variables support for substitutions
authorAndrei Listochkin <andrei.listochkin@ferrous-systems.com>
Wed, 11 May 2022 12:34:43 +0000 (13:34 +0100)
committerAndrei Listochkin <andrei.listochkin@ferrous-systems.com>
Wed, 11 May 2022 14:50:59 +0000 (15:50 +0100)
Tests now open Rust-Analyzer extension code in order to populate
VSCode variables.

editors/code/src/config.ts
editors/code/tests/runTests.ts
editors/code/tests/unit/settings.test.ts

index cfbdd696652c3ce1e28a3697f266ed8cbe00507d..9165ba861d4a5ee61dff9400b9711e55ac833ef0 100644 (file)
@@ -1,3 +1,4 @@
+import path = require('path');
 import * as vscode from 'vscode';
 import { Env } from './client';
 import { log } from "./util";
@@ -253,7 +254,10 @@ export function substituteVariablesInEnv(env: Env): Env {
                 resolved.add(dep);
             }
         } else {
-            // TODO: handle VSCode variables
+            envWithDeps[dep] = {
+                value: computeVscodeVar(dep),
+                deps: []
+            };
         }
     }
     const toResolve = new Set(Object.keys(envWithDeps));
@@ -279,3 +283,52 @@ export function substituteVariablesInEnv(env: Env): Env {
     }
     return resolvedEnv;
 }
+
+function computeVscodeVar(varName: string): string {
+    // https://code.visualstudio.com/docs/editor/variables-reference
+    const supportedVariables: { [k: string]: () => string } = {
+        workspaceFolder: () => {
+            const folders = vscode.workspace.workspaceFolders ?? [];
+            if (folders.length === 1) {
+                // TODO: support for remote workspaces?
+                return folders[0].uri.fsPath;
+            } else if (folders.length > 1) {
+                // could use currently opened document to detect the correct
+                // workspace. However, that would be determined by the document
+                // user has opened on Editor startup. Could lead to
+                // unpredictable workspace selection in practice.
+                // It's better to pick the first one
+                return folders[0].uri.fsPath;
+            } else {
+                // no workspace opened
+                return '';
+            }
+        },
+
+        workspaceFolderBasename: () => {
+            const workspaceFolder = computeVscodeVar('workspaceFolder');
+            if (workspaceFolder) {
+                return path.basename(workspaceFolder);
+            } else {
+                return '';
+            }
+        },
+
+        cwd: () => process.cwd(),
+
+        // see
+        // https://github.com/microsoft/vscode/blob/08ac1bb67ca2459496b272d8f4a908757f24f56f/src/vs/workbench/api/common/extHostVariableResolverService.ts#L81
+        // or
+        // https://github.com/microsoft/vscode/blob/29eb316bb9f154b7870eb5204ec7f2e7cf649bec/src/vs/server/node/remoteTerminalChannel.ts#L56
+        execPath: () => process.env.VSCODE_EXEC_PATH ?? process.execPath,
+
+        pathSeparator: () => path.sep
+    };
+
+    if (varName in supportedVariables) {
+        return supportedVariables[varName]();
+    } else {
+        // can't resolve, keep the expression as is
+        return '${' + varName + '}';
+    }
+}
index 7a8f3ef698bbd304307cab760f54c0ee5717ef6b..6172cc7d5f96d5f19a3ddf7e6955a5e8f9c1e42a 100644 (file)
@@ -14,7 +14,7 @@ async function main() {
     let minimalVersion: string = json.engines.vscode;
     if (minimalVersion.startsWith('^')) minimalVersion = minimalVersion.slice(1);
 
-    const launchArgs = ["--disable-extensions"];
+    const launchArgs = ["--disable-extensions", extensionDevelopmentPath];
 
     // All test suites (either unit tests or integration tests) should be in subfolders.
     const extensionTestsPath = path.resolve(__dirname, './unit/index');
index f4b022b421c739d7a629b9478bbdfd97744c26fc..dca4e38d1381e1c358f0d66d566a4ae1075df9d7 100644 (file)
@@ -49,5 +49,13 @@ export async function getTests(ctx: Context) {
             const actualEnv = await substituteVariablesInEnv(envJson);
             assert.deepStrictEqual(actualEnv, expectedEnv);
         });
+
+        suite.addTest('should support VSCode variables', async () => {
+            const envJson = {
+                USING_VSCODE_VAR: "${workspaceFolderBasename}"
+            };
+            const actualEnv = await substituteVariablesInEnv(envJson);
+            assert.deepStrictEqual(actualEnv.USING_VSCODE_VAR, 'code');
+        });
     });
 }