Skip to content
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

Add default debug config and fix labels #3860

Merged
merged 2 commits into from
Jan 4, 2019
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
58 changes: 58 additions & 0 deletions resources/default.launch.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
[
{
"name": "Python: Current File (Integrated Terminal)",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "integratedTerminal"
},
{
"name": "Python: Attach",
"type": "python",
"request": "attach",
"port": 5678,
"host": "localhost"
},
{
"name": "Python: Module",
"type": "python",
"request": "launch",
"module": "enter-your-module-name-here",
"console": "integratedTerminal"
},
{
"name": "Python: Django",
"type": "python",
"request": "launch",
"program": "${workspaceFolder}/manage.py",
"console": "integratedTerminal",
"args": [
"runserver",
"--noreload",
"--nothreading"
],
"django": true
},
{
"name": "Python: Flask",
"type": "python",
"request": "launch",
"module": "flask",
"env": {
"FLASK_APP": "app.py"
},
"args": [
"run",
"--no-debugger",
"--no-reload"
],
"jinja": true
},
{
"name": "Python: Current File (External Terminal)",
"type": "python",
"request": "launch",
"program": "${file}",
"console": "externalTerminal"
}
]
22 changes: 11 additions & 11 deletions src/client/common/utils/localize.ts
Original file line number Diff line number Diff line change
Expand Up @@ -110,38 +110,38 @@ export namespace DebugConfigurationPrompts {
export const selectConfigurationTitle = localize('debug.selectConfigurationTitle', 'Select a debug configuration');
export const selectConfigurationPlaceholder = localize('debug.selectConfigurationPlaceholder', 'Debug Configuration');
export const debugFileConfigurationLabel = localize('debug.debugFileConfigurationLabel', 'Python File');
export const debugFileConfigurationDescription = localize('debug.debugFileConfigurationDescription', 'Debug Python file');
export const debugFileConfigurationDescription = localize('debug.debugFileConfigurationDescription', 'Debug currently active Python file');
export const debugModuleConfigurationLabel = localize('debug.debugModuleConfigurationLabel', 'Module');
export const debugModuleConfigurationDescription = localize('debug.debugModuleConfigurationDescription', 'Debug Python module/package');
export const debugModuleConfigurationDescription = localize('debug.debugModuleConfigurationDescription', 'Debug a python module by invoking it with \'-m\'');
export const remoteAttachConfigurationLabel = localize('debug.remoteAttachConfigurationLabel', 'Remote Attach');
export const remoteAttachConfigurationDescription = localize('debug.remoteAttachConfigurationDescription', 'Debug a remote Python program');
export const remoteAttachConfigurationDescription = localize('debug.remoteAttachConfigurationDescription', 'Attach to a remote ptsvd debug server');
export const debugDjangoConfigurationLabel = localize('debug.debugDjangoConfigurationLabel', 'Django');
export const debugDjangoConfigurationDescription = localize('debug.debugDjangoConfigurationDescription', 'Web Application');
export const debugDjangoConfigurationDescription = localize('debug.debugDjangoConfigurationDescription', 'Launch and debug a Django web application');
export const debugFlaskConfigurationLabel = localize('debug.debugFlaskConfigurationLabel', 'Flask');
export const debugFlaskConfigurationDescription = localize('debug.debugFlaskConfigurationDescription', 'Web Application');
export const debugFlaskConfigurationDescription = localize('debug.debugFlaskConfigurationDescription', 'Launch and debug a Flask web application');
export const debugPyramidConfigurationLabel = localize('debug.debugPyramidConfigurationLabel', 'Pyramid');
export const debugPyramidConfigurationDescription = localize('debug.debugPyramidConfigurationDescription', 'Web Application');
export const djangoEnterManagePyPathTitle = localize('debug.djangoEnterManagePyPathTitle', 'Debug Django');
// tslint:disable-next-line:no-invalid-template-strings
export const djangoEnterManagePyPathPrompt = localize('debug.djangoEnterManagePyPathPrompt', 'Enter path to manage.py (\'${workspaceFolderToken}\' points to the root of the current workspace folder)');
export const djangoEnterManagePyPathInvalidFilePathError = localize('debug.djangoEnterManagePyPathInvalidFilePathError', 'Enter a valid Python file path');
export const djangoEnterManagePyPathPrompt = localize('debug.djangoEnterManagePyPathPrompt', 'Enter path to manage.py (\'${workspaceFolder}\' points to the root of the current workspace folder)');
export const djangoEnterManagePyPathInvalidFilePathError = localize('debug.djangoEnterManagePyPathInvalidFilePathError', 'Enter a valid python file path');
export const flaskEnterAppPathOrNamePathTitle = localize('debug.flaskEnterAppPathOrNamePathTitle', 'Debug Flask');
export const flaskEnterAppPathOrNamePathPrompt = localize('debug.flaskEnterAppPathOrNamePathPrompt', 'Enter path to application, e.g. \'app.py\' or \'app\'');
export const flaskEnterAppPathOrNamePathInvalidNameError = localize('debug.flaskEnterAppPathOrNamePathInvalidNameError', 'Enter a valid name');

export const moduleEnterModuleTitle = localize('debug.moduleEnterModuleTitle', 'Debug Module');
export const moduleEnterModulePrompt = localize('debug.moduleEnterModulePrompt', 'Enter Python module/package name');
export const moduleEnterModuleInvalidNameError = localize('debug.moduleEnterModuleInvalidNameError', 'Enter a valid name');
export const moduleEnterModuleInvalidNameError = localize('debug.moduleEnterModuleInvalidNameError', 'Enter a valid module name');
export const pyramidEnterDevelopmentIniPathTitle = localize('debug.pyramidEnterDevelopmentIniPathTitle', 'Debug Pyramid');
// tslint:disable-next-line:no-invalid-template-strings
export const pyramidEnterDevelopmentIniPathPrompt = localize('debug.pyramidEnterDevelopmentIniPathPrompt', '`Enter path to development.ini (\'${workspaceFolderToken}\' points to the root of the current workspace folder)`');
export const pyramidEnterDevelopmentIniPathInvalidFilePathError = localize('debug.pyramidEnterDevelopmentIniPathInvalidFilePathError', 'Enter a valid file path');
export const attachRemotePortTitle = localize('debug.attachRemotePortTitle', 'Remote Debugging');
export const attachRemotePortPrompt = localize('debug.attachRemotePortPrompt', 'Enter port number');
export const attachRemotePortPrompt = localize('debug.attachRemotePortPrompt', 'Enter the port number that the ptvsd server is listening on');
export const attachRemotePortValidationError = localize('debug.attachRemotePortValidationError', 'Enter a valid port number');
export const attachRemoteHostTitle = localize('debug.attachRemoteHostTitle', 'Remote Debugging');
export const attachRemoteHostPrompt = localize('debug.attachRemoteHostPrompt', 'Enter a host name or IP address');
export const attachRemoteHostValidationError = localize('debug.attachRemoteHostValidationError', 'Enter a valid host name or IP address');
export const attachRemoteHostPrompt = localize('debug.attachRemoteHostPrompt', 'Enter host name');
export const attachRemoteHostValidationError = localize('debug.attachRemoteHostValidationError', 'Enter a host name or IP address');
}

// Skip using vscode-nls and instead just compute our strings based on key values. Key values
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,14 @@
'use strict';

import { inject, injectable, named } from 'inversify';
import * as path from 'path';
import { CancellationToken, DebugConfiguration, QuickPickItem, WorkspaceFolder } from 'vscode';
import { IFileSystem } from '../../../common/platform/types';
import { DebugConfigurationPrompts } from '../../../common/utils/localize';
import { IMultiStepInput, IMultiStepInputFactory, InputStep, IQuickPickParameters } from '../../../common/utils/multiStepInput';
import { EXTENSION_ROOT_DIR } from '../../../constants';
import { sendTelemetryEvent } from '../../../telemetry';
import { DEBUGGER_CONFIGURATION_PROMPTS } from '../../../telemetry/constants';
import { AttachRequestArguments, DebugConfigurationArguments, LaunchRequestArguments } from '../../types';
import { DebugConfigurationState, DebugConfigurationType, IDebugConfigurationService } from '../types';
import { IDebugConfigurationProviderFactory, IDebugConfigurationResolver } from './types';
Expand All @@ -16,14 +21,19 @@ export class PythonDebugConfigurationService implements IDebugConfigurationServi
constructor(@inject(IDebugConfigurationResolver) @named('attach') private readonly attachResolver: IDebugConfigurationResolver<AttachRequestArguments>,
@inject(IDebugConfigurationResolver) @named('launch') private readonly launchResolver: IDebugConfigurationResolver<LaunchRequestArguments>,
@inject(IDebugConfigurationProviderFactory) private readonly providerFactory: IDebugConfigurationProviderFactory,
@inject(IMultiStepInputFactory) private readonly multiStepFactory: IMultiStepInputFactory) {
@inject(IMultiStepInputFactory) private readonly multiStepFactory: IMultiStepInputFactory,
@inject(IFileSystem) private readonly fs: IFileSystem) {
}
public async provideDebugConfigurations?(folder: WorkspaceFolder | undefined, token?: CancellationToken): Promise<DebugConfiguration[] | undefined> {
public async provideDebugConfigurations(folder: WorkspaceFolder | undefined, token?: CancellationToken): Promise<DebugConfiguration[] | undefined> {
DonJayamanne marked this conversation as resolved.
Show resolved Hide resolved
const config: Partial<DebugConfigurationArguments> = {};
const state = { config, folder, token };
const multiStep = this.multiStepFactory.create<DebugConfigurationState>();
await multiStep.run((input, s) => this.pickDebugConfiguration(input, s), state);
return state.config as DebugConfiguration[];
if (Object.keys(state.config).length === 0) {
return this.getDefaultDebugConfig();
} else {
return [state.config as DebugConfiguration];
}
}
public async resolveDebugConfiguration(folder: WorkspaceFolder | undefined, debugConfiguration: DebugConfiguration, token?: CancellationToken): Promise<DebugConfiguration | undefined> {
if (debugConfiguration.request === 'attach') {
Expand All @@ -32,6 +42,12 @@ export class PythonDebugConfigurationService implements IDebugConfigurationServi
return this.launchResolver.resolveDebugConfiguration(folder, debugConfiguration as LaunchRequestArguments, token);
}
}
protected async getDefaultDebugConfig(): Promise<DebugConfiguration[]> {
sendTelemetryEvent(DEBUGGER_CONFIGURATION_PROMPTS, undefined, { configurationType: DebugConfigurationType.default });
const jsFilePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'default.launch.json');
const jsonStr = await this.fs.readFile(jsFilePath);
return JSON.parse(jsonStr) as DebugConfiguration[];
}
protected async pickDebugConfiguration(input: IMultiStepInput<DebugConfigurationState>, state: DebugConfigurationState): Promise<InputStep<DebugConfigurationState> | void> {
type DebugConfigurationQuickPickItem = QuickPickItem & { type: DebugConfigurationType };
const items: DebugConfigurationQuickPickItem[] = [
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ export class ModuleLaunchDebugConfigurationProvider implements IDebugConfigurati
name: localize('python.snippet.launch.module.label', 'Python: Module')(),
type: DebuggerTypeName,
request: 'launch',
module: 'enter-your-module-name-here'
module: 'enter-your-module-name'
};
const selectedModule = await input.showInputBox({
title: DebugConfigurationPrompts.moduleEnterModuleTitle(),
value: config.module || 'enter-your-module-name-here',
value: config.module || 'enter-your-module-name',
prompt: DebugConfigurationPrompts.moduleEnterModulePrompt(),
validate: value => Promise.resolve((value && value.trim().length > 0) ? undefined : DebugConfigurationPrompts.moduleEnterModuleInvalidNameError())
});
Expand Down
1 change: 1 addition & 0 deletions src/client/debugger/extension/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export interface IDebugConfigurationProvider {
}

export enum DebugConfigurationType {
default = 'default',
launchFile = 'launchFile',
remoteAttach = 'remoteAttach',
launchDjango = 'launchDjango',
Expand Down
5 changes: 4 additions & 1 deletion src/test/debugger/attach.ptvsd.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,14 @@ import '../../client/common/extensions';
import { ChildProcess, spawn } from 'child_process';
import * as getFreePort from 'get-port';
import * as path from 'path';
import { instance, mock } from 'ts-mockito';
import * as TypeMoq from 'typemoq';
import { DebugConfiguration, Uri } from 'vscode';
import { DebugClient } from 'vscode-debugadapter-testsupport';
import { IDocumentManager, IWorkspaceService } from '../../client/common/application/types';
import { EXTENSION_ROOT_DIR } from '../../client/common/constants';
import { IS_WINDOWS } from '../../client/common/platform/constants';
import { FileSystem } from '../../client/common/platform/fileSystem';
import { IPlatformService } from '../../client/common/platform/types';
import { IConfigurationService } from '../../client/common/types';
import { IMultiStepInputFactory } from '../../client/common/utils/multiStepInput';
Expand Down Expand Up @@ -99,7 +101,8 @@ suite('Debugging - Attach Debugger', () => {
const attachResolver = new AttachConfigurationResolver(workspaceService.object, documentManager.object, platformService.object, configurationService.object);
const providerFactory = TypeMoq.Mock.ofType<IDebugConfigurationProviderFactory>().object;
const multiStepIput = TypeMoq.Mock.ofType<IMultiStepInputFactory>().object;
const configProvider = new PythonDebugConfigurationService(attachResolver, launchResolver.object, providerFactory, multiStepIput);
const fs = mock(FileSystem);
const configProvider = new PythonDebugConfigurationService(attachResolver, launchResolver.object, providerFactory, multiStepIput, instance(fs));

await configProvider.resolveDebugConfiguration({ index: 0, name: 'root', uri: Uri.file(localRoot) }, options);
const attachPromise = debugClient.attachRequest(options);
Expand Down

This file was deleted.

Loading