Skip to content

Commit 247c9bf

Browse files
Zentrikrchiodo
andauthored
no config debug: Fix error when multiple vscode windows are open (#918)
* no config debug: Fix error when multiple vscode windows are open Should fix #916, but getting this installed locally seemed sufficiently complicated that I gave up. Fix is: 1. Only watch a specific endpoint file 2. Make sure this endpoint file is unique (I imagine the workspace file path can be non unique across vscode windows) * [AI] Update tests * Fix typo * Remove driveby fix * Format * Cleanup test and try to fix it failing on windows I guess this is what I get for trusting AI at midnight. * Fix failing test on windows take 2 The error seems to be that `base` is `c:\\Users\\RUNNER~1\\AppData\\Local\\Temp\\.noConfigDebugAdapterEndpoints` but `noConfigEndpointDir` is `C:\Users\RUNNER~1\AppData\Local\Temp\.noConfigDebugAdapterEndpoints` (the C is capitalised). Getting the fsPath of the URI should normalise the path the same as `base`. * Remove workspace from hash --------- Co-authored-by: Rich Chiodo <rchiodo@users.noreply.github.com>
1 parent 4c0fdc2 commit 247c9bf

File tree

2 files changed

+14
-23
lines changed

2 files changed

+14
-23
lines changed

src/extension/noConfigDebugInit.ts

Lines changed: 8 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@ import {
88
DebugSessionOptions,
99
Disposable,
1010
GlobalEnvironmentVariableCollection,
11+
env,
1112
l10n,
1213
RelativePattern,
13-
workspace,
1414
} from 'vscode';
1515
import { createFileSystemWatcher, debugStartDebugging } from './utils';
1616
import { traceError, traceVerbose } from './common/log/logging';
@@ -39,23 +39,13 @@ export async function registerNoConfigDebug(
3939
const collection = envVarCollection;
4040

4141
// create a temp directory for the noConfigDebugAdapterEndpoints
42-
// file path format: extPath/.noConfigDebugAdapterEndpoints/endpoint-stableWorkspaceHash.txt
43-
let workspaceString = workspace.workspaceFile?.fsPath;
44-
if (!workspaceString) {
45-
workspaceString = workspace.workspaceFolders?.map((e) => e.uri.fsPath).join(';');
46-
}
47-
if (!workspaceString) {
48-
traceError('No workspace folder found');
49-
return Promise.resolve(new Disposable(() => {}));
50-
}
51-
52-
// create a stable hash for the workspace folder, reduce terminal variable churn
53-
const hash = crypto.createHash('sha256');
54-
hash.update(workspaceString.toString());
55-
const stableWorkspaceHash = hash.digest('hex').slice(0, 16);
42+
// file path format: extPath/.noConfigDebugAdapterEndpoints/endpoint-<sessionId>.txt
43+
// sessionId is unique per VS Code window, ensuring isolation between windows
5644

5745
const tempDirPath = path.join(extPath, '.noConfigDebugAdapterEndpoints');
58-
const tempFilePath = path.join(tempDirPath, `endpoint-${stableWorkspaceHash}.txt`);
46+
const sessionIdHash = crypto.createHash('sha256').update(env.sessionId).digest('hex').slice(0, 16);
47+
const endpointFilename = `endpoint-${sessionIdHash}.txt`;
48+
const tempFilePath = path.join(tempDirPath, endpointFilename);
5949

6050
// create the temp directory if it doesn't exist
6151
if (!fs.existsSync(tempDirPath)) {
@@ -88,8 +78,8 @@ export async function registerNoConfigDebug(
8878
'Enables use of [no-config debugging](https://github.com/microsoft/vscode-python-debugger/wiki/No%E2%80%90Config-Debugging), `debugpy <script.py>`, in the terminal.',
8979
);
9080

91-
// create file system watcher for the debuggerAdapterEndpointFolder for when the communication port is written
92-
const fileSystemWatcher = createFileSystemWatcher(new RelativePattern(tempDirPath, '**/*.txt'));
81+
// create file system watcher for the debugger adapter endpoint for when the communication port is written
82+
const fileSystemWatcher = createFileSystemWatcher(new RelativePattern(tempDirPath, endpointFilename));
9383
const fileCreationEvent = fileSystemWatcher.onDidCreate(async (uri) => {
9484
sendTelemetryEvent(EventName.DEBUG_SESSION_START, undefined, {
9585
trigger: 'noConfig' as TriggerType,

src/test/unittest/noConfigDebugInit.unit.test.ts

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { IExtensionContext } from '../../extension/common/types';
66
import { registerNoConfigDebug as registerNoConfigDebug } from '../../extension/noConfigDebugInit';
77
import * as TypeMoq from 'typemoq';
88
import * as sinon from 'sinon';
9-
import { DebugConfiguration, DebugSessionOptions, RelativePattern, Uri, workspace } from 'vscode';
9+
import { DebugConfiguration, DebugSessionOptions, env, RelativePattern, Uri } from 'vscode';
1010
import * as utils from '../../extension/utils';
1111
import { assert } from 'console';
1212
import * as fs from 'fs';
@@ -21,7 +21,8 @@ suite('setup for no-config debug scenario', function () {
2121
let bundledDebugPath: string;
2222
let DEBUGPY_ADAPTER_ENDPOINTS = 'DEBUGPY_ADAPTER_ENDPOINTS';
2323
let BUNDLED_DEBUGPY_PATH = 'BUNDLED_DEBUGPY_PATH';
24-
let workspaceUriStub: sinon.SinonStub;
24+
const testSessionId = 'test-session-id-1234';
25+
const hashedSessionId = crypto.createHash('sha256').update(testSessionId).digest('hex').slice(0, 16);
2526

2627
const testDataDir = path.join(__dirname, 'testData');
2728
const testFilePath = path.join(testDataDir, 'debuggerAdapterEndpoint.txt');
@@ -39,14 +40,14 @@ suite('setup for no-config debug scenario', function () {
3940
// Provide a valid Buffer object
4041
randomBytesStub.callsFake((_size: number) => Buffer.from('1234567899', 'hex'));
4142

42-
workspaceUriStub = sinon.stub(workspace, 'workspaceFolders').value([{ uri: Uri.parse(os.tmpdir()) }]);
43+
// Stub env.sessionId to return a consistent value for tests
44+
sinon.stub(env, 'sessionId').value(testSessionId);
4345
} catch (error) {
4446
console.error('Error in setup:', error);
4547
}
4648
});
4749
teardown(() => {
4850
sinon.restore();
49-
workspaceUriStub.restore();
5051
});
5152

5253
test('should add environment variables for DEBUGPY_ADAPTER_ENDPOINTS, BUNDLED_DEBUGPY_PATH, and PATH', async () => {
@@ -136,7 +137,7 @@ suite('setup for no-config debug scenario', function () {
136137
sinon.assert.calledOnce(createFileSystemWatcherFunct);
137138
const expectedPattern = new RelativePattern(
138139
path.join(os.tmpdir(), '.noConfigDebugAdapterEndpoints'),
139-
'**/*.txt',
140+
`endpoint-${hashedSessionId}.txt`,
140141
);
141142
sinon.assert.calledWith(createFileSystemWatcherFunct, expectedPattern);
142143
});

0 commit comments

Comments
 (0)