Skip to content

Commit dcb1155

Browse files
committed
Fix debug adapter and ensure debug adapter gets bundled separately (#3493)
* Fix debug adapter and ensure it gets bundled separately * Smoke test for debugging
1 parent dda897c commit dcb1155

File tree

10 files changed

+223
-10
lines changed

10 files changed

+223
-10
lines changed

.travis.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -108,5 +108,10 @@ script:
108108
- if [[ $AZURE_STORAGE_ACCOUNT && "$TRAVIS_BRANCH" == release* && "$TRAVIS_PULL_REQUEST" == "false" ]]; then
109109
npm run clean;
110110
vsce package;
111+
azure storage blob upload python*.vsix $AZURE_STORAGE_CONTAINER ms-python-$TRAVIS_BRANCH-insiders.vsix --account-name $AZURE_STORAGE_ACCOUNT --account-key $AZURE_STORAGE_ACCESS_KEY --quiet;
112+
npm run clean;
113+
npm run package;
114+
npx gulp clean:cleanExceptTests;
115+
npm run testSmoke;
111116
azure storage blob upload python*.vsix $AZURE_STORAGE_CONTAINER ms-python-$TRAVIS_BRANCH.vsix --account-name $AZURE_STORAGE_ACCOUNT --account-key $AZURE_STORAGE_ACCESS_KEY --quiet;
112117
fi
Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,75 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
'use strict';
4+
Object.defineProperty(exports, "__esModule", { value: true });
5+
const path = require("path");
6+
const tsconfig_paths_webpack_plugin_1 = require("tsconfig-paths-webpack-plugin");
7+
const webpack_1 = require("webpack");
8+
const constants_1 = require("../constants");
9+
const common_1 = require("./common");
10+
// tslint:disable-next-line:no-var-requires no-require-imports
11+
const configFileName = path.join(constants_1.ExtensionRootDir, 'tsconfig.extension.json');
12+
const config = {
13+
mode: 'production',
14+
target: 'node',
15+
entry: {
16+
'debugger/debugAdapter/main': './src/client/debugger/debugAdapter/main.ts'
17+
},
18+
devtool: 'source-map',
19+
node: {
20+
__dirname: false
21+
},
22+
module: {
23+
rules: [
24+
{
25+
// JupyterServices imports node-fetch using `eval`.
26+
test: /@jupyterlab[\\\/]services[\\\/].*js$/,
27+
use: [
28+
{
29+
loader: path.join(__dirname, 'loaders', 'fixEvalRequire.js')
30+
}
31+
]
32+
},
33+
{
34+
// Do not use __dirname in getos when using require.
35+
test: /getos[\\\/]index.js$/,
36+
use: [
37+
{
38+
loader: path.join(__dirname, 'loaders', 'fixGetosRequire.js')
39+
}
40+
]
41+
},
42+
{
43+
test: /\.ts$/,
44+
exclude: /node_modules/,
45+
use: [
46+
{
47+
loader: 'ts-loader'
48+
}
49+
]
50+
}
51+
]
52+
},
53+
externals: [
54+
'vscode',
55+
'commonjs'
56+
],
57+
plugins: [
58+
...common_1.getDefaultPlugins('extension'),
59+
new webpack_1.ContextReplacementPlugin(/getos/, /logic\/.*.js/)
60+
],
61+
resolve: {
62+
extensions: ['.ts', '.js'],
63+
plugins: [
64+
new tsconfig_paths_webpack_plugin_1.TsconfigPathsPlugin({ configFile: configFileName })
65+
]
66+
},
67+
output: {
68+
filename: '[name].js',
69+
path: path.resolve(constants_1.ExtensionRootDir, 'out', 'client'),
70+
libraryTarget: 'commonjs2',
71+
devtoolModuleFilenameTemplate: '../../[resource-path]'
72+
}
73+
};
74+
// tslint:disable-next-line:no-default-export
75+
exports.default = config;
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
import * as path from 'path';
7+
import { TsconfigPathsPlugin } from 'tsconfig-paths-webpack-plugin';
8+
import { Configuration, ContextReplacementPlugin } from 'webpack';
9+
import { ExtensionRootDir } from '../constants';
10+
import { getDefaultPlugins } from './common';
11+
12+
// tslint:disable-next-line:no-var-requires no-require-imports
13+
const configFileName = path.join(ExtensionRootDir, 'tsconfig.extension.json');
14+
15+
const config: Configuration = {
16+
mode: 'production',
17+
target: 'node',
18+
entry: {
19+
'debugger/debugAdapter/main': './src/client/debugger/debugAdapter/main.ts'
20+
},
21+
devtool: 'source-map',
22+
node: {
23+
__dirname: false
24+
},
25+
module: {
26+
rules: [
27+
{
28+
// JupyterServices imports node-fetch using `eval`.
29+
test: /@jupyterlab[\\\/]services[\\\/].*js$/,
30+
use: [
31+
{
32+
loader: path.join(__dirname, 'loaders', 'fixEvalRequire.js')
33+
}
34+
]
35+
},
36+
{
37+
// Do not use __dirname in getos when using require.
38+
test: /getos[\\\/]index.js$/,
39+
use: [
40+
{
41+
loader: path.join(__dirname, 'loaders', 'fixGetosRequire.js')
42+
}
43+
]
44+
},
45+
{
46+
test: /\.ts$/,
47+
exclude: /node_modules/,
48+
use: [
49+
{
50+
loader: 'ts-loader'
51+
}
52+
]
53+
}
54+
]
55+
},
56+
externals: [
57+
'vscode',
58+
'commonjs'
59+
],
60+
plugins: [
61+
...getDefaultPlugins('extension'),
62+
new ContextReplacementPlugin(/getos/, /logic\/.*.js/)
63+
],
64+
resolve: {
65+
extensions: ['.ts', '.js'],
66+
plugins: [
67+
new TsconfigPathsPlugin({ configFile: configFileName })
68+
]
69+
},
70+
output: {
71+
filename: '[name].js',
72+
path: path.resolve(ExtensionRootDir, 'out', 'client'),
73+
libraryTarget: 'commonjs2',
74+
devtoolModuleFilenameTemplate: '../../[resource-path]'
75+
}
76+
};
77+
78+
// tslint:disable-next-line:no-default-export
79+
export default config;

build/webpack/webpack.extension.config.js

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,7 @@ const config = {
1818
mode: 'production',
1919
target: 'node',
2020
entry: {
21-
extension: './src/client/extension.ts',
22-
'debugger/debugAdapter/main': './src/client/debugger/debugAdapter/main.ts'
21+
extension: './src/client/extension.ts'
2322
},
2423
devtool: 'source-map',
2524
node: {

build/webpack/webpack.extension.config.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -23,8 +23,7 @@ const config: Configuration = {
2323
mode: 'production',
2424
target: 'node',
2525
entry: {
26-
extension: './src/client/extension.ts',
27-
'debugger/debugAdapter/main': './src/client/debugger/debugAdapter/main.ts'
26+
extension: './src/client/extension.ts'
2827
},
2928
devtool: 'source-map',
3029
node: {

gulpfile.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,7 @@ gulp.task('webpack', async () => {
196196
await spawnAsync('npx', ['webpack', '--mode', 'production']);
197197
await spawnAsync('npx', ['webpack', '--config', './build/webpack/webpack.extension.sourceMaps.config.js', '--mode', 'production']);
198198
await spawnAsync('npx', ['webpack', '--config', './build/webpack/webpack.extension.config.js', '--mode', 'production']);
199+
await spawnAsync('npx', ['webpack', '--config', './build/webpack/webpack.debugadapter.config.js', '--mode', 'production']);
199200
});
200201

201202
gulp.task('prePublishBundle', gulp.series('checkNativeDependencies', 'check-datascience-dependencies', 'compile', 'clean:cleanExceptTests', 'webpack'));

src/client/common/variables/environment.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -14,13 +14,12 @@ export class EnvironmentVariablesService implements IEnvironmentVariablesService
1414
constructor(@inject(IPathUtils) pathUtils: IPathUtils) {
1515
this.pathVariable = pathUtils.getPathVariableName();
1616
}
17-
public async parseFile(filePath: string): Promise<EnvironmentVariables | undefined> {
18-
const exists = filePath.length > 0 ? await fs.pathExists(filePath) : undefined;
19-
if (!exists) {
20-
return undefined;
17+
public async parseFile(filePath?: string): Promise<EnvironmentVariables | undefined> {
18+
if (!filePath || !await fs.pathExists(filePath)) {
19+
return;
2120
}
2221
if (!fs.lstatSync(filePath).isFile()) {
23-
return undefined;
22+
return;
2423
}
2524
return dotenv.parse(await fs.readFile(filePath));
2625
}

src/client/common/variables/types.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ export type EnvironmentVariables = Object & {
1010
export const IEnvironmentVariablesService = Symbol('IEnvironmentVariablesService');
1111

1212
export interface IEnvironmentVariablesService {
13-
parseFile(filePath: string): Promise<EnvironmentVariables | undefined>;
13+
parseFile(filePath?: string): Promise<EnvironmentVariables | undefined>;
1414
mergeVariables(source: EnvironmentVariables, target: EnvironmentVariables): void;
1515
appendPythonPath(vars: EnvironmentVariables, ...pythonPaths: string[]): void;
1616
appendPath(vars: EnvironmentVariables, ...paths: string[]): void;

src/test/common/variables/envVarsService.test.ts renamed to src/test/common/variables/envVarsService.unit.test.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
// Copyright (c) Microsoft Corporation. All rights reserved.
22
// Licensed under the MIT License.
33

4+
'use strict';
5+
46
import { expect, use } from 'chai';
57
import * as chaiAsPromised from 'chai-as-promised';
68
import * as path from 'path';
@@ -23,6 +25,11 @@ suite('Environment Variables Service', () => {
2325
variablesService = new EnvironmentVariablesService(pathUtils);
2426
});
2527

28+
test('Custom variables should be undefined with no argument', async () => {
29+
const vars = await variablesService.parseFile(undefined);
30+
expect(vars).to.equal(undefined, 'Variables should be undefined');
31+
});
32+
2633
test('Custom variables should be undefined with non-existent files', async () => {
2734
const vars = await variablesService.parseFile(path.join(envFilesFolderPath, 'abcd'));
2835
expect(vars).to.equal(undefined, 'Variables should be undefined');
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
'use strict';
5+
6+
// tslint:disable:max-func-body-length no-invalid-this no-any
7+
8+
import { expect } from 'chai';
9+
import * as fs from 'fs-extra';
10+
import * as path from 'path';
11+
import * as vscode from 'vscode';
12+
import { openFile, waitForCondition } from '../common';
13+
import { EXTENSION_ROOT_DIR_FOR_TESTS, IS_SMOKE_TEST } from '../constants';
14+
import { closeActiveWindows, initializeTest } from '../initialize';
15+
16+
suite('Smoke Test: Debug file', function () {
17+
// Large value to allow for LS to get downloaded.
18+
this.timeout(4 * 60_000);
19+
20+
suiteSetup(function () {
21+
if (!IS_SMOKE_TEST) {
22+
return this.skip();
23+
}
24+
});
25+
setup(initializeTest);
26+
suiteTeardown(closeActiveWindows);
27+
teardown(closeActiveWindows);
28+
29+
test('Debug', async () => {
30+
const file = path.join(EXTENSION_ROOT_DIR_FOR_TESTS, 'src', 'testMultiRootWkspc', 'smokeTests', 'testExecInTerminal.py');
31+
const outputFile = path.join(EXTENSION_ROOT_DIR_FOR_TESTS, 'src', 'testMultiRootWkspc', 'smokeTests', 'testExecInTerminal.log');
32+
if (await fs.pathExists(outputFile)) {
33+
await fs.unlink(outputFile);
34+
}
35+
await openFile(file);
36+
37+
const config = {
38+
name: 'Debug',
39+
request: 'launch',
40+
type: 'python',
41+
program: file
42+
};
43+
44+
const started = await vscode.debug.startDebugging(vscode.workspace.workspaceFolders![0], config);
45+
expect(started).to.be.equal(true, 'Debugger did not sart');
46+
const checkIfFileHasBeenCreated = () => fs.pathExists(outputFile);
47+
await waitForCondition(checkIfFileHasBeenCreated, 30_000, '\'testExecInTerminal.log\' file not created');
48+
});
49+
});

0 commit comments

Comments
 (0)