Skip to content

Commit

Permalink
get launch config from settings.json as fallback (#585)
Browse files Browse the repository at this point in the history
* get launch config from settings.json as fallback

* update error return

* remove dup getConfig
  • Loading branch information
eleanorjboyd authored Feb 13, 2025
1 parent 9ecfa9f commit 84ce2f2
Show file tree
Hide file tree
Showing 2 changed files with 140 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,18 @@ export async function getConfigurationsForWorkspace(workspace: WorkspaceFolder):
traceLog('Getting configurations for workspace');
const filename = path.join(workspace.uri.fsPath, '.vscode', 'launch.json');
if (!(await fs.pathExists(filename))) {
// Check launch config in the workspace file
const codeWorkspaceConfig = getConfiguration('launch', workspace);
if (!codeWorkspaceConfig.configurations || !Array.isArray(codeWorkspaceConfig.configurations)) {
return [];
}
traceLog('Using configuration in workspace');
return codeWorkspaceConfig.configurations;
return getConfigurationsFromSettings(workspace);
}

const text = await fs.readFile(filename, 'utf-8');
const parsed = parse(text, [], { allowTrailingComma: true, disallowComments: false });
if (!parsed.configurations || !Array.isArray(parsed.configurations)) {
throw Error('Missing field in launch.json: configurations');
// no launch.json or no configurations found in launch.json, look in settings.json
if (!parsed || !parsed.configurations) {
traceLog('No configurations found in launch.json, looking in settings.json.');
return getConfigurationsFromSettings(workspace);
}
// configurations found in launch.json, verify them then return
if (!Array.isArray(parsed.configurations) || parsed.configurations.length === 0) {
throw Error('Invalid configurations in launch.json');
}
if (!parsed.version) {
throw Error('Missing field in launch.json: version');
Expand All @@ -42,3 +41,18 @@ export async function getConfigurationsByUri(uri?: Uri): Promise<DebugConfigurat
}
return [];
}

export function getConfigurationsFromSettings(workspace: WorkspaceFolder): DebugConfiguration[] {
// look in settings.json
const codeWorkspaceConfig = getConfiguration('launch', workspace);
// if this includes user configs, how do I make sure it selects the workspace ones first
if (
!codeWorkspaceConfig.configurations ||
!Array.isArray(codeWorkspaceConfig.configurations) ||
codeWorkspaceConfig.configurations.length === 0
) {
throw Error('No configurations found in launch.json or settings.json');
}
traceLog('Using configuration in workspace settings.json.');
return codeWorkspaceConfig.configurations;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
'use strict';

import * as assert from 'assert';
import * as sinon from 'sinon';
import * as typemoq from 'typemoq';
import * as fs from 'fs-extra';
import { WorkspaceFolder, Uri, WorkspaceConfiguration } from 'vscode';
import {
getConfigurationsForWorkspace,
getConfigurationsFromSettings,
} from '../../../../extension/debugger/configuration/launch.json/launchJsonReader';
import * as vscodeapi from '../../../../extension/common/vscodeapi';

suite('Debugging - launchJsonReader', () => {
let sandbox: sinon.SinonSandbox;

setup(() => {
sandbox = sinon.createSandbox();
});

teardown(() => {
sandbox.restore();
});

suite('getConfigurationsForWorkspace', () => {
test('Should return configurations from launch.json if it exists', async () => {
const workspace = typemoq.Mock.ofType<WorkspaceFolder>();
workspace.setup((w) => w.uri).returns(() => Uri.file('/path/to/workspace'));

const launchJsonContent = `{
"version": "0.2.0",
"configurations": [
{
"name": "Launch Program",
"type": "python",
"request": "launch",
"program": "${workspace.object.uri}/app.py"
}
]
}`;

sandbox.stub(fs, 'pathExists').resolves(true);
sandbox.stub(fs, 'readFile').resolves(launchJsonContent);

const configurations = await getConfigurationsForWorkspace(workspace.object);
assert.strictEqual(configurations.length, 1);
assert.strictEqual(configurations[0].name, 'Launch Program');
});

test('Should return configurations from settings.json if launch.json does not exist', async () => {
const workspace = typemoq.Mock.ofType<WorkspaceFolder>();
workspace.setup((w) => w.uri).returns(() => Uri.file('/path/to/workspace'));

const mockConfig = typemoq.Mock.ofType<WorkspaceConfiguration>();
mockConfig
.setup((c) => c.configurations)
.returns(() => [
{
name: 'Launch Program 2',
type: 'python',
request: 'launch',
program: '${workspaceFolder}/app.py',
},
]);

sandbox.stub(fs, 'pathExists').resolves(false);
sandbox.stub(vscodeapi, 'getConfiguration').returns(mockConfig.object);

const configurations = await getConfigurationsForWorkspace(workspace.object);
assert.strictEqual(configurations.length, 1);
assert.strictEqual(configurations[0].name, 'Launch Program 2');
});
});

suite('getConfigurationsFromSettings', () => {
test('Should return configurations from settings.json', () => {
const workspace = typemoq.Mock.ofType<WorkspaceFolder>();
workspace.setup((w) => w.uri).returns(() => Uri.file('/path/to/workspace'));

const mockConfig = typemoq.Mock.ofType<WorkspaceConfiguration>();
mockConfig
.setup((c) => c.configurations)
.returns(() => [
{
name: 'Launch Program 3',
type: 'python',
request: 'launch',
program: '${workspaceFolder}/app.py',
},
]);

sandbox.stub(vscodeapi, 'getConfiguration').returns(mockConfig.object);

const configurations = getConfigurationsFromSettings(workspace.object);
assert.strictEqual(configurations.length, 1);
assert.strictEqual(configurations[0].name, 'Launch Program 3');
});

test('Should error if no configurations in settings.json', () => {
const workspace = typemoq.Mock.ofType<WorkspaceFolder>();
workspace.setup((w) => w.uri).returns(() => Uri.file('/path/to/workspace'));

const mockConfig = typemoq.Mock.ofType<WorkspaceConfiguration>();
mockConfig.setup((c) => c.get('configurations')).returns(() => []);
mockConfig.setup((c) => c.configurations).returns(() => []);

sandbox.stub(vscodeapi, 'getConfiguration').returns(mockConfig.object);

assert.throws(
() => getConfigurationsFromSettings(workspace.object),
Error,
'No configurations found in launch.json or settings.json',
);
});
});
});

1 comment on commit 84ce2f2

@Kedveslmre
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

microsoft/vscode-python-debugger

Please sign in to comment.