Skip to content

get launch config from settings.json as fallback #585

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Feb 13, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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',
);
});
});
});
Loading