Repository: stateful/vscode-runme
Pull request #457 (2023-04-26 22:32:51)

Add runme executable to PATH
Part of #430 


Patch:
diff --git a/__mocks__/vscode.ts b/__mocks__/vscode.ts
index 207b4b22..48b10869 100644
--- a/__mocks__/vscode.ts
+++ b/__mocks__/vscode.ts
@@ -25,7 +25,7 @@ export class Uri extends URI {
   static parse = vi.fn(super.parse)
 
   static joinPath = vi.fn((uri: Uri, ...paths: string[]) => {
-    return Uri.file(path.join(uri.fsPath, ...paths))
+    return super.file(path.join(uri.fsPath, ...paths))
   })
 }
 
diff --git a/src/extension/commands/index.ts b/src/extension/commands/index.ts
index 86dc0972..affab2be 100644
--- a/src/extension/commands/index.ts
+++ b/src/extension/commands/index.ts
@@ -1,5 +1,4 @@
 import path from 'node:path'
-import os from 'node:os'
 
 import {
   NotebookCell, Uri, window, env, NotebookDocument, TextDocument, ViewColumn,
@@ -7,7 +6,7 @@ import {
 } from 'vscode'
 import { v4 as uuidv4 } from 'uuid'
 
-import { getBinaryPath, getTLSDir, getTLSEnabled, isNotebookTerminalEnabledForCell } from '../../utils/configuration'
+import { getTLSDir, getTLSEnabled, isNotebookTerminalEnabledForCell } from '../../utils/configuration'
 import { Kernel } from '../kernel'
 import { getAnnotations, getTerminalByCell, openFileAsRunmeNotebook } from '../utils'
 import RunmeServer from '../server/runmeServer'
@@ -78,8 +77,6 @@ export function runCLICommand(
 
     const envs: Record<string, string> = { }
 
-    const runmeExecutable = getBinaryPath(extensionBaseUri, os.platform()).fsPath
-
     if (grpcRunner) {
       envs['RUNME_SERVER_ADDR'] = server.address()
 
@@ -103,7 +100,7 @@ export function runCLICommand(
     })
 
     term.show(false)
-    term.sendText(`${runmeExecutable} run ${annotations.name} ${args.join(' ')}`)
+    term.sendText(`runme run ${annotations.name} ${args.join(' ')}`)
   }
 }
 
diff --git a/src/extension/extension.ts b/src/extension/extension.ts
index 5f40717d..161bb5c1 100644
--- a/src/extension/extension.ts
+++ b/src/extension/extension.ts
@@ -2,6 +2,8 @@
 import { workspace, notebooks, commands, ExtensionContext, tasks, window, Uri } from 'vscode'
 import { TelemetryReporter } from 'vscode-telemetry'
 
+import { registerExtensionEnvironmentVariables } from '../utils/configuration'
+
 import { Kernel } from './kernel'
 import RunmeServer from './server/runmeServer'
 import RunmeServerError from './server/runmeServerError'
@@ -78,6 +80,8 @@ export class RunmeExtension {
 
     const codeLensProvider = new RunmeCodeLensProvider(serializer, runCLI, winCodeLensRunSurvey, runner, kernel)
 
+    registerExtensionEnvironmentVariables(context)
+
     context.subscriptions.push(
       kernel,
       serializer,
diff --git a/src/utils/configuration.ts b/src/utils/configuration.ts
index da32fe44..311d2048 100644
--- a/src/utils/configuration.ts
+++ b/src/utils/configuration.ts
@@ -1,7 +1,7 @@
 import path from 'node:path'
 import os from 'node:os'
 
-import { NotebookCell, Uri, workspace } from 'vscode'
+import { ExtensionContext, NotebookCell, Uri, workspace } from 'vscode'
 import { z } from 'zod'
 import { v4 as uuidv4 } from 'uuid'
 
@@ -148,6 +148,15 @@ const getCodeLensEnabled = (): boolean => {
   return getCodeLensConfigurationValue<boolean>('enable', true)
 }
 
+const registerExtensionEnvironmentVariables = (context: ExtensionContext): void => {
+  context.environmentVariableCollection.prepend(
+    'PATH',
+    path.dirname(
+      getBinaryPath(context.extensionUri, os.platform()).fsPath
+    ) + (isWindows() ? ';' : ':'),
+  )
+}
+
 export {
     getPortNumber,
     getBinaryPath,
@@ -161,4 +170,5 @@ export {
     getNotebookTerminalFontSize,
     getNotebookTerminalRows,
     getCodeLensEnabled,
+    registerExtensionEnvironmentVariables,
 }


Test patch:
diff --git a/tests/extension/commands/index.test.ts b/tests/extension/commands/index.test.ts
index c7534932..bcacc6d0 100644
--- a/tests/extension/commands/index.test.ts
+++ b/tests/extension/commands/index.test.ts
@@ -119,7 +119,7 @@ test('runCLICommand', async () => {
 
   await runCLICommand({} as any, false, {} as any, {} as any)(cell)
   expect(vi.mocked((terminal as any).sendText)).toHaveBeenCalledWith(
-    '/bin/runme run foo-bar --chdir="/foo/bar" --filename="README.md"'
+    'runme run foo-bar --chdir="/foo/bar" --filename="README.md"'
   )
 })
 
diff --git a/tests/extension/extension.test.ts b/tests/extension/extension.test.ts
index 06b33ba9..05b7e686 100644
--- a/tests/extension/extension.test.ts
+++ b/tests/extension/extension.test.ts
@@ -47,9 +47,18 @@ test('initializes all providers', async () => {
   vi.mocked(workspace.getConfiguration).mockReturnValue({
     get: vi.fn((config: string) => configValues[config])
   } as any)
-  vi.mocked(Uri.joinPath).mockReturnValue('/foo/bar' as any)
+  const dummyFilePath = Uri.file('/foo/bar')
+  vi.mocked(Uri.joinPath).mockReturnValue(dummyFilePath)
   RunmeServer['getTLS'] = vi.fn().mockResolvedValue({ privKeyPEM: testPrivKeyPEM, certPEM: testCertPEM })
-  const context: any = { subscriptions: [], extensionUri: { fsPath: '/foo/bar' } }
+  const context: any = {
+    subscriptions: [],
+    extensionUri: { fsPath: '/foo/bar' },
+    environmentVariableCollection: {
+      prepend: vi.fn(),
+      append: vi.fn(),
+      replace: vi.fn(),
+    }
+  }
   const ext = new RunmeExtension()
   await ext.initialize(context)
   expect(notebooks.registerNotebookCellStatusBarItemProvider).toBeCalledTimes(6)
@@ -58,7 +67,7 @@ test('initializes all providers', async () => {
   expect(window.registerTreeDataProvider).toBeCalledTimes(1)
   expect(window.registerUriHandler).toBeCalledTimes(1)
 
-  expect(commands.executeCommand).toBeCalledWith('vscode.openWith', '/foo/bar', 'runme')
-  expect(workspace.fs.stat).toBeCalledWith('/foo/bar')
-  expect(workspace.fs.delete).toBeCalledWith('/foo/bar')
+  expect(commands.executeCommand).toBeCalledWith('vscode.openWith', dummyFilePath, 'runme')
+  expect(workspace.fs.stat).toBeCalledWith(dummyFilePath)
+  expect(workspace.fs.delete).toBeCalledWith(dummyFilePath)
 })