From d7304ab0f0044c87bb8a9998cd202f9216774bd3 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 08:35:47 -0700 Subject: [PATCH 01/86] remove unwanted and unused deps and features --- .gitmodules | 4 - docs | 1 - gulpfile.js | 2 - package.json | 20 +--- src/client/common/constants.ts | 17 ---- src/client/extension.ts | 6 -- src/client/helpProvider.ts | 113 --------------------- src/client/jupyter/main.ts | 8 +- src/client/providers/codeActionProvider.ts | 40 -------- tsconfig.json | 3 +- 10 files changed, 8 insertions(+), 206 deletions(-) delete mode 100644 .gitmodules delete mode 160000 docs delete mode 100644 src/client/helpProvider.ts delete mode 100644 src/client/providers/codeActionProvider.ts diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index a49472051702..000000000000 --- a/.gitmodules +++ /dev/null @@ -1,4 +0,0 @@ -[submodule "docs"] - path = docs - url = https://github.com/DonJayamanne/pythonVSCodeDocs.git - branch = help diff --git a/docs b/docs deleted file mode 160000 index f37284e16b70..000000000000 --- a/docs +++ /dev/null @@ -1 +0,0 @@ -Subproject commit f37284e16b707ef9c43b126decde21929248a7dd diff --git a/gulpfile.js b/gulpfile.js index 052c3aa979fd..f284ad9edc91 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -43,7 +43,6 @@ const eolFilter = [ '!**/*.{svg,exe,png,bmp,scpt,bat,cmd,cur,ttf,woff,eot,txt,md,json,yml}', '!out/**/*', '!images/**/*', - '!docs/**/*', '!.vscode/**/*', '!pythonFiles/**/*', '!resources/**/*', @@ -64,7 +63,6 @@ const tslintFilter = [ '!**/node_modules/**', '!out/**/*', '!images/**/*', - '!docs/**/*', '!.vscode/**/*', '!pythonFiles/**/*', '!resources/**/*', diff --git a/package.json b/package.json index 63f80480c85c..1fcb1af34d28 100644 --- a/package.json +++ b/package.json @@ -65,7 +65,6 @@ "onCommand:jupyter.runSelectionLine", "onCommand:jupyter.execCurrentCell", "onCommand:jupyter.execCurrentCellAndAdvance", - "onCommand:python.displayHelp", "onCommand:python.buildWorkspaceSymbols", "onCommand:python.updateSparkLibrary", "onCommand:python.startREPL", @@ -202,11 +201,6 @@ "title": "Go to Next Cell", "category": "Jupyter" }, - { - "command": "python.displayHelp", - "title": "Help", - "category": "Python" - }, { "command": "python.goToPythonObject", "title": "Go to Python Object", @@ -1600,8 +1594,6 @@ "lint": "tslint src/**/*.ts -t verbose" }, "dependencies": { - "anser": "^1.1.0", - "copy-paste": "^1.3.0", "diff-match-patch": "^1.0.0", "fs-extra": "^4.0.2", "fuzzy": "^0.1.3", @@ -1609,14 +1601,10 @@ "lodash": "^4.17.4", "minimatch": "^3.0.3", "named-js-regexp": "^1.3.1", - "node-static": "^0.7.9", - "prepend-file": "^1.3.0", "rx": "^4.1.0", "semver": "^5.4.1", "socket.io": "^1.4.8", "tmp": "0.0.29", - "transformime": "^3.1.2", - "transformime-marked": "0.0.1", "tree-kill": "^1.1.0", "uint64be": "^1.0.1", "untildify": "^3.0.2", @@ -1626,8 +1614,7 @@ "vscode-languageclient": "^3.1.0", "vscode-languageserver": "^3.1.0", "winreg": "^1.2.4", - "xml2js": "^0.4.17", - "vscode": "^1.1.5" + "xml2js": "^0.4.17" }, "devDependencies": { "@types/chai": "^4.0.4", @@ -1660,12 +1647,15 @@ "relative": "^3.0.2", "retyped-diff-match-patch-tsd-ambient": "^1.0.0-0", "sinon": "^2.3.6", + "transformime": "^3.1.2", + "transformime-marked": "0.0.1", "ts-loader": "^2.3.4", "tslint": "^5.7.0", "tslint-eslint-rules": "^4.1.1", "tslint-microsoft-contrib": "^5.0.1", "typescript": "^2.5.2", "typescript-formatter": "^6.0.0", - "webpack": "^1.13.2" + "webpack": "^1.13.2", + "vscode": "^1.1.5" } } diff --git a/src/client/common/constants.ts b/src/client/common/constants.ts index 5ab6c470e79d..c332257d1170 100644 --- a/src/client/common/constants.ts +++ b/src/client/common/constants.ts @@ -80,20 +80,3 @@ export namespace LinterErrors { export const InvalidSyntax = 'E999'; } } - -export namespace Documentation { - export const Home = '/docs/python-path/'; - export namespace Jupyter { - export const GettingStarted = '/docs/jupyter_getting-started/'; - export const Examples = '/docs/jupyter_examples/'; - export const Setup = '/docs/jupyter_prerequisites/'; - export const VersionIncompatiblity = '/docs/troubleshooting_jupyter/#Incompatible-dependencies'; - } - export namespace Formatting { - export const FormatOnSave = '/docs/formatting/'; - } - export namespace Workspace { - export const Home = '/docs/workspaceSymbols/'; - export const InstallOnWindows = '/docs/workspaceSymbols/#Install-Windows'; - } -} diff --git a/src/client/extension.ts b/src/client/extension.ts index bb5cf5252048..827c95324eb3 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -1,8 +1,6 @@ 'use strict'; -import * as fs from 'fs'; import * as os from 'os'; -import { workspace } from 'vscode'; import * as vscode from 'vscode'; import * as settings from './common/configSettings'; import { Commands } from './common/constants'; @@ -10,7 +8,6 @@ import { createDeferred } from './common/helpers'; import * as telemetryHelper from './common/telemetry'; import * as telemetryContracts from './common/telemetryContracts'; import { SimpleConfigurationProvider } from './debugger'; -import { HelpProvider } from './helpProvider'; import { InterpreterManager } from './interpreter'; import { SetInterpreterProvider } from './interpreter/configuration/setInterpreterProvider'; import { ShebangCodeLensProvider } from './interpreter/display/shebangCodeLensProvider'; @@ -142,9 +139,6 @@ export async function activate(context: vscode.ExtensionContext) { const triggerCharacters: string[] = os.EOL.split(''); triggerCharacters.shift(); - const hepProvider = new HelpProvider(); - context.subscriptions.push(hepProvider); - context.subscriptions.push(vscode.debug.registerDebugConfigurationProvider('python', new SimpleConfigurationProvider())); activationDeferred.resolve(); } diff --git a/src/client/helpProvider.ts b/src/client/helpProvider.ts deleted file mode 100644 index 74a524cccff1..000000000000 --- a/src/client/helpProvider.ts +++ /dev/null @@ -1,113 +0,0 @@ -'use strict'; - -import * as vscode from 'vscode'; -import {Disposable} from 'vscode'; -import * as path from 'path'; -import * as http from 'http'; -import {createDeferred} from './common/helpers'; -import {Documentation} from './common/constants'; -const nodeStatic = require('node-static'); - -let serverAddress = "http://localhost:8080"; -let helpPageToDisplay = Documentation.Home; -export class TextDocumentContentProvider extends Disposable implements vscode.TextDocumentContentProvider { - private _onDidChange = new vscode.EventEmitter(); - private lastUri: vscode.Uri; - constructor() { - super(() => { }); - } - public provideTextDocumentContent(uri: vscode.Uri, token: vscode.CancellationToken): Thenable { - this.lastUri = uri; - return this.generateResultsView(); - } - - get onDidChange(): vscode.Event { - return this._onDidChange.event; - } - - public update() { - this._onDidChange.fire(this.lastUri); - } - - private generateResultsView(): Promise { - const addresss = serverAddress + helpPageToDisplay; - const htmlContent = ` - - - - - - - - `; - return Promise.resolve(htmlContent); - } -} -const helpSchema = 'help-viewer'; -const previewUri = vscode.Uri.parse(helpSchema + '://authority/python'); - -export class HelpProvider { - private disposables: Disposable[] = []; - constructor() { - const textProvider = new TextDocumentContentProvider(); - this.disposables.push(vscode.workspace.registerTextDocumentContentProvider(helpSchema, textProvider)); - this.disposables.push(vscode.commands.registerCommand('python.displayHelp', (page: string) => { - this.startServer().then(port => { - let viewColumn = vscode.ViewColumn.Two; - if (!page || typeof page !== 'string' || page.length === 0) { - helpPageToDisplay = Documentation.Home; - viewColumn = vscode.ViewColumn.One; - } - else { - helpPageToDisplay = page; - } - vscode.commands.executeCommand('vscode.previewHtml', previewUri, viewColumn, 'Help'); - }); - })); - } - dispose() { - this.disposables.forEach(d => d.dispose()); - this.stop(); - } - private httpServer: http.Server; - private port: number; - private startServer(): Promise { - if (this.port) { - return Promise.resolve(this.port); - } - - let def = createDeferred(); - var file = new nodeStatic.Server(path.join(__dirname, '..', '..', 'docs')); - this.httpServer = http.createServer((request, response) => { - request.addListener('end', function () { - // - // Serve files! - // - file.serve(request, response); - }).resume(); - }); - - this.httpServer.listen(0, () => { - this.port = this.httpServer.address().port; - serverAddress = 'http://localhost:' + this.port.toString(); - def.resolve(this.port); - def = null; - }); - this.httpServer.on('error', error => { - if (def) { - def.reject(error); - def = null; - } - }); - - return def.promise; - } - - private stop() { - if (!this.httpServer) { - return; - } - this.httpServer.close(); - this.httpServer = null; - } -} \ No newline at end of file diff --git a/src/client/jupyter/main.ts b/src/client/jupyter/main.ts index 8cb402b4aa0d..c7f01370abae 100644 --- a/src/client/jupyter/main.ts +++ b/src/client/jupyter/main.ts @@ -7,7 +7,6 @@ import { Commands, PythonLanguage } from '../common/constants'; import { JupyterCodeLensProvider } from './editorIntegration/codeLensProvider'; import { JupyterSymbolProvider } from './editorIntegration/symbolProvider'; import { formatErrorForLogging } from '../common/utils'; -import { Documentation } from '../common/constants'; // import * as telemetryHelper from '../common/telemetry'; // import * as telemetryContracts from '../common/telemetryContracts'; import * as main from './jupyter_client/main'; @@ -147,10 +146,7 @@ export class Jupyter extends vscode.Disposable { }).catch(reason => { const message = typeof reason === 'string' ? reason : reason.message; this.outputChannel.appendLine(formatErrorForLogging(reason)); - vscode.window.showErrorMessage(message, 'Help', 'View Errors').then(item => { - if (item === 'Help') { - vscode.commands.executeCommand('python.displayHelp', Documentation.Jupyter.Setup); - } + vscode.window.showErrorMessage(message, 'View Errors').then(item => { if (item === 'View Errors') { this.outputChannel.show(); } @@ -230,4 +226,4 @@ export class Jupyter extends vscode.Disposable { this.onKernelChanged(); })); } -}; \ No newline at end of file +}; diff --git a/src/client/providers/codeActionProvider.ts b/src/client/providers/codeActionProvider.ts deleted file mode 100644 index 14e03c9a4b9a..000000000000 --- a/src/client/providers/codeActionProvider.ts +++ /dev/null @@ -1,40 +0,0 @@ -'use strict'; - -import * as vscode from 'vscode'; -import {TextDocument, Range, CodeActionContext, CancellationToken, Command} from 'vscode'; - -export class PythonCodeActionsProvider implements vscode.CodeActionProvider { - public constructor(context: vscode.ExtensionContext) { - } - provideCodeActions(document: TextDocument, range: Range, context: CodeActionContext, token: CancellationToken): Thenable { - return new Promise((resolve, reject) => { - let commands: Command[] = [ - { - command: 'python.sortImports', - title: 'Sort Imports' - } - ]; - - if (vscode.window.activeTextEditor.document === document && !vscode.window.activeTextEditor.selection.isEmpty) { - let wordRange = document.getWordRangeAtPosition(range.start); - // If no word has been selected by the user, then don't display rename - // If something has been selected, then ensure we have selected a word (i.e. end and start matches the word range) - if (wordRange && !wordRange.isEmpty && wordRange.isEqual(vscode.window.activeTextEditor.selection)) { - let word = document.getText(wordRange).trim(); - if (word.length > 0) { - commands.push({ command: 'editor.action.rename', title: 'Rename Symbol' }); - } - } - } - - if (!range.isEmpty) { - let word = document.getText(range).trim(); - if (word.trim().length > 0) { - commands.push({ command: 'python.refactorExtractVariable', title: 'Extract Variable', arguments: [range] }); - commands.push({ command: 'python.refactorExtractMethod', title: 'Extract Method', arguments: [range] }); - } - } - resolve(commands); - }); - } -} diff --git a/tsconfig.json b/tsconfig.json index 0b10f6fac53d..aacfa96ef3de 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -17,7 +17,6 @@ "src/server/node_modules", "src/client/node_modules", "src/server/src/typings", - "src/client/src/typings", - "docs" + "src/client/src/typings" ] } From 0b5f90fac373f589d8b237bec376f7931cdefd6b Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 11:41:16 -0700 Subject: [PATCH 02/86] enable decorators --- tsconfig.json | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tsconfig.json b/tsconfig.json index aacfa96ef3de..f43311b23009 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -7,7 +7,8 @@ "es6" ], "sourceMap": true, - "rootDir": "src" + "rootDir": "src", + "experimentalDecorators": true // TODO: enable to ensure all code complies with strict coding standards // , "strict": true }, From 4d93442fd6501f188761135e433342ac4bcf7ac7 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 12:08:32 -0700 Subject: [PATCH 03/86] telemetry helper --- src/client/common/telemetry.ts | 184 ++++++++++++++++++++------------- 1 file changed, 115 insertions(+), 69 deletions(-) diff --git a/src/client/common/telemetry.ts b/src/client/common/telemetry.ts index 64f05c58f6d6..75301b8bd814 100644 --- a/src/client/common/telemetry.ts +++ b/src/client/common/telemetry.ts @@ -1,79 +1,125 @@ -import { extensions, workspace } from "vscode"; -import TelemetryReporter from "vscode-extension-telemetry"; +import { extensions, workspace } from 'vscode'; +// tslint:disable-next-line:import-name +import TelemetryReporter from 'vscode-extension-telemetry'; -// Borrowed from omnisharpServer.ts (omnisharp-vscode) -export class Delays { - immediateDelays: number = 0; // 0-25 milliseconds - nearImmediateDelays: number = 0; // 26-50 milliseconds - shortDelays: number = 0; // 51-250 milliseconds - mediumDelays: number = 0; // 251-500 milliseconds - idleDelays: number = 0; // 501-1500 milliseconds - nonFocusDelays: number = 0; // 1501-3000 milliseconds - bigDelays: number = 0; // 3000+ milliseconds - private startTime: number = Date.now(); - public stop() { - let endTime = Date.now(); - let elapsedTime = endTime - this.startTime; +export const COMPLETION = 'COMPLETION'; +export const DEFINITION = 'DEFINITION'; +export const HOVER_DEFINITION = 'HOVER_DEFINITION'; +export const REFERENCE = 'REFERENCE'; +export const SIGNATURE = 'SIGNATURE'; +export const SYMBOL = 'SYMBOL'; +export const FORMAT_SORT_IMPORTS = 'FORMAT.SORT_IMPORTS'; +export const FORMAT = 'FORMAT.FORMAT'; +export const EDITOR_LOAD = 'EDITOR.LOAD'; +export const LINTING = 'LINTING'; +export const GO_TO_OBJECT_DEFINITION = 'GO_TO_OBJECT_DEFINITION'; +export const UPDATE_PYSPARK_LIBRARY = 'UPDATE_PYSPARK_LIBRARY'; +export const REFACTOR_RENAME = 'REFACTOR_RENAME'; +export const REFACTOR_EXTRACT_VAR = 'REFACTOR_EXTRACT_VAR'; +export const REFACTOR_EXTRACT_FUNCTION = 'REFACTOR_EXTRACT_FUNCTION'; +export const REPL = 'REPL'; - if (elapsedTime <= 25) { - this.immediateDelays += 1; - } - else if (elapsedTime <= 50) { - this.nearImmediateDelays += 1; - } - else if (elapsedTime <= 250) { - this.shortDelays += 1; - } - else if (elapsedTime <= 500) { - this.mediumDelays += 1; - } - else if (elapsedTime <= 1500) { - this.idleDelays += 1; - } - else if (elapsedTime <= 3000) { - this.nonFocusDelays += 1; - } - else { - this.bigDelays += 1; - } +type TelemetryProperties = { [key: string]: string; }; +type FormatTelemetry = { + tool: 'autoppep8' | 'yapf'; + hasCustomArgs: boolean; + formatSelection: boolean; +}; +type LintingTelemetry = { + tool: 'flake8' | 'mypy' | 'pep8' | 'prospector' | 'pydocstyle' | 'pylama' | 'pylint'; + hasCustomArgs: boolean; + trigger: 'save' | 'auto'; + executableSpecified: boolean; +}; +let s: FormatTelemetry; +s = { tool: 'yapf', hasCustomArgs: false, formatSelection: false }; +export class StopWatch { + private started: number = Date.now(); + private stopped?: number; + public get elpsedTime() { + return (this.stopped ? this.stopped : Date.now()) - this.started; } - public toMeasures(): { [key: string]: number } { - return { - immedateDelays: this.immediateDelays, - nearImmediateDelays: this.nearImmediateDelays, - shortDelays: this.shortDelays, - mediumDelays: this.mediumDelays, - idleDelays: this.idleDelays, - nonFocusDelays: this.nonFocusDelays, - bigDelays: this.bigDelays - }; + public stop() { + this.stopped = Date.now(); } } -const extensionId = "donjayamanne.python"; -const extension = extensions.getExtension(extensionId); -const extensionVersion = extension.packageJSON.version; -const aiKey = "fce7a3d5-4665-4404-b786-31a6306749a6"; -let reporter: TelemetryReporter; -let telemetryEnabled: boolean | undefined = undefined; -/** - * Sends a telemetry event - * @param {string} eventName The event name - * @param {object} properties An associative array of strings - * @param {object} measures An associative array of numbers - */ -export function sendTelemetryEvent(eventName: string, properties?: { - [key: string]: string; -}, measures?: { - [key: string]: number; -}) { - if (telemetryEnabled === undefined) { - telemetryEnabled = workspace.getConfiguration('telemetry').get('enableTelemetry', true); +let telemetryReporter: TelemetryReporter; +function getTelemetryReporter() { + if (telemetryReporter) { + return telemetryReporter; } - if (!telemetryEnabled) { - return; + const extensionId = 'donjayamanne.python'; + const extension = extensions.getExtension(extensionId); + const extensionVersion = extension.packageJSON.version; + const aiKey = extension.packageJSON.contributes.debuggers[0].aiKey; + return telemetryReporter = new TelemetryReporter(extensionId, extensionVersion, aiKey); +} +export function sendTelemetryEvent(eventName: string, durationMs?: number, properties?: FormatTelemetry | LintingTelemetry) { + const reporter = getTelemetryReporter(); + const measures = typeof durationMs === 'number' ? { duration: durationMs } : undefined; + + const customProperties = {}; + if (properties) { + Object.getOwnPropertyNames(properties).forEach(prop => { + customProperties[prop] = typeof properties[prop] === 'string' ? properties[prop] : properties[prop].toString(); + }); } - reporter = reporter ? reporter : new TelemetryReporter(extensionId, extensionVersion, aiKey); - reporter.sendTelemetryEvent.apply(reporter, arguments); + reporter.sendTelemetryEvent(eventName, properties ? customProperties : undefined, measures); +} + +// tslint:disable-next-line:no-any +type Handler = (...args: any[]) => any; + +// tslint:disable-next-line:no-any function-name +export function captureTelemetry(eventName: string) { + // tslint:disable-next-line:no-function-expression no-any + return function (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor) { + const originalMethod = descriptor.value; + // tslint:disable-next-line:no-function-expression no-any + descriptor.value = function (...args: any[]) { + const stopWatch = new StopWatch(); + // tslint:disable-next-line:no-invalid-this + const result = originalMethod.apply(this, args); + + // If method being wrapped returns a promise then wait for it + if (result && typeof result.then === 'function' && typeof result.catch === 'function') { + // tslint:disable-next-line:prefer-type-cast + (result as Promise) + .then(data => { + sendTelemetryEvent(eventName, stopWatch.elpsedTime); + return data; + }) + .catch(ex => { + sendTelemetryEvent(eventName, stopWatch.elpsedTime); + return Promise.reject(ex); + }); + } else { + sendTelemetryEvent(eventName, stopWatch.elpsedTime); + } + + return result; + }; + + return descriptor; + }; } +// tslint:disable-next-line:no-any function-name +export function sendTelemetryWhenDone(eventName: string, promise: Promise | Thenable, + stopWatch?: StopWatch, properties?: FormatTelemetry | LintingTelemetry) { + stopWatch = stopWatch || new StopWatch(); + if (typeof promise.then === 'function') { + // tslint:disable-next-line:prefer-type-cast no-any + (promise as Promise) + .then(data => { + sendTelemetryEvent(eventName, stopWatch.elpsedTime, properties); + return data; + }, ex => { + sendTelemetryEvent(eventName, stopWatch.elpsedTime, properties); + return Promise.reject(ex); + }); + } else { + throw new Error('Method is neither a Promise nor a Theneable'); + } +} From 07421552ae946cf676b3c82c97326abc1cb7180a Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 12:24:46 -0700 Subject: [PATCH 04/86] telemetry for activation of extension --- src/client/extension.ts | 20 +++++++++++++++----- 1 file changed, 15 insertions(+), 5 deletions(-) diff --git a/src/client/extension.ts b/src/client/extension.ts index 827c95324eb3..2cb929e9a8b1 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -2,15 +2,16 @@ import * as os from 'os'; import * as vscode from 'vscode'; +import { workspace } from 'vscode'; import * as settings from './common/configSettings'; import { Commands } from './common/constants'; import { createDeferred } from './common/helpers'; -import * as telemetryHelper from './common/telemetry'; -import * as telemetryContracts from './common/telemetryContracts'; +import { EDITOR_LOAD, sendTelemetryEvent, StopWatch } from './common/telemetry'; import { SimpleConfigurationProvider } from './debugger'; import { InterpreterManager } from './interpreter'; import { SetInterpreterProvider } from './interpreter/configuration/setInterpreterProvider'; import { ShebangCodeLensProvider } from './interpreter/display/shebangCodeLensProvider'; +import { getCondaVersion } from './interpreter/helpers'; import * as jup from './jupyter/main'; import { JupyterProvider } from './jupyter/provider'; import { JediFactory } from './languageServices/jediProxyFactory'; @@ -44,7 +45,11 @@ export const activated = activationDeferred.promise; // tslint:disable-next-line:max-func-body-length export async function activate(context: vscode.ExtensionContext) { const pythonSettings = settings.PythonSettings.getInstance(); - sendStartupTelemetry(); + const stopwatch = new StopWatch(); + activated.then(() => { + // Do not wait for this to complete. + sendStartupTelemetry(stopwatch.elpsedTime); + }); lintingOutChannel = vscode.window.createOutputChannel(pythonSettings.linting.outputWindow); formatOutChannel = lintingOutChannel; if (pythonSettings.linting.outputWindow !== pythonSettings.formatting.outputWindow) { @@ -143,6 +148,11 @@ export async function activate(context: vscode.ExtensionContext) { activationDeferred.resolve(); } -function sendStartupTelemetry() { - telemetryHelper.sendTelemetryEvent(telemetryContracts.EVENT_LOAD); +async function sendStartupTelemetry(duration: number) { + let condaVersion: string | undefined; + try { + condaVersion = await getCondaVersion(); + // tslint:disable-next-line:no-empty + } catch { } + sendTelemetryEvent(EDITOR_LOAD, duration, { condaVersion }); } From 5c1995b30739be76d32c3e95340ad62036ac52d5 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 12:26:15 -0700 Subject: [PATCH 05/86] moved type declaration close to source --- src/client/common/telemetry.ts | 81 ++++++++++++++----- src/client/typings/node.d.ts | 3 - .../vscode-extension-telemetry.d.ts | 36 --------- src/client/typings/vscode-typings.d.ts | 1 - 4 files changed, 59 insertions(+), 62 deletions(-) delete mode 100644 src/client/typings/node.d.ts delete mode 100644 src/client/typings/vscode-extension-telemetry/vscode-extension-telemetry.d.ts delete mode 100644 src/client/typings/vscode-typings.d.ts diff --git a/src/client/common/telemetry.ts b/src/client/common/telemetry.ts index 75301b8bd814..6bc4de2a50fa 100644 --- a/src/client/common/telemetry.ts +++ b/src/client/common/telemetry.ts @@ -1,6 +1,6 @@ -import { extensions, workspace } from 'vscode'; -// tslint:disable-next-line:import-name -import TelemetryReporter from 'vscode-extension-telemetry'; +import { extensions } from 'vscode'; +// tslint:disable-next-line:variable-name no-require-imports no-var-requires no-use-before-declare no-unsafe-any +const TelemetryReporter: typeof TelemetryReporterType = require('vscode-extension-telemetry'); export const COMPLETION = 'COMPLETION'; export const DEFINITION = 'DEFINITION'; @@ -19,7 +19,9 @@ export const REFACTOR_EXTRACT_VAR = 'REFACTOR_EXTRACT_VAR'; export const REFACTOR_EXTRACT_FUNCTION = 'REFACTOR_EXTRACT_FUNCTION'; export const REPL = 'REPL'; -type TelemetryProperties = { [key: string]: string; }; +type EditorLoadTelemetry = { + condaVersion: string; +}; type FormatTelemetry = { tool: 'autoppep8' | 'yapf'; hasCustomArgs: boolean; @@ -31,8 +33,7 @@ type LintingTelemetry = { trigger: 'save' | 'auto'; executableSpecified: boolean; }; -let s: FormatTelemetry; -s = { tool: 'yapf', hasCustomArgs: false, formatSelection: false }; +type Terlemetries = FormatTelemetry | LintingTelemetry | EditorLoadTelemetry; export class StopWatch { private started: number = Date.now(); private stopped?: number; @@ -44,45 +45,52 @@ export class StopWatch { } } -let telemetryReporter: TelemetryReporter; +let telemetryReporter: TelemetryReporterType; function getTelemetryReporter() { if (telemetryReporter) { return telemetryReporter; } const extensionId = 'donjayamanne.python'; - const extension = extensions.getExtension(extensionId); + // tslint:disable-next-line:no-non-null-assertion + const extension = extensions.getExtension(extensionId)!; + // tslint:disable-next-line:no-unsafe-any const extensionVersion = extension.packageJSON.version; + // tslint:disable-next-line:no-unsafe-any const aiKey = extension.packageJSON.contributes.debuggers[0].aiKey; + // tslint:disable-next-line:no-unsafe-any return telemetryReporter = new TelemetryReporter(extensionId, extensionVersion, aiKey); } -export function sendTelemetryEvent(eventName: string, durationMs?: number, properties?: FormatTelemetry | LintingTelemetry) { +export function sendTelemetryEvent(eventName: string, durationMs?: number, properties?: Terlemetries) { const reporter = getTelemetryReporter(); const measures = typeof durationMs === 'number' ? { duration: durationMs } : undefined; - const customProperties = {}; + // tslint:disable-next-line:no-any + const customProperties: { [key: string]: string } = {}; if (properties) { - Object.getOwnPropertyNames(properties).forEach(prop => { - customProperties[prop] = typeof properties[prop] === 'string' ? properties[prop] : properties[prop].toString(); + // tslint:disable-next-line:prefer-type-cast no-any + const data = properties as any; + Object.getOwnPropertyNames(data).forEach(prop => { + // tslint:disable-next-line:prefer-type-cast no-any no-unsafe-any + (customProperties as any)[prop] = typeof data[prop] === 'string' ? data[prop] : data[prop].toString(); }); } + // reporter.sendTelemetryEvent(eventName, properties ? customProperties : undefined, measures); } -// tslint:disable-next-line:no-any -type Handler = (...args: any[]) => any; - // tslint:disable-next-line:no-any function-name export function captureTelemetry(eventName: string) { // tslint:disable-next-line:no-function-expression no-any - return function (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor) { + return function (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor) { const originalMethod = descriptor.value; // tslint:disable-next-line:no-function-expression no-any descriptor.value = function (...args: any[]) { const stopWatch = new StopWatch(); - // tslint:disable-next-line:no-invalid-this + // tslint:disable-next-line:no-invalid-this no-use-before-declare no-unsafe-any const result = originalMethod.apply(this, args); - // If method being wrapped returns a promise then wait for it + // If method being wrapped returns a promise then wait for it. + // tslint:disable-next-line:no-unsafe-any if (result && typeof result.then === 'function' && typeof result.catch === 'function') { // tslint:disable-next-line:prefer-type-cast (result as Promise) @@ -90,6 +98,7 @@ export function captureTelemetry(eventName: string) { sendTelemetryEvent(eventName, stopWatch.elpsedTime); return data; }) + // tslint:disable-next-line:promise-function-async .catch(ex => { sendTelemetryEvent(eventName, stopWatch.elpsedTime); return Promise.reject(ex); @@ -107,19 +116,47 @@ export function captureTelemetry(eventName: string) { // tslint:disable-next-line:no-any function-name export function sendTelemetryWhenDone(eventName: string, promise: Promise | Thenable, - stopWatch?: StopWatch, properties?: FormatTelemetry | LintingTelemetry) { - stopWatch = stopWatch || new StopWatch(); + stopWatch?: StopWatch, properties?: Terlemetries) { + stopWatch = stopWatch ? stopWatch : new StopWatch(); if (typeof promise.then === 'function') { // tslint:disable-next-line:prefer-type-cast no-any (promise as Promise) .then(data => { - sendTelemetryEvent(eventName, stopWatch.elpsedTime, properties); + // tslint:disable-next-line:no-non-null-assertion + sendTelemetryEvent(eventName, stopWatch!.elpsedTime, properties); return data; + // tslint:disable-next-line:promise-function-async }, ex => { - sendTelemetryEvent(eventName, stopWatch.elpsedTime, properties); + // tslint:disable-next-line:no-non-null-assertion + sendTelemetryEvent(eventName, stopWatch!.elpsedTime, properties); return Promise.reject(ex); }); } else { throw new Error('Method is neither a Promise nor a Theneable'); } } + +class TelemetryReporterType { + /** + * Constructs a new telemetry reporter + * @param {string} extensionId All events will be prefixed with this event name + * @param {string} extensionVersion Extension version to be reported with each event + * @param {string} key The application insights key + */ + // tslint:disable-next-line:no-empty + constructor(extensionId: string, extensionVersion: string, key: string) { } + + /** + * Sends a telemetry event + * @param {string} eventName The event name + * @param {object} properties An associative array of strings + * @param {object} measures An associative array of numbers + */ + // tslint:disable-next-line:member-access + public sendTelemetryEvent(eventName: string, properties?: { + [key: string]: string; + }, measures?: { + [key: string]: number; + // tslint:disable-next-line:no-empty + }): void { } +} diff --git a/src/client/typings/node.d.ts b/src/client/typings/node.d.ts deleted file mode 100644 index 90d55c6f4c08..000000000000 --- a/src/client/typings/node.d.ts +++ /dev/null @@ -1,3 +0,0 @@ -/// -/// -/// \ No newline at end of file diff --git a/src/client/typings/vscode-extension-telemetry/vscode-extension-telemetry.d.ts b/src/client/typings/vscode-extension-telemetry/vscode-extension-telemetry.d.ts deleted file mode 100644 index 8b3e01df591a..000000000000 --- a/src/client/typings/vscode-extension-telemetry/vscode-extension-telemetry.d.ts +++ /dev/null @@ -1,36 +0,0 @@ -declare module "vscode-extension-telemetry" { - export default class TelemetryReporter { - private extensionId; - private extensionVersion; - private appInsightsClient; - private commonProperties; - private static SQM_KEY; - private static REGISTRY_USERID_VALUE; - private static REGISTRY_MACHINEID_VALUE; - - /** - * Constructs a new telemetry reporter - * @param {string} extensionId All events will be prefixed with this event name - * @param {string} extensionVersion Extension version to be reported with each event - * @param {string} key The application insights key - */ - constructor(extensionId: string, extensionVersion: string, key: string); - private setupAIClient(client); - private loadVSCodeCommonProperties(machineId, sessionId, version); - private loadCommonProperties(); - private addCommonProperties(properties); - private getWinRegKeyData(key, name, hive, callback); - - /** - * Sends a telemetry event - * @param {string} eventName The event name - * @param {object} properties An associative array of strings - * @param {object} measures An associative array of numbers - */ - sendTelemetryEvent(eventName: string, properties?: { - [key: string]: string; - }, measures?: { - [key: string]: number; - }): void; - } -} \ No newline at end of file diff --git a/src/client/typings/vscode-typings.d.ts b/src/client/typings/vscode-typings.d.ts deleted file mode 100644 index a9c71567c847..000000000000 --- a/src/client/typings/vscode-typings.d.ts +++ /dev/null @@ -1 +0,0 @@ -/// \ No newline at end of file From ba24f1b24960fbf0b0d032a66ffd8a181cc49aa4 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 12:30:47 -0700 Subject: [PATCH 06/86] changes to how conda version is captured --- src/client/interpreter/helpers.ts | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) diff --git a/src/client/interpreter/helpers.ts b/src/client/interpreter/helpers.ts index dc8308344d2f..f78df63a31f8 100644 --- a/src/client/interpreter/helpers.ts +++ b/src/client/interpreter/helpers.ts @@ -1,5 +1,10 @@ +import * as child_process from 'child_process'; import { ConfigurationTarget, window, workspace } from 'vscode'; +import { RegistryImplementation } from '../common/registry'; +import { Is_64Bit, IS_WINDOWS } from '../common/utils'; import { WorkspacePythonPath } from './contracts'; +import { CondaEnvService } from './locators/services/condaEnvService'; +import { WindowsRegistryService } from './locators/services/windowsRegistryService'; export function getFirstNonEmptyLineFromMultilineString(stdout: string) { if (!stdout) { @@ -23,3 +28,24 @@ export function getActiveWorkspaceUri(): WorkspacePythonPath | undefined { } return undefined; } +export async function getCondaVersion() { + let condaService: CondaEnvService; + if (IS_WINDOWS) { + const windowsRegistryProvider = new WindowsRegistryService(new RegistryImplementation(), Is_64Bit); + condaService = new CondaEnvService(windowsRegistryProvider); + } else { + condaService = new CondaEnvService(); + } + return condaService.getCondaFile() + .then(async condaFile => { + return new Promise((resolve, reject) => { + child_process.execFile(condaFile, ['--version'], (_, stdout) => { + if (stdout && stdout.length > 0) { + resolve(getFirstNonEmptyLineFromMultilineString(stdout)); + } else { + reject(); + } + }); + }); + }); +} From b9ae68f44a1fa0daaa4c16b4e0ab565522d36031 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 12:36:33 -0700 Subject: [PATCH 07/86] telemetry for formatters --- src/client/common/telemetryContracts.ts | 62 +++++++++++----------- src/client/formatters/autoPep8Formatter.ts | 20 ++++--- src/client/formatters/yapfFormatter.ts | 23 +++++--- 3 files changed, 60 insertions(+), 45 deletions(-) diff --git a/src/client/common/telemetryContracts.ts b/src/client/common/telemetryContracts.ts index 735793d078b5..2a00a022f24d 100644 --- a/src/client/common/telemetryContracts.ts +++ b/src/client/common/telemetryContracts.ts @@ -1,31 +1,31 @@ -export namespace Debugger { - export const Load = 'DEBUGGER_LOAD'; - export const Attach = 'DEBUGGER_ATTACH'; -} -export namespace Commands { - export const SortImports = 'COMMAND_SORT_IMPORTS'; - export const UnitTests = 'COMMAND_UNIT_TEST'; -} -export namespace IDE { - export const Completion = 'CODE_COMPLETION'; - export const Definition = 'CODE_DEFINITION'; - export const Format = 'CODE_FORMAT'; - export const HoverDefinition = 'CODE_HOVER_DEFINITION'; - export const Reference = 'CODE_REFERENCE'; - export const Rename = 'CODE_RENAME'; - export const Symbol = 'CODE_SYMBOL'; - export const Lint = 'LINTING'; -} -export namespace REFACTOR { - export const Rename = 'REFACTOR_RENAME'; - export const ExtractVariable = 'REFACTOR_EXTRACT_VAR'; - export const ExtractMethod = 'REFACTOR_EXTRACT_METHOD'; -} -export namespace UnitTests { - export const Run = 'UNITTEST_RUN'; - export const Discover = 'UNITTEST_DISCOVER'; -} -export namespace Jupyter { - export const Usage = 'JUPYTER'; -} -export const EVENT_LOAD = 'IDE_LOAD'; \ No newline at end of file +// export namespace Debugger { +// export const Load = 'DEBUGGER_LOAD'; +// export const Attach = 'DEBUGGER_ATTACH'; +// } +// export namespace Commands { +// export const SortImports = 'COMMAND_SORT_IMPORTS'; +// export const UnitTests = 'COMMAND_UNIT_TEST'; +// } +// export namespace IDE { +// export const Completion = 'CODE_COMPLETION'; +// export const Definition = 'CODE_DEFINITION'; +// export const Format = 'CODE_FORMAT'; +// export const HoverDefinition = 'CODE_HOVER_DEFINITION'; +// export const Reference = 'CODE_REFERENCE'; +// export const Rename = 'CODE_RENAME'; +// export const Symbol = 'CODE_SYMBOL'; +// export const Lint = 'LINTING'; +// } +// export namespace REFACTOR { +// export const Rename = 'REFACTOR_RENAME'; +// export const ExtractVariable = 'REFACTOR_EXTRACT_VAR'; +// export const ExtractMethod = 'REFACTOR_EXTRACT_METHOD'; +// } +// export namespace UnitTests { +// export const Run = 'UNITTEST_RUN'; +// export const Discover = 'UNITTEST_DISCOVER'; +// } +// export namespace Jupyter { +// export const Usage = 'JUPYTER'; +// } +// export const EVENT_LOAD = 'IDE_LOAD'; diff --git a/src/client/formatters/autoPep8Formatter.ts b/src/client/formatters/autoPep8Formatter.ts index 35afef4a57cf..e3589c9e1787 100644 --- a/src/client/formatters/autoPep8Formatter.ts +++ b/src/client/formatters/autoPep8Formatter.ts @@ -1,9 +1,10 @@ 'use strict'; import * as vscode from 'vscode'; -import { BaseFormatter } from './baseFormatter'; import { PythonSettings } from '../common/configSettings'; import { Product } from '../common/installer'; +import { FORMAT, sendTelemetryWhenDone, StopWatch } from '../common/telemetry'; +import { BaseFormatter } from './baseFormatter'; export class AutoPep8Formatter extends BaseFormatter { constructor(outputChannel: vscode.OutputChannel) { @@ -11,13 +12,20 @@ export class AutoPep8Formatter extends BaseFormatter { } public formatDocument(document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken, range?: vscode.Range): Thenable { + const stopWatch = new StopWatch(); const settings = PythonSettings.getInstance(document.uri); const autopep8Path = settings.formatting.autopep8Path; - let autoPep8Args = Array.isArray(settings.formatting.autopep8Args) ? settings.formatting.autopep8Args : []; - autoPep8Args = autoPep8Args.concat(['--diff']); - if (range && !range.isEmpty) { - autoPep8Args = autoPep8Args.concat(['--line-range', (range.start.line + 1).toString(), (range.end.line + 1).toString()]); + const autoPep8Args = Array.isArray(settings.formatting.autopep8Args) ? settings.formatting.autopep8Args : []; + const hasCustomArgs = autoPep8Args.length > 0; + const formatSelection = range ? !range.isEmpty : false; + + autoPep8Args.push('--diff'); + if (formatSelection) { + // tslint:disable-next-line:no-non-null-assertion + autoPep8Args.push(...['--line-range', (range!.start.line + 1).toString(), (range!.end.line + 1).toString()]); } - return super.provideDocumentFormattingEdits(document, options, token, autopep8Path, autoPep8Args); + const promise = super.provideDocumentFormattingEdits(document, options, token, autopep8Path, autoPep8Args); + sendTelemetryWhenDone(FORMAT, promise, stopWatch, { tool: 'autoppep8', hasCustomArgs, formatSelection }); + return promise; } } diff --git a/src/client/formatters/yapfFormatter.ts b/src/client/formatters/yapfFormatter.ts index ff8e40e21066..f425f6ddeb6b 100644 --- a/src/client/formatters/yapfFormatter.ts +++ b/src/client/formatters/yapfFormatter.ts @@ -1,10 +1,10 @@ 'use strict'; import * as vscode from 'vscode'; -import * as path from 'path'; -import { BaseFormatter } from './baseFormatter'; import { PythonSettings } from '../common/configSettings'; import { Product } from '../common/installer'; +import { FORMAT, sendTelemetryWhenDone, StopWatch } from '../common/telemetry'; +import { BaseFormatter } from './baseFormatter'; export class YapfFormatter extends BaseFormatter { constructor(outputChannel: vscode.OutputChannel) { @@ -12,16 +12,23 @@ export class YapfFormatter extends BaseFormatter { } public formatDocument(document: vscode.TextDocument, options: vscode.FormattingOptions, token: vscode.CancellationToken, range?: vscode.Range): Thenable { + const stopWatch = new StopWatch(); const settings = PythonSettings.getInstance(document.uri); const yapfPath = settings.formatting.yapfPath; - let yapfArgs = Array.isArray(settings.formatting.yapfArgs) ? settings.formatting.yapfArgs : []; - yapfArgs = yapfArgs.concat(['--diff']); - if (range && !range.isEmpty) { - yapfArgs = yapfArgs.concat(['--lines', `${range.start.line + 1}-${range.end.line + 1}`]); + const yapfArgs = Array.isArray(settings.formatting.yapfArgs) ? settings.formatting.yapfArgs : []; + const hasCustomArgs = yapfArgs.length > 0; + const formatSelection = range ? !range.isEmpty : false; + + yapfArgs.push('--diff'); + if (formatSelection) { + // tslint:disable-next-line:no-non-null-assertion + yapfArgs.push(...['--lines', `${range!.start.line + 1}-${range!.end.line + 1}`]); } - // Yapf starts looking for config file starting from the file path + // Yapf starts looking for config file starting from the file path. const fallbarFolder = this.getWorkspaceUri(document).fsPath; const cwd = this.getDocumentPath(document, fallbarFolder); - return super.provideDocumentFormattingEdits(document, options, token, yapfPath, yapfArgs, cwd); + const promise = super.provideDocumentFormattingEdits(document, options, token, yapfPath, yapfArgs, cwd); + sendTelemetryWhenDone(FORMAT, promise, stopWatch, { tool: 'yapf', hasCustomArgs, formatSelection }); + return promise; } } From 731d37470f5467b342a04f6dc90c66a5833e1bef Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 12:41:49 -0700 Subject: [PATCH 08/86] telemetry added --- package.json | 3325 +++++++++-------- src/client/common/commands.ts | 46 + src/client/debugger/Main.ts | 3 +- .../editorIntegration/codeLensProvider.ts | 5 +- .../editorIntegration/symbolProvider.ts | 3 +- src/client/linters/baseLinter.ts | 101 +- src/client/providers/completionProvider.ts | 26 +- src/client/providers/definitionProvider.ts | 15 +- src/client/providers/hoverProvider.ts | 55 +- src/client/providers/importSortProvider.ts | 2 + src/client/providers/jediProxy.ts | 4 +- src/client/providers/lintProvider.ts | 75 +- .../providers/objectDefinitionProvider.ts | 4 +- src/client/providers/referenceProvider.ts | 20 +- src/client/providers/renameProvider.ts | 15 +- src/client/providers/replProvider.ts | 2 + src/client/providers/signatureProvider.ts | 48 +- .../providers/simpleRefactorProvider.ts | 42 +- src/client/providers/symbolProvider.ts | 14 +- .../providers/updateSparkLibraryProvider.ts | 17 +- src/client/refactor/proxy.ts | 9 +- src/test/jupyter/jupyterKernelManager.test.ts | 2 +- 22 files changed, 1972 insertions(+), 1861 deletions(-) create mode 100644 src/client/common/commands.ts diff --git a/package.json b/package.json index 1fcb1af34d28..bfb75e4a1d48 100644 --- a/package.json +++ b/package.json @@ -1,1661 +1,1666 @@ { - "name": "python", - "displayName": "Python", - "description": "Linting, Debugging (multi-threaded, remote), Intellisense, code formatting, refactoring, unit tests, snippets, Data Science (with Jupyter), PySpark and more.", - "version": "0.7.0", - "publisher": "donjayamanne", - "author": { - "name": "Don Jayamanne", - "email": "don.jayamanne@yahoo.com" - }, - "license": "MIT", - "homepage": "http://donjayamanne.github.io/pythonVSCode/", - "repository": { - "type": "git", - "url": "https://github.com/DonJayamanne/pythonVSCode" - }, - "bugs": { - "url": "https://github.com/DonJayamanne/pythonVSCode/issues" - }, - "icon": "icon.png", - "galleryBanner": { - "color": "#1e415e", - "theme": "dark" - }, - "engines": { - "vscode": "^1.17.0" - }, - "recommendations": [ - "donjayamanne.jupyter" - ], - "keywords": [ - "python", - "jupyter", - "django", - "debugger", - "unittest", - "multi-root ready" - ], - "categories": [ - "Languages", - "Debuggers", - "Linters", - "Snippets", - "Formatters", - "Other" - ], - "activationEvents": [ - "onDebug", - "onLanguage:python", - "onCommand:python.execInTerminal", - "onCommand:python.sortImports", - "onCommand:python.runtests", - "onCommand:python.debugtests", - "onCommand:python.setInterpreter", - "onCommand:python.setShebangInterpreter", - "onCommand:python.viewTestUI", - "onCommand:python.viewTestOutput", - "onCommand:python.selectAndRunTestMethod", - "onCommand:python.selectAndDebugTestMethod", - "onCommand:python.selectAndRunTestFile", - "onCommand:python.runCurrentTestFile", - "onCommand:python.runFailedTests", - "onCommand:python.execSelectionInTerminal", - "onCommand:python.execSelectionInDjangoShell", - "onCommand:jupyter.runSelectionLine", - "onCommand:jupyter.execCurrentCell", - "onCommand:jupyter.execCurrentCellAndAdvance", - "onCommand:python.buildWorkspaceSymbols", - "onCommand:python.updateSparkLibrary", - "onCommand:python.startREPL", - "onCommand:python.goToPythonObject" - ], - "main": "./out/client/extension", - "contributes": { - "snippets": [ - { - "language": "python", - "path": "./snippets/python.json" - } - ], - "keybindings": [ - { - "command": "jupyter.runSelectionLine", - "key": "ctrl+alt+enter", - "when": "editorFocus && !replaceActive && !searchViewletVisible && !findWidgetVisible" - } - ], - "commands": [ - { - "command": "python.sortImports", - "title": "Sort Imports", - "category": "Python Refactor" - }, - { - "command": "python.startREPL", - "title": "Start REPL", - "category": "Python" - }, - { - "command": "python.buildWorkspaceSymbols", - "title": "Build Workspace Symbols", - "category": "Python" - }, - { - "command": "python.runtests", - "title": "Run All Unit Tests", - "category": "Python" - }, - { - "command": "python.debugtests", - "title": "Debug All Unit Tests", - "category": "Python" - }, - { - "command": "python.execInTerminal", - "title": "Run Python File in Terminal", - "category": "Python" - }, - { - "command": "python.setInterpreter", - "title": "Select Interpreter", - "category": "Python" - }, - { - "command": "python.updateSparkLibrary", - "title": "Update Workspace PySpark Libraries", - "category": "Python" - }, - { - "command": "python.refactorExtractVariable", - "title": "Extract Variable", - "category": "Python Refactor" - }, - { - "command": "python.refactorExtractMethod", - "title": "Extract Method", - "category": "Python Refactor" - }, - { - "command": "python.viewTestOutput", - "title": "Show Unit Test Output", - "category": "Python" - }, - { - "command": "python.selectAndRunTestMethod", - "title": "Run Unit Test Method ...", - "category": "Python" - }, - { - "command": "python.selectAndDebugTestMethod", - "title": "Debug Unit Test Method ...", - "category": "Python" - }, - { - "command": "python.selectAndRunTestFile", - "title": "Run Unit Test File ...", - "category": "Python" - }, - { - "command": "python.runCurrentTestFile", - "title": "Run Current Unit Test File", - "category": "Python" - }, - { - "command": "python.runFailedTests", - "title": "Run Failed Unit Tests", - "category": "Python" - }, - { - "command": "python.execSelectionInTerminal", - "title": "Run Selection/Line in Python Terminal", - "category": "Python" - }, - { - "command": "python.execSelectionInDjangoShell", - "title": "Run Selection/Line in Django Shell", - "category": "Python" - }, - { - "command": "jupyter.runSelectionLine", - "title": "Run Selection/Line", - "category": "Jupyter" - }, - { - "command": "jupyter.execCurrentCell", - "title": "Run Cell", - "category": "Jupyter" - }, - { - "command": "jupyter.execCurrentCellAndAdvance", - "title": "Run Cell and Advance", - "category": "Jupyter" - }, - { - "command": "jupyter.gotToPreviousCell", - "title": "Go to Previous Cell", - "category": "Jupyter" - }, - { - "command": "jupyter.gotToNextCell", - "title": "Go to Next Cell", - "category": "Jupyter" - }, - { - "command": "python.goToPythonObject", - "title": "Go to Python Object", - "category": "Python" - } - ], - "menus": { - "editor/context": [ - { - "command": "python.refactorExtractVariable", - "title": "Refactor: Extract Variable", - "group": "Refactor", - "when": "editorHasSelection && editorLangId == python" - }, - { - "command": "python.refactorExtractMethod", - "title": "Refactor: Extract Method", - "group": "Refactor", - "when": "editorHasSelection && editorLangId == python" - }, - { - "command": "python.sortImports", - "title": "Refactor: Sort Imports", - "group": "Refactor", - "when": "editorLangId == python" - }, - { - "command": "python.execSelectionInTerminal", - "group": "Python", - "when": "editorHasSelection && editorLangId == python" - }, - { - "command": "python.execSelectionInDjangoShell", - "group": "Python", - "when": "editorHasSelection && editorLangId == python && python.isDjangoProject" - }, - { - "when": "resourceLangId == python", - "command": "python.execInTerminal", - "group": "Python" - }, - { - "when": "resourceLangId == python", - "command": "python.runCurrentTestFile", - "group": "Python" - } - ], - "explorer/context": [ - { - "when": "resourceLangId == python", - "command": "python.runtests", - "group": "Python" - }, - { - "when": "resourceLangId == python", - "command": "python.debugtests", - "group": "Python" - }, - { - "when": "resourceLangId == python", - "command": "python.execInTerminal", - "group": "Python" - } - ] - }, - "debuggers": [ - { - "type": "python", - "label": "Python", - "languages": [ - "python" - ], - "enableBreakpointsFor": { - "languageIds": [ - "python", - "html" - ] - }, - "aiKey": "fce7a3d5-4665-4404-b786-31a6306749a6", - "program": "./out/client/debugger/Main.js", - "runtime": "node", - "configurationSnippets": [ - { - "label": "%python.snippet.launch.standard.label%", - "description": "%python.snippet.launch.standard.description%", - "body": { - "name": "Python", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${file}\"", - "cwd": "^\"\\${workspaceRoot}\"", - "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.pyspark.label%", - "description": "%python.snippet.launch.pyspark.description%", - "body": { - "name": "PySpark", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "osx": { - "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit\"" - }, - "windows": { - "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit.cmd\"" - }, - "linux": { - "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit\"" - }, - "program": "^\"\\${file}\"", - "cwd": "^\"\\${workspaceRoot}\"", - "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.module.label%", - "description": "%python.snippet.launch.module.description%", - "body": { - "name": "Python Module", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "module": "module.name", - "cwd": "^\"\\${workspaceRoot}\"", - "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.terminal.label%", - "description": "%python.snippet.launch.terminal.description%", - "body": { - "name": "Integrated Terminal/Console", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${file}\"", - "cwd": "", - "console": "integratedTerminal", - "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit" - ] - } - }, - { - "label": "%python.snippet.launch.externalTerminal.label%", - "description": "%python.snippet.launch.externalTerminal.description%", - "body": { - "name": "External Terminal/Console", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${file}\"", - "cwd": "", - "console": "externalTerminal", - "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit" - ] - } - }, - { - "label": "%python.snippet.launch.django.label%", - "description": "%python.snippet.launch.django.description%", - "body": { - "name": "Django", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${workspaceRoot}/manage.py\"", - "cwd": "^\"\\${workspaceRoot}\"", - "args": [ - "runserver", - "--noreload", - "--nothreading" - ], - "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput", - "DjangoDebugging" - ] - } - }, - { - "label": "%python.snippet.launch.flask.label%", - "description": "%python.snippet.launch.flask.description%", - "body": { - "name": "Flask", - "type": "python", - "request": "launch", - "stopOnEntry": false, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "fully qualified path fo 'flask' executable. Generally located along with python interpreter", - "cwd": "^\"\\${workspaceRoot}\"", - "env": { - "FLASK_APP": "^\"\\${workspaceRoot}/quickstart/app.py\"" - }, - "args": [ - "run", - "--no-debugger", - "--no-reload" - ], - "envFile": "^\"\\${workspaceRoot}/.env\"", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.flaskOld.label%", - "description": "%python.snippet.launch.flaskOld.description%", - "body": { - "name": "Flask (old)", - "type": "python", - "request": "launch", - "stopOnEntry": false, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${workspaceRoot}/run.py\"", - "cwd": "^\"\\${workspaceRoot}\"", - "args": [], - "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.pyramid.label%", - "description": "%python.snippet.launch.pyramid.description%", - "body": { - "name": "Pyramid", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "cwd": "^\"\\${workspaceRoot}\"", - "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", - "args": [ - "^\"\\${workspaceRoot}/development.ini\"" - ], - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput", - "Pyramid" - ] - } - }, - { - "label": "%python.snippet.launch.watson.label%", - "description": "%python.snippet.launch.watson.description%", - "body": { - "name": "Watson", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "^\"\\${workspaceRoot}/console.py\"", - "cwd": "^\"\\${workspaceRoot}\"", - "args": [ - "dev", - "runserver", - "--noreload=True" - ], - "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - } - }, - { - "label": "%python.snippet.launch.scrapy.label%", - "description": "%python.snippet.launch.scrapy.description%", - "body": { - "name": "Scrapy", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "^\"\\${config:python.pythonPath}\"", - "program": "~/.virtualenvs/scrapy/bin/scrapy", - "cwd": "^\"\\${workspaceRoot}\"", - "args": [ - "crawl", - "specs", - "-o", - "bikes.json" - ], - "console": "integratedTerminal", - "env": {}, - "envFile": "^\"\\${workspaceRoot}/.env\"", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit" - ] - } - }, - { - "label": "%python.snippet.launch.attach.label%", - "description": "%python.snippet.launch.attach.description%", - "body": { - "name": "Attach (Remote Debug)", - "type": "python", - "request": "attach", - "localRoot": "^\"\\${workspaceRoot}\"", - "remoteRoot": "^\"\\${workspaceRoot}\"", - "port": 3000, - "secret": "my_secret", - "host": "localhost" - } - } - ], - "configurationAttributes": { - "launch": { - "required": [ - "program" - ], - "properties": { - "module": { - "type": "string", - "description": "Name of the module to be debugged.", - "default": "" - }, - "program": { - "type": "string", - "description": "Absolute path to the program.", - "default": "${file}" - }, - "pythonPath": { - "type": "string", - "description": "Path (fully qualified) to python executable. Defaults to the value in settings.json", - "default": "${config:python.pythonPath}" - }, - "args": { - "type": "array", - "description": "Command line arguments passed to the program", - "default": [], - "items": { - "type": "string" - } - }, - "stopOnEntry": { - "type": "boolean", - "description": "Automatically stop after launch.", - "default": true - }, - "externalConsole": { - "type": "boolean", - "description": "Deprecated: use 'console' attribute instead.", - "default": false - }, - "console": { - "enum": [ - "none", - "integratedTerminal", - "externalTerminal" - ], - "description": "Where to launch the debug target: internal console, integrated terminal, or external terminal.", - "default": "none" - }, - "cwd": { - "type": "string", - "description": "Absolute path to the working directory of the program being debugged. Default is the root directory of the file (leave empty).", - "default": "" - }, - "debugOptions": { - "type": "array", - "description": "Advanced options, view read me for further details.", - "items": { - "type": "string", - "enum": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput", - "DebugStdLib", - "BreakOnSystemExitZero", - "DjangoDebugging", - "Sudo", - "IgnoreDjangoTemplateWarnings", - "Pyramid" - ] - }, - "default": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - }, - "exceptionHandling": { - "description": "List of exception types and how they are handled during debugging (ignore, always break or break only if unhandled).", - "properties": { - "ignore": { - "type": "array", - "description": "Never break into these exceptions, e.g. 'copy.Error'", - "default": [], - "items": { - "type": "string" - } - }, - "always": { - "type": "array", - "description": "Always break into these exceptions, e.g. 'copy.Error'", - "default": [], - "items": { - "type": "string" - } - }, - "unhandled": { - "type": "array", - "description": "Break into these exceptions if they aren't handled, e.g. 'copy.Error'", - "default": [], - "items": { - "type": "string" - } - } - } - }, - "env": { - "type": "object", - "description": "Environment variables defined as a key value pair. Property ends up being the Environment Variable and the value of the property ends up being the value of the Env Variable.", - "default": {} - }, - "envFile": { - "type": "string", - "description": "Absolute path to a file containing environment variable definitions.", - "default": "" - } - } - }, - "attach": { - "required": [ - "localRoot", - "remoteRoot" - ], - "properties": { - "localRoot": { - "type": "string", - "description": "Local source root that corrresponds to the 'remoteRoot'.", - "default": "${workspaceRoot}" - }, - "remoteRoot": { - "type": "string", - "description": "The source root of the remote host.", - "default": "" - }, - "port": { - "type": "number", - "description": "Debug port to attach", - "default": 0 - }, - "host": { - "type": "string", - "description": "IP Address of the of remote server (default is localhost or use 127.0.0.1).", - "default": "localhost" - }, - "secret": { - "type": "string", - "description": "Secret used to authenticate for remote debugging.", - "default": "" - } - } - } - }, - "initialConfigurations": [ - { - "name": "Python", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "program": "${file}", - "cwd": "${workspaceRoot}", - "env": {}, - "envFile": "${workspaceRoot}/.env", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - }, - { - "name": "PySpark", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "osx": { - "pythonPath": "${env:SPARK_HOME}/bin/spark-submit" - }, - "windows": { - "pythonPath": "${env:SPARK_HOME}/bin/spark-submit.cmd" - }, - "linux": { - "pythonPath": "${env:SPARK_HOME}/bin/spark-submit" - }, - "program": "${file}", - "cwd": "${workspaceRoot}", - "env": {}, - "envFile": "${workspaceRoot}/.env", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - }, - { - "name": "Python Module", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "module": "module.name", - "cwd": "${workspaceRoot}", - "env": {}, - "envFile": "${workspaceRoot}/.env", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - }, - { - "name": "Integrated Terminal/Console", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "program": "${file}", - "cwd": "", - "console": "integratedTerminal", - "env": {}, - "envFile": "${workspaceRoot}/.env", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit" - ] - }, - { - "name": "External Terminal/Console", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "program": "${file}", - "cwd": "", - "console": "externalTerminal", - "env": {}, - "envFile": "${workspaceRoot}/.env", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit" - ] - }, - { - "name": "Django", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "program": "${workspaceRoot}/manage.py", - "cwd": "${workspaceRoot}", - "args": [ - "runserver", - "--noreload", - "--nothreading" - ], - "env": {}, - "envFile": "${workspaceRoot}/.env", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput", - "DjangoDebugging" - ] - }, - { - "name": "Flask", - "type": "python", - "request": "launch", - "stopOnEntry": false, - "pythonPath": "${config:python.pythonPath}", - "program": "fully qualified path fo 'flask' executable. Generally located along with python interpreter", - "cwd": "${workspaceRoot}", - "env": { - "FLASK_APP": "${workspaceRoot}/quickstart/app.py" - }, - "args": [ - "run", - "--no-debugger", - "--no-reload" - ], - "envFile": "${workspaceRoot}/.env", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - }, - { - "name": "Flask (old)", - "type": "python", - "request": "launch", - "stopOnEntry": false, - "pythonPath": "${config:python.pythonPath}", - "program": "${workspaceRoot}/run.py", - "cwd": "${workspaceRoot}", - "args": [], - "env": {}, - "envFile": "${workspaceRoot}/.env", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - }, - { - "name": "Pyramid", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "cwd": "${workspaceRoot}", - "env": {}, - "envFile": "${workspaceRoot}/.env", - "args": [ - "${workspaceRoot}/development.ini" - ], - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput", - "Pyramid" - ] - }, - { - "name": "Watson", - "type": "python", - "request": "launch", - "stopOnEntry": true, - "pythonPath": "${config:python.pythonPath}", - "program": "${workspaceRoot}/console.py", - "cwd": "${workspaceRoot}", - "args": [ - "dev", - "runserver", - "--noreload=True" - ], - "env": {}, - "envFile": "${workspaceRoot}/.env", - "debugOptions": [ - "WaitOnAbnormalExit", - "WaitOnNormalExit", - "RedirectOutput" - ] - }, - { - "name": "Attach (Remote Debug)", - "type": "python", - "request": "attach", - "localRoot": "${workspaceRoot}", - "remoteRoot": "${workspaceRoot}", - "port": 3000, - "secret": "my_secret", - "host": "localhost" - } - ] - } - ], - "configuration": { - "type": "object", - "title": "Python Configuration", - "properties": { - "python.promptToInstallJupyter": { - "type": "boolean", - "default": true, - "description": "Display prompt to install Jupyter Extension.", - "scope": "resource" - }, - "python.pythonPath": { - "type": "string", - "default": "python", - "description": "Path to Python, you can use a custom version of Python by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.venvPath": { - "type": "string", - "default": "", - "description": "Path to folder with a list of Virtual Environments (e.g. ~/.pyenv, ~/Envs, ~/.virtualenvs).", - "scope": "resource" - }, - "python.envFile": { - "type": "string", - "description": "Absolute path to a file containing environment variable definitions.", - "default": "${workspaceRoot}/.env", - "scope": "resource" - }, - "python.jediPath": { - "type": "string", - "default": "", - "description": "Path to directory containing the Jedi library (this path will contain the 'Jedi' sub directory).", - "scope": "resource" - }, - "python.sortImports.path": { - "type": "string", - "description": "Path to isort script, default using inner version", - "default": "", - "scope": "resource" - }, - "python.sortImports.args": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.disablePromptForFeatures": { - "type": "array", - "default": [], - "description": "Do not display a prompt to install these features", - "items": { - "type": "string", - "default": "pylint", - "description": "Feature", - "enum": [ - "flake8", - "mypy", - "pep8", - "pylama", - "prospector", - "pydocstyle", - "pylint" - ] - }, - "scope": "resource" - }, - "python.linting.enabled": { - "type": "boolean", - "default": true, - "description": "Whether to lint Python files.", - "scope": "resource" - }, - "python.linting.enabledWithoutWorkspace": { - "type": "boolean", - "default": true, - "description": "Whether to lint Python files when no workspace is opened.", - "scope": "resource" - }, - "python.linting.prospectorEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using prospector.", - "scope": "resource" - }, - "python.linting.pylintEnabled": { - "type": "boolean", - "default": true, - "description": "Whether to lint Python files using pylint.", - "scope": "resource" - }, - "python.linting.pep8Enabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using pep8", - "scope": "resource" - }, - "python.linting.flake8Enabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using flake8", - "scope": "resource" - }, - "python.linting.pydocstyleEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using pydocstyle", - "scope": "resource" - }, - "python.linting.mypyEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using mypy.", - "scope": "resource" - }, - "python.linting.lintOnTextChange": { - "type": "boolean", - "default": true, - "description": "Whether to lint Python files when modified.", - "scope": "resource" - }, - "python.linting.lintOnSave": { - "type": "boolean", - "default": true, - "description": "Whether to lint Python files when saved.", - "scope": "resource" - }, - "python.linting.maxNumberOfProblems": { - "type": "number", - "default": 100, - "description": "Controls the maximum number of problems produced by the server.", - "scope": "resource" - }, - "python.linting.pylintCategorySeverity.convention": { - "type": "string", - "default": "Information", - "description": "Severity of Pylint message type 'Convention/C'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pylintCategorySeverity.refactor": { - "type": "string", - "default": "Hint", - "description": "Severity of Pylint message type 'Refactor/R'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pylintCategorySeverity.warning": { - "type": "string", - "default": "Warning", - "description": "Severity of Pylint message type 'Warning/W'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pylintCategorySeverity.error": { - "type": "string", - "default": "Error", - "description": "Severity of Pylint message type 'Error/E'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pylintCategorySeverity.fatal": { - "type": "string", - "default": "Error", - "description": "Severity of Pylint message type 'Fatal/F'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pep8CategorySeverity.W": { - "type": "string", - "default": "Warning", - "description": "Severity of Pep8 message type 'W'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.pep8CategorySeverity.E": { - "type": "string", - "default": "Error", - "description": "Severity of Pep8 message type 'E'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.flake8CategorySeverity.F": { - "type": "string", - "default": "Error", - "description": "Severity of Flake8 message type 'F'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.flake8CategorySeverity.E": { - "type": "string", - "default": "Error", - "description": "Severity of Flake8 message type 'E'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.flake8CategorySeverity.W": { - "type": "string", - "default": "Warning", - "description": "Severity of Flake8 message type 'W'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.mypyCategorySeverity.error": { - "type": "string", - "default": "Error", - "description": "Severity of Mypy message type 'Error'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.mypyCategorySeverity.note": { - "type": "string", - "default": "Information", - "description": "Severity of Mypy message type 'Note'.", - "enum": [ - "Hint", - "Error", - "Information", - "Warning" - ], - "scope": "resource" - }, - "python.linting.prospectorPath": { - "type": "string", - "default": "prospector", - "description": "Path to Prospector, you can use a custom version of prospector by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.pylintPath": { - "type": "string", - "default": "pylint", - "description": "Path to Pylint, you can use a custom version of pylint by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.pep8Path": { - "type": "string", - "default": "pep8", - "description": "Path to pep8, you can use a custom version of pep8 by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.flake8Path": { - "type": "string", - "default": "flake8", - "description": "Path to flake8, you can use a custom version of flake8 by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.pydocstylePath": { - "type": "string", - "default": "pydocstyle", - "description": "Path to pydocstyle, you can use a custom version of pydocstyle by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.mypyPath": { - "type": "string", - "default": "mypy", - "description": "Path to mypy, you can use a custom version of mypy by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.prospectorArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.pylintArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.pep8Args": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.flake8Args": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.pydocstyleArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.mypyArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [ - "--ignore-missing-imports", - "--follow-imports=silent" - ], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.outputWindow": { - "type": "string", - "default": "Python", - "description": "The output window name for the linting messages, defaults to Python output window.", - "scope": "resource" - }, - "python.formatting.provider": { - "type": "string", - "default": "autopep8", - "description": "Provider for formatting. Possible options include 'autopep8' and 'yapf'.", - "enum": [ - "autopep8", - "yapf", - "none" - ], - "scope": "resource" - }, - "python.formatting.autopep8Path": { - "type": "string", - "default": "autopep8", - "description": "Path to autopep8, you can use a custom version of autopep8 by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.formatting.yapfPath": { - "type": "string", - "default": "yapf", - "description": "Path to yapf, you can use a custom version of yapf by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.formatting.autopep8Args": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.formatting.yapfArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.formatting.formatOnSave": { - "type": "boolean", - "default": false, - "description": "Format the document upon saving.", - "scope": "resource" - }, - "python.formatting.outputWindow": { - "type": "string", - "default": "Python", - "description": "The output window name for the formatting messages, defaults to Python output window.", - "scope": "resource" - }, - "python.autoComplete.preloadModules": { - "type": "array", - "items": { - "type": "string" - }, - "default": [], - "description": "Comma delimited list of modules preloaded to speed up Auto Complete (e.g. add Numpy, Pandas, etc, items slow to load when autocompleting).", - "scope": "resource" - }, - "python.autoComplete.extraPaths": { - "type": "array", - "default": [], - "description": "List of paths to libraries and the like that need to be imported by auto complete engine. E.g. when using Google App SDK, the paths are not in system path, hence need to be added into this list.", - "scope": "resource" - }, - "python.autoComplete.addBrackets": { - "type": "boolean", - "default": false, - "description": "Automatically add brackets for functions.", - "scope": "resource" - }, - "python.workspaceSymbols.tagFilePath": { - "type": "string", - "default": "${workspaceRoot}/.vscode/tags", - "description": "Fully qualified path to tag file (exuberant ctag file), used to provide workspace symbols.", - "scope": "resource" - }, - "python.workspaceSymbols.enabled": { - "type": "boolean", - "default": true, - "description": "Set to 'false' to disable Workspace Symbol provider using ctags.", - "scope": "resource" - }, - "python.workspaceSymbols.rebuildOnStart": { - "type": "boolean", - "default": true, - "description": "Whether to re-build the tags file on start (defaults to true).", - "scope": "resource" - }, - "python.workspaceSymbols.rebuildOnFileSave": { - "type": "boolean", - "default": true, - "description": "Whether to re-build the tags file on when changes made to python files are saved.", - "scope": "resource" - }, - "python.workspaceSymbols.ctagsPath": { - "type": "string", - "default": "ctags", - "description": "Fully qualilified path to the ctags executable (else leave as ctags, assuming it is in current path).", - "scope": "resource" - }, - "python.workspaceSymbols.exclusionPatterns": { - "type": "array", - "default": [ - "**/site-packages/**" - ], - "items": { - "type": "string" - }, - "description": "Pattern used to exclude files and folders from ctags See http://ctags.sourceforge.net/ctags.html.", - "scope": "resource" - }, - "python.unitTest.promptToConfigure": { - "type": "boolean", - "default": true, - "description": "Where to prompt to configure a test framework if potential tests directories are discovered.", - "scope": "resource" - }, - "python.unitTest.debugPort": { - "type": "number", - "default": 3000, - "description": "Port number used for debugging of unittests.", - "scope": "resource" - }, - "python.unitTest.cwd": { - "type": "string", - "default": null, - "description": "Optional working directory for unit tests.", - "scope": "resource" - }, - "python.unitTest.nosetestsEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to enable or disable unit testing using nosetests.", - "scope": "resource" - }, - "python.unitTest.nosetestPath": { - "type": "string", - "default": "nosetests", - "description": "Path to nosetests, you can use a custom version of nosetests by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.unitTest.pyTestEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to enable or disable unit testing using pytest.", - "scope": "resource" - }, - "python.unitTest.pyTestPath": { - "type": "string", - "default": "py.test", - "description": "Path to pytest (py.test), you can use a custom version of pytest by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.unitTest.nosetestArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.unitTest.pyTestArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.unitTest.unittestEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to enable or disable unit testing using unittest.", - "scope": "resource" - }, - "python.unitTest.unittestArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [ - "-v", - "-s", - ".", - "-p", - "*test*.py" - ], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.ignorePatterns": { - "type": "array", - "description": "Patterns used to exclude files or folders from being linted.", - "default": [ - ".vscode/*.py", - "**/site-packages/**/*.py" - ], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.linting.pylamaEnabled": { - "type": "boolean", - "default": false, - "description": "Whether to lint Python files using pylama.", - "scope": "resource" - }, - "python.linting.pylamaPath": { - "type": "string", - "default": "pylama", - "description": "Path to pylama, you can use a custom version of pylama by modifying this setting to include the full path.", - "scope": "resource" - }, - "python.linting.pylamaArgs": { - "type": "array", - "description": "Arguments passed in. Each argument is a separate item in the array.", - "default": [], - "items": { - "type": "string" - }, - "scope": "resource" - }, - "python.unitTest.outputWindow": { - "type": "string", - "default": "Python Test Log", - "description": "The output window name for the unit test messages, defaults to Python output window.", - "scope": "resource" - }, - "python.terminal.executeInFileDir": { - "type": "boolean", - "default": false, - "description": "When executing a file in the terminal, whether to use execute in the file's directory, instead of the current open folder.", - "scope": "resource" - }, - "python.terminal.launchArgs": { - "type": "array", - "default": [], - "description": "Python launch arguments to use when executing a file in the terminal.", - "scope": "resource" - }, - "python.jupyter.appendResults": { - "type": "boolean", - "default": true, - "description": "Whether to appen the results to results window, else clear and display.", - "scope": "resource" - }, - "python.jupyter.defaultKernel": { - "type": "string", - "default": "", - "description": "Default kernel to be used. By default the first available kernel is used.", - "scope": "resource" - }, - "python.jupyter.startupCode": { - "type": "array", - "items": { - "type": "string" - }, - "default": [ - "%matplotlib inline" - ], - "description": "Code executed when the kernel starts. Such as the default of '%matplotlib inline'. Individual lines can be placed in separate items of the array.", - "scope": "resource" - } - } - }, - "languages": [ - { - "id": "pip-requirements", - "aliases": [ - "pip requirements", - "requirements.txt" - ], - "filenames": [ - "requirements.txt" - ], - "filenamePatterns": [ - "*-requirements.txt", - "requirements-*.txt" - ], - "configuration": "./languages/pip-requirements.json" - } - ], - "grammars": [ - { - "language": "pip-requirements", - "scopeName": "source.pip-requirements", - "path": "./syntaxes/pip-requirements.tmLanguage.json" - } - ] - }, - "scripts": { - "vscode:prepublish": "tsc -p ./ && webpack", - "compile": "webpack && tsc -watch -p ./", - "postinstall": "node ./node_modules/vscode/bin/install", - "test": "node ./out/test/standardTest.js && node ./out/test/multiRootTest.js", - "precommit": "node gulpfile.js", - "lint-staged": "node gulpfile.js", - "lint": "tslint src/**/*.ts -t verbose" - }, - "dependencies": { - "diff-match-patch": "^1.0.0", - "fs-extra": "^4.0.2", - "fuzzy": "^0.1.3", - "line-by-line": "^0.1.5", - "lodash": "^4.17.4", - "minimatch": "^3.0.3", - "named-js-regexp": "^1.3.1", - "rx": "^4.1.0", - "semver": "^5.4.1", - "socket.io": "^1.4.8", - "tmp": "0.0.29", - "tree-kill": "^1.1.0", - "uint64be": "^1.0.1", - "untildify": "^3.0.2", - "vscode-debugadapter": "^1.0.1", - "vscode-debugprotocol": "^1.0.1", - "vscode-extension-telemetry": "^0.0.5", - "vscode-languageclient": "^3.1.0", - "vscode-languageserver": "^3.1.0", - "winreg": "^1.2.4", - "xml2js": "^0.4.17" - }, - "devDependencies": { - "@types/chai": "^4.0.4", - "@types/chai-as-promised": "^7.1.0", - "@types/fs-extra": "^4.0.2", - "@types/jquery": "^1.10.31", - "@types/lodash": "^4.14.74", - "@types/mocha": "^2.2.43", - "@types/node": "^6.0.40", - "@types/rx": "^2.5.33", - "@types/semver": "^5.4.0", - "@types/sinon": "^2.3.2", - "@types/socket.io": "^1.4.27", - "@types/socket.io-client": "^1.4.27", - "@types/uuid": "^3.3.27", - "@types/winreg": "^1.2.30", - "@types/xml2js": "^0.4.0", - "babel-core": "^6.14.0", - "babel-loader": "^6.2.5", - "babel-preset-es2015": "^6.14.0", - "chai": "^4.1.2", - "chai-as-promised": "^7.1.1", - "event-stream": "^3.3.4", - "gulp": "^3.9.1", - "gulp-filter": "^5.0.1", - "gulp-typescript": "^3.2.2", - "husky": "^0.14.3", - "ignore-loader": "^0.1.1", - "mocha": "^2.3.3", - "relative": "^3.0.2", - "retyped-diff-match-patch-tsd-ambient": "^1.0.0-0", - "sinon": "^2.3.6", - "transformime": "^3.1.2", - "transformime-marked": "0.0.1", - "ts-loader": "^2.3.4", - "tslint": "^5.7.0", - "tslint-eslint-rules": "^4.1.1", - "tslint-microsoft-contrib": "^5.0.1", - "typescript": "^2.5.2", - "typescript-formatter": "^6.0.0", - "webpack": "^1.13.2", - "vscode": "^1.1.5" - } -} + "name": "python", + "displayName": "Python", + "description": "Linting, Debugging (multi-threaded, remote), Intellisense, code formatting, refactoring, unit tests, snippets, Data Science (with Jupyter), PySpark and more.", + "version": "0.7.0", + "publisher": "donjayamanne", + "author": { + "name": "Don Jayamanne", + "email": "don.jayamanne@yahoo.com" + }, + "license": "MIT", + "homepage": "http://donjayamanne.github.io/pythonVSCode/", + "repository": { + "type": "git", + "url": "https://github.com/DonJayamanne/pythonVSCode" + }, + "bugs": { + "url": "https://github.com/DonJayamanne/pythonVSCode/issues" + }, + "icon": "icon.png", + "galleryBanner": { + "color": "#1e415e", + "theme": "dark" + }, + "engines": { + "vscode": "^1.17.0" + }, + "recommendations": [ + "donjayamanne.jupyter" + ], + "keywords": [ + "python", + "jupyter", + "django", + "debugger", + "unittest", + "multi-root ready" + ], + "categories": [ + "Languages", + "Debuggers", + "Linters", + "Snippets", + "Formatters", + "Other" + ], + "activationEvents": [ + "onDebug", + "onLanguage:python", + "onCommand:python.execInTerminal", + "onCommand:python.sortImports", + "onCommand:python.runtests", + "onCommand:python.debugtests", + "onCommand:python.setInterpreter", + "onCommand:python.setShebangInterpreter", + "onCommand:python.viewTestUI", + "onCommand:python.viewTestOutput", + "onCommand:python.selectAndRunTestMethod", + "onCommand:python.selectAndDebugTestMethod", + "onCommand:python.selectAndRunTestFile", + "onCommand:python.runCurrentTestFile", + "onCommand:python.runFailedTests", + "onCommand:python.execSelectionInTerminal", + "onCommand:python.execSelectionInDjangoShell", + "onCommand:jupyter.runSelectionLine", + "onCommand:jupyter.execCurrentCell", + "onCommand:jupyter.execCurrentCellAndAdvance", + "onCommand:python.buildWorkspaceSymbols", + "onCommand:python.updateSparkLibrary", + "onCommand:python.startREPL", + "onCommand:python.goToPythonObject" + ], + "main": "./out/client/extension", + "contributes": { + "snippets": [ + { + "language": "python", + "path": "./snippets/python.json" + } + ], + "keybindings": [ + { + "command": "jupyter.runSelectionLine", + "key": "ctrl+alt+enter", + "when": "editorFocus && !replaceActive && !searchViewletVisible && !findWidgetVisible" + } + ], + "commands": [ + { + "command": "python.sortImports", + "title": "Sort Imports", + "category": "Python Refactor" + }, + { + "command": "python.startREPL", + "title": "Start REPL", + "category": "Python" + }, + { + "command": "python.buildWorkspaceSymbols", + "title": "Build Workspace Symbols", + "category": "Python" + }, + { + "command": "python.runtests", + "title": "Run All Unit Tests", + "category": "Python" + }, + { + "command": "python.debugtests", + "title": "Debug All Unit Tests", + "category": "Python" + }, + { + "command": "python.execInTerminal", + "title": "Run Python File in Terminal", + "category": "Python" + }, + { + "command": "python.setInterpreter", + "title": "Select Interpreter", + "category": "Python" + }, + { + "command": "python.updateSparkLibrary", + "title": "Update Workspace PySpark Libraries", + "category": "Python" + }, + { + "command": "python.refactorExtractVariable", + "title": "Extract Variable", + "category": "Python Refactor" + }, + { + "command": "python.refactorExtractMethod", + "title": "Extract Method", + "category": "Python Refactor" + }, + { + "command": "python.viewTestOutput", + "title": "Show Unit Test Output", + "category": "Python" + }, + { + "command": "python.selectAndRunTestMethod", + "title": "Run Unit Test Method ...", + "category": "Python" + }, + { + "command": "python.selectAndDebugTestMethod", + "title": "Debug Unit Test Method ...", + "category": "Python" + }, + { + "command": "python.selectAndRunTestFile", + "title": "Run Unit Test File ...", + "category": "Python" + }, + { + "command": "python.runCurrentTestFile", + "title": "Run Current Unit Test File", + "category": "Python" + }, + { + "command": "python.runFailedTests", + "title": "Run Failed Unit Tests", + "category": "Python" + }, + { + "command": "python.execSelectionInTerminal", + "title": "Run Selection/Line in Python Terminal", + "category": "Python" + }, + { + "command": "python.execSelectionInDjangoShell", + "title": "Run Selection/Line in Django Shell", + "category": "Python" + }, + { + "command": "jupyter.runSelectionLine", + "title": "Run Selection/Line", + "category": "Jupyter" + }, + { + "command": "jupyter.execCurrentCell", + "title": "Run Cell", + "category": "Jupyter" + }, + { + "command": "jupyter.execCurrentCellAndAdvance", + "title": "Run Cell and Advance", + "category": "Jupyter" + }, + { + "command": "jupyter.gotToPreviousCell", + "title": "Go to Previous Cell", + "category": "Jupyter" + }, + { + "command": "jupyter.gotToNextCell", + "title": "Go to Next Cell", + "category": "Jupyter" + }, + { + "command": "python.goToPythonObject", + "title": "Go to Python Object", + "category": "Python" + } + ], + "menus": { + "editor/context": [ + { + "command": "python.refactorExtractVariable", + "title": "Refactor: Extract Variable", + "group": "Refactor", + "when": "editorHasSelection && editorLangId == python" + }, + { + "command": "python.refactorExtractMethod", + "title": "Refactor: Extract Method", + "group": "Refactor", + "when": "editorHasSelection && editorLangId == python" + }, + { + "command": "python.sortImports", + "title": "Refactor: Sort Imports", + "group": "Refactor", + "when": "editorLangId == python" + }, + { + "command": "python.execSelectionInTerminal", + "group": "Python", + "when": "editorHasSelection && editorLangId == python" + }, + { + "command": "python.execSelectionInDjangoShell", + "group": "Python", + "when": "editorHasSelection && editorLangId == python && python.isDjangoProject" + }, + { + "when": "resourceLangId == python", + "command": "python.execInTerminal", + "group": "Python" + }, + { + "when": "resourceLangId == python", + "command": "python.runCurrentTestFile", + "group": "Python" + } + ], + "explorer/context": [ + { + "when": "resourceLangId == python", + "command": "python.runtests", + "group": "Python" + }, + { + "when": "resourceLangId == python", + "command": "python.debugtests", + "group": "Python" + }, + { + "when": "resourceLangId == python", + "command": "python.execInTerminal", + "group": "Python" + } + ] + }, + "debuggers": [ + { + "type": "python", + "label": "Python", + "languages": [ + "python" + ], + "enableBreakpointsFor": { + "languageIds": [ + "python", + "html" + ] + }, + "aiKey": "fce7a3d5-4665-4404-b786-31a6306749a6", + "program": "./out/client/debugger/Main.js", + "runtime": "node", + "configurationSnippets": [ + { + "label": "%python.snippet.launch.standard.label%", + "description": "%python.snippet.launch.standard.description%", + "body": { + "name": "Python", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${file}\"", + "cwd": "^\"\\${workspaceRoot}\"", + "env": {}, + "envFile": "^\"\\${workspaceRoot}/.env\"", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.pyspark.label%", + "description": "%python.snippet.launch.pyspark.description%", + "body": { + "name": "PySpark", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "osx": { + "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit\"" + }, + "windows": { + "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit.cmd\"" + }, + "linux": { + "pythonPath": "^\"\\${env:SPARK_HOME}/bin/spark-submit\"" + }, + "program": "^\"\\${file}\"", + "cwd": "^\"\\${workspaceRoot}\"", + "env": {}, + "envFile": "^\"\\${workspaceRoot}/.env\"", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.module.label%", + "description": "%python.snippet.launch.module.description%", + "body": { + "name": "Python Module", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "module": "module.name", + "cwd": "^\"\\${workspaceRoot}\"", + "env": {}, + "envFile": "^\"\\${workspaceRoot}/.env\"", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.terminal.label%", + "description": "%python.snippet.launch.terminal.description%", + "body": { + "name": "Integrated Terminal/Console", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${file}\"", + "cwd": "", + "console": "integratedTerminal", + "env": {}, + "envFile": "^\"\\${workspaceRoot}/.env\"", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit" + ] + } + }, + { + "label": "%python.snippet.launch.externalTerminal.label%", + "description": "%python.snippet.launch.externalTerminal.description%", + "body": { + "name": "External Terminal/Console", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${file}\"", + "cwd": "", + "console": "externalTerminal", + "env": {}, + "envFile": "^\"\\${workspaceRoot}/.env\"", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit" + ] + } + }, + { + "label": "%python.snippet.launch.django.label%", + "description": "%python.snippet.launch.django.description%", + "body": { + "name": "Django", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${workspaceRoot}/manage.py\"", + "cwd": "^\"\\${workspaceRoot}\"", + "args": [ + "runserver", + "--noreload", + "--nothreading" + ], + "env": {}, + "envFile": "^\"\\${workspaceRoot}/.env\"", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput", + "DjangoDebugging" + ] + } + }, + { + "label": "%python.snippet.launch.flask.label%", + "description": "%python.snippet.launch.flask.description%", + "body": { + "name": "Flask", + "type": "python", + "request": "launch", + "stopOnEntry": false, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "fully qualified path fo 'flask' executable. Generally located along with python interpreter", + "cwd": "^\"\\${workspaceRoot}\"", + "env": { + "FLASK_APP": "^\"\\${workspaceRoot}/quickstart/app.py\"" + }, + "args": [ + "run", + "--no-debugger", + "--no-reload" + ], + "envFile": "^\"\\${workspaceRoot}/.env\"", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.flaskOld.label%", + "description": "%python.snippet.launch.flaskOld.description%", + "body": { + "name": "Flask (old)", + "type": "python", + "request": "launch", + "stopOnEntry": false, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${workspaceRoot}/run.py\"", + "cwd": "^\"\\${workspaceRoot}\"", + "args": [], + "env": {}, + "envFile": "^\"\\${workspaceRoot}/.env\"", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.pyramid.label%", + "description": "%python.snippet.launch.pyramid.description%", + "body": { + "name": "Pyramid", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "cwd": "^\"\\${workspaceRoot}\"", + "env": {}, + "envFile": "^\"\\${workspaceRoot}/.env\"", + "args": [ + "^\"\\${workspaceRoot}/development.ini\"" + ], + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput", + "Pyramid" + ] + } + }, + { + "label": "%python.snippet.launch.watson.label%", + "description": "%python.snippet.launch.watson.description%", + "body": { + "name": "Watson", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "^\"\\${workspaceRoot}/console.py\"", + "cwd": "^\"\\${workspaceRoot}\"", + "args": [ + "dev", + "runserver", + "--noreload=True" + ], + "env": {}, + "envFile": "^\"\\${workspaceRoot}/.env\"", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + } + }, + { + "label": "%python.snippet.launch.scrapy.label%", + "description": "%python.snippet.launch.scrapy.description%", + "body": { + "name": "Scrapy", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "^\"\\${config:python.pythonPath}\"", + "program": "~/.virtualenvs/scrapy/bin/scrapy", + "cwd": "^\"\\${workspaceRoot}\"", + "args": [ + "crawl", + "specs", + "-o", + "bikes.json" + ], + "console": "integratedTerminal", + "env": {}, + "envFile": "^\"\\${workspaceRoot}/.env\"", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit" + ] + } + }, + { + "label": "%python.snippet.launch.attach.label%", + "description": "%python.snippet.launch.attach.description%", + "body": { + "name": "Attach (Remote Debug)", + "type": "python", + "request": "attach", + "localRoot": "^\"\\${workspaceRoot}\"", + "remoteRoot": "^\"\\${workspaceRoot}\"", + "port": 3000, + "secret": "my_secret", + "host": "localhost" + } + } + ], + "configurationAttributes": { + "launch": { + "required": [ + "program" + ], + "properties": { + "module": { + "type": "string", + "description": "Name of the module to be debugged.", + "default": "" + }, + "program": { + "type": "string", + "description": "Absolute path to the program.", + "default": "${file}" + }, + "pythonPath": { + "type": "string", + "description": "Path (fully qualified) to python executable. Defaults to the value in settings.json", + "default": "${config:python.pythonPath}" + }, + "args": { + "type": "array", + "description": "Command line arguments passed to the program", + "default": [], + "items": { + "type": "string" + } + }, + "stopOnEntry": { + "type": "boolean", + "description": "Automatically stop after launch.", + "default": true + }, + "externalConsole": { + "type": "boolean", + "description": "Deprecated: use 'console' attribute instead.", + "default": false + }, + "console": { + "enum": [ + "none", + "integratedTerminal", + "externalTerminal" + ], + "description": "Where to launch the debug target: internal console, integrated terminal, or external terminal.", + "default": "none" + }, + "cwd": { + "type": "string", + "description": "Absolute path to the working directory of the program being debugged. Default is the root directory of the file (leave empty).", + "default": "" + }, + "debugOptions": { + "type": "array", + "description": "Advanced options, view read me for further details.", + "items": { + "type": "string", + "enum": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput", + "DebugStdLib", + "BreakOnSystemExitZero", + "DjangoDebugging", + "Sudo", + "IgnoreDjangoTemplateWarnings", + "Pyramid" + ] + }, + "default": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + }, + "exceptionHandling": { + "description": "List of exception types and how they are handled during debugging (ignore, always break or break only if unhandled).", + "properties": { + "ignore": { + "type": "array", + "description": "Never break into these exceptions, e.g. 'copy.Error'", + "default": [], + "items": { + "type": "string" + } + }, + "always": { + "type": "array", + "description": "Always break into these exceptions, e.g. 'copy.Error'", + "default": [], + "items": { + "type": "string" + } + }, + "unhandled": { + "type": "array", + "description": "Break into these exceptions if they aren't handled, e.g. 'copy.Error'", + "default": [], + "items": { + "type": "string" + } + } + } + }, + "env": { + "type": "object", + "description": "Environment variables defined as a key value pair. Property ends up being the Environment Variable and the value of the property ends up being the value of the Env Variable.", + "default": {} + }, + "envFile": { + "type": "string", + "description": "Absolute path to a file containing environment variable definitions.", + "default": "" + } + } + }, + "attach": { + "required": [ + "localRoot", + "remoteRoot" + ], + "properties": { + "localRoot": { + "type": "string", + "description": "Local source root that corrresponds to the 'remoteRoot'.", + "default": "${workspaceRoot}" + }, + "remoteRoot": { + "type": "string", + "description": "The source root of the remote host.", + "default": "" + }, + "port": { + "type": "number", + "description": "Debug port to attach", + "default": 0 + }, + "host": { + "type": "string", + "description": "IP Address of the of remote server (default is localhost or use 127.0.0.1).", + "default": "localhost" + }, + "secret": { + "type": "string", + "description": "Secret used to authenticate for remote debugging.", + "default": "" + } + } + } + }, + "initialConfigurations": [ + { + "name": "Python", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "program": "${file}", + "cwd": "${workspaceRoot}", + "env": {}, + "envFile": "${workspaceRoot}/.env", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + }, + { + "name": "PySpark", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "osx": { + "pythonPath": "${env:SPARK_HOME}/bin/spark-submit" + }, + "windows": { + "pythonPath": "${env:SPARK_HOME}/bin/spark-submit.cmd" + }, + "linux": { + "pythonPath": "${env:SPARK_HOME}/bin/spark-submit" + }, + "program": "${file}", + "cwd": "${workspaceRoot}", + "env": {}, + "envFile": "${workspaceRoot}/.env", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + }, + { + "name": "Python Module", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "module": "module.name", + "cwd": "${workspaceRoot}", + "env": {}, + "envFile": "${workspaceRoot}/.env", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + }, + { + "name": "Integrated Terminal/Console", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "program": "${file}", + "cwd": "", + "console": "integratedTerminal", + "env": {}, + "envFile": "${workspaceRoot}/.env", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit" + ] + }, + { + "name": "External Terminal/Console", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "program": "${file}", + "cwd": "", + "console": "externalTerminal", + "env": {}, + "envFile": "${workspaceRoot}/.env", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit" + ] + }, + { + "name": "Django", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "program": "${workspaceRoot}/manage.py", + "cwd": "${workspaceRoot}", + "args": [ + "runserver", + "--noreload", + "--nothreading" + ], + "env": {}, + "envFile": "${workspaceRoot}/.env", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput", + "DjangoDebugging" + ] + }, + { + "name": "Flask", + "type": "python", + "request": "launch", + "stopOnEntry": false, + "pythonPath": "${config:python.pythonPath}", + "program": "fully qualified path fo 'flask' executable. Generally located along with python interpreter", + "cwd": "${workspaceRoot}", + "env": { + "FLASK_APP": "${workspaceRoot}/quickstart/app.py" + }, + "args": [ + "run", + "--no-debugger", + "--no-reload" + ], + "envFile": "${workspaceRoot}/.env", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + }, + { + "name": "Flask (old)", + "type": "python", + "request": "launch", + "stopOnEntry": false, + "pythonPath": "${config:python.pythonPath}", + "program": "${workspaceRoot}/run.py", + "cwd": "${workspaceRoot}", + "args": [], + "env": {}, + "envFile": "${workspaceRoot}/.env", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + }, + { + "name": "Pyramid", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "cwd": "${workspaceRoot}", + "env": {}, + "envFile": "${workspaceRoot}/.env", + "args": [ + "${workspaceRoot}/development.ini" + ], + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput", + "Pyramid" + ] + }, + { + "name": "Watson", + "type": "python", + "request": "launch", + "stopOnEntry": true, + "pythonPath": "${config:python.pythonPath}", + "program": "${workspaceRoot}/console.py", + "cwd": "${workspaceRoot}", + "args": [ + "dev", + "runserver", + "--noreload=True" + ], + "env": {}, + "envFile": "${workspaceRoot}/.env", + "debugOptions": [ + "WaitOnAbnormalExit", + "WaitOnNormalExit", + "RedirectOutput" + ] + }, + { + "name": "Attach (Remote Debug)", + "type": "python", + "request": "attach", + "localRoot": "${workspaceRoot}", + "remoteRoot": "${workspaceRoot}", + "port": 3000, + "secret": "my_secret", + "host": "localhost" + } + ] + } + ], + "configuration": { + "type": "object", + "title": "Python Configuration", + "properties": { + "python.promptToInstallJupyter": { + "type": "boolean", + "default": true, + "description": "Display prompt to install Jupyter Extension.", + "scope": "resource" + }, + "python.pythonPath": { + "type": "string", + "default": "python", + "description": "Path to Python, you can use a custom version of Python by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.venvPath": { + "type": "string", + "default": "", + "description": "Path to folder with a list of Virtual Environments (e.g. ~/.pyenv, ~/Envs, ~/.virtualenvs).", + "scope": "resource" + }, + "python.envFile": { + "type": "string", + "description": "Absolute path to a file containing environment variable definitions.", + "default": "${workspaceRoot}/.env", + "scope": "resource" + }, + "python.jediPath": { + "type": "string", + "default": "", + "description": "Path to directory containing the Jedi library (this path will contain the 'Jedi' sub directory).", + "scope": "resource" + }, + "python.sortImports.path": { + "type": "string", + "description": "Path to isort script, default using inner version", + "default": "", + "scope": "resource" + }, + "python.sortImports.args": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.disablePromptForFeatures": { + "type": "array", + "default": [], + "description": "Do not display a prompt to install these features", + "items": { + "type": "string", + "default": "pylint", + "description": "Feature", + "enum": [ + "flake8", + "mypy", + "pep8", + "pylama", + "prospector", + "pydocstyle", + "pylint" + ] + }, + "scope": "resource" + }, + "python.linting.enabled": { + "type": "boolean", + "default": true, + "description": "Whether to lint Python files.", + "scope": "resource" + }, + "python.linting.enabledWithoutWorkspace": { + "type": "boolean", + "default": true, + "description": "Whether to lint Python files when no workspace is opened.", + "scope": "resource" + }, + "python.linting.prospectorEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using prospector.", + "scope": "resource" + }, + "python.linting.pylintEnabled": { + "type": "boolean", + "default": true, + "description": "Whether to lint Python files using pylint.", + "scope": "resource" + }, + "python.linting.pep8Enabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using pep8", + "scope": "resource" + }, + "python.linting.flake8Enabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using flake8", + "scope": "resource" + }, + "python.linting.pydocstyleEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using pydocstyle", + "scope": "resource" + }, + "python.linting.mypyEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using mypy.", + "scope": "resource" + }, + "python.linting.lintOnTextChange": { + "type": "boolean", + "default": true, + "description": "Whether to lint Python files when modified.", + "scope": "resource" + }, + "python.linting.lintOnSave": { + "type": "boolean", + "default": true, + "description": "Whether to lint Python files when saved.", + "scope": "resource" + }, + "python.linting.maxNumberOfProblems": { + "type": "number", + "default": 100, + "description": "Controls the maximum number of problems produced by the server.", + "scope": "resource" + }, + "python.linting.pylintCategorySeverity.convention": { + "type": "string", + "default": "Information", + "description": "Severity of Pylint message type 'Convention/C'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pylintCategorySeverity.refactor": { + "type": "string", + "default": "Hint", + "description": "Severity of Pylint message type 'Refactor/R'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pylintCategorySeverity.warning": { + "type": "string", + "default": "Warning", + "description": "Severity of Pylint message type 'Warning/W'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pylintCategorySeverity.error": { + "type": "string", + "default": "Error", + "description": "Severity of Pylint message type 'Error/E'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pylintCategorySeverity.fatal": { + "type": "string", + "default": "Error", + "description": "Severity of Pylint message type 'Fatal/F'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pep8CategorySeverity.W": { + "type": "string", + "default": "Warning", + "description": "Severity of Pep8 message type 'W'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.pep8CategorySeverity.E": { + "type": "string", + "default": "Error", + "description": "Severity of Pep8 message type 'E'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.flake8CategorySeverity.F": { + "type": "string", + "default": "Error", + "description": "Severity of Flake8 message type 'F'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.flake8CategorySeverity.E": { + "type": "string", + "default": "Error", + "description": "Severity of Flake8 message type 'E'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.flake8CategorySeverity.W": { + "type": "string", + "default": "Warning", + "description": "Severity of Flake8 message type 'W'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.mypyCategorySeverity.error": { + "type": "string", + "default": "Error", + "description": "Severity of Mypy message type 'Error'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.mypyCategorySeverity.note": { + "type": "string", + "default": "Information", + "description": "Severity of Mypy message type 'Note'.", + "enum": [ + "Hint", + "Error", + "Information", + "Warning" + ], + "scope": "resource" + }, + "python.linting.prospectorPath": { + "type": "string", + "default": "prospector", + "description": "Path to Prospector, you can use a custom version of prospector by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.pylintPath": { + "type": "string", + "default": "pylint", + "description": "Path to Pylint, you can use a custom version of pylint by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.pep8Path": { + "type": "string", + "default": "pep8", + "description": "Path to pep8, you can use a custom version of pep8 by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.flake8Path": { + "type": "string", + "default": "flake8", + "description": "Path to flake8, you can use a custom version of flake8 by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.pydocstylePath": { + "type": "string", + "default": "pydocstyle", + "description": "Path to pydocstyle, you can use a custom version of pydocstyle by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.mypyPath": { + "type": "string", + "default": "mypy", + "description": "Path to mypy, you can use a custom version of mypy by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.prospectorArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.pylintArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.pep8Args": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.flake8Args": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.pydocstyleArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.mypyArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [ + "--ignore-missing-imports", + "--follow-imports=silent" + ], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.outputWindow": { + "type": "string", + "default": "Python", + "description": "The output window name for the linting messages, defaults to Python output window.", + "scope": "resource" + }, + "python.formatting.provider": { + "type": "string", + "default": "autopep8", + "description": "Provider for formatting. Possible options include 'autopep8' and 'yapf'.", + "enum": [ + "autopep8", + "yapf", + "none" + ], + "scope": "resource" + }, + "python.formatting.autopep8Path": { + "type": "string", + "default": "autopep8", + "description": "Path to autopep8, you can use a custom version of autopep8 by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.formatting.yapfPath": { + "type": "string", + "default": "yapf", + "description": "Path to yapf, you can use a custom version of yapf by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.formatting.autopep8Args": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.formatting.yapfArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.formatting.formatOnSave": { + "type": "boolean", + "default": false, + "description": "Format the document upon saving.", + "scope": "resource" + }, + "python.formatting.outputWindow": { + "type": "string", + "default": "Python", + "description": "The output window name for the formatting messages, defaults to Python output window.", + "scope": "resource" + }, + "python.autoComplete.preloadModules": { + "type": "array", + "items": { + "type": "string" + }, + "default": [], + "description": "Comma delimited list of modules preloaded to speed up Auto Complete (e.g. add Numpy, Pandas, etc, items slow to load when autocompleting).", + "scope": "resource" + }, + "python.autoComplete.extraPaths": { + "type": "array", + "default": [], + "description": "List of paths to libraries and the like that need to be imported by auto complete engine. E.g. when using Google App SDK, the paths are not in system path, hence need to be added into this list.", + "scope": "resource" + }, + "python.autoComplete.addBrackets": { + "type": "boolean", + "default": false, + "description": "Automatically add brackets for functions.", + "scope": "resource" + }, + "python.workspaceSymbols.tagFilePath": { + "type": "string", + "default": "${workspaceRoot}/.vscode/tags", + "description": "Fully qualified path to tag file (exuberant ctag file), used to provide workspace symbols.", + "scope": "resource" + }, + "python.workspaceSymbols.enabled": { + "type": "boolean", + "default": true, + "description": "Set to 'false' to disable Workspace Symbol provider using ctags.", + "scope": "resource" + }, + "python.workspaceSymbols.rebuildOnStart": { + "type": "boolean", + "default": true, + "description": "Whether to re-build the tags file on start (defaults to true).", + "scope": "resource" + }, + "python.workspaceSymbols.rebuildOnFileSave": { + "type": "boolean", + "default": true, + "description": "Whether to re-build the tags file on when changes made to python files are saved.", + "scope": "resource" + }, + "python.workspaceSymbols.ctagsPath": { + "type": "string", + "default": "ctags", + "description": "Fully qualilified path to the ctags executable (else leave as ctags, assuming it is in current path).", + "scope": "resource" + }, + "python.workspaceSymbols.exclusionPatterns": { + "type": "array", + "default": [ + "**/site-packages/**" + ], + "items": { + "type": "string" + }, + "description": "Pattern used to exclude files and folders from ctags See http://ctags.sourceforge.net/ctags.html.", + "scope": "resource" + }, + "python.unitTest.promptToConfigure": { + "type": "boolean", + "default": true, + "description": "Where to prompt to configure a test framework if potential tests directories are discovered.", + "scope": "resource" + }, + "python.unitTest.debugPort": { + "type": "number", + "default": 3000, + "description": "Port number used for debugging of unittests.", + "scope": "resource" + }, + "python.unitTest.cwd": { + "type": "string", + "default": null, + "description": "Optional working directory for unit tests.", + "scope": "resource" + }, + "python.unitTest.nosetestsEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to enable or disable unit testing using nosetests.", + "scope": "resource" + }, + "python.unitTest.nosetestPath": { + "type": "string", + "default": "nosetests", + "description": "Path to nosetests, you can use a custom version of nosetests by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.unitTest.pyTestEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to enable or disable unit testing using pytest.", + "scope": "resource" + }, + "python.unitTest.pyTestPath": { + "type": "string", + "default": "py.test", + "description": "Path to pytest (py.test), you can use a custom version of pytest by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.unitTest.nosetestArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.unitTest.pyTestArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.unitTest.unittestEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to enable or disable unit testing using unittest.", + "scope": "resource" + }, + "python.unitTest.unittestArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [ + "-v", + "-s", + ".", + "-p", + "*test*.py" + ], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.ignorePatterns": { + "type": "array", + "description": "Patterns used to exclude files or folders from being linted.", + "default": [ + ".vscode/*.py", + "**/site-packages/**/*.py" + ], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.linting.pylamaEnabled": { + "type": "boolean", + "default": false, + "description": "Whether to lint Python files using pylama.", + "scope": "resource" + }, + "python.linting.pylamaPath": { + "type": "string", + "default": "pylama", + "description": "Path to pylama, you can use a custom version of pylama by modifying this setting to include the full path.", + "scope": "resource" + }, + "python.linting.pylamaArgs": { + "type": "array", + "description": "Arguments passed in. Each argument is a separate item in the array.", + "default": [], + "items": { + "type": "string" + }, + "scope": "resource" + }, + "python.unitTest.outputWindow": { + "type": "string", + "default": "Python Test Log", + "description": "The output window name for the unit test messages, defaults to Python output window.", + "scope": "resource" + }, + "python.terminal.executeInFileDir": { + "type": "boolean", + "default": false, + "description": "When executing a file in the terminal, whether to use execute in the file's directory, instead of the current open folder.", + "scope": "resource" + }, + "python.terminal.launchArgs": { + "type": "array", + "default": [], + "description": "Python launch arguments to use when executing a file in the terminal.", + "scope": "resource" + }, + "python.jupyter.appendResults": { + "type": "boolean", + "default": true, + "description": "Whether to appen the results to results window, else clear and display.", + "scope": "resource" + }, + "python.jupyter.defaultKernel": { + "type": "string", + "default": "", + "description": "Default kernel to be used. By default the first available kernel is used.", + "scope": "resource" + }, + "python.jupyter.startupCode": { + "type": "array", + "items": { + "type": "string" + }, + "default": [ + "%matplotlib inline" + ], + "description": "Code executed when the kernel starts. Such as the default of '%matplotlib inline'. Individual lines can be placed in separate items of the array.", + "scope": "resource" + } + } + }, + "languages": [ + { + "id": "pip-requirements", + "aliases": [ + "pip requirements", + "requirements.txt" + ], + "filenames": [ + "requirements.txt" + ], + "filenamePatterns": [ + "*-requirements.txt", + "requirements-*.txt" + ], + "configuration": "./languages/pip-requirements.json" + } + ], + "grammars": [ + { + "language": "pip-requirements", + "scopeName": "source.pip-requirements", + "path": "./syntaxes/pip-requirements.tmLanguage.json" + } + ] + }, + "scripts": { + "vscode:prepublish": "tsc -p ./ && webpack", + "compile": "webpack && tsc -watch -p ./", + "postinstall": "node ./node_modules/vscode/bin/install", + "test": "node ./out/test/standardTest.js && node ./out/test/multiRootTest.js", + "precommit": "node gulpfile.js", + "lint-staged": "node gulpfile.js", + "lint": "tslint src/**/*.ts -t verbose" + }, + "dependencies": { + "diff-match-patch": "^1.0.0", + "fs-extra": "^4.0.2", + "fuzzy": "^0.1.3", + "line-by-line": "^0.1.5", + "lodash": "^4.17.4", + "minimatch": "^3.0.3", + "named-js-regexp": "^1.3.1", + "rx": "^4.1.0", + "semver": "^5.4.1", + "socket.io": "^1.4.8", + "tmp": "0.0.29", + "tree-kill": "^1.1.0", + "uint64be": "^1.0.1", + "untildify": "^3.0.2", + "vscode-debugadapter": "^1.0.1", + "vscode-debugprotocol": "^1.0.1", + "vscode-extension-telemetry": "^0.0.5", + "vscode-languageclient": "^3.1.0", + "vscode-languageserver": "^3.1.0", + "winreg": "^1.2.4", + "xml2js": "^0.4.17" + }, + "devDependencies": { + "@types/chai": "^4.0.4", + "@types/chai-as-promised": "^7.1.0", + "@types/fs-extra": "^4.0.2", + "@types/jquery": "^1.10.31", + "@types/lodash": "^4.14.74", + "@types/mocha": "^2.2.43", + "@types/node": "^6.0.40", + "@types/rx": "^2.5.33", + "@types/semver": "^5.4.0", + "@types/sinon": "^2.3.2", + "@types/socket.io": "^1.4.27", + "@types/socket.io-client": "^1.4.27", + "@types/uuid": "^3.3.27", + "@types/winreg": "^1.2.30", + "@types/xml2js": "^0.4.0", + "babel-core": "^6.14.0", + "babel-loader": "^6.2.5", + "babel-preset-es2015": "^6.14.0", + "chai": "^4.1.2", + "chai-as-promised": "^7.1.1", + "event-stream": "^3.3.4", + "gulp": "^3.9.1", + "gulp-filter": "^5.0.1", + "gulp-typescript": "^3.2.2", + "husky": "^0.14.3", + "ignore-loader": "^0.1.1", + "mocha": "^2.3.3", + "relative": "^3.0.2", + "retyped-diff-match-patch-tsd-ambient": "^1.0.0-0", + "sinon": "^2.3.6", + "transformime": "^3.1.2", + "transformime-marked": "0.0.1", + "ts-loader": "^2.3.4", + "tslint": "^5.7.0", + "tslint-eslint-rules": "^4.1.1", + "tslint-microsoft-contrib": "^5.0.1", + "typescript": "^2.5.2", + "typescript-formatter": "^6.0.0", + "webpack": "^1.13.2", + "vscode": "^1.1.5" + }, + "__metadata": { + "id": "f1f59ae4-9318-4f3c-a9b5-81b2eaa5f8a5", + "publisherDisplayName": "Don Jayamanne", + "publisherId": "1ba8bd00-2ad1-4be0-a007-5b4b954c1ee7" + } +} \ No newline at end of file diff --git a/src/client/common/commands.ts b/src/client/common/commands.ts new file mode 100644 index 000000000000..82e769b0ae2e --- /dev/null +++ b/src/client/common/commands.ts @@ -0,0 +1,46 @@ +// import { interfaces } from 'inversify'; +// import { commands, Disposable, window } from 'vscode'; +// import { getServiceContainer } from '../ioc/index'; + +// // tslint:disable-next-line:no-any +// type CommandHandler = (...args: any[]) => any; +// // tslint:disable-next-line:no-stateless-class +// export class CommandRegister implements Disposable { +// private static disposables: Disposable[] = []; +// // tslint:disable-next-line:no-any function-name +// public static register(commandName: string, handler: CommandHandler) { +// const disposable = commands.registerCommand(commandName, handler); +// CommandRegister.disposables.push(disposable); +// } +// public dispose() { +// CommandRegister.disposables.forEach(disposable => disposable.dispose()); +// CommandRegister.disposables = []; +// } +// } +// // const container = getDiContainer(); + +// // tslint:disable-next-line:no-any function-name +// export function command(commandName: string, serviceIdentifier: interfaces.ServiceIdentifier) { +// // tslint:disable-next-line:no-function-expression no-any +// return function (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor) { +// // tslint:disable-next-line:no-function-expression +// CommandRegister.register(commandName, async function () { +// try { +// // hack hack (but this preserves context) +// const container = getServiceContainer(); +// const newTarget = container.get(serviceIdentifier) as { propertyKey: Function }; +// const value = newTarget[propertyKey].call(newTarget, ...Array.from(arguments)); +// // const value = descriptor.value!.call(target, ...Array.from(arguments)); +// // If its a promise await the value +// if (value && value.then && value.catch) { +// await value; +// } +// } +// catch (reason) { +// console.error(`Failed to execute the command ${commandName}`, reason); +// window.showErrorMessage(`Failed to execute '${commandName}'. ${reason}`); +// } +// }); +// return descriptor; +// }; +// } diff --git a/src/client/debugger/Main.ts b/src/client/debugger/Main.ts index 8c7d3a71bd79..a3e98ae92c1a 100644 --- a/src/client/debugger/Main.ts +++ b/src/client/debugger/Main.ts @@ -12,7 +12,6 @@ import { BaseDebugServer } from "./DebugServers/BaseDebugServer"; import { DebugClient } from "./DebugClients/DebugClient"; import { CreateAttachDebugClient, CreateLaunchDebugClient } from "./DebugClients/DebugFactory"; import { LaunchRequestArguments, AttachRequestArguments, DebugOptions, TelemetryEvent, PythonEvaluationResultFlags } from "./Common/Contracts"; -import * as telemetryContracts from "../common/telemetryContracts"; import { validatePath, getPythonExecutable } from './Common/Utils'; import { isNotInstalledError } from '../common/helpers'; @@ -274,7 +273,7 @@ export class PythonDebugger extends DebugSession { this.sendEvent(new TerminatedEvent()); } protected attachRequest(response: DebugProtocol.AttachResponse, args: AttachRequestArguments) { - this.sendEvent(new TelemetryEvent(telemetryContracts.Debugger.Attach)); + // this.sendEvent(new TelemetryEvent(telemetryContracts.Debugger.Attach)); this.attachArgs = args; this.debugClient = CreateAttachDebugClient(args, this); this.entryResponse = response; diff --git a/src/client/jupyter/editorIntegration/codeLensProvider.ts b/src/client/jupyter/editorIntegration/codeLensProvider.ts index 908bdd3a6d0d..a0548848aabf 100644 --- a/src/client/jupyter/editorIntegration/codeLensProvider.ts +++ b/src/client/jupyter/editorIntegration/codeLensProvider.ts @@ -1,7 +1,6 @@ 'use strict'; -import {CodeLensProvider, TextDocument, CancellationToken, CodeLens, Command} from 'vscode'; -import * as telemetryContracts from '../../common/telemetryContracts'; +import {CancellationToken, CodeLens, CodeLensProvider, Command, TextDocument} from 'vscode'; import {Commands} from '../../common/constants'; import {CellHelper} from '../common/cellHelper'; @@ -37,4 +36,4 @@ export class JupyterCodeLensProvider implements CodeLensProvider { this.cache.push({ fileName: document.fileName, documentVersion: document.version, lenses: lenses }); return Promise.resolve(lenses); } -} \ No newline at end of file +} diff --git a/src/client/jupyter/editorIntegration/symbolProvider.ts b/src/client/jupyter/editorIntegration/symbolProvider.ts index 4c9a49a6fa04..64afc98d3eb2 100644 --- a/src/client/jupyter/editorIntegration/symbolProvider.ts +++ b/src/client/jupyter/editorIntegration/symbolProvider.ts @@ -1,6 +1,5 @@ 'use strict'; -import {DocumentSymbolProvider, TextDocument, CancellationToken, SymbolInformation, SymbolKind} from 'vscode'; -import * as telemetryContracts from '../../common/telemetryContracts'; +import {CancellationToken, DocumentSymbolProvider, SymbolInformation, SymbolKind, TextDocument} from 'vscode'; import {CellHelper} from '../common/cellHelper'; export class JupyterSymbolProvider implements DocumentSymbolProvider { diff --git a/src/client/linters/baseLinter.ts b/src/client/linters/baseLinter.ts index 46c89d16dff9..4b4f1d61541e 100644 --- a/src/client/linters/baseLinter.ts +++ b/src/client/linters/baseLinter.ts @@ -1,11 +1,13 @@ 'use strict'; -import { IPythonSettings, PythonSettings } from '../common/configSettings'; -import { execPythonFile } from './../common/utils'; +import * as path from 'path'; import { OutputChannel, Uri } from 'vscode'; -import { Installer, Product } from '../common/installer'; import * as vscode from 'vscode'; +import { IPythonSettings, PythonSettings } from '../common/configSettings'; +import { Installer, Product } from '../common/installer'; +import { execPythonFile } from './../common/utils'; import { ErrorHandler } from './errorHandlers/main'; +// tslint:disable-next-line:variable-name let NamedRegexp = null; const REGEX = '(?\\d+),(?\\d+),(?\\w+),(?\\w\\d+):(?.*)\\r?(\\n|$)'; @@ -35,11 +37,12 @@ export enum LintMessageSeverity { export function matchNamedRegEx(data, regex): IRegexGroup { if (NamedRegexp === null) { + // tslint:disable-next-line:no-require-imports NamedRegexp = require('named-js-regexp'); } - let compiledRegexp = NamedRegexp(regex, 'g'); - let rawMatch = compiledRegexp.exec(data); + const compiledRegexp = NamedRegexp(regex, 'g'); + const rawMatch = compiledRegexp.exec(data); if (rawMatch !== null) { return rawMatch.groups(); } @@ -47,31 +50,56 @@ export function matchNamedRegEx(data, regex): IRegexGroup { return null; } +type LinterId = 'flake8' | 'mypy' | 'pep8' | 'prospector' | 'pydocstyle' | 'pylama' | 'pylint'; export abstract class BaseLinter { - public Id: string; + // tslint:disable-next-line:variable-name + public Id: LinterId; + // tslint:disable-next-line:variable-name protected _columnOffset = 0; + // tslint:disable-next-line:variable-name private _errorHandler: ErrorHandler; + // tslint:disable-next-line:variable-name private _pythonSettings: IPythonSettings; protected get pythonSettings(): IPythonSettings { return this._pythonSettings; } - protected getWorkspaceRootPath(document: vscode.TextDocument): string { - const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri); - const workspaceRootPath = (workspaceFolder && typeof workspaceFolder.uri.fsPath === 'string') ? workspaceFolder.uri.fsPath : undefined; - return typeof workspaceRootPath === 'string' ? workspaceRootPath : __dirname; - } - constructor(id: string, public product: Product, protected outputChannel: OutputChannel) { + constructor(id: LinterId, public product: Product, protected outputChannel: OutputChannel) { this.Id = id; this._errorHandler = new ErrorHandler(this.Id, product, new Installer(), this.outputChannel); } + public isEnabled(resource: Uri) { + this._pythonSettings = PythonSettings.getInstance(resource); + const enabledSetting = `${this.Id}Enabled`; + // tslint:disable-next-line:prefer-type-cast + return this._pythonSettings.linting[enabledSetting] as boolean; + } + public linterArgs(resource: Uri) { + this._pythonSettings = PythonSettings.getInstance(resource); + const argsSetting = `${this.Id}Args`; + // tslint:disable-next-line:prefer-type-cast + return this._pythonSettings.linting[argsSetting] as string[]; + } + public isLinterExecutableSpecified(resource: Uri) { + this._pythonSettings = PythonSettings.getInstance(resource); + const argsSetting = `${this.Id}Path`; + // tslint:disable-next-line:prefer-type-cast + const executablePath = this._pythonSettings.linting[argsSetting] as string; + return path.basename(executablePath).length > 0 && path.basename(executablePath) !== executablePath; + } public lint(document: vscode.TextDocument, cancellation: vscode.CancellationToken): Promise { this._pythonSettings = PythonSettings.getInstance(document.uri); return this.runLinter(document, cancellation); } + protected getWorkspaceRootPath(document: vscode.TextDocument): string { + const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri); + const workspaceRootPath = (workspaceFolder && typeof workspaceFolder.uri.fsPath === 'string') ? workspaceFolder.uri.fsPath : undefined; + return typeof workspaceRootPath === 'string' ? workspaceRootPath : __dirname; + } protected abstract runLinter(document: vscode.TextDocument, cancellation: vscode.CancellationToken): Promise; + // tslint:disable-next-line:no-any protected parseMessagesSeverity(error: string, categorySeverity: any): LintMessageSeverity { if (categorySeverity[error]) { - let severityName = categorySeverity[error]; + const severityName = categorySeverity[error]; switch (severityName) { case 'Error': return LintMessageSeverity.Error; @@ -83,6 +111,7 @@ export abstract class BaseLinter { return LintMessageSeverity.Warning; default: { if (LintMessageSeverity[severityName]) { + // tslint:disable-next-line:no-any return LintMessageSeverity[severityName]; } } @@ -91,14 +120,32 @@ export abstract class BaseLinter { return LintMessageSeverity.Information; } + protected run(command: string, args: string[], document: vscode.TextDocument, cwd: string, cancellation: vscode.CancellationToken, regEx: string = REGEX): Promise { + return execPythonFile(document.uri, command, args, cwd, true, null, cancellation).then(data => { + if (!data) { + data = ''; + } + this.displayLinterResultHeader(data); + const outputLines = data.split(/\r?\n/g); + return this.parseLines(outputLines, regEx); + }).catch(error => { + this.handleError(this.Id, command, error, document.uri); + return []; + }); + } + protected handleError(expectedFileName: string, fileName: string, error: Error, resource: Uri) { + this._errorHandler.handleError(expectedFileName, fileName, error, resource); + } private parseLine(line: string, regEx: string) { - let match = matchNamedRegEx(line, regEx); + const match = matchNamedRegEx(line, regEx); if (!match) { return; } + // tslint:disable-next-line:no-any match.line = Number(match.line); + // tslint:disable-next-line:no-any match.column = Number(match.column); return { @@ -111,15 +158,14 @@ export abstract class BaseLinter { }; } private parseLines(outputLines: string[], regEx: string) { - let diagnostics: ILintMessage[] = []; + const diagnostics: ILintMessage[] = []; outputLines.filter((value, index) => index <= this.pythonSettings.linting.maxNumberOfProblems).forEach(line => { try { - let msg = this.parseLine(line, regEx); + const msg = this.parseLine(line, regEx); if (msg) { diagnostics.push(msg); } - } - catch (ex) { + } catch (ex) { // Hmm, need to handle this later // TODO: } @@ -127,24 +173,7 @@ export abstract class BaseLinter { return diagnostics; } private displayLinterResultHeader(data: string) { - this.outputChannel.append('#'.repeat(10) + 'Linting Output - ' + this.Id + '#'.repeat(10) + '\n'); + this.outputChannel.append(`${'#'.repeat(10)}Linting Output - ${this.Id}${'#'.repeat(10)}\n`); this.outputChannel.append(data); } - protected run(command: string, args: string[], document: vscode.TextDocument, cwd: string, cancellation: vscode.CancellationToken, regEx: string = REGEX): Promise { - return execPythonFile(document.uri, command, args, cwd, true, null, cancellation).then(data => { - if (!data) { - data = ''; - } - this.displayLinterResultHeader(data); - let outputLines = data.split(/\r?\n/g); - return this.parseLines(outputLines, regEx); - }).catch(error => { - this.handleError(this.Id, command, error, document.uri); - return []; - }); - } - - protected handleError(expectedFileName: string, fileName: string, error: Error, resource: Uri) { - this._errorHandler.handleError(expectedFileName, fileName, error, resource); - } } diff --git a/src/client/providers/completionProvider.ts b/src/client/providers/completionProvider.ts index a72e45a679bf..78b665d8b795 100644 --- a/src/client/providers/completionProvider.ts +++ b/src/client/providers/completionProvider.ts @@ -1,14 +1,13 @@ 'use strict'; -import * as vscode from 'vscode'; -import * as proxy from './jediProxy'; -import * as telemetryHelper from '../common/telemetry'; -import * as telemetryContracts from '../common/telemetryContracts'; -import { extractSignatureAndDocumentation } from './jediHelpers'; import { EOL } from 'os'; +import * as vscode from 'vscode'; +import { ProviderResult, SnippetString, Uri } from 'vscode'; import { PythonSettings } from '../common/configSettings'; -import { SnippetString, Uri } from 'vscode'; +import { captureTelemetry, COMPLETION } from '../common/telemetry'; import { JediFactory } from '../languageServices/jediProxyFactory'; +import { extractSignatureAndDocumentation } from './jediHelpers'; +import * as proxy from './jediProxy'; export class PythonCompletionItemProvider implements vscode.CompletionItemProvider { @@ -17,13 +16,13 @@ export class PythonCompletionItemProvider implements vscode.CompletionItemProvid if (data && data.items.length > 0) { return data.items.map(item => { const sigAndDocs = extractSignatureAndDocumentation(item); - let completionItem = new vscode.CompletionItem(item.text); + const completionItem = new vscode.CompletionItem(item.text); completionItem.kind = item.type; completionItem.documentation = sigAndDocs[1].length === 0 ? item.description : sigAndDocs[1]; completionItem.detail = sigAndDocs[0].split(/\r?\n/).join(''); if (PythonSettings.getInstance(resource).autoComplete.addBrackets === true && (item.kind === vscode.SymbolKind.Function || item.kind === vscode.SymbolKind.Method)) { - completionItem.insertText = new SnippetString(item.text).appendText("(").appendTabstop().appendText(")"); + completionItem.insertText = new SnippetString(item.text).appendText('(').appendTabstop().appendText(')'); } // ensure the built in memebers are at the bottom @@ -33,7 +32,8 @@ export class PythonCompletionItemProvider implements vscode.CompletionItemProvid } return []; } - public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable { + @captureTelemetry(COMPLETION) + public provideCompletionItems(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): ProviderResult { if (position.character <= 0) { return Promise.resolve([]); } @@ -62,12 +62,8 @@ export class PythonCompletionItemProvider implements vscode.CompletionItemProvid source: source }; - const timer = new telemetryHelper.Delays(); return this.jediFactory.getJediProxyHandler(document.uri).sendCommand(cmd, token).then(data => { - timer.stop(); - telemetryHelper.sendTelemetryEvent(telemetryContracts.IDE.Completion, {}, timer.toMeasures()); - const completions = PythonCompletionItemProvider.parseData(data, document.uri); - return completions; + return PythonCompletionItemProvider.parseData(data, document.uri); }); } -} \ No newline at end of file +} diff --git a/src/client/providers/definitionProvider.ts b/src/client/providers/definitionProvider.ts index 9fd32b58c222..3d98e8f3e269 100644 --- a/src/client/providers/definitionProvider.ts +++ b/src/client/providers/definitionProvider.ts @@ -1,9 +1,9 @@ 'use strict'; import * as vscode from 'vscode'; -import * as proxy from './jediProxy'; -import * as telemetryContracts from '../common/telemetryContracts'; +import { captureTelemetry, DEFINITION } from '../common/telemetry'; import { JediFactory } from '../languageServices/jediProxyFactory'; +import * as proxy from './jediProxy'; export class PythonDefinitionProvider implements vscode.DefinitionProvider { public constructor(private jediFactory: JediFactory) { } @@ -19,8 +19,9 @@ export class PythonDefinitionProvider implements vscode.DefinitionProvider { } return null; } + @captureTelemetry(DEFINITION) public provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Thenable { - var filename = document.fileName; + const filename = document.fileName; if (document.lineAt(position.line).text.match(/^\s*\/\//)) { return Promise.resolve(null); } @@ -28,9 +29,9 @@ export class PythonDefinitionProvider implements vscode.DefinitionProvider { return Promise.resolve(null); } - var range = document.getWordRangeAtPosition(position); - var columnIndex = range.isEmpty ? position.character : range.end.character; - var cmd: proxy.ICommand = { + const range = document.getWordRangeAtPosition(position); + const columnIndex = range.isEmpty ? position.character : range.end.character; + const cmd: proxy.ICommand = { command: proxy.CommandType.Definitions, fileName: filename, columnIndex: columnIndex, @@ -39,7 +40,7 @@ export class PythonDefinitionProvider implements vscode.DefinitionProvider { if (document.isDirty) { cmd.source = document.getText(); } - let possibleWord = document.getText(range); + const possibleWord = document.getText(range); return this.jediFactory.getJediProxyHandler(document.uri).sendCommand(cmd, token).then(data => { return PythonDefinitionProvider.parseData(data, possibleWord); }); diff --git a/src/client/providers/hoverProvider.ts b/src/client/providers/hoverProvider.ts index 376150f298a8..d4c91a68d3ee 100644 --- a/src/client/providers/hoverProvider.ts +++ b/src/client/providers/hoverProvider.ts @@ -1,27 +1,28 @@ 'use strict'; -import * as vscode from 'vscode'; -import * as proxy from './jediProxy'; -import { highlightCode } from './jediHelpers'; import { EOL } from 'os'; +import * as vscode from 'vscode'; +import { captureTelemetry, HOVER_DEFINITION } from '../common/telemetry'; import { JediFactory } from '../languageServices/jediProxyFactory'; +import { highlightCode } from './jediHelpers'; +import * as proxy from './jediProxy'; export class PythonHoverProvider implements vscode.HoverProvider { public constructor(private jediFactory: JediFactory) { } private static parseData(data: proxy.IHoverResult, currentWord: string): vscode.Hover { - let results = []; - let capturedInfo: string[] = []; + const results = []; + const capturedInfo: string[] = []; data.items.forEach(item => { let { signature } = item; switch (item.kind) { case vscode.SymbolKind.Constructor: case vscode.SymbolKind.Function: case vscode.SymbolKind.Method: { - signature = 'def ' + signature; + signature = `def ${signature}`; break; } case vscode.SymbolKind.Class: { - signature = 'class ' + signature; + signature = `class ${signature}`; break; } default: { @@ -30,10 +31,10 @@ export class PythonHoverProvider implements vscode.HoverProvider { } if (item.docstring) { let lines = item.docstring.split(/\r?\n/); - // If the docstring starts with the signature, then remove those lines from the docstring + // If the docstring starts with the signature, then remove those lines from the docstring. if (lines.length > 0 && item.signature.indexOf(lines[0]) === 0) { lines.shift(); - let endIndex = lines.findIndex(line => item.signature.endsWith(line)); + const endIndex = lines.findIndex(line => item.signature.endsWith(line)); if (endIndex >= 0) { lines = lines.filter((line, index) => index > endIndex); } @@ -41,36 +42,38 @@ export class PythonHoverProvider implements vscode.HoverProvider { if (lines.length > 0 && item.signature.startsWith(currentWord) && lines[0].startsWith(currentWord) && lines[0].endsWith(')')) { lines.shift(); } - let descriptionWithHighlightedCode = highlightCode(lines.join(EOL)); - let hoverInfo = ['```python', signature, '```', descriptionWithHighlightedCode].join(EOL); - let key = signature + lines.join(''); - // Sometimes we have duplicate documentation, one with a period at the end - if (capturedInfo.indexOf(key) >= 0 || capturedInfo.indexOf(key + '.') >= 0) { + const descriptionWithHighlightedCode = highlightCode(lines.join(EOL)); + const hoverInfo = ['```python', signature, '```', descriptionWithHighlightedCode].join(EOL); + const key = signature + lines.join(''); + // Sometimes we have duplicate documentation, one with a period at the end. + if (capturedInfo.indexOf(key) >= 0 || capturedInfo.indexOf(`${key}.`) >= 0) { return; } capturedInfo.push(key); - capturedInfo.push(key + '.'); + capturedInfo.push(`${key}.`); results.push(hoverInfo); return; } if (item.description) { - let descriptionWithHighlightedCode = highlightCode(item.description); - let hoverInfo = '```python' + EOL + signature + EOL + '```' + EOL + descriptionWithHighlightedCode; - let lines = item.description.split(EOL); - let key = signature + lines.join(''); - // Sometimes we have duplicate documentation, one with a period at the end - if (capturedInfo.indexOf(key) >= 0 || capturedInfo.indexOf(key + '.') >= 0) { + const descriptionWithHighlightedCode = highlightCode(item.description); + // tslint:disable-next-line:prefer-template + const hoverInfo = '```python' + EOL + signature + EOL + '```' + EOL + descriptionWithHighlightedCode; + const lines = item.description.split(EOL); + const key = signature + lines.join(''); + // Sometimes we have duplicate documentation, one with a period at the end. + if (capturedInfo.indexOf(key) >= 0 || capturedInfo.indexOf(`${key}.`) >= 0) { return; } capturedInfo.push(key); - capturedInfo.push(key + '.'); + capturedInfo.push(`${key}.`); results.push(hoverInfo); } }); return new vscode.Hover(results); } + @captureTelemetry(HOVER_DEFINITION) public async provideHover(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): Promise { - var filename = document.fileName; + const filename = document.fileName; if (document.lineAt(position.line).text.match(/^\s*\/\//)) { return null; } @@ -78,12 +81,12 @@ export class PythonHoverProvider implements vscode.HoverProvider { return null; } - var range = document.getWordRangeAtPosition(position); + const range = document.getWordRangeAtPosition(position); if (!range || range.isEmpty) { return null; } - let word = document.getText(range); - var cmd: proxy.ICommand = { + const word = document.getText(range); + const cmd: proxy.ICommand = { command: proxy.CommandType.Hover, fileName: filename, columnIndex: range.end.character, diff --git a/src/client/providers/importSortProvider.ts b/src/client/providers/importSortProvider.ts index 9084547de29f..055f4147b0e3 100644 --- a/src/client/providers/importSortProvider.ts +++ b/src/client/providers/importSortProvider.ts @@ -5,9 +5,11 @@ import * as path from 'path'; import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { getTempFileWithDocumentContents, getTextEditsFromPatch } from '../common/editor'; +import { captureTelemetry, FORMAT_SORT_IMPORTS } from '../common/telemetry'; // tslint:disable-next-line:completed-docs export class PythonImportSortProvider { + @captureTelemetry(FORMAT_SORT_IMPORTS) public async sortImports(extensionDir: string, document: vscode.TextDocument): Promise { if (document.lineCount === 1) { return []; diff --git a/src/client/providers/jediProxy.ts b/src/client/providers/jediProxy.ts index 9b01703ba13a..6fdb26278c85 100644 --- a/src/client/providers/jediProxy.ts +++ b/src/client/providers/jediProxy.ts @@ -281,7 +281,7 @@ export class JediProxy implements vscode.Disposable { var index = this.commandQueue.indexOf(cmd.id); this.commandQueue.splice(index, 1); - if (cmd.delays && typeof cmd.telemetryEvent === 'string') { + if (cmd.delay && typeof cmd.telemetryEvent === 'string') { // cmd.delays.stop(); // telemetryHelper.sendTelemetryEvent(cmd.telemetryEvent, null, cmd.delays.toMeasures()); } @@ -589,7 +589,7 @@ interface IExecutionCommand extends ICommand { id?: number; deferred?: Deferred; token: vscode.CancellationToken; - delays?: telemetryHelper.Delays; + delay?: number; } export interface ICommandError { diff --git a/src/client/providers/lintProvider.ts b/src/client/providers/lintProvider.ts index b9b5b92107a7..02a6cb619b83 100644 --- a/src/client/providers/lintProvider.ts +++ b/src/client/providers/lintProvider.ts @@ -1,19 +1,22 @@ 'use strict'; +import { sendTelemetryEvent, sendTelemetryWhenDone, StopWatch, LINTING } from '../common/telemetry'; -import * as vscode from 'vscode'; +import * as fs from 'fs'; import * as path from 'path'; +import * as vscode from 'vscode'; +import { PythonSettings } from '../common/configSettings'; +import { LinterErrors } from '../common/constants'; import * as linter from '../linters/baseLinter'; -import * as prospector from './../linters/prospector'; -import * as pylint from './../linters/pylint'; -import * as pep8 from './../linters/pep8Linter'; -import * as pylama from './../linters/pylama'; import * as flake8 from './../linters/flake8'; -import * as pydocstyle from './../linters/pydocstyle'; import * as mypy from './../linters/mypy'; -import { PythonSettings } from '../common/configSettings'; -import * as fs from 'fs'; -import { LinterErrors } from '../common/constants'; -const Minimatch = require("minimatch").Minimatch; +import * as pep8 from './../linters/pep8Linter'; +import * as prospector from './../linters/prospector'; +import * as pydocstyle from './../linters/pydocstyle'; +import * as pylama from './../linters/pylama'; +import * as pylint from './../linters/pylint'; +import { BaseLinter } from '../linters/baseLinter'; +// tslint:disable-next-line:no-require-imports no-var-requires +const Minimatch = require('minimatch').Minimatch; const uriSchemesToIgnore = ['git', 'showModifications']; const lintSeverityToVSSeverity = new Map(); @@ -23,20 +26,22 @@ lintSeverityToVSSeverity.set(linter.LintMessageSeverity.Information, vscode.Diag lintSeverityToVSSeverity.set(linter.LintMessageSeverity.Warning, vscode.DiagnosticSeverity.Warning); function createDiagnostics(message: linter.ILintMessage, document: vscode.TextDocument): vscode.Diagnostic { - let position = new vscode.Position(message.line - 1, message.column); - let range = new vscode.Range(position, position); + const position = new vscode.Position(message.line - 1, message.column); + const range = new vscode.Range(position, position); - let severity = lintSeverityToVSSeverity.get(message.severity); - let diagnostic = new vscode.Diagnostic(range, message.code + ':' + message.message, severity); + const severity = lintSeverityToVSSeverity.get(message.severity); + const diagnostic = new vscode.Diagnostic(range, `${message.code}:${message.message}`, severity); diagnostic.code = message.code; diagnostic.source = message.provider; return diagnostic; } +// tslint:disable-next-line:interface-name interface DocumentHasJupyterCodeCells { + // tslint:disable-next-line:callable-types (doc: vscode.TextDocument, token: vscode.CancellationToken): Promise; } -export class LintProvider extends vscode.Disposable { +export class LintProvider implements vscode.Disposable { private diagnosticCollection: vscode.DiagnosticCollection; private linters: linter.BaseLinter[] = []; private pendingLintings = new Map(); @@ -45,13 +50,12 @@ export class LintProvider extends vscode.Disposable { private disposables: vscode.Disposable[]; public constructor(context: vscode.ExtensionContext, outputChannel: vscode.OutputChannel, public documentHasJupyterCodeCells: DocumentHasJupyterCodeCells) { - super(() => { }); this.outputChannel = outputChannel; this.context = context; this.disposables = []; this.initialize(); } - dispose() { + public dispose() { this.disposables.forEach(d => d.dispose()); } private isDocumentOpen(uri: vscode.Uri): boolean { @@ -74,7 +78,7 @@ export class LintProvider extends vscode.Disposable { if (e.languageId !== 'python' || !settings.linting.enabled || !settings.linting.lintOnSave) { return; } - this.lintDocument(e, 100); + this.lintDocument(e, 100, 'save'); }); this.context.subscriptions.push(disposable); @@ -90,7 +94,7 @@ export class LintProvider extends vscode.Disposable { if (!e.uri.path || (path.basename(e.uri.path) === e.uri.path && !fs.existsSync(e.uri.path))) { return; } - this.lintDocument(e, 100); + this.lintDocument(e, 100, 'auto'); }, this.context.subscriptions); disposable = vscode.workspace.onDidCloseTextDocument(textDocument => { @@ -106,8 +110,9 @@ export class LintProvider extends vscode.Disposable { this.context.subscriptions.push(disposable); } + // tslint:disable-next-line:member-ordering private lastTimeout: number; - private lintDocument(document: vscode.TextDocument, delay: number): void { + private lintDocument(document: vscode.TextDocument, delay: number, trigger: 'auto' | 'save'): void { // Since this is a hack, lets wait for 2 seconds before linting // Give user to continue typing before we waste CPU time if (this.lastTimeout) { @@ -116,11 +121,10 @@ export class LintProvider extends vscode.Disposable { } this.lastTimeout = setTimeout(() => { - this.onLintDocument(document); + this.onLintDocument(document, trigger); }, delay); } - - private onLintDocument(document: vscode.TextDocument): void { + private onLintDocument(document: vscode.TextDocument, trigger: 'auto' | 'save'): void { // Check if we need to lint this document const workspaceFolder = vscode.workspace.getWorkspaceFolder(document.uri); const workspaceRootPath = (workspaceFolder && typeof workspaceFolder.uri.fsPath === 'string') ? workspaceFolder.uri.fsPath : undefined; @@ -138,7 +142,7 @@ export class LintProvider extends vscode.Disposable { this.pendingLintings.delete(document.uri.fsPath); } - let cancelToken = new vscode.CancellationTokenSource(); + const cancelToken = new vscode.CancellationTokenSource(); cancelToken.token.onCancellationRequested(() => { if (this.pendingLintings.has(document.uri.fsPath)) { this.pendingLintings.delete(document.uri.fsPath); @@ -147,15 +151,22 @@ export class LintProvider extends vscode.Disposable { this.pendingLintings.set(document.uri.fsPath, cancelToken); this.outputChannel.clear(); - let promises: Promise[] = this.linters.map(linter => { - if (typeof workspaceRootPath !== 'string' && !settings.linting.enabledWithoutWorkspace) { - return Promise.resolve([]); - } - return linter.lint(document, cancelToken.token); - }); + const promises: Promise[] = this.linters + .filter(item => item.isEnabled(document.uri)) + .map(item => { + if (typeof workspaceRootPath !== 'string' && !settings.linting.enabledWithoutWorkspace) { + return Promise.resolve([]); + } + const stopWatch = new StopWatch(); + const promise = item.lint(document, cancelToken.token); + const hasCustomArgs = item.linterArgs(document.uri).length > 0; + const executableSpecified = item.isLinterExecutableSpecified(document.uri); + sendTelemetryWhenDone(LINTING, promise, stopWatch, { tool: item.Id, hasCustomArgs, trigger, executableSpecified }); + return promise; + }); this.documentHasJupyterCodeCells(document, cancelToken.token).then(hasJupyterCodeCells => { - // linters will resolve asynchronously - keep a track of all - // diagnostics reported as them come in + // linters will resolve asynchronously - keep a track of all + // diagnostics reported as them come in. let diagnostics: vscode.Diagnostic[] = []; promises.forEach(p => { diff --git a/src/client/providers/objectDefinitionProvider.ts b/src/client/providers/objectDefinitionProvider.ts index b455c4ba1933..01c160b08774 100644 --- a/src/client/providers/objectDefinitionProvider.ts +++ b/src/client/providers/objectDefinitionProvider.ts @@ -1,8 +1,9 @@ 'use strict'; import * as vscode from 'vscode'; -import * as defProvider from './definitionProvider'; +import { captureTelemetry, GO_TO_OBJECT_DEFINITION } from '../common/telemetry'; import { JediFactory } from '../languageServices/jediProxyFactory'; +import * as defProvider from './definitionProvider'; export function activateGoToObjectDefinitionProvider(jediFactory: JediFactory): vscode.Disposable[] { const def = new PythonObjectDefinitionProvider(jediFactory); @@ -16,6 +17,7 @@ export class PythonObjectDefinitionProvider { this._defProvider = new defProvider.PythonDefinitionProvider(jediFactory); } + @captureTelemetry(GO_TO_OBJECT_DEFINITION) public async goToObjectDefinition() { let pathDef = await this.getObjectDefinition(); if (typeof pathDef !== 'string' || pathDef.length === 0) { diff --git a/src/client/providers/referenceProvider.ts b/src/client/providers/referenceProvider.ts index c8f2031cf5ed..714fe04e69a7 100644 --- a/src/client/providers/referenceProvider.ts +++ b/src/client/providers/referenceProvider.ts @@ -1,23 +1,24 @@ 'use strict'; import * as vscode from 'vscode'; -import * as proxy from './jediProxy'; +import { captureTelemetry, REFERENCE } from '../common/telemetry'; import { JediFactory } from '../languageServices/jediProxyFactory'; - +import * as proxy from './jediProxy'; export class PythonReferenceProvider implements vscode.ReferenceProvider { public constructor(private jediFactory: JediFactory) { } private static parseData(data: proxy.IReferenceResult): vscode.Location[] { if (data && data.references.length > 0) { - var references = data.references.filter(ref => { + // tslint:disable-next-line:no-unnecessary-local-variable + const references = data.references.filter(ref => { if (!ref || typeof ref.columnIndex !== 'number' || typeof ref.lineIndex !== 'number' || typeof ref.fileName !== 'string' || ref.columnIndex === -1 || ref.lineIndex === -1 || ref.fileName.length === 0) { return false; } return true; }).map(ref => { - var definitionResource = vscode.Uri.file(ref.fileName); - var range = new vscode.Range(ref.lineIndex, ref.columnIndex, ref.lineIndex, ref.columnIndex); + const definitionResource = vscode.Uri.file(ref.fileName); + const range = new vscode.Range(ref.lineIndex, ref.columnIndex, ref.lineIndex, ref.columnIndex); return new vscode.Location(definitionResource, range); }); @@ -27,8 +28,9 @@ export class PythonReferenceProvider implements vscode.ReferenceProvider { return []; } + @captureTelemetry(REFERENCE) public provideReferences(document: vscode.TextDocument, position: vscode.Position, context: vscode.ReferenceContext, token: vscode.CancellationToken): Thenable { - var filename = document.fileName; + const filename = document.fileName; if (document.lineAt(position.line).text.match(/^\s*\/\//)) { return Promise.resolve(null); } @@ -36,9 +38,9 @@ export class PythonReferenceProvider implements vscode.ReferenceProvider { return Promise.resolve(null); } - var range = document.getWordRangeAtPosition(position); - var columnIndex = range.isEmpty ? position.character : range.end.character; - var cmd: proxy.ICommand = { + const range = document.getWordRangeAtPosition(position); + const columnIndex = range.isEmpty ? position.character : range.end.character; + const cmd: proxy.ICommand = { command: proxy.CommandType.Usages, fileName: filename, columnIndex: columnIndex, diff --git a/src/client/providers/renameProvider.ts b/src/client/providers/renameProvider.ts index e65b915b856b..43ec20e62688 100644 --- a/src/client/providers/renameProvider.ts +++ b/src/client/providers/renameProvider.ts @@ -1,11 +1,12 @@ 'use strict'; -import * as vscode from 'vscode'; -import { RefactorProxy } from '../refactor/proxy'; -import { getWorkspaceEditsFromPatch } from '../common/editor'; import * as path from 'path'; +import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; +import { getWorkspaceEditsFromPatch } from '../common/editor'; import { Installer, Product } from '../common/installer'; +import { captureTelemetry, REFACTOR_RENAME } from '../common/telemetry'; +import { RefactorProxy } from '../refactor/proxy'; const EXTENSION_DIR = path.join(__dirname, '..', '..', '..'); interface RenameResponse { @@ -17,6 +18,7 @@ export class PythonRenameProvider implements vscode.RenameProvider { constructor(private outputChannel: vscode.OutputChannel) { this.installer = new Installer(outputChannel); } + @captureTelemetry(REFACTOR_RENAME) public provideRenameEdits(document: vscode.TextDocument, position: vscode.Position, newName: string, token: vscode.CancellationToken): Thenable { return vscode.workspace.saveAll(false).then(() => { return this.doRename(document, position, newName, token); @@ -31,7 +33,7 @@ export class PythonRenameProvider implements vscode.RenameProvider { return; } - var range = document.getWordRangeAtPosition(position); + const range = document.getWordRangeAtPosition(position); if (!range || range.isEmpty) { return; } @@ -47,7 +49,7 @@ export class PythonRenameProvider implements vscode.RenameProvider { const workspaceRoot = workspaceFolder ? workspaceFolder.uri.fsPath : __dirname; const pythonSettings = PythonSettings.getInstance(workspaceFolder ? workspaceFolder.uri : undefined); - let proxy = new RefactorProxy(EXTENSION_DIR, pythonSettings, workspaceRoot); + const proxy = new RefactorProxy(EXTENSION_DIR, pythonSettings, workspaceRoot); return proxy.rename(document, newName, document.uri.fsPath, range).then(response => { const fileDiffs = response.results.map(fileChanges => fileChanges.diff); return getWorkspaceEditsFromPatch(fileDiffs, workspaceRoot); @@ -55,8 +57,7 @@ export class PythonRenameProvider implements vscode.RenameProvider { if (reason === 'Not installed') { this.installer.promptToInstall(Product.rope, document.uri); return Promise.reject(''); - } - else { + } else { vscode.window.showErrorMessage(reason); this.outputChannel.appendLine(reason); } diff --git a/src/client/providers/replProvider.ts b/src/client/providers/replProvider.ts index 1ef8b6cffc8e..7146b5982944 100644 --- a/src/client/providers/replProvider.ts +++ b/src/client/providers/replProvider.ts @@ -1,6 +1,7 @@ import { commands, Disposable, Uri, window, workspace } from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { Commands } from '../common/constants'; +import { captureTelemetry, REPL } from '../common/telemetry'; import { getPathFromPythonCommand } from '../common/utils'; export class ReplProvider implements Disposable { @@ -15,6 +16,7 @@ export class ReplProvider implements Disposable { const disposable = commands.registerCommand(Commands.Start_REPL, this.commandHandler, this); this.disposables.push(disposable); } + @captureTelemetry(REPL) private async commandHandler() { const pythonPath = await this.getPythonPath(); if (!pythonPath) { diff --git a/src/client/providers/signatureProvider.ts b/src/client/providers/signatureProvider.ts index 5ed411ed47b6..7add3529ecf3 100644 --- a/src/client/providers/signatureProvider.ts +++ b/src/client/providers/signatureProvider.ts @@ -1,42 +1,42 @@ -"use strict"; +'use strict'; import * as vscode from 'vscode'; -import * as proxy from './jediProxy'; -import { TextDocument, Position, CancellationToken, SignatureHelp } from "vscode"; +import { CancellationToken, Position, SignatureHelp, TextDocument } from 'vscode'; +import { captureTelemetry, SIGNATURE } from '../common/telemetry'; import { JediFactory } from '../languageServices/jediProxyFactory'; +import * as proxy from './jediProxy'; const DOCSTRING_PARAM_PATTERNS = [ - "\\s*:type\\s*PARAMNAME:\\s*([^\\n, ]+)", // Sphinx - "\\s*:param\\s*(\\w?)\\s*PARAMNAME:[^\\n]+", // Sphinx param with type - "\\s*@type\\s*PARAMNAME:\\s*([^\\n, ]+)" // Epydoc + '\\s*:type\\s*PARAMNAME:\\s*([^\\n, ]+)', // Sphinx + '\\s*:param\\s*(\\w?)\\s*PARAMNAME:[^\\n]+', // Sphinx param with type + '\\s*@type\\s*PARAMNAME:\\s*([^\\n, ]+)' // Epydoc ]; /** - * Extrct the documentation for parameters from a given docstring - * + * Extract the documentation for parameters from a given docstring. * @param {string} paramName Name of the parameter * @param {string} docString The docstring for the function * @returns {string} Docstring for the parameter */ function extractParamDocString(paramName: string, docString: string): string { - let paramDocString = ""; + let paramDocString = ''; // In docstring the '*' is escaped with a backslash - paramName = paramName.replace(new RegExp("\\*", "g"), "\\\\\\*"); + paramName = paramName.replace(new RegExp('\\*', 'g'), '\\\\\\*'); DOCSTRING_PARAM_PATTERNS.forEach(pattern => { if (paramDocString.length > 0) { return; } - pattern = pattern.replace("PARAMNAME", paramName); - let regExp = new RegExp(pattern); - let matches = regExp.exec(docString); + pattern = pattern.replace('PARAMNAME', paramName); + const regExp = new RegExp(pattern); + const matches = regExp.exec(docString); if (matches && matches.length > 0) { paramDocString = matches[0]; - if (paramDocString.indexOf(":") >= 0) { - paramDocString = paramDocString.substring(paramDocString.indexOf(":") + 1); + if (paramDocString.indexOf(':') >= 0) { + paramDocString = paramDocString.substring(paramDocString.indexOf(':') + 1); } - if (paramDocString.indexOf(":") >= 0) { - paramDocString = paramDocString.substring(paramDocString.indexOf(":") + 1); + if (paramDocString.indexOf(':') >= 0) { + paramDocString = paramDocString.substring(paramDocString.indexOf(':') + 1); } } }); @@ -47,15 +47,14 @@ export class PythonSignatureProvider implements vscode.SignatureHelpProvider { public constructor(private jediFactory: JediFactory) { } private static parseData(data: proxy.IArgumentsResult): vscode.SignatureHelp { if (data && Array.isArray(data.definitions) && data.definitions.length > 0) { - let signature = new SignatureHelp(); + const signature = new SignatureHelp(); signature.activeSignature = 0; data.definitions.forEach(def => { signature.activeParameter = def.paramindex; - // Don't display the documentation, as vs code doesn't format the docmentation - // i.e. line feeds are not respected, long content is stripped - let sig = { - // documentation: def.docstring, + // Don't display the documentation, as vs code doesn't format the docmentation. + // i.e. line feeds are not respected, long content is stripped. + const sig = { label: def.description, parameters: [] }; @@ -75,8 +74,9 @@ export class PythonSignatureProvider implements vscode.SignatureHelpProvider { return new SignatureHelp(); } - provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): Thenable { - let cmd: proxy.ICommand = { + @captureTelemetry(SIGNATURE) + public provideSignatureHelp(document: TextDocument, position: Position, token: CancellationToken): Thenable { + const cmd: proxy.ICommand = { command: proxy.CommandType.Arguments, fileName: document.fileName, columnIndex: position.character, diff --git a/src/client/providers/simpleRefactorProvider.ts b/src/client/providers/simpleRefactorProvider.ts index 35f765165eb1..186c53a5801a 100644 --- a/src/client/providers/simpleRefactorProvider.ts +++ b/src/client/providers/simpleRefactorProvider.ts @@ -1,10 +1,11 @@ 'use strict'; import * as vscode from 'vscode'; -import { RefactorProxy } from '../refactor/proxy'; -import { getTextEditsFromPatch } from '../common/editor'; import { PythonSettings } from '../common/configSettings'; +import { getTextEditsFromPatch } from '../common/editor'; import { Installer, Product } from '../common/installer'; +import { REFACTOR_EXTRACT_FUNCTION, REFACTOR_EXTRACT_VAR, sendTelemetryWhenDone, StopWatch } from '../common/telemetry'; +import { RefactorProxy } from '../refactor/proxy'; interface RenameResponse { results: [{ diff: string }]; @@ -14,18 +15,24 @@ let installer: Installer; export function activateSimplePythonRefactorProvider(context: vscode.ExtensionContext, outputChannel: vscode.OutputChannel) { let disposable = vscode.commands.registerCommand('python.refactorExtractVariable', () => { - extractVariable(context.extensionPath, + const stopWatch = new StopWatch(); + const promise = extractVariable(context.extensionPath, vscode.window.activeTextEditor, vscode.window.activeTextEditor.selection, + // tslint:disable-next-line:no-empty outputChannel).catch(() => { }); + sendTelemetryWhenDone(REFACTOR_EXTRACT_VAR, promise, stopWatch); }); context.subscriptions.push(disposable); disposable = vscode.commands.registerCommand('python.refactorExtractMethod', () => { - extractMethod(context.extensionPath, + const stopWatch = new StopWatch(); + const promise = extractMethod(context.extensionPath, vscode.window.activeTextEditor, vscode.window.activeTextEditor.selection, + // tslint:disable-next-line:no-empty outputChannel).catch(() => { }); + sendTelemetryWhenDone(REFACTOR_EXTRACT_FUNCTION, promise, stopWatch); }); context.subscriptions.push(disposable); installer = new Installer(outputChannel); @@ -34,6 +41,7 @@ export function activateSimplePythonRefactorProvider(context: vscode.ExtensionCo // Exported for unit testing export function extractVariable(extensionDir: string, textEditor: vscode.TextEditor, range: vscode.Range, + // tslint:disable-next-line:no-any outputChannel: vscode.OutputChannel): Promise { let workspaceFolder = vscode.workspace.getWorkspaceFolder(textEditor.document.uri); @@ -44,9 +52,9 @@ export function extractVariable(extensionDir: string, textEditor: vscode.TextEdi const pythonSettings = PythonSettings.getInstance(workspaceFolder ? workspaceFolder.uri : undefined); return validateDocumentForRefactor(textEditor).then(() => { - let newName = 'newvariable' + new Date().getMilliseconds().toString(); - let proxy = new RefactorProxy(extensionDir, pythonSettings, workspaceRoot); - let rename = proxy.extractVariable(textEditor.document, newName, textEditor.document.uri.fsPath, range, textEditor.options).then(response => { + const newName = `newvariable${new Date().getMilliseconds().toString()}`; + const proxy = new RefactorProxy(extensionDir, pythonSettings, workspaceRoot); + const rename = proxy.extractVariable(textEditor.document, newName, textEditor.document.uri.fsPath, range, textEditor.options).then(response => { return response.results[0].diff; }); @@ -56,6 +64,7 @@ export function extractVariable(extensionDir: string, textEditor: vscode.TextEdi // Exported for unit testing export function extractMethod(extensionDir: string, textEditor: vscode.TextEditor, range: vscode.Range, + // tslint:disable-next-line:no-any outputChannel: vscode.OutputChannel): Promise { let workspaceFolder = vscode.workspace.getWorkspaceFolder(textEditor.document.uri); @@ -66,9 +75,9 @@ export function extractMethod(extensionDir: string, textEditor: vscode.TextEdito const pythonSettings = PythonSettings.getInstance(workspaceFolder ? workspaceFolder.uri : undefined); return validateDocumentForRefactor(textEditor).then(() => { - let newName = 'newmethod' + new Date().getMilliseconds().toString(); - let proxy = new RefactorProxy(extensionDir, pythonSettings, workspaceRoot); - let rename = proxy.extractMethod(textEditor.document, newName, textEditor.document.uri.fsPath, range, textEditor.options).then(response => { + const newName = `newmethod${new Date().getMilliseconds().toString()}`; + const proxy = new RefactorProxy(extensionDir, pythonSettings, workspaceRoot); + const rename = proxy.extractMethod(textEditor.document, newName, textEditor.document.uri.fsPath, range, textEditor.options).then(response => { return response.results[0].diff; }); @@ -76,17 +85,18 @@ export function extractMethod(extensionDir: string, textEditor: vscode.TextEdito }); } +// tslint:disable-next-line:no-any function validateDocumentForRefactor(textEditor: vscode.TextEditor): Promise { if (!textEditor.document.isDirty) { return Promise.resolve(); } + // tslint:disable-next-line:no-any return new Promise((resolve, reject) => { vscode.window.showInformationMessage('Please save changes before refactoring', 'Save').then(item => { if (item === 'Save') { textEditor.document.save().then(resolve, reject); - } - else { + } else { return reject(); } }); @@ -94,14 +104,14 @@ function validateDocumentForRefactor(textEditor: vscode.TextEditor): Promise, outputChannel: vscode.OutputChannel): Promise { let changeStartsAtLine = -1; return renameResponse.then(diff => { if (diff.length === 0) { return []; } - let edits = getTextEditsFromPatch(textEditor.document.getText(), diff); - return edits; + return getTextEditsFromPatch(textEditor.document.getText(), diff); }).then(edits => { return textEditor.edit(editBuilder => { edits.forEach(edit => { @@ -115,8 +125,8 @@ function extractName(extensionDir: string, textEditor: vscode.TextEditor, range: if (done && changeStartsAtLine >= 0) { let newWordPosition: vscode.Position; for (let lineNumber = changeStartsAtLine; lineNumber < textEditor.document.lineCount; lineNumber++) { - let line = textEditor.document.lineAt(lineNumber); - let indexOfWord = line.text.indexOf(newName); + const line = textEditor.document.lineAt(lineNumber); + const indexOfWord = line.text.indexOf(newName); if (indexOfWord >= 0) { newWordPosition = new vscode.Position(line.range.start.line, indexOfWord); break; diff --git a/src/client/providers/symbolProvider.ts b/src/client/providers/symbolProvider.ts index 78181b2a62e8..a8f367b134d0 100644 --- a/src/client/providers/symbolProvider.ts +++ b/src/client/providers/symbolProvider.ts @@ -1,14 +1,15 @@ 'use strict'; import * as vscode from 'vscode'; -import * as proxy from './jediProxy'; +import { captureTelemetry, SYMBOL } from '../common/telemetry'; import { JediFactory } from '../languageServices/jediProxyFactory'; +import * as proxy from './jediProxy'; export class PythonSymbolProvider implements vscode.DocumentSymbolProvider { public constructor(private jediFactory: JediFactory) { } private static parseData(document: vscode.TextDocument, data: proxy.ISymbolResult): vscode.SymbolInformation[] { if (data) { - let symbols = data.definitions.filter(sym => sym.fileName === document.fileName); + const symbols = data.definitions.filter(sym => sym.fileName === document.fileName); return symbols.map(sym => { const symbol = sym.kind; const range = new vscode.Range( @@ -21,10 +22,11 @@ export class PythonSymbolProvider implements vscode.DocumentSymbolProvider { } return []; } + @captureTelemetry(SYMBOL) public provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): Thenable { - var filename = document.fileName; + const filename = document.fileName; - var cmd: proxy.ICommand = { + const cmd: proxy.ICommand = { command: proxy.CommandType.Symbols, fileName: filename, columnIndex: 0, @@ -40,9 +42,9 @@ export class PythonSymbolProvider implements vscode.DocumentSymbolProvider { }); } public provideDocumentSymbolsForInternalUse(document: vscode.TextDocument, token: vscode.CancellationToken): Thenable { - var filename = document.fileName; + const filename = document.fileName; - var cmd: proxy.ICommand = { + const cmd: proxy.ICommand = { command: proxy.CommandType.Symbols, fileName: filename, columnIndex: 0, diff --git a/src/client/providers/updateSparkLibraryProvider.ts b/src/client/providers/updateSparkLibraryProvider.ts index 20defe5528b7..7a44e33864a8 100644 --- a/src/client/providers/updateSparkLibraryProvider.ts +++ b/src/client/providers/updateSparkLibraryProvider.ts @@ -1,7 +1,8 @@ -"use strict"; -import { Commands } from '../common/constants'; -import * as vscode from "vscode"; +'use strict'; import * as path from 'path'; +import * as vscode from 'vscode'; +import { Commands } from '../common/constants'; +import { sendTelemetryEvent, UPDATE_PYSPARK_LIBRARY } from '../common/telemetry'; export function activateUpdateSparkLibraryProvider(): vscode.Disposable { return vscode.commands.registerCommand(Commands.Update_SparkLibrary, updateSparkLibrary); @@ -10,13 +11,15 @@ export function activateUpdateSparkLibraryProvider(): vscode.Disposable { function updateSparkLibrary() { const pythonConfig = vscode.workspace.getConfiguration('python'); const extraLibPath = 'autoComplete.extraPaths'; - let sparkHomePath = '${env.SPARK_HOME}'; + // tslint:disable-next-line:no-invalid-template-strings + const sparkHomePath = '${env.SPARK_HOME}'; pythonConfig.update(extraLibPath, [path.join(sparkHomePath, 'python'), path.join(sparkHomePath, 'python/pyspark')]).then(() => { //Done }, reason => { vscode.window.showErrorMessage(`Failed to update ${extraLibPath}. Error: ${reason.message}`); console.error(reason); - }); - vscode.window.showInformationMessage(`Make sure you have SPARK_HOME environment variable set to the root path of the local spark installation!`); -} \ No newline at end of file + }); + vscode.window.showInformationMessage('Make sure you have SPARK_HOME environment variable set to the root path of the local spark installation!'); + sendTelemetryEvent(UPDATE_PYSPARK_LIBRARY); +} diff --git a/src/client/refactor/proxy.ts b/src/client/refactor/proxy.ts index 5a238273d8d8..bba0f5eae343 100644 --- a/src/client/refactor/proxy.ts +++ b/src/client/refactor/proxy.ts @@ -4,7 +4,6 @@ import * as vscode from 'vscode'; import * as path from 'path'; import * as child_process from 'child_process'; import { IPythonSettings } from '../common/configSettings'; -import { REFACTOR } from '../common/telemetryContracts'; import { getCustomEnvVars, getCustomEnvVarsSync, getWindowsLineEndingCount, IS_WINDOWS } from '../common/utils'; import { mergeEnvVariables } from '../common/envFileParser'; @@ -57,7 +56,7 @@ export class RefactorProxy extends vscode.Disposable { "indent_size": options.tabSize }; - return this.sendCommand(JSON.stringify(command), REFACTOR.Rename); + return this.sendCommand(JSON.stringify(command)); } extractVariable(document: vscode.TextDocument, name: string, filePath: string, range: vscode.Range, options?: vscode.TextEditorOptions): Promise { if (!options) { @@ -72,7 +71,7 @@ export class RefactorProxy extends vscode.Disposable { "name": name, "indent_size": options.tabSize }; - return this.sendCommand(JSON.stringify(command), REFACTOR.ExtractVariable); + return this.sendCommand(JSON.stringify(command)); } extractMethod(document: vscode.TextDocument, name: string, filePath: string, range: vscode.Range, options?: vscode.TextEditorOptions): Promise { if (!options) { @@ -91,9 +90,9 @@ export class RefactorProxy extends vscode.Disposable { "name": name, "indent_size": options.tabSize }; - return this.sendCommand(JSON.stringify(command), REFACTOR.ExtractMethod); + return this.sendCommand(JSON.stringify(command)); } - private sendCommand(command: string, telemetryEvent: string): Promise { + private sendCommand(command: string, telemetryEvent?: string): Promise { return this.initialize(this.pythonSettings.pythonPath).then(() => { return new Promise((resolve, reject) => { this._commandResolve = resolve; diff --git a/src/test/jupyter/jupyterKernelManager.test.ts b/src/test/jupyter/jupyterKernelManager.test.ts index 27b99e77c5e6..7d43024ccfca 100644 --- a/src/test/jupyter/jupyterKernelManager.test.ts +++ b/src/test/jupyter/jupyterKernelManager.test.ts @@ -5,7 +5,7 @@ import { initialize, initializeTest, IS_MULTI_ROOT_TEST } from './../initialize' import { JupyterClientAdapter } from '../../client/jupyter/jupyter_client/main'; import { KernelManagerImpl } from '../../client/jupyter/kernel-manager'; -suite('Kernel Manager', () => { +suite('Jupyter Kernel Manager', () => { suiteSetup(async function () { if (IS_MULTI_ROOT_TEST) { // tslint:disable-next-line:no-invalid-this From 83c27335bb714f2476e6f68e5a49346282bb000a Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 13:33:11 -0700 Subject: [PATCH 09/86] capture telemetry when interpreter is set --- src/client/common/telemetry.ts | 9 +++++- src/client/common/utils.ts | 2 +- src/client/extension.ts | 4 ++- .../configuration/pythonPathUpdaterService.ts | 29 +++++++++++++++++-- .../pythonPathUpdaterServiceFactory.ts | 1 - .../services/globalUpdaterService.ts | 2 +- .../services/workspaceFolderUpdaterService.ts | 2 -- .../configuration/setInterpreterProvider.ts | 13 +++++---- src/client/interpreter/index.ts | 2 +- src/client/interpreter/interpreterVersion.ts | 23 ++++++++++++--- src/test/common/common.test.ts | 4 +-- .../pythonPathUpdater.multiroot.test.ts | 2 +- .../interpreters/pythonPathUpdater.test.ts | 2 +- .../shebangCodeLenseProvider.test.ts | 1 - 14 files changed, 70 insertions(+), 26 deletions(-) diff --git a/src/client/common/telemetry.ts b/src/client/common/telemetry.ts index 6bc4de2a50fa..43a70c32be2d 100644 --- a/src/client/common/telemetry.ts +++ b/src/client/common/telemetry.ts @@ -18,6 +18,7 @@ export const REFACTOR_RENAME = 'REFACTOR_RENAME'; export const REFACTOR_EXTRACT_VAR = 'REFACTOR_EXTRACT_VAR'; export const REFACTOR_EXTRACT_FUNCTION = 'REFACTOR_EXTRACT_FUNCTION'; export const REPL = 'REPL'; +export const PYTHON_INTERPRETER = 'PYTHON_INTERPRETER'; type EditorLoadTelemetry = { condaVersion: string; @@ -33,7 +34,13 @@ type LintingTelemetry = { trigger: 'save' | 'auto'; executableSpecified: boolean; }; -type Terlemetries = FormatTelemetry | LintingTelemetry | EditorLoadTelemetry; +type PythonInterpreterTelemetry = { + trigger: 'ui' | 'shebang' | 'load'; + failed: boolean; + version: string; + pipVersion: string; +}; +type Terlemetries = FormatTelemetry | LintingTelemetry | EditorLoadTelemetry | PythonInterpreterTelemetry; export class StopWatch { private started: number = Date.now(); private stopped?: number; diff --git a/src/client/common/utils.ts b/src/client/common/utils.ts index 85930a837a8c..820c81b596da 100644 --- a/src/client/common/utils.ts +++ b/src/client/common/utils.ts @@ -423,7 +423,7 @@ export function areBasePathsSame(path1: string, path2: string) { path2 = IS_WINDOWS ? path2.replace(/\//g, "\\") : path2; return path.dirname(path1).toUpperCase() === path.dirname(path2).toUpperCase(); } -export async function getInterpreterDisplayName(pythonPath: string) { +export async function getInterpreterVersion(pythonPath: string) { return await new Promise((resolve, reject) => { child_process.execFile(pythonPath, ['--version'], (error, stdout, stdErr) => { const out = (typeof stdErr === 'string' ? stdErr : '') + os.EOL + (typeof stdout === 'string' ? stdout : ''); diff --git a/src/client/extension.ts b/src/client/extension.ts index 2cb929e9a8b1..28338f9cbb00 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -34,6 +34,7 @@ import * as sortImports from './sortImports'; import { BlockFormatProviders } from './typeFormatters/blockFormatProvider'; import * as tests from './unittests/main'; import { WorkspaceSymbols } from './workspaceSymbols/main'; +import { InterpreterVersionService } from './interpreter/interpreterVersion'; const PYTHON: vscode.DocumentFilter = { language: 'python' }; let unitTestOutChannel: vscode.OutputChannel; @@ -66,7 +67,8 @@ export async function activate(context: vscode.ExtensionContext) { await interpreterManager.autoSetInterpreter(); await interpreterManager.refresh(); context.subscriptions.push(interpreterManager); - context.subscriptions.push(new SetInterpreterProvider(interpreterManager)); + const interpreterVersionService = new InterpreterVersionService(); + context.subscriptions.push(new SetInterpreterProvider(interpreterManager, interpreterVersionService)); context.subscriptions.push(...activateExecInTerminalProvider()); context.subscriptions.push(activateUpdateSparkLibraryProvider()); activateSimplePythonRefactorProvider(context, formatOutChannel); diff --git a/src/client/interpreter/configuration/pythonPathUpdaterService.ts b/src/client/interpreter/configuration/pythonPathUpdaterService.ts index b81963f9d8fe..de2652288fa1 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterService.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterService.ts @@ -1,21 +1,44 @@ import * as path from 'path'; import { ConfigurationTarget, Uri, window } from 'vscode'; +import { sendTelemetryEvent, StopWatch, PYTHON_INTERPRETER } from '../../common/telemetry'; import { WorkspacePythonPath } from '../contracts'; +import { IInterpreterVersionService } from '../interpreterVersion'; import { IPythonPathUpdaterService, IPythonPathUpdaterServiceFactory } from './types'; export class PythonPathUpdaterService { - constructor(private pythonPathSettingsUpdaterFactory: IPythonPathUpdaterServiceFactory) { } - public async updatePythonPath(pythonPath: string, configTarget: ConfigurationTarget, wkspace?: Uri): Promise { + constructor(private pythonPathSettingsUpdaterFactory: IPythonPathUpdaterServiceFactory, + private interpreterVersionService: IInterpreterVersionService) { } + public async updatePythonPath(pythonPath: string, configTarget: ConfigurationTarget, trigger: 'ui' | 'shebang' | 'load', wkspace?: Uri): Promise { + const stopWatch = new StopWatch(); const pythonPathUpdater = this.getPythonUpdaterService(configTarget, wkspace); - + let failed = false; try { await pythonPathUpdater.updatePythonPath(path.normalize(pythonPath)); } catch (reason) { + failed = true; // tslint:disable-next-line:no-unsafe-any prefer-type-cast const message = reason && typeof reason.message === 'string' ? reason.message as string : ''; window.showErrorMessage(`Failed to set 'pythonPath'. Error: ${message}`); console.error(reason); } + // do not wait for this to complete + this.sendTelemetry(stopWatch.elpsedTime, failed, trigger, pythonPath); + } + private async sendTelemetry(duration: number, failed: boolean, trigger: 'ui' | 'shebang' | 'load', pythonPath: string) { + let version: string | undefined; + let pipVersion: string | undefined; + if (!failed) { + const pyVersionPromise = this.interpreterVersionService.getVersion(pythonPath, '') + .then(pyVersion => pyVersion.length === 0 ? undefined : pyVersion); + const pipVersionPromise = this.interpreterVersionService.getPipVersion(pythonPath) + .then(value => value.length === 0 ? undefined : value) + .catch(() => undefined); + const versions = await Promise.all([pyVersionPromise, pipVersionPromise]); + version = versions[0]; + // tslint:disable-next-line:prefer-type-cast + pipVersion = versions[1] as string; + } + sendTelemetryEvent(PYTHON_INTERPRETER, duration, { failed, trigger, version, pipVersion }); } private getPythonUpdaterService(configTarget: ConfigurationTarget, wkspace?: Uri) { switch (configTarget) { diff --git a/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts b/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts index a46c18275d35..c48d20cdac1c 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts @@ -1,5 +1,4 @@ import { Uri } from 'vscode'; -import { InterpreterManager } from '../index'; import { GlobalPythonPathUpdaterService } from './services/globalUpdaterService'; import { WorkspaceFolderPythonPathUpdaterService } from './services/workspaceFolderUpdaterService'; import { WorkspacePythonPathUpdaterService } from './services/workspaceUpdaterService'; diff --git a/src/client/interpreter/configuration/services/globalUpdaterService.ts b/src/client/interpreter/configuration/services/globalUpdaterService.ts index 4b775adf0b71..bb717cb0159c 100644 --- a/src/client/interpreter/configuration/services/globalUpdaterService.ts +++ b/src/client/interpreter/configuration/services/globalUpdaterService.ts @@ -1,4 +1,4 @@ -import { ConfigurationTarget, Uri, workspace } from 'vscode'; +import { Uri, workspace } from 'vscode'; import { InterpreterManager } from '../..'; import { WorkspacePythonPath } from '../../contracts'; import { IPythonPathUpdaterService } from '../types'; diff --git a/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts b/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts index d39f9a831f93..37f45d5cde14 100644 --- a/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts +++ b/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts @@ -1,7 +1,5 @@ import * as path from 'path'; import { ConfigurationTarget, Uri, workspace } from 'vscode'; -import { InterpreterManager } from '../..'; -import { WorkspacePythonPath } from '../../contracts'; import { IPythonPathUpdaterService } from '../types'; export class WorkspaceFolderPythonPathUpdaterService implements IPythonPathUpdaterService { diff --git a/src/client/interpreter/configuration/setInterpreterProvider.ts b/src/client/interpreter/configuration/setInterpreterProvider.ts index b155d7caa049..f08278217372 100644 --- a/src/client/interpreter/configuration/setInterpreterProvider.ts +++ b/src/client/interpreter/configuration/setInterpreterProvider.ts @@ -5,6 +5,7 @@ import { InterpreterManager } from '../'; import * as settings from '../../common/configSettings'; import { PythonInterpreter, WorkspacePythonPath } from '../contracts'; import { ShebangCodeLensProvider } from '../display/shebangCodeLensProvider'; +import { IInterpreterVersionService } from '../interpreterVersion'; import { PythonPathUpdaterService } from './pythonPathUpdaterService'; import { PythonPathUpdaterServiceFactory } from './pythonPathUpdaterServiceFactory'; import { IPythonPathUpdaterServiceFactory } from './types'; @@ -17,10 +18,10 @@ interface PythonPathQuickPickItem extends QuickPickItem { export class SetInterpreterProvider implements Disposable { private disposables: Disposable[] = []; private pythonPathUpdaterService: PythonPathUpdaterService; - constructor(private interpreterManager: InterpreterManager) { + constructor(private interpreterManager: InterpreterManager, interpreterVersionService: IInterpreterVersionService) { this.disposables.push(commands.registerCommand('python.setInterpreter', this.setInterpreter.bind(this))); this.disposables.push(commands.registerCommand('python.setShebangInterpreter', this.setShebangInterpreter.bind(this))); - this.pythonPathUpdaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory()); + this.pythonPathUpdaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory(), interpreterVersionService); } public dispose() { this.disposables.forEach(disposable => disposable.dispose()); @@ -85,7 +86,7 @@ export class SetInterpreterProvider implements Disposable { const selection = await window.showQuickPick(suggestions, quickPickOptions); if (selection !== undefined) { - await this.pythonPathUpdaterService.updatePythonPath(selection.path, configTarget, wkspace); + await this.pythonPathUpdaterService.updatePythonPath(selection.path, configTarget, 'ui', wkspace); } } @@ -100,15 +101,15 @@ export class SetInterpreterProvider implements Disposable { const isWorkspaceChange = Array.isArray(workspace.workspaceFolders) && workspace.workspaceFolders.length === 1; if (isGlobalChange) { - await this.pythonPathUpdaterService.updatePythonPath(shebang, ConfigurationTarget.Global); + await this.pythonPathUpdaterService.updatePythonPath(shebang, ConfigurationTarget.Global, 'shebang'); return; } if (isWorkspaceChange || !workspaceFolder) { - await this.pythonPathUpdaterService.updatePythonPath(shebang, ConfigurationTarget.Workspace, workspace.workspaceFolders[0].uri); + await this.pythonPathUpdaterService.updatePythonPath(shebang, ConfigurationTarget.Workspace, 'shebang', workspace.workspaceFolders[0].uri); return; } - await this.pythonPathUpdaterService.updatePythonPath(shebang, ConfigurationTarget.WorkspaceFolder, workspaceFolder.uri); + await this.pythonPathUpdaterService.updatePythonPath(shebang, ConfigurationTarget.WorkspaceFolder, 'shebang', workspaceFolder.uri); } } diff --git a/src/client/interpreter/index.ts b/src/client/interpreter/index.ts index a90c2592fcb0..c2fd3052c1de 100644 --- a/src/client/interpreter/index.ts +++ b/src/client/interpreter/index.ts @@ -58,7 +58,7 @@ export class InterpreterManager implements Disposable { const pythonPath = interpretersInWorkspace[0].path; const relativePath = path.dirname(pythonPath).substring(activeWorkspace.folderUri.fsPath.length); if (relativePath.split(path.sep).filter(l => l.length > 0).length === 2) { - await this.pythonPathUpdaterService.updatePythonPath(pythonPath, activeWorkspace.configTarget, activeWorkspace.folderUri); + await this.pythonPathUpdaterService.updatePythonPath(pythonPath, activeWorkspace.configTarget, 'load', activeWorkspace.folderUri); } } public dispose(): void { diff --git a/src/client/interpreter/interpreterVersion.ts b/src/client/interpreter/interpreterVersion.ts index de9fddc57575..20af4a3bb743 100644 --- a/src/client/interpreter/interpreterVersion.ts +++ b/src/client/interpreter/interpreterVersion.ts @@ -1,13 +1,28 @@ -import { getInterpreterDisplayName } from '../common/utils'; +import * as child_process from 'child_process'; +import { getInterpreterVersion } from '../common/utils'; export interface IInterpreterVersionService { getVersion(pythonPath: string, defaultValue: string): Promise; + getPipVersion(pythonPath: string): Promise; } export class InterpreterVersionService implements IInterpreterVersionService { - getVersion(pythonPath: string, defaultValue: string): Promise { - return getInterpreterDisplayName(pythonPath) + public getVersion(pythonPath: string, defaultValue: string): Promise { + return getInterpreterVersion(pythonPath) .catch(() => defaultValue); } + public async getPipVersion(pythonPath: string): Promise { + return new Promise((resolve, reject) => { + child_process.execFile(pythonPath, ['-m', 'pip', '--version'], (error, stdout, stdErr) => { + if (stdout && stdout.length > 0) { + const parts = stdout.split(' '); + if (parts.length > 1) { + resolve(parts[1].trim()); + return; + } + } + reject(); + }); + }); + } } - diff --git a/src/test/common/common.test.ts b/src/test/common/common.test.ts index 0e72ac770b71..aeccb54166da 100644 --- a/src/test/common/common.test.ts +++ b/src/test/common/common.test.ts @@ -2,7 +2,7 @@ import * as assert from 'assert'; import { EOL } from 'os'; import * as vscode from 'vscode'; import { createDeferred } from '../../client/common/helpers'; -import { execPythonFile, getInterpreterDisplayName } from '../../client/common/utils'; +import { execPythonFile, getInterpreterVersion } from '../../client/common/utils'; import { initialize } from './../initialize'; // Defines a Mocha test suite to group tests of similar kind together @@ -83,7 +83,7 @@ suite('ChildProc', () => { }); test('Get Python display name', async () => { - const displayName = await getInterpreterDisplayName('python'); + const displayName = await getInterpreterVersion('python'); assert.equal(typeof displayName, 'string', 'Display name not returned'); assert.notEqual(displayName.length, 0, 'Display name cannot be empty'); }); diff --git a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts index 7f7c1040c68b..aa66e99e32ea 100644 --- a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts +++ b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts @@ -57,7 +57,7 @@ suite('Multiroot Python Path Settings Updater', () => { const workspaceUri = workspace3Uri; const updaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory()); const pythonPath = `xWorkspacePythonPathFromUpdater${new Date().getMilliseconds()}`; - await updaterService.updatePythonPath(pythonPath, ConfigurationTarget.WorkspaceFolder, workspace.getWorkspaceFolder(workspaceUri).uri); + await updaterService.updatePythonPath(pythonPath, ConfigurationTarget.WorkspaceFolder, 'ui', workspace.getWorkspaceFolder(workspaceUri).uri); const folderValue = workspace.getConfiguration('python', workspace3Uri).inspect('pythonPath').workspaceFolderValue; assert.equal(folderValue, pythonPath, 'Workspace Python Path not updated'); }); diff --git a/src/test/interpreters/pythonPathUpdater.test.ts b/src/test/interpreters/pythonPathUpdater.test.ts index 4b11c96ebd60..2e75c5e4cfe5 100644 --- a/src/test/interpreters/pythonPathUpdater.test.ts +++ b/src/test/interpreters/pythonPathUpdater.test.ts @@ -74,7 +74,7 @@ suite('Python Path Settings Updater', () => { const workspaceUri = Uri.file(workspaceRoot); const updaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory()); const pythonPath = `xWorkspacePythonPathFromUpdater${new Date().getMilliseconds()}`; - await updaterService.updatePythonPath(pythonPath, ConfigurationTarget.Workspace, workspace.getWorkspaceFolder(workspaceUri).uri); + await updaterService.updatePythonPath(pythonPath, ConfigurationTarget.Workspace, 'ui', workspace.getWorkspaceFolder(workspaceUri).uri); const workspaceValue = workspace.getConfiguration('python').inspect('pythonPath').workspaceValue; assert.equal(workspaceValue, pythonPath, 'Workspace Python Path not updated'); }); diff --git a/src/test/providers/shebangCodeLenseProvider.test.ts b/src/test/providers/shebangCodeLenseProvider.test.ts index 23616ebb3e70..36b45b78a616 100644 --- a/src/test/providers/shebangCodeLenseProvider.test.ts +++ b/src/test/providers/shebangCodeLenseProvider.test.ts @@ -2,7 +2,6 @@ import * as assert from 'assert'; import * as child_process from 'child_process'; import * as path from 'path'; import * as vscode from 'vscode'; -import { ConfigurationTarget } from 'vscode'; import { IS_WINDOWS, PythonSettings } from '../../client/common/configSettings'; import { ShebangCodeLensProvider } from '../../client/interpreter/display/shebangCodeLensProvider'; import { getFirstNonEmptyLineFromMultilineString } from '../../client/interpreter/helpers'; From 9c8ab22647616df345ca77930fb2e23e607bf75c Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 13:36:01 -0700 Subject: [PATCH 10/86] resolved linter warning --- src/client/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/extension.ts b/src/client/extension.ts index 28338f9cbb00..fa9f100b4c1c 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -12,6 +12,7 @@ import { InterpreterManager } from './interpreter'; import { SetInterpreterProvider } from './interpreter/configuration/setInterpreterProvider'; import { ShebangCodeLensProvider } from './interpreter/display/shebangCodeLensProvider'; import { getCondaVersion } from './interpreter/helpers'; +import { InterpreterVersionService } from './interpreter/interpreterVersion'; import * as jup from './jupyter/main'; import { JupyterProvider } from './jupyter/provider'; import { JediFactory } from './languageServices/jediProxyFactory'; @@ -34,7 +35,6 @@ import * as sortImports from './sortImports'; import { BlockFormatProviders } from './typeFormatters/blockFormatProvider'; import * as tests from './unittests/main'; import { WorkspaceSymbols } from './workspaceSymbols/main'; -import { InterpreterVersionService } from './interpreter/interpreterVersion'; const PYTHON: vscode.DocumentFilter = { language: 'python' }; let unitTestOutChannel: vscode.OutputChannel; From 6d33aa728f9032cf0dcb71a924ddba3d50c68e05 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 13:40:14 -0700 Subject: [PATCH 11/86] added telemetry for workspace symbols --- src/client/common/telemetry.ts | 2 ++ src/client/workspaceSymbols/generator.ts | 15 ++++++++------- src/client/workspaceSymbols/provider.ts | 10 ++++++---- 3 files changed, 16 insertions(+), 11 deletions(-) diff --git a/src/client/common/telemetry.ts b/src/client/common/telemetry.ts index 43a70c32be2d..cc81fec15410 100644 --- a/src/client/common/telemetry.ts +++ b/src/client/common/telemetry.ts @@ -19,6 +19,8 @@ export const REFACTOR_EXTRACT_VAR = 'REFACTOR_EXTRACT_VAR'; export const REFACTOR_EXTRACT_FUNCTION = 'REFACTOR_EXTRACT_FUNCTION'; export const REPL = 'REPL'; export const PYTHON_INTERPRETER = 'PYTHON_INTERPRETER'; +export const WORKSPACE_SYMBOLS_BUILD = 'WORKSPACE_SYMBOLS_BUILD'; +export const WORKSPACE_SYMBOLS_GO_TO = 'WORKSPACE_SYMBOLS_GO_TO'; type EditorLoadTelemetry = { condaVersion: string; diff --git a/src/client/workspaceSymbols/generator.ts b/src/client/workspaceSymbols/generator.ts index dcb1b5ae3d35..90b88fbeda67 100644 --- a/src/client/workspaceSymbols/generator.ts +++ b/src/client/workspaceSymbols/generator.ts @@ -1,8 +1,9 @@ -import * as vscode from 'vscode'; -import * as path from 'path'; -import * as fs from 'fs'; import * as child_process from 'child_process'; +import * as fs from 'fs'; +import * as path from 'path'; +import * as vscode from 'vscode'; import { IPythonSettings, PythonSettings } from '../common/configSettings'; +import { captureTelemetry, WORKSPACE_SYMBOLS_BUILD } from '../common/telemetry'; export class Generator implements vscode.Disposable { private optionsFile: string; @@ -20,7 +21,7 @@ export class Generator implements vscode.Disposable { this.pythonSettings = PythonSettings.getInstance(workspaceFolder); } - dispose() { + public dispose() { this.disposables.forEach(d => d.dispose()); } @@ -32,13 +33,13 @@ export class Generator implements vscode.Disposable { return [`--options=${optionsFile}`, '--languages=Python'].concat(excludes); } - async generateWorkspaceTags(): Promise { + public async generateWorkspaceTags(): Promise { if (!this.pythonSettings.workspaceSymbols.enabled) { return; } return await this.generateTags({ directory: this.workspaceFolder.fsPath }); } - + @captureTelemetry(WORKSPACE_SYMBOLS_BUILD) private generateTags(source: { directory?: string, file?: string }): Promise { const tagFile = path.normalize(this.pythonSettings.workspaceSymbols.tagFilePath); const cmd = this.pythonSettings.workspaceSymbols.ctagsPath; @@ -94,4 +95,4 @@ export class Generator implements vscode.Disposable { return promise; } -} \ No newline at end of file +} diff --git a/src/client/workspaceSymbols/provider.ts b/src/client/workspaceSymbols/provider.ts index e9124212e9a8..1d6ea19f93ac 100644 --- a/src/client/workspaceSymbols/provider.ts +++ b/src/client/workspaceSymbols/provider.ts @@ -1,15 +1,17 @@ -import * as vscode from 'vscode'; import * as _ from 'lodash'; +import * as vscode from 'vscode'; +import { Commands } from '../common/constants'; +import { captureTelemetry, WORKSPACE_SYMBOLS_GO_TO } from '../common/telemetry'; +import { fsExistsAsync } from '../common/utils'; import { Generator } from './generator'; import { parseTags } from './parser'; -import { fsExistsAsync } from '../common/utils'; -import { Commands } from '../common/constants'; export class WorkspaceSymbolProvider implements vscode.WorkspaceSymbolProvider { public constructor(private tagGenerators: Generator[], private outputChannel: vscode.OutputChannel) { } - async provideWorkspaceSymbols(query: string, token: vscode.CancellationToken): Promise { + @captureTelemetry(WORKSPACE_SYMBOLS_GO_TO) + public async provideWorkspaceSymbols(query: string, token: vscode.CancellationToken): Promise { if (this.tagGenerators.length === 0) { return []; } From 2a53c3acef90d991b6d4cb71f4880bcbbe651d11 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 13:45:29 -0700 Subject: [PATCH 12/86] added telemetry for code execution --- src/client/common/telemetry.ts | 7 ++++++- src/client/providers/execInTerminalProvider.ts | 5 ++++- 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/client/common/telemetry.ts b/src/client/common/telemetry.ts index cc81fec15410..5e1e7677eae5 100644 --- a/src/client/common/telemetry.ts +++ b/src/client/common/telemetry.ts @@ -21,6 +21,8 @@ export const REPL = 'REPL'; export const PYTHON_INTERPRETER = 'PYTHON_INTERPRETER'; export const WORKSPACE_SYMBOLS_BUILD = 'WORKSPACE_SYMBOLS_BUILD'; export const WORKSPACE_SYMBOLS_GO_TO = 'WORKSPACE_SYMBOLS_GO_TO'; +export const EXECUTION_CODE = 'EXECUTION_CODE'; +export const EXECUTION_DJANGO = 'EXECUTION_DJANGO'; type EditorLoadTelemetry = { condaVersion: string; @@ -42,7 +44,10 @@ type PythonInterpreterTelemetry = { version: string; pipVersion: string; }; -type Terlemetries = FormatTelemetry | LintingTelemetry | EditorLoadTelemetry | PythonInterpreterTelemetry; +type CodeExecutionTelemetry = { + scope: 'file'|'selection'; +}; +type Terlemetries = FormatTelemetry | LintingTelemetry | EditorLoadTelemetry | PythonInterpreterTelemetry | CodeExecutionTelemetry; export class StopWatch { private started: number = Date.now(); private stopped?: number; diff --git a/src/client/providers/execInTerminalProvider.ts b/src/client/providers/execInTerminalProvider.ts index c25d784dc5d2..e41c325a36b1 100644 --- a/src/client/providers/execInTerminalProvider.ts +++ b/src/client/providers/execInTerminalProvider.ts @@ -7,6 +7,7 @@ import { Disposable, workspace } from 'vscode'; import * as settings from '../common/configSettings'; import { Commands, PythonLanguage } from '../common/constants'; import { ContextKey } from '../common/contextKey'; +import { EXECUTION_CODE, EXECUTION_DJANGO, sendTelemetryEvent } from '../common/telemetry'; import { IS_WINDOWS } from '../common/utils'; let terminal: vscode.Terminal; @@ -71,7 +72,6 @@ function execInTerminal(fileUri?: vscode.Uri) { if (filePath.indexOf(' ') > 0) { filePath = `"${filePath}"`; } - terminal = terminal ? terminal : vscode.window.createTerminal('Python'); if (pythonSettings.terminal && pythonSettings.terminal.executeInFileDir) { const fileDirPath = path.dirname(filePath); @@ -94,6 +94,7 @@ function execInTerminal(fileUri?: vscode.Uri) { terminal.sendText(command); } terminal.show(); + sendTelemetryEvent(EXECUTION_CODE, undefined, { scope: 'file' }); } function execSelectionInTerminal() { @@ -147,6 +148,7 @@ function execSelectionInTerminal() { terminal.sendText(unix_code); } terminal.show(); + sendTelemetryEvent(EXECUTION_CODE, undefined, { scope: 'selection' }); } function execSelectionInDjangoShell() { @@ -203,6 +205,7 @@ function execSelectionInDjangoShell() { terminal.sendText(unix_code); } terminal.show(); + sendTelemetryEvent(EXECUTION_DJANGO, undefined, { scope: 'selection' }); } class DjangoContextInitializer implements vscode.Disposable { From b7ee666db63cd5e39d729e74af50f395ec1e1c3c Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 14:32:27 -0700 Subject: [PATCH 13/86] refactorred telemetry code --- src/client/common/constants.ts | 24 +++ src/client/common/telemetry.ts | 176 ------------------ src/client/common/telemetry/constants.ts | 22 +++ src/client/common/telemetry/index.ts | 79 ++++++++ src/client/common/telemetry/stopWatch.ts | 10 + src/client/common/telemetry/telemetry.ts | 44 +++++ src/client/common/telemetry/types.ts | 31 +++ src/client/common/telemetryContracts.ts | 31 --- src/client/debugger/Main.ts | 28 +-- src/client/extension.ts | 31 +-- src/client/formatters/autoPep8Formatter.ts | 4 +- src/client/formatters/yapfFormatter.ts | 4 +- .../configuration/pythonPathUpdaterService.ts | 4 +- src/client/interpreter/index.ts | 3 +- src/client/providers/completionProvider.ts | 3 +- src/client/providers/definitionProvider.ts | 3 +- .../providers/execInTerminalProvider.ts | 3 +- src/client/providers/hoverProvider.ts | 3 +- src/client/providers/importSortProvider.ts | 3 +- src/client/providers/lintProvider.ts | 6 +- .../providers/objectDefinitionProvider.ts | 3 +- src/client/providers/referenceProvider.ts | 3 +- src/client/providers/renameProvider.ts | 3 +- src/client/providers/replProvider.ts | 3 +- src/client/providers/signatureProvider.ts | 3 +- .../providers/simpleRefactorProvider.ts | 4 +- src/client/providers/symbolProvider.ts | 3 +- .../providers/updateSparkLibraryProvider.ts | 3 +- src/client/workspaceSymbols/generator.ts | 3 +- src/client/workspaceSymbols/provider.ts | 3 +- src/test/interpreters/mocks.ts | 6 +- .../pythonPathUpdater.multiroot.test.ts | 3 +- .../interpreters/pythonPathUpdater.test.ts | 3 +- 33 files changed, 298 insertions(+), 257 deletions(-) delete mode 100644 src/client/common/telemetry.ts create mode 100644 src/client/common/telemetry/constants.ts create mode 100644 src/client/common/telemetry/index.ts create mode 100644 src/client/common/telemetry/stopWatch.ts create mode 100644 src/client/common/telemetry/telemetry.ts create mode 100644 src/client/common/telemetry/types.ts delete mode 100644 src/client/common/telemetryContracts.ts diff --git a/src/client/common/constants.ts b/src/client/common/constants.ts index c332257d1170..28c793f09135 100644 --- a/src/client/common/constants.ts +++ b/src/client/common/constants.ts @@ -80,3 +80,27 @@ export namespace LinterErrors { export const InvalidSyntax = 'E999'; } } + +export namespace TelemetryEvents { + export const COMPLETION = 'COMPLETION'; + export const DEFINITION = 'DEFINITION'; + export const HOVER_DEFINITION = 'HOVER_DEFINITION'; + export const REFERENCE = 'REFERENCE'; + export const SIGNATURE = 'SIGNATURE'; + export const SYMBOL = 'SYMBOL'; + export const FORMAT_SORT_IMPORTS = 'FORMAT.SORT_IMPORTS'; + export const FORMAT = 'FORMAT.FORMAT'; + export const EDITOR_LOAD = 'EDITOR.LOAD'; + export const LINTING = 'LINTING'; + export const GO_TO_OBJECT_DEFINITION = 'GO_TO_OBJECT_DEFINITION'; + export const UPDATE_PYSPARK_LIBRARY = 'UPDATE_PYSPARK_LIBRARY'; + export const REFACTOR_RENAME = 'REFACTOR_RENAME'; + export const REFACTOR_EXTRACT_VAR = 'REFACTOR_EXTRACT_VAR'; + export const REFACTOR_EXTRACT_FUNCTION = 'REFACTOR_EXTRACT_FUNCTION'; + export const REPL = 'REPL'; + export const PYTHON_INTERPRETER = 'PYTHON_INTERPRETER'; + export const WORKSPACE_SYMBOLS_BUILD = 'WORKSPACE_SYMBOLS_BUILD'; + export const WORKSPACE_SYMBOLS_GO_TO = 'WORKSPACE_SYMBOLS_GO_TO'; + export const EXECUTION_CODE = 'EXECUTION_CODE'; + export const EXECUTION_DJANGO = 'EXECUTION_DJANGO'; +} diff --git a/src/client/common/telemetry.ts b/src/client/common/telemetry.ts deleted file mode 100644 index 5e1e7677eae5..000000000000 --- a/src/client/common/telemetry.ts +++ /dev/null @@ -1,176 +0,0 @@ -import { extensions } from 'vscode'; -// tslint:disable-next-line:variable-name no-require-imports no-var-requires no-use-before-declare no-unsafe-any -const TelemetryReporter: typeof TelemetryReporterType = require('vscode-extension-telemetry'); - -export const COMPLETION = 'COMPLETION'; -export const DEFINITION = 'DEFINITION'; -export const HOVER_DEFINITION = 'HOVER_DEFINITION'; -export const REFERENCE = 'REFERENCE'; -export const SIGNATURE = 'SIGNATURE'; -export const SYMBOL = 'SYMBOL'; -export const FORMAT_SORT_IMPORTS = 'FORMAT.SORT_IMPORTS'; -export const FORMAT = 'FORMAT.FORMAT'; -export const EDITOR_LOAD = 'EDITOR.LOAD'; -export const LINTING = 'LINTING'; -export const GO_TO_OBJECT_DEFINITION = 'GO_TO_OBJECT_DEFINITION'; -export const UPDATE_PYSPARK_LIBRARY = 'UPDATE_PYSPARK_LIBRARY'; -export const REFACTOR_RENAME = 'REFACTOR_RENAME'; -export const REFACTOR_EXTRACT_VAR = 'REFACTOR_EXTRACT_VAR'; -export const REFACTOR_EXTRACT_FUNCTION = 'REFACTOR_EXTRACT_FUNCTION'; -export const REPL = 'REPL'; -export const PYTHON_INTERPRETER = 'PYTHON_INTERPRETER'; -export const WORKSPACE_SYMBOLS_BUILD = 'WORKSPACE_SYMBOLS_BUILD'; -export const WORKSPACE_SYMBOLS_GO_TO = 'WORKSPACE_SYMBOLS_GO_TO'; -export const EXECUTION_CODE = 'EXECUTION_CODE'; -export const EXECUTION_DJANGO = 'EXECUTION_DJANGO'; - -type EditorLoadTelemetry = { - condaVersion: string; -}; -type FormatTelemetry = { - tool: 'autoppep8' | 'yapf'; - hasCustomArgs: boolean; - formatSelection: boolean; -}; -type LintingTelemetry = { - tool: 'flake8' | 'mypy' | 'pep8' | 'prospector' | 'pydocstyle' | 'pylama' | 'pylint'; - hasCustomArgs: boolean; - trigger: 'save' | 'auto'; - executableSpecified: boolean; -}; -type PythonInterpreterTelemetry = { - trigger: 'ui' | 'shebang' | 'load'; - failed: boolean; - version: string; - pipVersion: string; -}; -type CodeExecutionTelemetry = { - scope: 'file'|'selection'; -}; -type Terlemetries = FormatTelemetry | LintingTelemetry | EditorLoadTelemetry | PythonInterpreterTelemetry | CodeExecutionTelemetry; -export class StopWatch { - private started: number = Date.now(); - private stopped?: number; - public get elpsedTime() { - return (this.stopped ? this.stopped : Date.now()) - this.started; - } - public stop() { - this.stopped = Date.now(); - } -} - -let telemetryReporter: TelemetryReporterType; -function getTelemetryReporter() { - if (telemetryReporter) { - return telemetryReporter; - } - const extensionId = 'donjayamanne.python'; - // tslint:disable-next-line:no-non-null-assertion - const extension = extensions.getExtension(extensionId)!; - // tslint:disable-next-line:no-unsafe-any - const extensionVersion = extension.packageJSON.version; - // tslint:disable-next-line:no-unsafe-any - const aiKey = extension.packageJSON.contributes.debuggers[0].aiKey; - // tslint:disable-next-line:no-unsafe-any - return telemetryReporter = new TelemetryReporter(extensionId, extensionVersion, aiKey); -} -export function sendTelemetryEvent(eventName: string, durationMs?: number, properties?: Terlemetries) { - const reporter = getTelemetryReporter(); - const measures = typeof durationMs === 'number' ? { duration: durationMs } : undefined; - - // tslint:disable-next-line:no-any - const customProperties: { [key: string]: string } = {}; - if (properties) { - // tslint:disable-next-line:prefer-type-cast no-any - const data = properties as any; - Object.getOwnPropertyNames(data).forEach(prop => { - // tslint:disable-next-line:prefer-type-cast no-any no-unsafe-any - (customProperties as any)[prop] = typeof data[prop] === 'string' ? data[prop] : data[prop].toString(); - }); - } - // - reporter.sendTelemetryEvent(eventName, properties ? customProperties : undefined, measures); -} - -// tslint:disable-next-line:no-any function-name -export function captureTelemetry(eventName: string) { - // tslint:disable-next-line:no-function-expression no-any - return function (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor) { - const originalMethod = descriptor.value; - // tslint:disable-next-line:no-function-expression no-any - descriptor.value = function (...args: any[]) { - const stopWatch = new StopWatch(); - // tslint:disable-next-line:no-invalid-this no-use-before-declare no-unsafe-any - const result = originalMethod.apply(this, args); - - // If method being wrapped returns a promise then wait for it. - // tslint:disable-next-line:no-unsafe-any - if (result && typeof result.then === 'function' && typeof result.catch === 'function') { - // tslint:disable-next-line:prefer-type-cast - (result as Promise) - .then(data => { - sendTelemetryEvent(eventName, stopWatch.elpsedTime); - return data; - }) - // tslint:disable-next-line:promise-function-async - .catch(ex => { - sendTelemetryEvent(eventName, stopWatch.elpsedTime); - return Promise.reject(ex); - }); - } else { - sendTelemetryEvent(eventName, stopWatch.elpsedTime); - } - - return result; - }; - - return descriptor; - }; -} - -// tslint:disable-next-line:no-any function-name -export function sendTelemetryWhenDone(eventName: string, promise: Promise | Thenable, - stopWatch?: StopWatch, properties?: Terlemetries) { - stopWatch = stopWatch ? stopWatch : new StopWatch(); - if (typeof promise.then === 'function') { - // tslint:disable-next-line:prefer-type-cast no-any - (promise as Promise) - .then(data => { - // tslint:disable-next-line:no-non-null-assertion - sendTelemetryEvent(eventName, stopWatch!.elpsedTime, properties); - return data; - // tslint:disable-next-line:promise-function-async - }, ex => { - // tslint:disable-next-line:no-non-null-assertion - sendTelemetryEvent(eventName, stopWatch!.elpsedTime, properties); - return Promise.reject(ex); - }); - } else { - throw new Error('Method is neither a Promise nor a Theneable'); - } -} - -class TelemetryReporterType { - /** - * Constructs a new telemetry reporter - * @param {string} extensionId All events will be prefixed with this event name - * @param {string} extensionVersion Extension version to be reported with each event - * @param {string} key The application insights key - */ - // tslint:disable-next-line:no-empty - constructor(extensionId: string, extensionVersion: string, key: string) { } - - /** - * Sends a telemetry event - * @param {string} eventName The event name - * @param {object} properties An associative array of strings - * @param {object} measures An associative array of numbers - */ - // tslint:disable-next-line:member-access - public sendTelemetryEvent(eventName: string, properties?: { - [key: string]: string; - }, measures?: { - [key: string]: number; - // tslint:disable-next-line:no-empty - }): void { } -} diff --git a/src/client/common/telemetry/constants.ts b/src/client/common/telemetry/constants.ts new file mode 100644 index 000000000000..62471a65034d --- /dev/null +++ b/src/client/common/telemetry/constants.ts @@ -0,0 +1,22 @@ +export const COMPLETION = 'COMPLETION'; +export const DEFINITION = 'DEFINITION'; +export const HOVER_DEFINITION = 'HOVER_DEFINITION'; +export const REFERENCE = 'REFERENCE'; +export const SIGNATURE = 'SIGNATURE'; +export const SYMBOL = 'SYMBOL'; +export const FORMAT_SORT_IMPORTS = 'FORMAT.SORT_IMPORTS'; +export const FORMAT = 'FORMAT.FORMAT'; +export const EDITOR_LOAD = 'EDITOR.LOAD'; +export const LINTING = 'LINTING'; +export const GO_TO_OBJECT_DEFINITION = 'GO_TO_OBJECT_DEFINITION'; +export const UPDATE_PYSPARK_LIBRARY = 'UPDATE_PYSPARK_LIBRARY'; +export const REFACTOR_RENAME = 'REFACTOR_RENAME'; +export const REFACTOR_EXTRACT_VAR = 'REFACTOR_EXTRACT_VAR'; +export const REFACTOR_EXTRACT_FUNCTION = 'REFACTOR_EXTRACT_FUNCTION'; +export const REPL = 'REPL'; +export const PYTHON_INTERPRETER = 'PYTHON_INTERPRETER'; +export const WORKSPACE_SYMBOLS_BUILD = 'WORKSPACE_SYMBOLS_BUILD'; +export const WORKSPACE_SYMBOLS_GO_TO = 'WORKSPACE_SYMBOLS_GO_TO'; +export const EXECUTION_CODE = 'EXECUTION_CODE'; +export const EXECUTION_DJANGO = 'EXECUTION_DJANGO'; +export const DEBUGGER = 'DEBUGGER'; diff --git a/src/client/common/telemetry/index.ts b/src/client/common/telemetry/index.ts new file mode 100644 index 000000000000..1145f7fe8740 --- /dev/null +++ b/src/client/common/telemetry/index.ts @@ -0,0 +1,79 @@ +import { StopWatch } from './stopWatch'; +import { getTelemetryReporter } from './telemetry'; +import { TelemetryProperties } from './types'; + +export function sendTelemetryEvent(eventName: string, durationMs?: number, properties?: TelemetryProperties) { + const reporter = getTelemetryReporter(); + const measures = typeof durationMs === 'number' ? { duration: durationMs } : undefined; + + // tslint:disable-next-line:no-any + const customProperties: { [key: string]: string } = {}; + if (properties) { + // tslint:disable-next-line:prefer-type-cast no-any + const data = properties as any; + Object.getOwnPropertyNames(data).forEach(prop => { + // tslint:disable-next-line:prefer-type-cast no-any no-unsafe-any + (customProperties as any)[prop] = typeof data[prop] === 'string' ? data[prop] : data[prop].toString(); + }); + } + // + reporter.sendTelemetryEvent(eventName, properties ? customProperties : undefined, measures); +} + +// tslint:disable-next-line:no-any function-name +export function captureTelemetry(eventName: string) { + // tslint:disable-next-line:no-function-expression no-any + return function (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor) { + const originalMethod = descriptor.value; + // tslint:disable-next-line:no-function-expression no-any + descriptor.value = function (...args: any[]) { + const stopWatch = new StopWatch(); + // tslint:disable-next-line:no-invalid-this no-use-before-declare no-unsafe-any + const result = originalMethod.apply(this, args); + + // If method being wrapped returns a promise then wait for it. + // tslint:disable-next-line:no-unsafe-any + if (result && typeof result.then === 'function' && typeof result.catch === 'function') { + // tslint:disable-next-line:prefer-type-cast + (result as Promise) + .then(data => { + sendTelemetryEvent(eventName, stopWatch.elpsedTime); + return data; + }) + // tslint:disable-next-line:promise-function-async + .catch(ex => { + sendTelemetryEvent(eventName, stopWatch.elpsedTime); + return Promise.reject(ex); + }); + } else { + sendTelemetryEvent(eventName, stopWatch.elpsedTime); + } + + return result; + }; + + return descriptor; + }; +} + +// tslint:disable-next-line:no-any function-name +export function sendTelemetryWhenDone(eventName: string, promise: Promise | Thenable, + stopWatch?: StopWatch, properties?: TelemetryProperties) { + stopWatch = stopWatch ? stopWatch : new StopWatch(); + if (typeof promise.then === 'function') { + // tslint:disable-next-line:prefer-type-cast no-any + (promise as Promise) + .then(data => { + // tslint:disable-next-line:no-non-null-assertion + sendTelemetryEvent(eventName, stopWatch!.elpsedTime, properties); + return data; + // tslint:disable-next-line:promise-function-async + }, ex => { + // tslint:disable-next-line:no-non-null-assertion + sendTelemetryEvent(eventName, stopWatch!.elpsedTime, properties); + return Promise.reject(ex); + }); + } else { + throw new Error('Method is neither a Promise nor a Theneable'); + } +} diff --git a/src/client/common/telemetry/stopWatch.ts b/src/client/common/telemetry/stopWatch.ts new file mode 100644 index 000000000000..d1f44345500c --- /dev/null +++ b/src/client/common/telemetry/stopWatch.ts @@ -0,0 +1,10 @@ +export class StopWatch { + private started: number = Date.now(); + private stopped?: number; + public get elpsedTime() { + return (this.stopped ? this.stopped : Date.now()) - this.started; + } + public stop() { + this.stopped = Date.now(); + } +} diff --git a/src/client/common/telemetry/telemetry.ts b/src/client/common/telemetry/telemetry.ts new file mode 100644 index 000000000000..6659493f7abb --- /dev/null +++ b/src/client/common/telemetry/telemetry.ts @@ -0,0 +1,44 @@ +import { extensions } from 'vscode'; +// tslint:disable-next-line:variable-name no-require-imports no-var-requires no-use-before-declare no-unsafe-any +const TelemetryReporter: typeof TelemetryReporterType = require('vscode-extension-telemetry'); + +let telemetryReporter: TelemetryReporterType; +export function getTelemetryReporter() { + if (telemetryReporter) { + return telemetryReporter; + } + const extensionId = 'donjayamanne.python'; + // tslint:disable-next-line:no-non-null-assertion + const extension = extensions.getExtension(extensionId)!; + // tslint:disable-next-line:no-unsafe-any + const extensionVersion = extension.packageJSON.version; + // tslint:disable-next-line:no-unsafe-any + const aiKey = extension.packageJSON.contributes.debuggers[0].aiKey; + // tslint:disable-next-line:no-unsafe-any + return telemetryReporter = new TelemetryReporter(extensionId, extensionVersion, aiKey); +} + +class TelemetryReporterType { + /** + * Constructs a new telemetry reporter + * @param {string} extensionId All events will be prefixed with this event name + * @param {string} extensionVersion Extension version to be reported with each event + * @param {string} key The application insights key + */ + // tslint:disable-next-line:no-empty + constructor(extensionId: string, extensionVersion: string, key: string) { } + + /** + * Sends a telemetry event + * @param {string} eventName The event name + * @param {object} properties An associative array of strings + * @param {object} measures An associative array of numbers + */ + // tslint:disable-next-line:member-access + public sendTelemetryEvent(eventName: string, properties?: { + [key: string]: string; + }, measures?: { + [key: string]: number; + // tslint:disable-next-line:no-empty + }): void { } +} diff --git a/src/client/common/telemetry/types.ts b/src/client/common/telemetry/types.ts new file mode 100644 index 000000000000..e3f472799e4c --- /dev/null +++ b/src/client/common/telemetry/types.ts @@ -0,0 +1,31 @@ +export type EditorLoadTelemetry = { + condaVersion: string; +}; +export type FormatTelemetry = { + tool: 'autoppep8' | 'yapf'; + hasCustomArgs: boolean; + formatSelection: boolean; +}; +export type LintingTelemetry = { + tool: 'flake8' | 'mypy' | 'pep8' | 'prospector' | 'pydocstyle' | 'pylama' | 'pylint'; + hasCustomArgs: boolean; + trigger: 'save' | 'auto'; + executableSpecified: boolean; +}; +export type PythonInterpreterTelemetry = { + trigger: 'ui' | 'shebang' | 'load'; + failed: boolean; + version: string; + pipVersion: string; +}; +export type CodeExecutionTelemetry = { + scope: 'file' | 'selection'; +}; +export type DebuggerTelemetry = { + trigger: 'launch' | 'attach' + console?: 'none' | 'integratedTerminal' | 'externalTerminal'; + debugOptions?: string; + pyspark?: boolean; + hasEnvVars?: boolean; +}; +export type TelemetryProperties = FormatTelemetry | LintingTelemetry | EditorLoadTelemetry | PythonInterpreterTelemetry | CodeExecutionTelemetry; diff --git a/src/client/common/telemetryContracts.ts b/src/client/common/telemetryContracts.ts deleted file mode 100644 index 2a00a022f24d..000000000000 --- a/src/client/common/telemetryContracts.ts +++ /dev/null @@ -1,31 +0,0 @@ -// export namespace Debugger { -// export const Load = 'DEBUGGER_LOAD'; -// export const Attach = 'DEBUGGER_ATTACH'; -// } -// export namespace Commands { -// export const SortImports = 'COMMAND_SORT_IMPORTS'; -// export const UnitTests = 'COMMAND_UNIT_TEST'; -// } -// export namespace IDE { -// export const Completion = 'CODE_COMPLETION'; -// export const Definition = 'CODE_DEFINITION'; -// export const Format = 'CODE_FORMAT'; -// export const HoverDefinition = 'CODE_HOVER_DEFINITION'; -// export const Reference = 'CODE_REFERENCE'; -// export const Rename = 'CODE_RENAME'; -// export const Symbol = 'CODE_SYMBOL'; -// export const Lint = 'LINTING'; -// } -// export namespace REFACTOR { -// export const Rename = 'REFACTOR_RENAME'; -// export const ExtractVariable = 'REFACTOR_EXTRACT_VAR'; -// export const ExtractMethod = 'REFACTOR_EXTRACT_METHOD'; -// } -// export namespace UnitTests { -// export const Run = 'UNITTEST_RUN'; -// export const Discover = 'UNITTEST_DISCOVER'; -// } -// export namespace Jupyter { -// export const Usage = 'JUPYTER'; -// } -// export const EVENT_LOAD = 'IDE_LOAD'; diff --git a/src/client/debugger/Main.ts b/src/client/debugger/Main.ts index a3e98ae92c1a..dcc276a65c5a 100644 --- a/src/client/debugger/Main.ts +++ b/src/client/debugger/Main.ts @@ -14,6 +14,8 @@ import { CreateAttachDebugClient, CreateLaunchDebugClient } from "./DebugClients import { LaunchRequestArguments, AttachRequestArguments, DebugOptions, TelemetryEvent, PythonEvaluationResultFlags } from "./Common/Contracts"; import { validatePath, getPythonExecutable } from './Common/Utils'; import { isNotInstalledError } from '../common/helpers'; +import { DEBUGGER } from '../../client/common/telemetry/constants'; +import { DebuggerTelemetry } from '../../client/common/telemetry/types'; const CHILD_ENUMEARATION_TIMEOUT = 5000; @@ -189,7 +191,7 @@ export class PythonDebugger extends DebugSession { protected launchRequest(response: DebugProtocol.LaunchResponse, args: LaunchRequestArguments): void { // Some versions may still exist with incorrect launch.json values const setting = '${config.python.pythonPath}'; - if (args.pythonPath === setting){ + if (args.pythonPath === setting) { return this.sendErrorResponse(response, 2001, `Invalid launch.json (re-create it or replace 'config.python.pythonPath' with 'config:python.pythonPath')`); } // Add support for specifying just the directory where the python executable will be located @@ -227,17 +229,18 @@ export class PythonDebugger extends DebugSession { if (args && typeof args.cwd === 'string' && args.cwd.length > 0 && args.cwd !== 'null') { programDirectory = args.cwd; } - if (programDirectory.length > 0 && fs.existsSync(path.join(programDirectory, 'pyenv.cfg'))){ - this.sendEvent(new OutputEvent(`Warning 'pyenv.cfg' can interfere with the debugger. Please rename or delete this file (temporary solution)`)); + if (programDirectory.length > 0 && fs.existsSync(path.join(programDirectory, 'pyenv.cfg'))) { + this.sendEvent(new OutputEvent(`Warning 'pyenv.cfg' can interfere with the debugger. Please rename or delete this file (temporary solution)`)); } - - // this.sendEvent(new TelemetryEvent(telemetryContracts.Debugger.Load, { - // Debug_Console: args.console, - // Debug_DebugOptions: args.debugOptions.join(","), - // Debug_DJango: args.debugOptions.indexOf("DjangoDebugging") >= 0 ? "true" : "false", - // Debug_PySpark: typeof args.pythonPath === 'string' && args.pythonPath.indexOf('spark-submit') > 0 ? 'true' : 'false', - // Debug_HasEnvVaraibles: args.env && typeof args.env === "object" && Object.keys(args.env).length > 0 ? "true" : "false" - // })); + + const telemetryProps: DebuggerTelemetry = { + trigger: 'launch', + console: args.console, + debugOptions: args.debugOptions.join(","), + pyspark: typeof args.pythonPath === 'string' && args.pythonPath.indexOf('spark-submit') > 0, + hasEnvVars: args.env && typeof args.env === "object" && Object.keys(args.env).length > 0 + }; + this.sendEvent(new TelemetryEvent(DEBUGGER, telemetryProps)); this.launchArgs = args; this.debugClient = CreateLaunchDebugClient(args, this); @@ -273,7 +276,8 @@ export class PythonDebugger extends DebugSession { this.sendEvent(new TerminatedEvent()); } protected attachRequest(response: DebugProtocol.AttachResponse, args: AttachRequestArguments) { - // this.sendEvent(new TelemetryEvent(telemetryContracts.Debugger.Attach)); + this.sendEvent(new TelemetryEvent(DEBUGGER, { trigger: 'attach' })); + this.attachArgs = args; this.debugClient = CreateAttachDebugClient(args, this); this.entryResponse = response; diff --git a/src/client/extension.ts b/src/client/extension.ts index fa9f100b4c1c..6b45a62f2ec6 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -1,12 +1,14 @@ 'use strict'; +import { EDITOR_LOAD } from './common/telemetry/constants'; import * as os from 'os'; -import * as vscode from 'vscode'; import { workspace } from 'vscode'; +import * as vscode from 'vscode'; import * as settings from './common/configSettings'; import { Commands } from './common/constants'; import { createDeferred } from './common/helpers'; -import { EDITOR_LOAD, sendTelemetryEvent, StopWatch } from './common/telemetry'; +import { sendTelemetryEvent } from './common/telemetry'; +import { StopWatch } from './common/telemetry/stopWatch'; import { SimpleConfigurationProvider } from './debugger'; import { InterpreterManager } from './interpreter'; import { SetInterpreterProvider } from './interpreter/configuration/setInterpreterProvider'; @@ -46,11 +48,8 @@ export const activated = activationDeferred.promise; // tslint:disable-next-line:max-func-body-length export async function activate(context: vscode.ExtensionContext) { const pythonSettings = settings.PythonSettings.getInstance(); - const stopwatch = new StopWatch(); - activated.then(() => { - // Do not wait for this to complete. - sendStartupTelemetry(stopwatch.elpsedTime); - }); + sendStartupTelemetry(activated) + lintingOutChannel = vscode.window.createOutputChannel(pythonSettings.linting.outputWindow); formatOutChannel = lintingOutChannel; if (pythonSettings.linting.outputWindow !== pythonSettings.formatting.outputWindow) { @@ -150,11 +149,15 @@ export async function activate(context: vscode.ExtensionContext) { activationDeferred.resolve(); } -async function sendStartupTelemetry(duration: number) { - let condaVersion: string | undefined; - try { - condaVersion = await getCondaVersion(); - // tslint:disable-next-line:no-empty - } catch { } - sendTelemetryEvent(EDITOR_LOAD, duration, { condaVersion }); +async function sendStartupTelemetry(activatedPromise: Promise) { + const stopWatch = new StopWatch(); + activatedPromise.then(async () => { + const duration = stopWatch.elpsedTime; + let condaVersion: string | undefined; + try { + condaVersion = await getCondaVersion(); + // tslint:disable-next-line:no-empty + } catch { } + sendTelemetryEvent(EDITOR_LOAD, duration, { condaVersion }); + }); } diff --git a/src/client/formatters/autoPep8Formatter.ts b/src/client/formatters/autoPep8Formatter.ts index e3589c9e1787..1953143618c5 100644 --- a/src/client/formatters/autoPep8Formatter.ts +++ b/src/client/formatters/autoPep8Formatter.ts @@ -3,7 +3,9 @@ import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { Product } from '../common/installer'; -import { FORMAT, sendTelemetryWhenDone, StopWatch } from '../common/telemetry'; +import { sendTelemetryWhenDone } from '../common/telemetry'; +import { FORMAT } from '../common/telemetry/constants'; +import { StopWatch } from '../common/telemetry/stopWatch'; import { BaseFormatter } from './baseFormatter'; export class AutoPep8Formatter extends BaseFormatter { diff --git a/src/client/formatters/yapfFormatter.ts b/src/client/formatters/yapfFormatter.ts index f425f6ddeb6b..1a221098fe81 100644 --- a/src/client/formatters/yapfFormatter.ts +++ b/src/client/formatters/yapfFormatter.ts @@ -3,7 +3,9 @@ import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { Product } from '../common/installer'; -import { FORMAT, sendTelemetryWhenDone, StopWatch } from '../common/telemetry'; +import { sendTelemetryWhenDone} from '../common/telemetry'; +import { FORMAT } from '../common/telemetry/constants'; +import { StopWatch } from '../common/telemetry/stopWatch'; import { BaseFormatter } from './baseFormatter'; export class YapfFormatter extends BaseFormatter { diff --git a/src/client/interpreter/configuration/pythonPathUpdaterService.ts b/src/client/interpreter/configuration/pythonPathUpdaterService.ts index de2652288fa1..36226c5f42f7 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterService.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterService.ts @@ -1,6 +1,8 @@ import * as path from 'path'; import { ConfigurationTarget, Uri, window } from 'vscode'; -import { sendTelemetryEvent, StopWatch, PYTHON_INTERPRETER } from '../../common/telemetry'; +import { sendTelemetryEvent } from '../../common/telemetry'; +import { PYTHON_INTERPRETER } from '../../common/telemetry/constants'; +import { StopWatch } from '../../common/telemetry/stopWatch'; import { WorkspacePythonPath } from '../contracts'; import { IInterpreterVersionService } from '../interpreterVersion'; import { IPythonPathUpdaterService, IPythonPathUpdaterServiceFactory } from './types'; diff --git a/src/client/interpreter/index.ts b/src/client/interpreter/index.ts index c2fd3052c1de..639c83bd6d8f 100644 --- a/src/client/interpreter/index.ts +++ b/src/client/interpreter/index.ts @@ -25,7 +25,8 @@ export class InterpreterManager implements Disposable { this.interpreterProvider = new PythonInterpreterLocatorService(virtualEnvMgr); const versionService = new InterpreterVersionService(); this.display = new InterpreterDisplay(statusBar, this.interpreterProvider, virtualEnvMgr, versionService); - this.pythonPathUpdaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory()); + const interpreterVersionService = new InterpreterVersionService(); + this.pythonPathUpdaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory(), interpreterVersionService); PythonSettings.getInstance().addListener('change', () => this.onConfigChanged()); this.disposables.push(window.onDidChangeActiveTextEditor(() => this.refresh())); this.disposables.push(statusBar); diff --git a/src/client/providers/completionProvider.ts b/src/client/providers/completionProvider.ts index 78b665d8b795..f8559a5e3e16 100644 --- a/src/client/providers/completionProvider.ts +++ b/src/client/providers/completionProvider.ts @@ -4,7 +4,8 @@ import { EOL } from 'os'; import * as vscode from 'vscode'; import { ProviderResult, SnippetString, Uri } from 'vscode'; import { PythonSettings } from '../common/configSettings'; -import { captureTelemetry, COMPLETION } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { COMPLETION } from '../common/telemetry/constants'; import { JediFactory } from '../languageServices/jediProxyFactory'; import { extractSignatureAndDocumentation } from './jediHelpers'; import * as proxy from './jediProxy'; diff --git a/src/client/providers/definitionProvider.ts b/src/client/providers/definitionProvider.ts index 3d98e8f3e269..7c9a66aa92ea 100644 --- a/src/client/providers/definitionProvider.ts +++ b/src/client/providers/definitionProvider.ts @@ -1,7 +1,8 @@ 'use strict'; import * as vscode from 'vscode'; -import { captureTelemetry, DEFINITION } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { DEFINITION } from '../common/telemetry/constants'; import { JediFactory } from '../languageServices/jediProxyFactory'; import * as proxy from './jediProxy'; diff --git a/src/client/providers/execInTerminalProvider.ts b/src/client/providers/execInTerminalProvider.ts index e41c325a36b1..025c0b07789d 100644 --- a/src/client/providers/execInTerminalProvider.ts +++ b/src/client/providers/execInTerminalProvider.ts @@ -7,7 +7,8 @@ import { Disposable, workspace } from 'vscode'; import * as settings from '../common/configSettings'; import { Commands, PythonLanguage } from '../common/constants'; import { ContextKey } from '../common/contextKey'; -import { EXECUTION_CODE, EXECUTION_DJANGO, sendTelemetryEvent } from '../common/telemetry'; +import { sendTelemetryEvent } from '../common/telemetry'; +import { EXECUTION_CODE, EXECUTION_DJANGO } from '../common/telemetry/constants'; import { IS_WINDOWS } from '../common/utils'; let terminal: vscode.Terminal; diff --git a/src/client/providers/hoverProvider.ts b/src/client/providers/hoverProvider.ts index d4c91a68d3ee..05c3e1c0a395 100644 --- a/src/client/providers/hoverProvider.ts +++ b/src/client/providers/hoverProvider.ts @@ -2,7 +2,8 @@ import { EOL } from 'os'; import * as vscode from 'vscode'; -import { captureTelemetry, HOVER_DEFINITION } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { HOVER_DEFINITION } from '../common/telemetry/constants'; import { JediFactory } from '../languageServices/jediProxyFactory'; import { highlightCode } from './jediHelpers'; import * as proxy from './jediProxy'; diff --git a/src/client/providers/importSortProvider.ts b/src/client/providers/importSortProvider.ts index 055f4147b0e3..8ec1b2cc0371 100644 --- a/src/client/providers/importSortProvider.ts +++ b/src/client/providers/importSortProvider.ts @@ -5,7 +5,8 @@ import * as path from 'path'; import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { getTempFileWithDocumentContents, getTextEditsFromPatch } from '../common/editor'; -import { captureTelemetry, FORMAT_SORT_IMPORTS } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { FORMAT_SORT_IMPORTS } from '../common/telemetry/constants'; // tslint:disable-next-line:completed-docs export class PythonImportSortProvider { diff --git a/src/client/providers/lintProvider.ts b/src/client/providers/lintProvider.ts index 02a6cb619b83..592676764547 100644 --- a/src/client/providers/lintProvider.ts +++ b/src/client/providers/lintProvider.ts @@ -1,11 +1,14 @@ 'use strict'; -import { sendTelemetryEvent, sendTelemetryWhenDone, StopWatch, LINTING } from '../common/telemetry'; import * as fs from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { LinterErrors } from '../common/constants'; +import { sendTelemetryEvent, sendTelemetryWhenDone } from '../common/telemetry'; +import { LINTING } from '../common/telemetry/constants'; +import { StopWatch } from '../common/telemetry/stopWatch'; +import { BaseLinter } from '../linters/baseLinter'; import * as linter from '../linters/baseLinter'; import * as flake8 from './../linters/flake8'; import * as mypy from './../linters/mypy'; @@ -14,7 +17,6 @@ import * as prospector from './../linters/prospector'; import * as pydocstyle from './../linters/pydocstyle'; import * as pylama from './../linters/pylama'; import * as pylint from './../linters/pylint'; -import { BaseLinter } from '../linters/baseLinter'; // tslint:disable-next-line:no-require-imports no-var-requires const Minimatch = require('minimatch').Minimatch; diff --git a/src/client/providers/objectDefinitionProvider.ts b/src/client/providers/objectDefinitionProvider.ts index 01c160b08774..2caf816b555f 100644 --- a/src/client/providers/objectDefinitionProvider.ts +++ b/src/client/providers/objectDefinitionProvider.ts @@ -1,7 +1,8 @@ 'use strict'; import * as vscode from 'vscode'; -import { captureTelemetry, GO_TO_OBJECT_DEFINITION } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { GO_TO_OBJECT_DEFINITION } from '../common/telemetry/constants'; import { JediFactory } from '../languageServices/jediProxyFactory'; import * as defProvider from './definitionProvider'; diff --git a/src/client/providers/referenceProvider.ts b/src/client/providers/referenceProvider.ts index 714fe04e69a7..afb5ec7c148a 100644 --- a/src/client/providers/referenceProvider.ts +++ b/src/client/providers/referenceProvider.ts @@ -1,7 +1,8 @@ 'use strict'; import * as vscode from 'vscode'; -import { captureTelemetry, REFERENCE } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { REFERENCE } from '../common/telemetry/constants'; import { JediFactory } from '../languageServices/jediProxyFactory'; import * as proxy from './jediProxy'; diff --git a/src/client/providers/renameProvider.ts b/src/client/providers/renameProvider.ts index 43ec20e62688..4f1270e5a423 100644 --- a/src/client/providers/renameProvider.ts +++ b/src/client/providers/renameProvider.ts @@ -5,7 +5,8 @@ import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { getWorkspaceEditsFromPatch } from '../common/editor'; import { Installer, Product } from '../common/installer'; -import { captureTelemetry, REFACTOR_RENAME } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { REFACTOR_RENAME } from '../common/telemetry/constants'; import { RefactorProxy } from '../refactor/proxy'; const EXTENSION_DIR = path.join(__dirname, '..', '..', '..'); diff --git a/src/client/providers/replProvider.ts b/src/client/providers/replProvider.ts index 7146b5982944..e089845cfeee 100644 --- a/src/client/providers/replProvider.ts +++ b/src/client/providers/replProvider.ts @@ -1,7 +1,8 @@ import { commands, Disposable, Uri, window, workspace } from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { Commands } from '../common/constants'; -import { captureTelemetry, REPL } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { REPL } from '../common/telemetry/constants'; import { getPathFromPythonCommand } from '../common/utils'; export class ReplProvider implements Disposable { diff --git a/src/client/providers/signatureProvider.ts b/src/client/providers/signatureProvider.ts index 7add3529ecf3..135886a528d8 100644 --- a/src/client/providers/signatureProvider.ts +++ b/src/client/providers/signatureProvider.ts @@ -2,7 +2,8 @@ import * as vscode from 'vscode'; import { CancellationToken, Position, SignatureHelp, TextDocument } from 'vscode'; -import { captureTelemetry, SIGNATURE } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { SIGNATURE } from '../common/telemetry/constants'; import { JediFactory } from '../languageServices/jediProxyFactory'; import * as proxy from './jediProxy'; diff --git a/src/client/providers/simpleRefactorProvider.ts b/src/client/providers/simpleRefactorProvider.ts index 186c53a5801a..9ea4995e70c5 100644 --- a/src/client/providers/simpleRefactorProvider.ts +++ b/src/client/providers/simpleRefactorProvider.ts @@ -4,8 +4,10 @@ import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { getTextEditsFromPatch } from '../common/editor'; import { Installer, Product } from '../common/installer'; -import { REFACTOR_EXTRACT_FUNCTION, REFACTOR_EXTRACT_VAR, sendTelemetryWhenDone, StopWatch } from '../common/telemetry'; +import { sendTelemetryWhenDone } from '../common/telemetry'; import { RefactorProxy } from '../refactor/proxy'; +import { StopWatch } from '../common/telemetry/stopWatch'; +import { REFACTOR_EXTRACT_VAR, REFACTOR_EXTRACT_FUNCTION } from '../common/telemetry/constants'; interface RenameResponse { results: [{ diff: string }]; diff --git a/src/client/providers/symbolProvider.ts b/src/client/providers/symbolProvider.ts index a8f367b134d0..8c4ba6f42aa6 100644 --- a/src/client/providers/symbolProvider.ts +++ b/src/client/providers/symbolProvider.ts @@ -1,7 +1,8 @@ 'use strict'; import * as vscode from 'vscode'; -import { captureTelemetry, SYMBOL } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { SYMBOL } from '../common/telemetry/constants'; import { JediFactory } from '../languageServices/jediProxyFactory'; import * as proxy from './jediProxy'; diff --git a/src/client/providers/updateSparkLibraryProvider.ts b/src/client/providers/updateSparkLibraryProvider.ts index 7a44e33864a8..cc2f1616fcc7 100644 --- a/src/client/providers/updateSparkLibraryProvider.ts +++ b/src/client/providers/updateSparkLibraryProvider.ts @@ -2,7 +2,8 @@ import * as path from 'path'; import * as vscode from 'vscode'; import { Commands } from '../common/constants'; -import { sendTelemetryEvent, UPDATE_PYSPARK_LIBRARY } from '../common/telemetry'; +import { sendTelemetryEvent } from '../common/telemetry'; +import { UPDATE_PYSPARK_LIBRARY } from '../common/telemetry/constants'; export function activateUpdateSparkLibraryProvider(): vscode.Disposable { return vscode.commands.registerCommand(Commands.Update_SparkLibrary, updateSparkLibrary); diff --git a/src/client/workspaceSymbols/generator.ts b/src/client/workspaceSymbols/generator.ts index 90b88fbeda67..acbc3b5354cc 100644 --- a/src/client/workspaceSymbols/generator.ts +++ b/src/client/workspaceSymbols/generator.ts @@ -3,7 +3,8 @@ import * as fs from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; import { IPythonSettings, PythonSettings } from '../common/configSettings'; -import { captureTelemetry, WORKSPACE_SYMBOLS_BUILD } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { WORKSPACE_SYMBOLS_BUILD } from '../common/telemetry/constants'; export class Generator implements vscode.Disposable { private optionsFile: string; diff --git a/src/client/workspaceSymbols/provider.ts b/src/client/workspaceSymbols/provider.ts index 1d6ea19f93ac..736c6ff0f750 100644 --- a/src/client/workspaceSymbols/provider.ts +++ b/src/client/workspaceSymbols/provider.ts @@ -1,7 +1,8 @@ import * as _ from 'lodash'; import * as vscode from 'vscode'; import { Commands } from '../common/constants'; -import { captureTelemetry, WORKSPACE_SYMBOLS_GO_TO } from '../common/telemetry'; +import { captureTelemetry } from '../common/telemetry'; +import { WORKSPACE_SYMBOLS_GO_TO } from '../common/telemetry/constants'; import { fsExistsAsync } from '../common/utils'; import { Generator } from './generator'; import { parseTags } from './parser'; diff --git a/src/test/interpreters/mocks.ts b/src/test/interpreters/mocks.ts index 34c41bb41c75..db4cfed0c474 100644 --- a/src/test/interpreters/mocks.ts +++ b/src/test/interpreters/mocks.ts @@ -55,10 +55,14 @@ export class MockVirtualEnv implements IVirtualEnvironment { // tslint:disable-next-line:max-classes-per-file export class MockInterpreterVersionProvider implements IInterpreterVersionService { - constructor(private displayName: string, private useDefaultDisplayName: boolean = false) { } + constructor(private displayName: string, private useDefaultDisplayName: boolean = false, + private pipVersionPromise?: Promise) { } public getVersion(pythonPath: string, defaultDisplayName: string): Promise { return this.useDefaultDisplayName ? Promise.resolve(defaultDisplayName) : Promise.resolve(this.displayName); } + public getPipVersion(pythonPath: string): Promise { + return this.pipVersionPromise; + } // tslint:disable-next-line:no-empty public dispose() { } } diff --git a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts index aa66e99e32ea..a60d29b14474 100644 --- a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts +++ b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts @@ -8,6 +8,7 @@ import { GlobalPythonPathUpdaterService } from '../../client/interpreter/configu import { WorkspaceFolderPythonPathUpdaterService } from '../../client/interpreter/configuration/services/workspaceFolderUpdaterService'; import { WorkspacePythonPathUpdaterService } from '../../client/interpreter/configuration/services/workspaceUpdaterService'; import { WorkspacePythonPath } from '../../client/interpreter/contracts'; +import { InterpreterVersionService } from '../../client/interpreter/interpreterVersion'; import { clearPythonPathInWorkspaceFolder } from '../common'; import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST } from '../initialize'; @@ -55,7 +56,7 @@ suite('Multiroot Python Path Settings Updater', () => { test('Updating Workspace Python Path using the PythonPathUpdaterService should work', async () => { const workspaceUri = workspace3Uri; - const updaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory()); + const updaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory(), new InterpreterVersionService()); const pythonPath = `xWorkspacePythonPathFromUpdater${new Date().getMilliseconds()}`; await updaterService.updatePythonPath(pythonPath, ConfigurationTarget.WorkspaceFolder, 'ui', workspace.getWorkspaceFolder(workspaceUri).uri); const folderValue = workspace.getConfiguration('python', workspace3Uri).inspect('pythonPath').workspaceFolderValue; diff --git a/src/test/interpreters/pythonPathUpdater.test.ts b/src/test/interpreters/pythonPathUpdater.test.ts index 2e75c5e4cfe5..65e12a3c2a78 100644 --- a/src/test/interpreters/pythonPathUpdater.test.ts +++ b/src/test/interpreters/pythonPathUpdater.test.ts @@ -7,6 +7,7 @@ import { PythonPathUpdaterServiceFactory } from '../../client/interpreter/config import { GlobalPythonPathUpdaterService } from '../../client/interpreter/configuration/services/globalUpdaterService'; import { WorkspacePythonPathUpdaterService } from '../../client/interpreter/configuration/services/workspaceUpdaterService'; import { WorkspacePythonPath } from '../../client/interpreter/contracts'; +import { InterpreterVersionService } from '../../client/interpreter/interpreterVersion'; import { clearPythonPathInWorkspaceFolder } from '../common'; import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST } from '../initialize'; @@ -72,7 +73,7 @@ suite('Python Path Settings Updater', () => { test('Updating Workspace Python Path using the PythonPathUpdaterService should work', async () => { const workspaceUri = Uri.file(workspaceRoot); - const updaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory()); + const updaterService = new PythonPathUpdaterService(new PythonPathUpdaterServiceFactory(), new InterpreterVersionService()); const pythonPath = `xWorkspacePythonPathFromUpdater${new Date().getMilliseconds()}`; await updaterService.updatePythonPath(pythonPath, ConfigurationTarget.Workspace, 'ui', workspace.getWorkspaceFolder(workspaceUri).uri); const workspaceValue = workspace.getConfiguration('python').inspect('pythonPath').workspaceValue; From 70c6054e387c2e3f0d6b008881cf3457e534dfb4 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 16:29:00 -0700 Subject: [PATCH 14/86] added telemetry for unit tests --- src/client/common/telemetry/constants.ts | 8 +- src/client/common/telemetry/telemetry.ts | 35 ++------- src/client/common/telemetry/types.ts | 14 +++- .../telemetry/vscode-extension-telemetry.d.ts | 26 +++++++ src/client/unittests/codeLenses/testFiles.ts | 17 ++-- .../unittests/common/baseTestManager.ts | 41 ++++++++-- src/client/unittests/common/constants.ts | 6 ++ src/client/unittests/common/testUtils.ts | 3 +- src/client/unittests/display/picker.ts | 13 ++-- src/client/unittests/main.ts | 77 +++++++++++-------- src/client/workspaceSymbols/contracts.ts | 2 +- .../interpreters/condaEnvFileService.test.ts | 14 ++-- src/test/unittests/debugger.test.ts | 18 ++--- src/test/unittests/nosetest.test.ts | 29 +++---- src/test/unittests/pytest.test.ts | 29 +++---- src/test/unittests/rediscover.test.ts | 6 +- src/test/unittests/unittest.test.ts | 27 +++---- 17 files changed, 216 insertions(+), 149 deletions(-) create mode 100644 src/client/common/telemetry/vscode-extension-telemetry.d.ts diff --git a/src/client/common/telemetry/constants.ts b/src/client/common/telemetry/constants.ts index 62471a65034d..0f01cf367ce9 100644 --- a/src/client/common/telemetry/constants.ts +++ b/src/client/common/telemetry/constants.ts @@ -15,8 +15,12 @@ export const REFACTOR_EXTRACT_VAR = 'REFACTOR_EXTRACT_VAR'; export const REFACTOR_EXTRACT_FUNCTION = 'REFACTOR_EXTRACT_FUNCTION'; export const REPL = 'REPL'; export const PYTHON_INTERPRETER = 'PYTHON_INTERPRETER'; -export const WORKSPACE_SYMBOLS_BUILD = 'WORKSPACE_SYMBOLS_BUILD'; -export const WORKSPACE_SYMBOLS_GO_TO = 'WORKSPACE_SYMBOLS_GO_TO'; +export const WORKSPACE_SYMBOLS_BUILD = 'WORKSPACE_SYMBOLS.BUILD'; +export const WORKSPACE_SYMBOLS_GO_TO = 'WORKSPACE_SYMBOLS.GO_TO'; export const EXECUTION_CODE = 'EXECUTION_CODE'; export const EXECUTION_DJANGO = 'EXECUTION_DJANGO'; export const DEBUGGER = 'DEBUGGER'; +export const UNITTEST_STOP = 'UNITTEST.STOP'; +export const UNITTEST_RUN = 'UNITTEST.RUN'; +export const UNITTEST_DISCOVER = 'UNITTEST.DISCOVER'; +export const UNITTEST_VIEW_OUTPUT = 'UNITTEST.VIEW_OUTPUT'; diff --git a/src/client/common/telemetry/telemetry.ts b/src/client/common/telemetry/telemetry.ts index 6659493f7abb..ab628ee3131f 100644 --- a/src/client/common/telemetry/telemetry.ts +++ b/src/client/common/telemetry/telemetry.ts @@ -1,8 +1,11 @@ +// tslint:disable-next-line:no-reference +/// import { extensions } from 'vscode'; -// tslint:disable-next-line:variable-name no-require-imports no-var-requires no-use-before-declare no-unsafe-any -const TelemetryReporter: typeof TelemetryReporterType = require('vscode-extension-telemetry'); +// tslint:disable-next-line:import-name +import TelemetryReporter from 'vscode-extension-telemetry'; -let telemetryReporter: TelemetryReporterType; +// tslint:disable-next-line:no-any +let telemetryReporter: TelemetryReporter; export function getTelemetryReporter() { if (telemetryReporter) { return telemetryReporter; @@ -14,31 +17,7 @@ export function getTelemetryReporter() { const extensionVersion = extension.packageJSON.version; // tslint:disable-next-line:no-unsafe-any const aiKey = extension.packageJSON.contributes.debuggers[0].aiKey; + // tslint:disable-next-line:no-unsafe-any return telemetryReporter = new TelemetryReporter(extensionId, extensionVersion, aiKey); } - -class TelemetryReporterType { - /** - * Constructs a new telemetry reporter - * @param {string} extensionId All events will be prefixed with this event name - * @param {string} extensionVersion Extension version to be reported with each event - * @param {string} key The application insights key - */ - // tslint:disable-next-line:no-empty - constructor(extensionId: string, extensionVersion: string, key: string) { } - - /** - * Sends a telemetry event - * @param {string} eventName The event name - * @param {object} properties An associative array of strings - * @param {object} measures An associative array of numbers - */ - // tslint:disable-next-line:member-access - public sendTelemetryEvent(eventName: string, properties?: { - [key: string]: string; - }, measures?: { - [key: string]: number; - // tslint:disable-next-line:no-empty - }): void { } -} diff --git a/src/client/common/telemetry/types.ts b/src/client/common/telemetry/types.ts index e3f472799e4c..7f966d7b6938 100644 --- a/src/client/common/telemetry/types.ts +++ b/src/client/common/telemetry/types.ts @@ -28,4 +28,16 @@ export type DebuggerTelemetry = { pyspark?: boolean; hasEnvVars?: boolean; }; -export type TelemetryProperties = FormatTelemetry | LintingTelemetry | EditorLoadTelemetry | PythonInterpreterTelemetry | CodeExecutionTelemetry; +export type TestRunTelemetry = { + tool: 'nosetest' | 'pytest' | 'unittest' + scope: 'currentFile' | 'all' | 'file' | 'class' | 'function' | 'failed'; + debugging: boolean; + trigger: 'ui' | 'codelens' | 'commandpalette' | 'auto'; + failed: boolean; +}; +export type TestDiscoverytTelemetry = { + tool: 'nosetest' | 'pytest' | 'unittest' + trigger: 'ui' | 'commandpalette'; + failed: boolean; +}; +export type TelemetryProperties = FormatTelemetry | LintingTelemetry | EditorLoadTelemetry | PythonInterpreterTelemetry | CodeExecutionTelemetry | TestRunTelemetry | TestDiscoverytTelemetry; diff --git a/src/client/common/telemetry/vscode-extension-telemetry.d.ts b/src/client/common/telemetry/vscode-extension-telemetry.d.ts new file mode 100644 index 000000000000..63944bc57471 --- /dev/null +++ b/src/client/common/telemetry/vscode-extension-telemetry.d.ts @@ -0,0 +1,26 @@ +declare module 'vscode-extension-telemetry' { + export default class TelemetryReporter { + /** + * Constructs a new telemetry reporter + * @param {string} extensionId All events will be prefixed with this event name + * @param {string} extensionVersion Extension version to be reported with each event + * @param {string} key The application insights key + */ + // tslint:disable-next-line:no-empty + constructor(extensionId: string, extensionVersion: string, key: string); + + /** + * Sends a telemetry event + * @param {string} eventName The event name + * @param {object} properties An associative array of strings + * @param {object} measures An associative array of numbers + */ + // tslint:disable-next-line:member-access + public sendTelemetryEvent(eventName: string, properties?: { + [key: string]: string; + }, measures?: { + [key: string]: number; + // tslint:disable-next-line:no-empty + }): void; + } +} diff --git a/src/client/unittests/codeLenses/testFiles.ts b/src/client/unittests/codeLenses/testFiles.ts index bfb3fd550ffe..8b444cb4c205 100644 --- a/src/client/unittests/codeLenses/testFiles.ts +++ b/src/client/unittests/codeLenses/testFiles.ts @@ -5,6 +5,7 @@ import { Uri } from 'vscode'; import * as constants from '../../common/constants'; import { PythonSymbolProvider } from '../../providers/symbolProvider'; import { ITestCollectionStorageService, TestFile, TestFunction, TestStatus, TestsToRun, TestSuite } from '../common/types'; +import { CommandSource } from '../common/constants'; type FunctionsAndSuites = { functions: TestFunction[]; @@ -107,12 +108,12 @@ export class TestFileCodeLensProvider implements CodeLensProvider { new CodeLens(range, { title: getTestStatusIcon(cls.status) + constants.Text.CodeLensRunUnitTest, command: constants.Commands.Tests_Run, - arguments: [file, { testSuite: [cls] }] + arguments: [CommandSource.codelens, file, { testSuite: [cls] }] }), new CodeLens(range, { title: getTestStatusIcon(cls.status) + constants.Text.CodeLensDebugUnitTest, command: constants.Commands.Tests_Debug, - arguments: [file, { testSuite: [cls] }] + arguments: [CommandSource.codelens, file, { testSuite: [cls] }] }) ]; } @@ -181,12 +182,12 @@ function getFunctionCodeLens(file: Uri, functionsAndSuites: FunctionsAndSuites, new CodeLens(range, { title: getTestStatusIcon(fn.status) + constants.Text.CodeLensRunUnitTest, command: constants.Commands.Tests_Run, - arguments: [file, { testFunction: [fn] }] + arguments: [CommandSource.codelens, file, { testFunction: [fn] }] }), new CodeLens(range, { title: getTestStatusIcon(fn.status) + constants.Text.CodeLensDebugUnitTest, command: constants.Commands.Tests_Debug, - arguments: [file, { testFunction: [fn] }] + arguments: [CommandSource.codelens, file, { testFunction: [fn] }] }) ]; } @@ -202,12 +203,12 @@ function getFunctionCodeLens(file: Uri, functionsAndSuites: FunctionsAndSuites, new CodeLens(range, { title: constants.Text.CodeLensRunUnitTest, command: constants.Commands.Tests_Run, - arguments: [file, { testFunction: functions }] + arguments: [CommandSource.codelens, file, { testFunction: functions }] }), new CodeLens(range, { title: constants.Text.CodeLensDebugUnitTest, command: constants.Commands.Tests_Debug, - arguments: [file, { testFunction: functions }] + arguments: [CommandSource.codelens, file, { testFunction: functions }] }) ]; } @@ -217,12 +218,12 @@ function getFunctionCodeLens(file: Uri, functionsAndSuites: FunctionsAndSuites, new CodeLens(range, { title: `${getTestStatusIcons(functions)}${constants.Text.CodeLensRunUnitTest} (Multiple)`, command: constants.Commands.Tests_Picker_UI, - arguments: [file, functions] + arguments: [CommandSource.codelens, file, functions] }), new CodeLens(range, { title: `${getTestStatusIcons(functions)}${constants.Text.CodeLensDebugUnitTest} (Multiple)`, command: constants.Commands.Tests_Picker_UI_Debug, - arguments: [file, functions] + arguments: [CommandSource.codelens, file, functions] }) ]; } diff --git a/src/client/unittests/common/baseTestManager.ts b/src/client/unittests/common/baseTestManager.ts index 4b4612c7da85..8cef0bf30bfc 100644 --- a/src/client/unittests/common/baseTestManager.ts +++ b/src/client/unittests/common/baseTestManager.ts @@ -4,7 +4,10 @@ import { Uri, workspace } from 'vscode'; import { IPythonSettings, PythonSettings } from '../../common/configSettings'; import { isNotInstalledError } from '../../common/helpers'; import { Installer, Product } from '../../common/installer'; -import { CANCELLATION_REASON } from './constants'; +import { UNITTEST_DISCOVER, UNITTEST_RUN } from '../../common/telemetry/constants'; +import { sendTelemetryEvent } from '../../common/telemetry/index'; +import { TestDiscoverytTelemetry, TestRunTelemetry } from '../../common/telemetry/types'; +import { CANCELLATION_REASON, CommandSource } from './constants'; import { displayTestErrorMessage } from './testUtils'; import { ITestCollectionStorageService, ITestResultsService, ITestsHelper, Tests, TestStatus, TestsToRun } from './types'; @@ -12,7 +15,7 @@ enum CancellationTokenType { testDiscovery, testRunner } - +type TestProvider = 'nosetest' | 'pytest' | 'unittest'; export abstract class BaseTestManager { public readonly workspace: Uri; protected readonly settings: IPythonSettings; @@ -23,7 +26,7 @@ export abstract class BaseTestManager { private testRunnerCancellationTokenSource: vscode.CancellationTokenSource; private installer: Installer; private discoverTestsPromise: Promise; - constructor(private testProvider: string, private product: Product, protected rootDirectory: string, + constructor(public readonly testProvider: TestProvider, private product: Product, protected rootDirectory: string, protected outputChannel: vscode.OutputChannel, private testCollectionStorage: ITestCollectionStorageService, protected testResultsService: ITestResultsService, protected testsHelper: ITestsHelper) { this._status = TestStatus.Unknown; @@ -66,7 +69,7 @@ export abstract class BaseTestManager { this.testResultsService.resetResults(this.tests); } - public async discoverTests(ignoreCache: boolean = false, quietMode: boolean = false, userInitiated: boolean = false): Promise { + public async discoverTests(cmdSource: CommandSource, ignoreCache: boolean = false, quietMode: boolean = false, userInitiated: boolean = false): Promise { if (this.discoverTestsPromise) { return this.discoverTestsPromise; } @@ -82,6 +85,12 @@ export abstract class BaseTestManager { if (userInitiated) { this.stop(); } + const telementryProperties: TestDiscoverytTelemetry = { + tool: this.testProvider, + // tslint:disable-next-line:no-any prefer-type-cast + trigger: cmdSource as any, + failed: false + }; this.createCancellationToken(CancellationTokenType.testDiscovery); return this.discoverTestsPromise = this.discoverTestsImpl(ignoreCache) @@ -108,7 +117,7 @@ export abstract class BaseTestManager { const wkspace = vscode.workspace.getWorkspaceFolder(vscode.Uri.file(this.rootDirectory)).uri; this.testCollectionStorage.storeTests(wkspace, tests); this.disposeCancellationToken(CancellationTokenType.testDiscovery); - + sendTelemetryEvent(UNITTEST_DISCOVER, undefined, telementryProperties); return tests; }).catch(reason => { if (isNotInstalledError(reason) && !quietMode) { @@ -122,6 +131,8 @@ export abstract class BaseTestManager { reason = CANCELLATION_REASON; this._status = TestStatus.Idle; } else { + telementryProperties.failed = true; + sendTelemetryEvent(UNITTEST_DISCOVER, undefined, telementryProperties); this._status = TestStatus.Error; this.outputChannel.appendLine('Test Disovery failed: '); // tslint:disable-next-line:prefer-template @@ -133,7 +144,7 @@ export abstract class BaseTestManager { return Promise.reject(reason); }); } - public runTest(testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise { + public runTest(cmdSource: CommandSource, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise { const moreInfo = { Test_Provider: this.testProvider, Run_Failed_Tests: 'false', @@ -141,22 +152,33 @@ export abstract class BaseTestManager { Run_Specific_Class: 'false', Run_Specific_Function: 'false' }; - + const telementryProperties: TestRunTelemetry = { + tool: this.testProvider, + scope: 'file', + debugging: debug === true, + trigger: cmdSource, + failed: false + }; if (runFailedTests === true) { // tslint:disable-next-line:prefer-template moreInfo.Run_Failed_Tests = runFailedTests + ''; + telementryProperties.scope = 'failed'; } if (testsToRun && typeof testsToRun === 'object') { if (Array.isArray(testsToRun.testFile) && testsToRun.testFile.length > 0) { + telementryProperties.scope = 'file'; moreInfo.Run_Specific_File = 'true'; } if (Array.isArray(testsToRun.testSuite) && testsToRun.testSuite.length > 0) { + telementryProperties.scope = 'class'; moreInfo.Run_Specific_Class = 'true'; } if (Array.isArray(testsToRun.testFunction) && testsToRun.testFunction.length > 0) { + telementryProperties.scope = 'function'; moreInfo.Run_Specific_Function = 'true'; } } + if (runFailedTests === false && testsToRun === null) { this.resetTestResults(); } @@ -167,7 +189,7 @@ export abstract class BaseTestManager { // If we do so, then we end up re-discovering the unit tests and clearing previously cached list of failed tests // Similarly, if running a specific test or test file, don't clear the cache (possible tests have some state information retained) const clearDiscoveredTestCache = runFailedTests || moreInfo.Run_Specific_File || moreInfo.Run_Specific_Class || moreInfo.Run_Specific_Function ? false : true; - return this.discoverTests(clearDiscoveredTestCache, true, true) + return this.discoverTests(cmdSource, clearDiscoveredTestCache, true, true) .catch(reason => { if (this.testDiscoveryCancellationToken && this.testDiscoveryCancellationToken.isCancellationRequested) { return Promise.reject(reason); @@ -184,6 +206,7 @@ export abstract class BaseTestManager { }).then(() => { this._status = TestStatus.Idle; this.disposeCancellationToken(CancellationTokenType.testRunner); + sendTelemetryEvent(UNITTEST_RUN, undefined, telementryProperties); return this.tests; }).catch(reason => { if (this.testRunnerCancellationToken && this.testRunnerCancellationToken.isCancellationRequested) { @@ -191,6 +214,8 @@ export abstract class BaseTestManager { this._status = TestStatus.Idle; } else { this._status = TestStatus.Error; + telementryProperties.failed = true; + sendTelemetryEvent(UNITTEST_RUN, undefined, telementryProperties); } this.disposeCancellationToken(CancellationTokenType.testRunner); return Promise.reject(reason); diff --git a/src/client/unittests/common/constants.ts b/src/client/unittests/common/constants.ts index 3d428cfad97c..9bd66948c6e3 100644 --- a/src/client/unittests/common/constants.ts +++ b/src/client/unittests/common/constants.ts @@ -1 +1,7 @@ export const CANCELLATION_REASON = 'cancelled_user_request'; +export enum CommandSource { + auto = 'auto', + ui = 'ui', + codelens = 'codelens', + commandPalette = 'commandpalette' +} diff --git a/src/client/unittests/common/testUtils.ts b/src/client/unittests/common/testUtils.ts index 7ce389bdf66f..9011df036caf 100644 --- a/src/client/unittests/common/testUtils.ts +++ b/src/client/unittests/common/testUtils.ts @@ -3,6 +3,7 @@ import * as vscode from 'vscode'; import { Uri, workspace } from 'vscode'; import { window } from 'vscode'; import * as constants from '../../common/constants'; +import { CommandSource } from './constants'; import { TestFlatteningVisitor } from './testVisitors/flatteningVisitor'; import { TestResultResetVisitor } from './testVisitors/resultResetVisitor'; import { TestFile, TestFolder, Tests, TestsToRun } from './types'; @@ -23,7 +24,7 @@ export async function selectTestWorkspace(): Promise { export function displayTestErrorMessage(message: string) { vscode.window.showErrorMessage(message, constants.Button_Text_Tests_View_Output).then(action => { if (action === constants.Button_Text_Tests_View_Output) { - vscode.commands.executeCommand(constants.Commands.Tests_ViewOutput); + vscode.commands.executeCommand(constants.Commands.Tests_ViewOutput, CommandSource.ui); } }); diff --git a/src/client/unittests/display/picker.ts b/src/client/unittests/display/picker.ts index 61c18840ae51..2b3d47652abf 100644 --- a/src/client/unittests/display/picker.ts +++ b/src/client/unittests/display/picker.ts @@ -2,6 +2,7 @@ import * as path from 'path'; import { QuickPickItem, Uri, window } from 'vscode'; import * as vscode from 'vscode'; import * as constants from '../../common/constants'; +import { CommandSource } from '../common/constants'; import { FlattenedTestFunction, ITestCollectionStorageService, TestFile, TestFunction, Tests, TestStatus, TestsToRun } from '../common/types'; export class TestDisplay { @@ -13,10 +14,10 @@ export class TestDisplay { } }); } - public displayTestUI(wkspace: Uri) { + public displayTestUI(cmdSource: CommandSource, wkspace: Uri) { const tests = this.testCollectionStorage.getTests(wkspace); window.showQuickPick(buildItems(tests), { matchOnDescription: true, matchOnDetail: true }) - .then(item => onItemSelected(wkspace, item, false)); + .then(item => onItemSelected(cmdSource, wkspace, item, false)); } public selectTestFunction(rootDirectory: string, tests: Tests): Promise { return new Promise((resolve, reject) => { @@ -40,7 +41,7 @@ export class TestDisplay { }, reject); }); } - public displayFunctionTestPickerUI(wkspace: Uri, rootDirectory: string, file: Uri, testFunctions: TestFunction[], debug?: boolean) { + public displayFunctionTestPickerUI(cmdSource: CommandSource, wkspace: Uri, rootDirectory: string, file: Uri, testFunctions: TestFunction[], debug?: boolean) { const tests = this.testCollectionStorage.getTests(wkspace); if (!tests) { return; @@ -57,7 +58,7 @@ export class TestDisplay { window.showQuickPick(buildItemsForFunctions(rootDirectory, flattenedFunctions, undefined, undefined, debug), { matchOnDescription: true, matchOnDetail: true }).then(testItem => { - return onItemSelected(wkspace, testItem, debug); + return onItemSelected(cmdSource, wkspace, testItem, debug); }); } } @@ -187,13 +188,13 @@ function buildItemsForTestFiles(rootDirectory: string, testFiles: TestFile[]): T }); return fileItems; } -function onItemSelected(wkspace: Uri, selection: TestItem, debug?: boolean) { +function onItemSelected(cmdSource: CommandSource, wkspace: Uri, selection: TestItem, debug?: boolean) { if (!selection || typeof selection.type !== 'number') { return; } let cmd = ''; // tslint:disable-next-line:no-any - const args: any[] = [wkspace]; + const args: any[] = [cmdSource, wkspace]; switch (selection.type) { case Type.Null: { return; diff --git a/src/client/unittests/main.ts b/src/client/unittests/main.ts index adb86808d695..cb98402e1aee 100644 --- a/src/client/unittests/main.ts +++ b/src/client/unittests/main.ts @@ -3,10 +3,13 @@ import { Uri, window, workspace } from 'vscode'; import * as vscode from 'vscode'; import { IUnitTestSettings, PythonSettings } from '../common/configSettings'; import * as constants from '../common/constants'; +import { UNITTEST_STOP, UNITTEST_VIEW_OUTPUT } from '../common/telemetry/constants'; +import { sendTelemetryEvent } from '../common/telemetry/index'; +import { TestRunTelemetry } from '../common/telemetry/types'; import { PythonSymbolProvider } from '../providers/symbolProvider'; import { activateCodeLenses } from './codeLenses/main'; import { BaseTestManager } from './common/baseTestManager'; -import { CANCELLATION_REASON } from './common/constants'; +import { CANCELLATION_REASON, CommandSource } from './common/constants'; import { DebugLauncher } from './common/debugLauncher'; import { TestCollectionStorageService } from './common/storageService'; import { TestManagerServiceFactory } from './common/testManagerServiceFactory'; @@ -73,7 +76,7 @@ async function onDocumentSaved(doc: vscode.TextDocument): Promise { if (!testManager) { return; } - const tests = await testManager.discoverTests(false, true); + const tests = await testManager.discoverTests(CommandSource.auto, false, true); if (!tests || !Array.isArray(tests.testFiles) || tests.testFiles.length === 0) { return; } @@ -84,7 +87,7 @@ async function onDocumentSaved(doc: vscode.TextDocument): Promise { if (timeoutId) { clearTimeout(timeoutId); } - timeoutId = setTimeout(() => discoverTests(doc.uri, true), 1000); + timeoutId = setTimeout(() => discoverTests(CommandSource.auto, doc.uri, true), 1000); } function dispose() { @@ -93,62 +96,67 @@ function dispose() { } function registerCommands(): vscode.Disposable[] { const disposables = []; - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Discover, (resource?: Uri) => { + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Discover, (cmdSource: CommandSource = CommandSource.commandPalette, resource?: Uri) => { // Ignore the exceptions returned. // This command will be invoked else where in the extension. // tslint:disable-next-line:no-empty - discoverTests(resource, true, true).catch(() => { }); + discoverTests(cmdSource, resource, true, true).catch(() => { }); })); - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Run_Failed, (resource: Uri) => runTestsImpl(resource, undefined, true))); + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Run_Failed, (cmdSource: CommandSource = CommandSource.commandPalette, resource: Uri) => runTestsImpl(cmdSource, resource, undefined, true))); // tslint:disable-next-line:no-unnecessary-callback-wrapper - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Run, (file: Uri, testToRun?: TestsToRun) => runTestsImpl(file, testToRun))); - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Debug, (file: Uri, testToRun: TestsToRun) => runTestsImpl(file, testToRun, false, true))); + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Run, (cmdSource: CommandSource = CommandSource.commandPalette, file: Uri, testToRun?: TestsToRun) => runTestsImpl(cmdSource, file, testToRun))); + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Debug, (cmdSource: CommandSource = CommandSource.commandPalette, file: Uri, testToRun: TestsToRun) => runTestsImpl(cmdSource, file, testToRun, false, true))); // tslint:disable-next-line:no-unnecessary-callback-wrapper - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_View_UI, () => displayUI())); + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_View_UI, () => displayUI(CommandSource.commandPalette))); // tslint:disable-next-line:no-unnecessary-callback-wrapper - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Picker_UI, (file: Uri, testFunctions: TestFunction[]) => displayPickerUI(file, testFunctions))); - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Picker_UI_Debug, (file, testFunctions) => displayPickerUI(file, testFunctions, true))); + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Picker_UI, (cmdSource: CommandSource = CommandSource.commandPalette, file: Uri, testFunctions: TestFunction[]) => displayPickerUI(cmdSource, file, testFunctions))); + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Picker_UI_Debug, (cmdSource: CommandSource = CommandSource.commandPalette, file: Uri, testFunctions: TestFunction[]) => displayPickerUI(cmdSource, file, testFunctions, true))); // tslint:disable-next-line:no-unnecessary-callback-wrapper disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Stop, (resource: Uri) => stopTests(resource))); - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_ViewOutput, () => outChannel.show())); + // tslint:disable-next-line:no-unnecessary-callback-wrapper + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_ViewOutput, (cmdSource: CommandSource = CommandSource.commandPalette) => viewOutput(cmdSource))); disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Ask_To_Stop_Discovery, () => displayStopUI('Stop discovering tests'))); disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Ask_To_Stop_Test, () => displayStopUI('Stop running tests'))); // tslint:disable-next-line:no-unnecessary-callback-wrapper - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Select_And_Run_Method, (resource: Uri) => selectAndRunTestMethod(resource))); - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Select_And_Debug_Method, (resource: Uri) => selectAndRunTestMethod(resource, true))); + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Select_And_Run_Method, (cmdSource: CommandSource = CommandSource.commandPalette, resource: Uri) => selectAndRunTestMethod(cmdSource, resource))); + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Select_And_Debug_Method, (cmdSource: CommandSource = CommandSource.commandPalette, resource: Uri) => selectAndRunTestMethod(cmdSource, resource, true))); // tslint:disable-next-line:no-unnecessary-callback-wrapper - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Select_And_Run_File, () => selectAndRunTestFile())); + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Select_And_Run_File, (cmdSource: CommandSource = CommandSource.commandPalette) => selectAndRunTestFile(cmdSource))); // tslint:disable-next-line:no-unnecessary-callback-wrapper - disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Run_Current_File, () => runCurrentTestFile())); + disposables.push(vscode.commands.registerCommand(constants.Commands.Tests_Run_Current_File, (cmdSource: CommandSource = CommandSource.commandPalette) => runCurrentTestFile(cmdSource))); return disposables; } -async function displayUI() { +function viewOutput(cmdSource: CommandSource) { + sendTelemetryEvent(UNITTEST_VIEW_OUTPUT); + outChannel.show(); +} +async function displayUI(cmdSource: CommandSource) { const testManager = await getTestManager(true); if (!testManager) { return; } testDisplay = testDisplay ? testDisplay : new TestDisplay(testCollectionStorage); - testDisplay.displayTestUI(testManager.workspace); + testDisplay.displayTestUI(cmdSource, testManager.workspace); } -async function displayPickerUI(file: Uri, testFunctions: TestFunction[], debug?: boolean) { +async function displayPickerUI(cmdSource: CommandSource, file: Uri, testFunctions: TestFunction[], debug?: boolean) { const testManager = await getTestManager(true, file); if (!testManager) { return; } testDisplay = testDisplay ? testDisplay : new TestDisplay(testCollectionStorage); - testDisplay.displayFunctionTestPickerUI(testManager.workspace, testManager.workingDirectory, file, testFunctions, debug); + testDisplay.displayFunctionTestPickerUI(cmdSource, testManager.workspace, testManager.workingDirectory, file, testFunctions, debug); } -async function selectAndRunTestMethod(resource: Uri, debug?: boolean) { +async function selectAndRunTestMethod(cmdSource: CommandSource, resource: Uri, debug?: boolean) { const testManager = await getTestManager(true, resource); if (!testManager) { return; } try { - await testManager.discoverTests(true, true, true); + await testManager.discoverTests(cmdSource, true, true, true); } catch (ex) { return; } @@ -160,15 +168,15 @@ async function selectAndRunTestMethod(resource: Uri, debug?: boolean) { return; } // tslint:disable-next-line:prefer-type-cast - await runTestsImpl(testManager.workspace, { testFunction: [selectedTestFn.testFunction] } as TestsToRun, debug); + await runTestsImpl(cmdSource, testManager.workspace, { testFunction: [selectedTestFn.testFunction] } as TestsToRun, debug); } -async function selectAndRunTestFile() { +async function selectAndRunTestFile(cmdSource: CommandSource) { const testManager = await getTestManager(true); if (!testManager) { return; } try { - await testManager.discoverTests(true, true, true); + await testManager.discoverTests(cmdSource, true, true, true); } catch (ex) { return; } @@ -180,9 +188,9 @@ async function selectAndRunTestFile() { return; } // tslint:disable-next-line:prefer-type-cast - await runTestsImpl(testManager.workspace, { testFile: [selectedFile] } as TestsToRun); + await runTestsImpl(cmdSource, testManager.workspace, { testFile: [selectedFile] } as TestsToRun); } -async function runCurrentTestFile() { +async function runCurrentTestFile(cmdSource: CommandSource) { if (!window.activeTextEditor) { return; } @@ -191,7 +199,7 @@ async function runCurrentTestFile() { return; } try { - await testManager.discoverTests(true, true, true); + await testManager.discoverTests(cmdSource, true, true, true); } catch (ex) { return; } @@ -203,7 +211,7 @@ async function runCurrentTestFile() { return; } // tslint:disable-next-line:prefer-type-cast - await runTestsImpl(testManager.workspace, { testFile: [testFiles[0]] } as TestsToRun); + await runTestsImpl(cmdSource, testManager.workspace, { testFile: [testFiles[0]] } as TestsToRun); } async function displayStopUI(message: string) { const testManager = await getTestManager(true); @@ -265,15 +273,16 @@ function autoDiscoverTests() { // No need to display errors. // tslint:disable-next-line:no-empty - discoverTests(workspace.workspaceFolders[0].uri, true).catch(() => { }); + discoverTests(CommandSource.auto, workspace.workspaceFolders[0].uri, true).catch(() => { }); } async function stopTests(resource: Uri) { + sendTelemetryEvent(UNITTEST_STOP); const testManager = await getTestManager(true, resource); if (testManager) { testManager.stop(); } } -async function discoverTests(resource?: Uri, ignoreCache?: boolean, userInitiated?: boolean) { +async function discoverTests(cmdSource: CommandSource, resource?: Uri, ignoreCache?: boolean, userInitiated?: boolean) { const testManager = await getTestManager(true, resource); if (!testManager) { return; @@ -281,7 +290,7 @@ async function discoverTests(resource?: Uri, ignoreCache?: boolean, userInitiate if (testManager && (testManager.status !== TestStatus.Discovering && testManager.status !== TestStatus.Running)) { testResultDisplay = testResultDisplay ? testResultDisplay : new TestResultDisplay(outChannel, onDidChange); - const discoveryPromise = testManager.discoverTests(ignoreCache, false, userInitiated); + const discoveryPromise = testManager.discoverTests(cmdSource, ignoreCache, false, userInitiated); testResultDisplay.displayDiscoverStatus(discoveryPromise); await discoveryPromise; } @@ -299,14 +308,14 @@ function isTestsToRun(arg: any): arg is TestsToRun { } return false; } -async function runTestsImpl(resource?: Uri, testsToRun?: TestsToRun, runFailedTests?: boolean, debug: boolean = false) { +async function runTestsImpl(cmdSource: CommandSource, resource?: Uri, testsToRun?: TestsToRun, runFailedTests?: boolean, debug: boolean = false) { const testManager = await getTestManager(true, resource); if (!testManager) { return; } testResultDisplay = testResultDisplay ? testResultDisplay : new TestResultDisplay(outChannel, onDidChange); - const promise = testManager.runTest(testsToRun, runFailedTests, debug) + const promise = testManager.runTest(cmdSource, testsToRun, runFailedTests, debug) .catch(reason => { if (reason !== CANCELLATION_REASON) { outChannel.appendLine(`Error: ${reason}`); diff --git a/src/client/workspaceSymbols/contracts.ts b/src/client/workspaceSymbols/contracts.ts index c5255c3fbcc2..cb53f8b7d397 100644 --- a/src/client/workspaceSymbols/contracts.ts +++ b/src/client/workspaceSymbols/contracts.ts @@ -1,4 +1,4 @@ -import { SymbolKind, Position } from 'vscode'; +import { Position, SymbolKind } from 'vscode'; export interface Tag { fileName: string; diff --git a/src/test/interpreters/condaEnvFileService.test.ts b/src/test/interpreters/condaEnvFileService.test.ts index 26bd45c9928d..88f3ae8934e3 100644 --- a/src/test/interpreters/condaEnvFileService.test.ts +++ b/src/test/interpreters/condaEnvFileService.test.ts @@ -1,24 +1,24 @@ import * as assert from 'assert'; -import * as path from 'path'; import * as fs from 'fs-extra'; import { EOL } from 'os'; -import { initialize, initializeTest } from '../initialize'; +import * as path from 'path'; import { IS_WINDOWS } from '../../client/common/utils'; -import { MockInterpreterVersionProvider } from './mocks'; -import { CondaEnvFileService } from '../../client/interpreter/locators/services/condaEnvFileService'; import { AnacondaCompanyName, AnacondaCompanyNames, AnacondaDisplayName, - CONDA_RELATIVE_PY_PATH, + CONDA_RELATIVE_PY_PATH } from '../../client/interpreter/locators/services/conda'; +import { CondaEnvFileService } from '../../client/interpreter/locators/services/condaEnvFileService'; +import { initialize, initializeTest } from '../initialize'; +import { MockInterpreterVersionProvider } from './mocks'; const environmentsPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'environments'); const environmentsFilePath = path.join(environmentsPath, 'environments.txt'); suite('Interpreters from Conda Environments Text File', () => { - suiteSetup(() => initialize()); - setup(() => initializeTest()); + suiteSetup(initialize); + setup(initializeTest); suiteTeardown(async () => { // Clear the file so we don't get unwanted changes prompting for a checkin of this file await updateEnvWithInterpreters([]); diff --git a/src/test/unittests/debugger.test.ts b/src/test/unittests/debugger.test.ts index c908a7f7080e..0ef0391483fb 100644 --- a/src/test/unittests/debugger.test.ts +++ b/src/test/unittests/debugger.test.ts @@ -5,7 +5,7 @@ import * as path from 'path'; import { ConfigurationTarget } from 'vscode'; import { createDeferred } from '../../client/common/helpers'; import { BaseTestManager } from '../../client/unittests/common/baseTestManager'; -import { CANCELLATION_REASON } from '../../client/unittests/common/constants'; +import { CANCELLATION_REASON, CommandSource } from '../../client/unittests/common/constants'; import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; import { TestResultsService } from '../../client/unittests/common/testResultsService'; import { TestsHelper } from '../../client/unittests/common/testUtils'; @@ -75,13 +75,13 @@ suite('Unit Tests Debugging', () => { } async function testStartingDebugger() { - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.commandPalette, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); const testFunction = [tests.testFunctions[0].testFunction]; - testManager.runTest({ testFunction }, false, true); + testManager.runTest(CommandSource.commandPalette, { testFunction }, false, true); const launched = await mockDebugLauncher.launched; assert.isTrue(launched, 'Debugger not launched'); } @@ -108,17 +108,17 @@ suite('Unit Tests Debugging', () => { }); async function testStoppingDebugger() { - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.commandPalette, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); const testFunction = [tests.testFunctions[0].testFunction]; - const runningPromise = testManager.runTest({ testFunction }, false, true); + const runningPromise = testManager.runTest(CommandSource.commandPalette, { testFunction }, false, true); const launched = await mockDebugLauncher.launched; assert.isTrue(launched, 'Debugger not launched'); - const discoveryPromise = testManager.discoverTests(true, true, true); + const discoveryPromise = testManager.discoverTests(CommandSource.commandPalette, true, true, true); expect(runningPromise).eventually.throws(CANCELLATION_REASON, 'Incorrect reason for ending the debugger'); } @@ -145,17 +145,17 @@ suite('Unit Tests Debugging', () => { }); async function testDebuggerWhenRediscoveringTests() { - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.commandPalette, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); const testFunction = [tests.testFunctions[0].testFunction]; - const runningPromise = testManager.runTest({ testFunction }, false, true); + const runningPromise = testManager.runTest(CommandSource.commandPalette, { testFunction }, false, true); const launched = await mockDebugLauncher.launched; assert.isTrue(launched, 'Debugger not launched'); - const discoveryPromise = testManager.discoverTests(false, true); + const discoveryPromise = testManager.discoverTests(CommandSource.commandPalette, false, true); const deferred = createDeferred(); discoveryPromise diff --git a/src/test/unittests/nosetest.test.ts b/src/test/unittests/nosetest.test.ts index 9105c483fec3..c932a1950332 100644 --- a/src/test/unittests/nosetest.test.ts +++ b/src/test/unittests/nosetest.test.ts @@ -2,6 +2,7 @@ import * as assert from 'assert'; import * as fs from 'fs'; import * as path from 'path'; import * as vscode from 'vscode'; +import { CommandSource } from '../../client/unittests/common/constants'; import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; import { TestResultsService } from '../../client/unittests/common/testResultsService'; import { TestsHelper } from '../../client/unittests/common/testUtils'; @@ -68,7 +69,7 @@ suite('Unit Tests (nosetest)', () => { test('Discover Tests (single test file)', async () => { createTestManager(UNITTEST_SINGLE_TEST_FILE_PATH); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); @@ -77,7 +78,7 @@ suite('Unit Tests (nosetest)', () => { test('Check that nameToRun in testSuites has class name after : (single test file)', async () => { createTestManager(UNITTEST_SINGLE_TEST_FILE_PATH); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); @@ -91,7 +92,7 @@ suite('Unit Tests (nosetest)', () => { test('Discover Tests (-m=test)', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 5, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 16, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 6, 'Incorrect number of test suites'); @@ -105,7 +106,7 @@ suite('Unit Tests (nosetest)', () => { test('Discover Tests (-w=specific -m=tst)', async () => { await updateSetting('unitTest.nosetestArgs', ['-w', 'specific', '-m', 'tst'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); @@ -116,7 +117,7 @@ suite('Unit Tests (nosetest)', () => { test('Discover Tests (-m=test_)', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test_'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 3, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); @@ -126,7 +127,7 @@ suite('Unit Tests (nosetest)', () => { test('Run Tests', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); createTestManager(); - const results = await testManager.runTest(); + const results = await testManager.runTest(CommandSource.ui); assert.equal(results.summary.errors, 1, 'Errors'); assert.equal(results.summary.failures, 7, 'Failures'); assert.equal(results.summary.passed, 6, 'Passed'); @@ -136,13 +137,13 @@ suite('Unit Tests (nosetest)', () => { test('Run Failed Tests', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); createTestManager(); - let results = await testManager.runTest(); + let results = await testManager.runTest(CommandSource.ui); assert.equal(results.summary.errors, 1, 'Errors'); assert.equal(results.summary.failures, 7, 'Failures'); assert.equal(results.summary.passed, 6, 'Passed'); assert.equal(results.summary.skipped, 2, 'skipped'); - results = await testManager.runTest(undefined, true); + results = await testManager.runTest(CommandSource.ui, undefined, true); assert.equal(results.summary.errors, 1, 'Errors again'); assert.equal(results.summary.failures, 7, 'Failures again'); assert.equal(results.summary.passed, 0, 'Passed again'); @@ -152,12 +153,12 @@ suite('Unit Tests (nosetest)', () => { test('Run Specific Test File', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); const testFileToRun = tests.testFiles.find(t => t.fullPath.endsWith('test_root.py')); assert.ok(testFileToRun, 'Test file not found'); // tslint:disable-next-line:no-non-null-assertion const testFile: TestsToRun = { testFile: [testFileToRun!], testFolder: [], testFunction: [], testSuite: [] }; - const results = await testManager.runTest(testFile); + const results = await testManager.runTest(CommandSource.ui, testFile); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 1, 'Failures'); assert.equal(results.summary.passed, 1, 'Passed'); @@ -167,12 +168,12 @@ suite('Unit Tests (nosetest)', () => { test('Run Specific Test Suite', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); const testSuiteToRun = tests.testSuites.find(s => s.xmlClassName === 'test_root.Test_Root_test1'); assert.ok(testSuiteToRun, 'Test suite not found'); // tslint:disable-next-line:no-non-null-assertion const testSuite: TestsToRun = { testFile: [], testFolder: [], testFunction: [], testSuite: [testSuiteToRun!.testSuite] }; - const results = await testManager.runTest(testSuite); + const results = await testManager.runTest(CommandSource.ui, testSuite); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 1, 'Failures'); assert.equal(results.summary.passed, 1, 'Passed'); @@ -182,12 +183,12 @@ suite('Unit Tests (nosetest)', () => { test('Run Specific Test Function', async () => { await updateSetting('unitTest.nosetestArgs', ['-m', 'test'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); const testFnToRun = tests.testFunctions.find(f => f.xmlClassName === 'test_root.Test_Root_test1'); assert.ok(testFnToRun, 'Test function not found'); // tslint:disable-next-line:no-non-null-assertion const testFn: TestsToRun = { testFile: [], testFolder: [], testFunction: [testFnToRun!.testFunction], testSuite: [] }; - const results = await testManager.runTest(testFn); + const results = await testManager.runTest(CommandSource.ui, testFn); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 1, 'Failures'); assert.equal(results.summary.passed, 0, 'Passed'); diff --git a/src/test/unittests/pytest.test.ts b/src/test/unittests/pytest.test.ts index cf0ba4130ca8..1b016f4228cc 100644 --- a/src/test/unittests/pytest.test.ts +++ b/src/test/unittests/pytest.test.ts @@ -1,6 +1,7 @@ import * as assert from 'assert'; import * as path from 'path'; import * as vscode from 'vscode'; +import { CommandSource } from '../../client/unittests/common/constants'; import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; import { TestResultsService } from '../../client/unittests/common/testResultsService'; import { TestsHelper } from '../../client/unittests/common/testUtils'; @@ -55,7 +56,7 @@ suite('Unit Tests (PyTest)', () => { resultsService = new TestResultsService(); testsHelper = new TestsHelper(); testManager = new pytest.TestManager(UNITTEST_SINGLE_TEST_FILE_PATH, outChannel, storageService, resultsService, testsHelper, new MockDebugLauncher()); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 6, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); @@ -66,7 +67,7 @@ suite('Unit Tests (PyTest)', () => { test('Discover Tests (pattern = test_)', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 6, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 29, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 8, 'Incorrect number of test suites'); @@ -81,7 +82,7 @@ suite('Unit Tests (PyTest)', () => { test('Discover Tests (pattern = _test)', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=_test.py'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); @@ -92,7 +93,7 @@ suite('Unit Tests (PyTest)', () => { await updateSetting('unitTest.pyTestArgs', [], rootWorkspaceUri, configTarget); rootDirectory = UNITTEST_TEST_FILES_PATH_WITH_CONFIGS; createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 14, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 4, 'Incorrect number of test suites'); @@ -103,7 +104,7 @@ suite('Unit Tests (PyTest)', () => { test('Run Tests', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); createTestManager(); - const results = await testManager.runTest(); + const results = await testManager.runTest(CommandSource.ui); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 9, 'Failures'); assert.equal(results.summary.passed, 17, 'Passed'); @@ -113,13 +114,13 @@ suite('Unit Tests (PyTest)', () => { test('Run Failed Tests', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); createTestManager(); - let results = await testManager.runTest(); + let results = await testManager.runTest(CommandSource.ui); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 9, 'Failures'); assert.equal(results.summary.passed, 17, 'Passed'); assert.equal(results.summary.skipped, 3, 'skipped'); - results = await testManager.runTest(undefined, true); + results = await testManager.runTest(CommandSource.ui, undefined, true); assert.equal(results.summary.errors, 0, 'Failed Errors'); assert.equal(results.summary.failures, 9, 'Failed Failures'); assert.equal(results.summary.passed, 0, 'Failed Passed'); @@ -129,7 +130,7 @@ suite('Unit Tests (PyTest)', () => { test('Run Specific Test File', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); createTestManager(); - await testManager.discoverTests(true, true); + await testManager.discoverTests(CommandSource.ui, true, true); const testFile: TestFile = { fullPath: path.join(rootDirectory, 'tests', 'test_another_pytest.py'), name: 'tests/test_another_pytest.py', @@ -140,7 +141,7 @@ suite('Unit Tests (PyTest)', () => { time: 0 }; const testFileToRun: TestsToRun = { testFile: [testFile], testFolder: [], testFunction: [], testSuite: [] }; - const results = await testManager.runTest(testFileToRun); + const results = await testManager.runTest(CommandSource.ui, testFileToRun); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 1, 'Failures'); assert.equal(results.summary.passed, 3, 'Passed'); @@ -150,9 +151,9 @@ suite('Unit Tests (PyTest)', () => { test('Run Specific Test Suite', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); const testSuite: TestsToRun = { testFile: [], testFolder: [], testFunction: [], testSuite: [tests.testSuites[0].testSuite] }; - const results = await testManager.runTest(testSuite); + const results = await testManager.runTest(CommandSource.ui, testSuite); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 1, 'Failures'); assert.equal(results.summary.passed, 1, 'Passed'); @@ -162,9 +163,9 @@ suite('Unit Tests (PyTest)', () => { test('Run Specific Test Function', async () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); const testFn: TestsToRun = { testFile: [], testFolder: [], testFunction: [tests.testFunctions[0].testFunction], testSuite: [] }; - const results = await testManager.runTest(testFn); + const results = await testManager.runTest(CommandSource.ui, testFn); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 1, 'Failures'); assert.equal(results.summary.passed, 0, 'Passed'); @@ -175,7 +176,7 @@ suite('Unit Tests (PyTest)', () => { await updateSetting('unitTest.pyTestArgs', ['-k=test_'], rootWorkspaceUri, configTarget); createTestManager(unitTestTestFilesCwdPath); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); assert.equal(tests.testFolders.length, 1, 'Incorrect number of test folders'); assert.equal(tests.testFunctions.length, 1, 'Incorrect number of test functions'); diff --git a/src/test/unittests/rediscover.test.ts b/src/test/unittests/rediscover.test.ts index 8478b9b8e14b..d8382a73b0d3 100644 --- a/src/test/unittests/rediscover.test.ts +++ b/src/test/unittests/rediscover.test.ts @@ -3,7 +3,7 @@ import * as fs from 'fs-extra'; import * as path from 'path'; import { ConfigurationTarget, Position, Range, Uri, window, workspace } from 'vscode'; import { BaseTestManager } from '../../client/unittests/common/baseTestManager'; -import { CANCELLATION_REASON } from '../../client/unittests/common/constants'; +import { CANCELLATION_REASON, CommandSource } from '../../client/unittests/common/constants'; import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; import { TestResultsService } from '../../client/unittests/common/testResultsService'; import { TestsHelper } from '../../client/unittests/common/testUtils'; @@ -75,13 +75,13 @@ suite('Unit Tests Discovery', () => { } async function discoverUnitTests() { - let tests = await testManager.discoverTests(true, true); + let tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); await deleteFile(path.join(path.dirname(testFile), `${path.basename(testFile, '.py')}.pyc`)); await fs.copy(testFileWithMoreTests, testFile, { overwrite: true }); - tests = await testManager.discoverTests(true, true); + tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFunctions.length, 4, 'Incorrect number of updated test functions'); } diff --git a/src/test/unittests/unittest.test.ts b/src/test/unittests/unittest.test.ts index bcf201bcc3dc..d333ed32fa9c 100644 --- a/src/test/unittests/unittest.test.ts +++ b/src/test/unittests/unittest.test.ts @@ -2,6 +2,7 @@ import * as assert from 'assert'; import * as fs from 'fs-extra'; import * as path from 'path'; import { ConfigurationTarget } from 'vscode'; +import { CommandSource } from '../../client/unittests/common/constants'; import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; import { TestResultsService } from '../../client/unittests/common/testResultsService'; import { TestsHelper } from '../../client/unittests/common/testUtils'; @@ -68,7 +69,7 @@ suite('Unit Tests (unittest)', () => { resultsService = new TestResultsService(); testsHelper = new TestsHelper(); testManager = new unittest.TestManager(UNITTEST_SINGLE_TEST_FILE_PATH, outChannel, storageService, resultsService, testsHelper, new MockDebugLauncher()); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 3, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); @@ -78,7 +79,7 @@ suite('Unit Tests (unittest)', () => { test('Discover Tests', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 2, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 9, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 3, 'Incorrect number of test suites'); @@ -89,7 +90,7 @@ suite('Unit Tests (unittest)', () => { test('Discover Tests (pattern = *_test_*.py)', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=*_test*.py'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); assert.equal(tests.testFunctions.length, 2, 'Incorrect number of test functions'); assert.equal(tests.testSuites.length, 1, 'Incorrect number of test suites'); @@ -99,7 +100,7 @@ suite('Unit Tests (unittest)', () => { test('Run Tests', async () => { await updateSetting('unitTest.unittestArgs', ['-v', '-s', './tests', '-p', 'test_unittest*.py'], rootWorkspaceUri, configTarget); createTestManager(); - const results = await testManager.runTest(); + const results = await testManager.runTest(CommandSource.ui); assert.equal(results.summary.errors, 1, 'Errors'); assert.equal(results.summary.failures, 4, 'Failures'); assert.equal(results.summary.passed, 3, 'Passed'); @@ -109,13 +110,13 @@ suite('Unit Tests (unittest)', () => { test('Run Failed Tests', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); createTestManager(); - let results = await testManager.runTest(); + let results = await testManager.runTest(CommandSource.ui); assert.equal(results.summary.errors, 1, 'Errors'); assert.equal(results.summary.failures, 4, 'Failures'); assert.equal(results.summary.passed, 3, 'Passed'); assert.equal(results.summary.skipped, 1, 'skipped'); - results = await testManager.runTest(undefined, true); + results = await testManager.runTest(CommandSource.ui, undefined, true); assert.equal(results.summary.errors, 1, 'Failed Errors'); assert.equal(results.summary.failures, 4, 'Failed Failures'); assert.equal(results.summary.passed, 0, 'Failed Passed'); @@ -125,12 +126,12 @@ suite('Unit Tests (unittest)', () => { test('Run Specific Test File', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); createTestManager(unitTestSpecificTestFilesPath); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); // tslint:disable-next-line:no-non-null-assertion const testFileToTest = tests.testFiles.find(f => f.name === 'test_unittest_one.py')!; const testFile: TestsToRun = { testFile: [testFileToTest], testFolder: [], testFunction: [], testSuite: [] }; - const results = await testManager.runTest(testFile); + const results = await testManager.runTest(CommandSource.ui, testFile); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 1, 'Failures'); @@ -141,12 +142,12 @@ suite('Unit Tests (unittest)', () => { test('Run Specific Test Suite', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); createTestManager(unitTestSpecificTestFilesPath); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); // tslint:disable-next-line:no-non-null-assertion const testSuiteToTest = tests.testSuites.find(s => s.testSuite.name === 'Test_test_one_1')!.testSuite; const testSuite: TestsToRun = { testFile: [], testFolder: [], testFunction: [], testSuite: [testSuiteToTest] }; - const results = await testManager.runTest(testSuite); + const results = await testManager.runTest(CommandSource.ui, testSuite); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 1, 'Failures'); @@ -157,9 +158,9 @@ suite('Unit Tests (unittest)', () => { test('Run Specific Test Function', async () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_unittest*.py'], rootWorkspaceUri, configTarget); createTestManager(); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); const testFn: TestsToRun = { testFile: [], testFolder: [], testFunction: [tests.testFunctions[0].testFunction], testSuite: [] }; - const results = await testManager.runTest(testFn); + const results = await testManager.runTest(CommandSource.ui, testFn); assert.equal(results.summary.errors, 0, 'Errors'); assert.equal(results.summary.failures, 1, 'Failures'); assert.equal(results.summary.passed, 0, 'Passed'); @@ -170,7 +171,7 @@ suite('Unit Tests (unittest)', () => { await updateSetting('unitTest.unittestArgs', ['-s=./tests', '-p=test_*.py'], rootWorkspaceUri, configTarget); createTestManager(unitTestTestFilesCwdPath); - const tests = await testManager.discoverTests(true, true); + const tests = await testManager.discoverTests(CommandSource.ui, true, true); assert.equal(tests.testFiles.length, 1, 'Incorrect number of test files'); assert.equal(tests.testFolders.length, 1, 'Incorrect number of test folders'); assert.equal(tests.testFunctions.length, 1, 'Incorrect number of test functions'); From 227582166c9676a33b766e6741fbb5c56bab80c6 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 16:44:29 -0700 Subject: [PATCH 15/86] added copyright header --- src/client/common/commands.ts | 46 ------------------- src/client/common/telemetry/constants.ts | 4 ++ src/client/common/telemetry/index.ts | 4 ++ src/client/common/telemetry/stopWatch.ts | 4 ++ src/client/common/telemetry/telemetry.ts | 4 ++ src/client/common/telemetry/types.ts | 4 ++ .../telemetry/vscode-extension-telemetry.d.ts | 4 ++ 7 files changed, 24 insertions(+), 46 deletions(-) delete mode 100644 src/client/common/commands.ts diff --git a/src/client/common/commands.ts b/src/client/common/commands.ts deleted file mode 100644 index 82e769b0ae2e..000000000000 --- a/src/client/common/commands.ts +++ /dev/null @@ -1,46 +0,0 @@ -// import { interfaces } from 'inversify'; -// import { commands, Disposable, window } from 'vscode'; -// import { getServiceContainer } from '../ioc/index'; - -// // tslint:disable-next-line:no-any -// type CommandHandler = (...args: any[]) => any; -// // tslint:disable-next-line:no-stateless-class -// export class CommandRegister implements Disposable { -// private static disposables: Disposable[] = []; -// // tslint:disable-next-line:no-any function-name -// public static register(commandName: string, handler: CommandHandler) { -// const disposable = commands.registerCommand(commandName, handler); -// CommandRegister.disposables.push(disposable); -// } -// public dispose() { -// CommandRegister.disposables.forEach(disposable => disposable.dispose()); -// CommandRegister.disposables = []; -// } -// } -// // const container = getDiContainer(); - -// // tslint:disable-next-line:no-any function-name -// export function command(commandName: string, serviceIdentifier: interfaces.ServiceIdentifier) { -// // tslint:disable-next-line:no-function-expression no-any -// return function (target: Object, propertyKey: string, descriptor: TypedPropertyDescriptor) { -// // tslint:disable-next-line:no-function-expression -// CommandRegister.register(commandName, async function () { -// try { -// // hack hack (but this preserves context) -// const container = getServiceContainer(); -// const newTarget = container.get(serviceIdentifier) as { propertyKey: Function }; -// const value = newTarget[propertyKey].call(newTarget, ...Array.from(arguments)); -// // const value = descriptor.value!.call(target, ...Array.from(arguments)); -// // If its a promise await the value -// if (value && value.then && value.catch) { -// await value; -// } -// } -// catch (reason) { -// console.error(`Failed to execute the command ${commandName}`, reason); -// window.showErrorMessage(`Failed to execute '${commandName}'. ${reason}`); -// } -// }); -// return descriptor; -// }; -// } diff --git a/src/client/common/telemetry/constants.ts b/src/client/common/telemetry/constants.ts index 0f01cf367ce9..b4896a4a5180 100644 --- a/src/client/common/telemetry/constants.ts +++ b/src/client/common/telemetry/constants.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ export const COMPLETION = 'COMPLETION'; export const DEFINITION = 'DEFINITION'; export const HOVER_DEFINITION = 'HOVER_DEFINITION'; diff --git a/src/client/common/telemetry/index.ts b/src/client/common/telemetry/index.ts index 1145f7fe8740..6f57fd72990d 100644 --- a/src/client/common/telemetry/index.ts +++ b/src/client/common/telemetry/index.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import { StopWatch } from './stopWatch'; import { getTelemetryReporter } from './telemetry'; import { TelemetryProperties } from './types'; diff --git a/src/client/common/telemetry/stopWatch.ts b/src/client/common/telemetry/stopWatch.ts index d1f44345500c..aab19efd0241 100644 --- a/src/client/common/telemetry/stopWatch.ts +++ b/src/client/common/telemetry/stopWatch.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ export class StopWatch { private started: number = Date.now(); private stopped?: number; diff --git a/src/client/common/telemetry/telemetry.ts b/src/client/common/telemetry/telemetry.ts index ab628ee3131f..131aa099391e 100644 --- a/src/client/common/telemetry/telemetry.ts +++ b/src/client/common/telemetry/telemetry.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ // tslint:disable-next-line:no-reference /// import { extensions } from 'vscode'; diff --git a/src/client/common/telemetry/types.ts b/src/client/common/telemetry/types.ts index 7f966d7b6938..04c102cba76b 100644 --- a/src/client/common/telemetry/types.ts +++ b/src/client/common/telemetry/types.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ export type EditorLoadTelemetry = { condaVersion: string; }; diff --git a/src/client/common/telemetry/vscode-extension-telemetry.d.ts b/src/client/common/telemetry/vscode-extension-telemetry.d.ts index 63944bc57471..b5ffba6cff5d 100644 --- a/src/client/common/telemetry/vscode-extension-telemetry.d.ts +++ b/src/client/common/telemetry/vscode-extension-telemetry.d.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ declare module 'vscode-extension-telemetry' { export default class TelemetryReporter { /** From dfa30f77e0c4f2e7e593952de55b6826cd31771a Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 18:29:38 -0700 Subject: [PATCH 16/86] fix test runner id --- src/client/unittests/unittest/main.ts | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/client/unittests/unittest/main.ts b/src/client/unittests/unittest/main.ts index 162ec396b6ef..09e96e307fa5 100644 --- a/src/client/unittests/unittest/main.ts +++ b/src/client/unittests/unittest/main.ts @@ -1,6 +1,5 @@ 'use strict'; import * as vscode from 'vscode'; -import { PythonSettings } from '../../common/configSettings'; import { Product } from '../../common/installer'; import { BaseTestManager } from '../common/baseTestManager'; import { ITestCollectionStorageService, ITestDebugLauncher, ITestResultsService, ITestsHelper, Tests, TestStatus, TestsToRun } from '../common/types'; @@ -10,16 +9,17 @@ export class TestManager extends BaseTestManager { constructor(rootDirectory: string, outputChannel: vscode.OutputChannel, testCollectionStorage: ITestCollectionStorageService, testResultsService: ITestResultsService, testsHelper: ITestsHelper, private debugLauncher: ITestDebugLauncher) { - super('unitest', Product.unittest, rootDirectory, outputChannel, testCollectionStorage, testResultsService, testsHelper); + super('unittest', Product.unittest, rootDirectory, outputChannel, testCollectionStorage, testResultsService, testsHelper); } // tslint:disable-next-line:no-empty public configure() { } - public discoverTestsImpl(ignoreCache: boolean): Promise { + public async discoverTestsImpl(ignoreCache: boolean): Promise { const args = this.settings.unitTest.unittestArgs.slice(0); - return discoverTests(this.rootDirectory, args, this.testDiscoveryCancellationToken, ignoreCache, this.outputChannel, this.testsHelper); + // tslint:disable-next-line:no-non-null-assertion + return discoverTests(this.rootDirectory, args, this.testDiscoveryCancellationToken!, ignoreCache, this.outputChannel, this.testsHelper); } - public runTestImpl(tests: Tests, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise<{}> { + public async runTestImpl(tests: Tests, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise<{}> { const args = this.settings.unitTest.unittestArgs.slice(0); if (runFailedTests === true) { testsToRun = { testFile: [], testFolder: [], testSuite: [], testFunction: [] }; From ad3efb491f30219ad98de5a1c946a15a517dc355 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Thu, 2 Nov 2017 18:31:06 -0700 Subject: [PATCH 17/86] more strictness for later --- tsconfig.json | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tsconfig.json b/tsconfig.json index f43311b23009..c6bac46ad4fa 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -10,6 +10,8 @@ "rootDir": "src", "experimentalDecorators": true // TODO: enable to ensure all code complies with strict coding standards + // , "noUnusedLocals": true + // , "noUnusedParameters": false // , "strict": true }, "exclude": [ From 8ba7495f6585f40455f0ad923841c6922e802ba8 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 08:20:09 -0700 Subject: [PATCH 18/86] add copyright header --- src/client/common/utils.ts | 4 ++++ src/client/debugger/Main.ts | 4 ++++ src/client/extension.ts | 4 ++++ src/client/formatters/autoPep8Formatter.ts | 4 ++++ src/client/formatters/yapfFormatter.ts | 4 ++++ .../configuration/pythonPathUpdaterService.ts | 7 +++++-- .../configuration/pythonPathUpdaterServiceFactory.ts | 4 ++++ .../configuration/services/globalUpdaterService.ts | 8 +++++--- .../services/workspaceFolderUpdaterService.ts | 4 ++++ .../services/workspaceUpdaterService.ts | 8 +++++--- .../configuration/setInterpreterProvider.ts | 5 ++++- src/client/interpreter/helpers.ts | 4 ++++ src/client/interpreter/index.ts | 8 +++++--- src/client/interpreter/interpreterVersion.ts | 4 ++++ src/client/linters/baseLinter.ts | 4 ++++ src/client/providers/completionProvider.ts | 5 ++++- src/client/providers/definitionProvider.ts | 4 ++++ src/client/providers/execInTerminalProvider.ts | 4 ++++ src/client/providers/hoverProvider.ts | 4 ++++ src/client/providers/importSortProvider.ts | 4 ++++ src/client/providers/lintProvider.ts | 7 +++++-- src/client/providers/objectDefinitionProvider.ts | 4 ++++ src/client/providers/referenceProvider.ts | 4 ++++ src/client/providers/renameProvider.ts | 4 ++++ src/client/providers/replProvider.ts | 6 +++++- src/client/providers/signatureProvider.ts | 4 ++++ src/client/providers/simpleRefactorProvider.ts | 8 ++++++-- src/client/providers/symbolProvider.ts | 4 ++++ src/client/providers/updateSparkLibraryProvider.ts | 4 ++++ src/client/refactor/proxy.ts | 10 +++++++--- src/client/unittests/codeLenses/testFiles.ts | 6 +++++- src/client/unittests/common/baseTestManager.ts | 4 ++++ src/client/unittests/common/constants.ts | 4 ++++ src/client/unittests/common/testUtils.ts | 5 ++++- src/client/unittests/display/picker.ts | 4 ++++ src/client/unittests/main.ts | 12 ++++++------ src/client/unittests/unittest/main.ts | 4 ++++ src/client/workspaceSymbols/generator.ts | 4 ++++ src/client/workspaceSymbols/provider.ts | 4 ++++ src/test/common/common.test.ts | 4 ++++ src/test/interpreters/condaEnvFileService.test.ts | 4 ++++ src/test/interpreters/mocks.ts | 4 ++++ .../interpreters/pythonPathUpdater.multiroot.test.ts | 9 ++++----- src/test/interpreters/pythonPathUpdater.test.ts | 10 +++++----- src/test/providers/shebangCodeLenseProvider.test.ts | 7 +++++-- src/test/unittests/debugger.test.ts | 9 ++++++--- src/test/unittests/nosetest.test.ts | 4 ++++ src/test/unittests/pytest.test.ts | 4 ++++ src/test/unittests/unittest.test.ts | 4 ++++ 49 files changed, 214 insertions(+), 44 deletions(-) diff --git a/src/client/common/utils.ts b/src/client/common/utils.ts index 820c81b596da..277946f64118 100644 --- a/src/client/common/utils.ts +++ b/src/client/common/utils.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; // TODO: Cleanup this place // Add options for execPythonFile diff --git a/src/client/debugger/Main.ts b/src/client/debugger/Main.ts index dcc276a65c5a..6faab638deee 100644 --- a/src/client/debugger/Main.ts +++ b/src/client/debugger/Main.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ "use strict"; import { DebugSession, InitializedEvent, TerminatedEvent, StoppedEvent, OutputEvent, Thread, StackFrame, Scope, Source, Handles } from "vscode-debugadapter"; diff --git a/src/client/extension.ts b/src/client/extension.ts index b5d2fbf3dece..42a2d154cc44 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import { EDITOR_LOAD } from './common/telemetry/constants'; diff --git a/src/client/formatters/autoPep8Formatter.ts b/src/client/formatters/autoPep8Formatter.ts index 1953143618c5..d14ae158c790 100644 --- a/src/client/formatters/autoPep8Formatter.ts +++ b/src/client/formatters/autoPep8Formatter.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; diff --git a/src/client/formatters/yapfFormatter.ts b/src/client/formatters/yapfFormatter.ts index 1a221098fe81..a668cfce96a2 100644 --- a/src/client/formatters/yapfFormatter.ts +++ b/src/client/formatters/yapfFormatter.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; diff --git a/src/client/interpreter/configuration/pythonPathUpdaterService.ts b/src/client/interpreter/configuration/pythonPathUpdaterService.ts index 36226c5f42f7..41a57bdbbf63 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterService.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterService.ts @@ -1,11 +1,14 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { ConfigurationTarget, Uri, window } from 'vscode'; import { sendTelemetryEvent } from '../../common/telemetry'; import { PYTHON_INTERPRETER } from '../../common/telemetry/constants'; import { StopWatch } from '../../common/telemetry/stopWatch'; -import { WorkspacePythonPath } from '../contracts'; import { IInterpreterVersionService } from '../interpreterVersion'; -import { IPythonPathUpdaterService, IPythonPathUpdaterServiceFactory } from './types'; +import { IPythonPathUpdaterServiceFactory } from './types'; export class PythonPathUpdaterService { constructor(private pythonPathSettingsUpdaterFactory: IPythonPathUpdaterServiceFactory, diff --git a/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts b/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts index c48d20cdac1c..87f1e4dd8553 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import { Uri } from 'vscode'; import { GlobalPythonPathUpdaterService } from './services/globalUpdaterService'; import { WorkspaceFolderPythonPathUpdaterService } from './services/workspaceFolderUpdaterService'; diff --git a/src/client/interpreter/configuration/services/globalUpdaterService.ts b/src/client/interpreter/configuration/services/globalUpdaterService.ts index bb717cb0159c..0bcd084f4cb8 100644 --- a/src/client/interpreter/configuration/services/globalUpdaterService.ts +++ b/src/client/interpreter/configuration/services/globalUpdaterService.ts @@ -1,6 +1,8 @@ -import { Uri, workspace } from 'vscode'; -import { InterpreterManager } from '../..'; -import { WorkspacePythonPath } from '../../contracts'; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { workspace } from 'vscode'; import { IPythonPathUpdaterService } from '../types'; export class GlobalPythonPathUpdaterService implements IPythonPathUpdaterService { diff --git a/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts b/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts index 37f45d5cde14..9d465e92dfdc 100644 --- a/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts +++ b/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { ConfigurationTarget, Uri, workspace } from 'vscode'; import { IPythonPathUpdaterService } from '../types'; diff --git a/src/client/interpreter/configuration/services/workspaceUpdaterService.ts b/src/client/interpreter/configuration/services/workspaceUpdaterService.ts index b0da1b168345..56b247399cd9 100644 --- a/src/client/interpreter/configuration/services/workspaceUpdaterService.ts +++ b/src/client/interpreter/configuration/services/workspaceUpdaterService.ts @@ -1,7 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; -import { ConfigurationTarget, Uri, workspace } from 'vscode'; -import { InterpreterManager } from '../..'; -import { WorkspacePythonPath } from '../../contracts'; +import { Uri, workspace } from 'vscode'; import { IPythonPathUpdaterService } from '../types'; export class WorkspacePythonPathUpdaterService implements IPythonPathUpdaterService { diff --git a/src/client/interpreter/configuration/setInterpreterProvider.ts b/src/client/interpreter/configuration/setInterpreterProvider.ts index f08278217372..5dddff5ff51a 100644 --- a/src/client/interpreter/configuration/setInterpreterProvider.ts +++ b/src/client/interpreter/configuration/setInterpreterProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; import { commands, ConfigurationTarget, Disposable, QuickPickItem, QuickPickOptions, Uri, window, workspace } from 'vscode'; @@ -8,7 +12,6 @@ import { ShebangCodeLensProvider } from '../display/shebangCodeLensProvider'; import { IInterpreterVersionService } from '../interpreterVersion'; import { PythonPathUpdaterService } from './pythonPathUpdaterService'; import { PythonPathUpdaterServiceFactory } from './pythonPathUpdaterServiceFactory'; -import { IPythonPathUpdaterServiceFactory } from './types'; // tslint:disable-next-line:interface-name interface PythonPathQuickPickItem extends QuickPickItem { diff --git a/src/client/interpreter/helpers.ts b/src/client/interpreter/helpers.ts index f78df63a31f8..c1b659153552 100644 --- a/src/client/interpreter/helpers.ts +++ b/src/client/interpreter/helpers.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as child_process from 'child_process'; import { ConfigurationTarget, window, workspace } from 'vscode'; import { RegistryImplementation } from '../common/registry'; diff --git a/src/client/interpreter/index.ts b/src/client/interpreter/index.ts index 639c83bd6d8f..2a000b7f21fc 100644 --- a/src/client/interpreter/index.ts +++ b/src/client/interpreter/index.ts @@ -1,11 +1,13 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; -import { ConfigurationTarget, Disposable, StatusBarAlignment, Uri, window, workspace } from 'vscode'; +import { Disposable, StatusBarAlignment, Uri, window, workspace } from 'vscode'; import { PythonSettings } from '../common/configSettings'; -import { IS_WINDOWS } from '../common/utils'; import { PythonPathUpdaterService } from './configuration/pythonPathUpdaterService'; import { PythonPathUpdaterServiceFactory } from './configuration/pythonPathUpdaterServiceFactory'; -import { WorkspacePythonPath } from './contracts'; import { InterpreterDisplay } from './display'; import { getActiveWorkspaceUri } from './helpers'; import { InterpreterVersionService } from './interpreterVersion'; diff --git a/src/client/interpreter/interpreterVersion.ts b/src/client/interpreter/interpreterVersion.ts index 20af4a3bb743..966c871e47f5 100644 --- a/src/client/interpreter/interpreterVersion.ts +++ b/src/client/interpreter/interpreterVersion.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as child_process from 'child_process'; import { getInterpreterVersion } from '../common/utils'; diff --git a/src/client/linters/baseLinter.ts b/src/client/linters/baseLinter.ts index 4b4f1d61541e..a3f794162b7a 100644 --- a/src/client/linters/baseLinter.ts +++ b/src/client/linters/baseLinter.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; import { OutputChannel, Uri } from 'vscode'; diff --git a/src/client/providers/completionProvider.ts b/src/client/providers/completionProvider.ts index f8559a5e3e16..2b1619c5e559 100644 --- a/src/client/providers/completionProvider.ts +++ b/src/client/providers/completionProvider.ts @@ -1,6 +1,9 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; -import { EOL } from 'os'; import * as vscode from 'vscode'; import { ProviderResult, SnippetString, Uri } from 'vscode'; import { PythonSettings } from '../common/configSettings'; diff --git a/src/client/providers/definitionProvider.ts b/src/client/providers/definitionProvider.ts index 7c9a66aa92ea..1bab8ebcb3ee 100644 --- a/src/client/providers/definitionProvider.ts +++ b/src/client/providers/definitionProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; diff --git a/src/client/providers/execInTerminalProvider.ts b/src/client/providers/execInTerminalProvider.ts index 025c0b07789d..e1405766194b 100644 --- a/src/client/providers/execInTerminalProvider.ts +++ b/src/client/providers/execInTerminalProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as fs from 'fs-extra'; import { EOL } from 'os'; diff --git a/src/client/providers/hoverProvider.ts b/src/client/providers/hoverProvider.ts index 05c3e1c0a395..180e2a0f99d0 100644 --- a/src/client/providers/hoverProvider.ts +++ b/src/client/providers/hoverProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import { EOL } from 'os'; diff --git a/src/client/providers/importSortProvider.ts b/src/client/providers/importSortProvider.ts index 8ec1b2cc0371..bc2858c91dc1 100644 --- a/src/client/providers/importSortProvider.ts +++ b/src/client/providers/importSortProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as child_process from 'child_process'; import * as fs from 'fs'; diff --git a/src/client/providers/lintProvider.ts b/src/client/providers/lintProvider.ts index 592676764547..667724f43783 100644 --- a/src/client/providers/lintProvider.ts +++ b/src/client/providers/lintProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as fs from 'fs'; @@ -5,10 +9,9 @@ import * as path from 'path'; import * as vscode from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { LinterErrors } from '../common/constants'; -import { sendTelemetryEvent, sendTelemetryWhenDone } from '../common/telemetry'; +import { sendTelemetryWhenDone } from '../common/telemetry'; import { LINTING } from '../common/telemetry/constants'; import { StopWatch } from '../common/telemetry/stopWatch'; -import { BaseLinter } from '../linters/baseLinter'; import * as linter from '../linters/baseLinter'; import * as flake8 from './../linters/flake8'; import * as mypy from './../linters/mypy'; diff --git a/src/client/providers/objectDefinitionProvider.ts b/src/client/providers/objectDefinitionProvider.ts index 2caf816b555f..92545aefd17d 100644 --- a/src/client/providers/objectDefinitionProvider.ts +++ b/src/client/providers/objectDefinitionProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; diff --git a/src/client/providers/referenceProvider.ts b/src/client/providers/referenceProvider.ts index afb5ec7c148a..39a38d212190 100644 --- a/src/client/providers/referenceProvider.ts +++ b/src/client/providers/referenceProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; diff --git a/src/client/providers/renameProvider.ts b/src/client/providers/renameProvider.ts index 4f1270e5a423..148612f7ef49 100644 --- a/src/client/providers/renameProvider.ts +++ b/src/client/providers/renameProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; diff --git a/src/client/providers/replProvider.ts b/src/client/providers/replProvider.ts index e089845cfeee..dfeb731c72f6 100644 --- a/src/client/providers/replProvider.ts +++ b/src/client/providers/replProvider.ts @@ -1,4 +1,8 @@ -import { commands, Disposable, Uri, window, workspace } from 'vscode'; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { commands, Disposable, window, workspace } from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { Commands } from '../common/constants'; import { captureTelemetry } from '../common/telemetry'; diff --git a/src/client/providers/signatureProvider.ts b/src/client/providers/signatureProvider.ts index 135886a528d8..1d28b598ff34 100644 --- a/src/client/providers/signatureProvider.ts +++ b/src/client/providers/signatureProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; diff --git a/src/client/providers/simpleRefactorProvider.ts b/src/client/providers/simpleRefactorProvider.ts index 9ea4995e70c5..7a749a7a8c1f 100644 --- a/src/client/providers/simpleRefactorProvider.ts +++ b/src/client/providers/simpleRefactorProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; @@ -5,9 +9,9 @@ import { PythonSettings } from '../common/configSettings'; import { getTextEditsFromPatch } from '../common/editor'; import { Installer, Product } from '../common/installer'; import { sendTelemetryWhenDone } from '../common/telemetry'; -import { RefactorProxy } from '../refactor/proxy'; +import { REFACTOR_EXTRACT_FUNCTION, REFACTOR_EXTRACT_VAR } from '../common/telemetry/constants'; import { StopWatch } from '../common/telemetry/stopWatch'; -import { REFACTOR_EXTRACT_VAR, REFACTOR_EXTRACT_FUNCTION } from '../common/telemetry/constants'; +import { RefactorProxy } from '../refactor/proxy'; interface RenameResponse { results: [{ diff: string }]; diff --git a/src/client/providers/symbolProvider.ts b/src/client/providers/symbolProvider.ts index 8c4ba6f42aa6..c7b18c7600e5 100644 --- a/src/client/providers/symbolProvider.ts +++ b/src/client/providers/symbolProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; diff --git a/src/client/providers/updateSparkLibraryProvider.ts b/src/client/providers/updateSparkLibraryProvider.ts index cc2f1616fcc7..4fd1a9907c2d 100644 --- a/src/client/providers/updateSparkLibraryProvider.ts +++ b/src/client/providers/updateSparkLibraryProvider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; import * as vscode from 'vscode'; diff --git a/src/client/refactor/proxy.ts b/src/client/refactor/proxy.ts index bba0f5eae343..d9efefb9c392 100644 --- a/src/client/refactor/proxy.ts +++ b/src/client/refactor/proxy.ts @@ -1,11 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; -import * as vscode from 'vscode'; -import * as path from 'path'; import * as child_process from 'child_process'; +import * as path from 'path'; +import * as vscode from 'vscode'; import { IPythonSettings } from '../common/configSettings'; -import { getCustomEnvVars, getCustomEnvVarsSync, getWindowsLineEndingCount, IS_WINDOWS } from '../common/utils'; import { mergeEnvVariables } from '../common/envFileParser'; +import { getCustomEnvVarsSync, getWindowsLineEndingCount, IS_WINDOWS } from '../common/utils'; export class RefactorProxy extends vscode.Disposable { private _process: child_process.ChildProcess; diff --git a/src/client/unittests/codeLenses/testFiles.ts b/src/client/unittests/codeLenses/testFiles.ts index 8b444cb4c205..47cf8e4d9fe1 100644 --- a/src/client/unittests/codeLenses/testFiles.ts +++ b/src/client/unittests/codeLenses/testFiles.ts @@ -1,11 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import { CancellationToken, CancellationTokenSource, CodeLens, CodeLensProvider, Event, EventEmitter, Position, Range, SymbolInformation, SymbolKind, TextDocument, workspace } from 'vscode'; import { Uri } from 'vscode'; import * as constants from '../../common/constants'; import { PythonSymbolProvider } from '../../providers/symbolProvider'; -import { ITestCollectionStorageService, TestFile, TestFunction, TestStatus, TestsToRun, TestSuite } from '../common/types'; import { CommandSource } from '../common/constants'; +import { ITestCollectionStorageService, TestFile, TestFunction, TestStatus, TestsToRun, TestSuite } from '../common/types'; type FunctionsAndSuites = { functions: TestFunction[]; diff --git a/src/client/unittests/common/baseTestManager.ts b/src/client/unittests/common/baseTestManager.ts index 8cef0bf30bfc..b94a8cdc737c 100644 --- a/src/client/unittests/common/baseTestManager.ts +++ b/src/client/unittests/common/baseTestManager.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ // import {TestFolder, TestsToRun, Tests, TestFile, TestSuite, TestFunction, TestStatus, FlattenedTestFunction, FlattenedTestSuite, CANCELLATION_REASON} from './contracts'; import * as vscode from 'vscode'; import { Uri, workspace } from 'vscode'; diff --git a/src/client/unittests/common/constants.ts b/src/client/unittests/common/constants.ts index 9bd66948c6e3..d79c373ef026 100644 --- a/src/client/unittests/common/constants.ts +++ b/src/client/unittests/common/constants.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ export const CANCELLATION_REASON = 'cancelled_user_request'; export enum CommandSource { auto = 'auto', diff --git a/src/client/unittests/common/testUtils.ts b/src/client/unittests/common/testUtils.ts index 9011df036caf..e9ecad84df35 100644 --- a/src/client/unittests/common/testUtils.ts +++ b/src/client/unittests/common/testUtils.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import * as vscode from 'vscode'; import { Uri, workspace } from 'vscode'; @@ -5,7 +9,6 @@ import { window } from 'vscode'; import * as constants from '../../common/constants'; import { CommandSource } from './constants'; import { TestFlatteningVisitor } from './testVisitors/flatteningVisitor'; -import { TestResultResetVisitor } from './testVisitors/resultResetVisitor'; import { TestFile, TestFolder, Tests, TestsToRun } from './types'; import { ITestsHelper } from './types'; diff --git a/src/client/unittests/display/picker.ts b/src/client/unittests/display/picker.ts index 2b3d47652abf..93cdc73519bb 100644 --- a/src/client/unittests/display/picker.ts +++ b/src/client/unittests/display/picker.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { QuickPickItem, Uri, window } from 'vscode'; import * as vscode from 'vscode'; diff --git a/src/client/unittests/main.ts b/src/client/unittests/main.ts index cb98402e1aee..cbb2d790e0c5 100644 --- a/src/client/unittests/main.ts +++ b/src/client/unittests/main.ts @@ -1,11 +1,14 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import { Uri, window, workspace } from 'vscode'; import * as vscode from 'vscode'; -import { IUnitTestSettings, PythonSettings } from '../common/configSettings'; +import { PythonSettings } from '../common/configSettings'; import * as constants from '../common/constants'; import { UNITTEST_STOP, UNITTEST_VIEW_OUTPUT } from '../common/telemetry/constants'; import { sendTelemetryEvent } from '../common/telemetry/index'; -import { TestRunTelemetry } from '../common/telemetry/types'; import { PythonSymbolProvider } from '../providers/symbolProvider'; import { activateCodeLenses } from './codeLenses/main'; import { BaseTestManager } from './common/baseTestManager'; @@ -15,14 +18,11 @@ import { TestCollectionStorageService } from './common/storageService'; import { TestManagerServiceFactory } from './common/testManagerServiceFactory'; import { TestResultsService } from './common/testResultsService'; import { selectTestWorkspace, TestsHelper } from './common/testUtils'; -import { FlattenedTestFunction, ITestCollectionStorageService, IWorkspaceTestManagerService, TestFile, TestFunction, TestStatus, TestsToRun } from './common/types'; +import { ITestCollectionStorageService, IWorkspaceTestManagerService, TestFile, TestFunction, TestStatus, TestsToRun } from './common/types'; import { WorkspaceTestManagerService } from './common/workspaceTestManagerService'; import { displayTestFrameworkError } from './configuration'; import { TestResultDisplay } from './display/main'; import { TestDisplay } from './display/picker'; -import * as nosetests from './nosetest/main'; -import * as pytest from './pytest/main'; -import * as unittest from './unittest/main'; let workspaceTestManagerService: IWorkspaceTestManagerService; let testResultDisplay: TestResultDisplay; diff --git a/src/client/unittests/unittest/main.ts b/src/client/unittests/unittest/main.ts index 09e96e307fa5..a426ec5ac155 100644 --- a/src/client/unittests/unittest/main.ts +++ b/src/client/unittests/unittest/main.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; import { Product } from '../../common/installer'; diff --git a/src/client/workspaceSymbols/generator.ts b/src/client/workspaceSymbols/generator.ts index acbc3b5354cc..e285f3b2d2dd 100644 --- a/src/client/workspaceSymbols/generator.ts +++ b/src/client/workspaceSymbols/generator.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as child_process from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; diff --git a/src/client/workspaceSymbols/provider.ts b/src/client/workspaceSymbols/provider.ts index 736c6ff0f750..bc1a4fc12d89 100644 --- a/src/client/workspaceSymbols/provider.ts +++ b/src/client/workspaceSymbols/provider.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as _ from 'lodash'; import * as vscode from 'vscode'; import { Commands } from '../common/constants'; diff --git a/src/test/common/common.test.ts b/src/test/common/common.test.ts index aeccb54166da..322579cec1ae 100644 --- a/src/test/common/common.test.ts +++ b/src/test/common/common.test.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import { EOL } from 'os'; import * as vscode from 'vscode'; diff --git a/src/test/interpreters/condaEnvFileService.test.ts b/src/test/interpreters/condaEnvFileService.test.ts index 88f3ae8934e3..d153918f6883 100644 --- a/src/test/interpreters/condaEnvFileService.test.ts +++ b/src/test/interpreters/condaEnvFileService.test.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as fs from 'fs-extra'; import { EOL } from 'os'; diff --git a/src/test/interpreters/mocks.ts b/src/test/interpreters/mocks.ts index db4cfed0c474..64bb01502c5e 100644 --- a/src/test/interpreters/mocks.ts +++ b/src/test/interpreters/mocks.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import { Architecture, Hive, IRegistry } from '../../client/common/registry'; import { IInterpreterLocatorService, PythonInterpreter } from '../../client/interpreter/contracts'; import { IInterpreterVersionService } from '../../client/interpreter/interpreterVersion'; diff --git a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts index a60d29b14474..a7ac15455e75 100644 --- a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts +++ b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts @@ -1,18 +1,17 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as path from 'path'; import { ConfigurationTarget, Uri, workspace } from 'vscode'; -import { PythonSettings } from '../../client/common/configSettings'; import { PythonPathUpdaterService } from '../../client/interpreter/configuration/pythonPathUpdaterService'; import { PythonPathUpdaterServiceFactory } from '../../client/interpreter/configuration/pythonPathUpdaterServiceFactory'; -import { GlobalPythonPathUpdaterService } from '../../client/interpreter/configuration/services/globalUpdaterService'; import { WorkspaceFolderPythonPathUpdaterService } from '../../client/interpreter/configuration/services/workspaceFolderUpdaterService'; import { WorkspacePythonPathUpdaterService } from '../../client/interpreter/configuration/services/workspaceUpdaterService'; -import { WorkspacePythonPath } from '../../client/interpreter/contracts'; import { InterpreterVersionService } from '../../client/interpreter/interpreterVersion'; -import { clearPythonPathInWorkspaceFolder } from '../common'; import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST } from '../initialize'; -const workspaceRoot = path.join(__dirname, '..', '..', '..', 'src', 'test'); const multirootPath = path.join(__dirname, '..', '..', '..', 'src', 'testMultiRootWkspc'); const workspace3Uri = Uri.file(path.join(multirootPath, 'workspace3')); diff --git a/src/test/interpreters/pythonPathUpdater.test.ts b/src/test/interpreters/pythonPathUpdater.test.ts index 65e12a3c2a78..114652587337 100644 --- a/src/test/interpreters/pythonPathUpdater.test.ts +++ b/src/test/interpreters/pythonPathUpdater.test.ts @@ -1,15 +1,15 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as path from 'path'; import { ConfigurationTarget, Uri, workspace } from 'vscode'; -import { PythonSettings } from '../../client/common/configSettings'; import { PythonPathUpdaterService } from '../../client/interpreter/configuration/pythonPathUpdaterService'; import { PythonPathUpdaterServiceFactory } from '../../client/interpreter/configuration/pythonPathUpdaterServiceFactory'; -import { GlobalPythonPathUpdaterService } from '../../client/interpreter/configuration/services/globalUpdaterService'; import { WorkspacePythonPathUpdaterService } from '../../client/interpreter/configuration/services/workspaceUpdaterService'; -import { WorkspacePythonPath } from '../../client/interpreter/contracts'; import { InterpreterVersionService } from '../../client/interpreter/interpreterVersion'; -import { clearPythonPathInWorkspaceFolder } from '../common'; -import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST } from '../initialize'; +import { closeActiveWindows, initialize, initializeTest } from '../initialize'; const workspaceRoot = path.join(__dirname, '..', '..', '..', 'src', 'test'); diff --git a/src/test/providers/shebangCodeLenseProvider.test.ts b/src/test/providers/shebangCodeLenseProvider.test.ts index 36b45b78a616..d89e0bd230db 100644 --- a/src/test/providers/shebangCodeLenseProvider.test.ts +++ b/src/test/providers/shebangCodeLenseProvider.test.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as child_process from 'child_process'; import * as path from 'path'; @@ -5,8 +9,7 @@ import * as vscode from 'vscode'; import { IS_WINDOWS, PythonSettings } from '../../client/common/configSettings'; import { ShebangCodeLensProvider } from '../../client/interpreter/display/shebangCodeLensProvider'; import { getFirstNonEmptyLineFromMultilineString } from '../../client/interpreter/helpers'; -import { rootWorkspaceUri, updateSetting } from '../common'; -import { closeActiveWindows, initialize, initializeTest, IS_MULTI_ROOT_TEST } from '../initialize'; +import { closeActiveWindows, initialize, initializeTest } from '../initialize'; const autoCompPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'shebang'); const fileShebang = path.join(autoCompPath, 'shebang.py'); diff --git a/src/test/unittests/debugger.test.ts b/src/test/unittests/debugger.test.ts index 0ef0391483fb..db750c610275 100644 --- a/src/test/unittests/debugger.test.ts +++ b/src/test/unittests/debugger.test.ts @@ -1,6 +1,9 @@ -import { assert, expect, should, use } from 'chai'; +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { assert, expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; -import * as fs from 'fs-extra'; import * as path from 'path'; import { ConfigurationTarget } from 'vscode'; import { createDeferred } from '../../client/common/helpers'; @@ -9,7 +12,7 @@ import { CANCELLATION_REASON, CommandSource } from '../../client/unittests/commo import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; import { TestResultsService } from '../../client/unittests/common/testResultsService'; import { TestsHelper } from '../../client/unittests/common/testUtils'; -import { ITestCollectionStorageService, ITestResultsService, ITestsHelper, TestsToRun } from '../../client/unittests/common/types'; +import { ITestCollectionStorageService, ITestResultsService, ITestsHelper } from '../../client/unittests/common/types'; import { TestResultDisplay } from '../../client/unittests/display/main'; import { TestManager as NosetestManager } from '../../client/unittests/nosetest/main'; import { TestManager as PytestManager } from '../../client/unittests/pytest/main'; diff --git a/src/test/unittests/nosetest.test.ts b/src/test/unittests/nosetest.test.ts index c932a1950332..ee5323a91b68 100644 --- a/src/test/unittests/nosetest.test.ts +++ b/src/test/unittests/nosetest.test.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as fs from 'fs'; import * as path from 'path'; diff --git a/src/test/unittests/pytest.test.ts b/src/test/unittests/pytest.test.ts index 1b016f4228cc..bc301f3dea27 100644 --- a/src/test/unittests/pytest.test.ts +++ b/src/test/unittests/pytest.test.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as path from 'path'; import * as vscode from 'vscode'; diff --git a/src/test/unittests/unittest.test.ts b/src/test/unittests/unittest.test.ts index d333ed32fa9c..0705395b2cd0 100644 --- a/src/test/unittests/unittest.test.ts +++ b/src/test/unittests/unittest.test.ts @@ -1,3 +1,7 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as fs from 'fs-extra'; import * as path from 'path'; From c62743af856e9ccc91e65d1e937deb64b55b7e30 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 08:54:58 -0700 Subject: [PATCH 19/86] tests for interpreter and pip version --- src/client/interpreter/interpreterVersion.ts | 5 +- .../interpreters/interpreterVersion.test.ts | 46 +++++++++++++++++++ 2 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 src/test/interpreters/interpreterVersion.test.ts diff --git a/src/client/interpreter/interpreterVersion.ts b/src/client/interpreter/interpreterVersion.ts index 966c871e47f5..2919201dd2f9 100644 --- a/src/client/interpreter/interpreterVersion.ts +++ b/src/client/interpreter/interpreterVersion.ts @@ -11,14 +11,17 @@ export interface IInterpreterVersionService { } export class InterpreterVersionService implements IInterpreterVersionService { - public getVersion(pythonPath: string, defaultValue: string): Promise { + public async getVersion(pythonPath: string, defaultValue: string): Promise { return getInterpreterVersion(pythonPath) + .then(version => version.length === 0 ? defaultValue : version) .catch(() => defaultValue); } public async getPipVersion(pythonPath: string): Promise { return new Promise((resolve, reject) => { child_process.execFile(pythonPath, ['-m', 'pip', '--version'], (error, stdout, stdErr) => { if (stdout && stdout.length > 0) { + // Take the second part, see below example. + // pip 9.0.1 from /Users/donjayamanne/anaconda3/lib/python3.6/site-packages (python 3.6). const parts = stdout.split(' '); if (parts.length > 1) { resolve(parts[1].trim()); diff --git a/src/test/interpreters/interpreterVersion.test.ts b/src/test/interpreters/interpreterVersion.test.ts new file mode 100644 index 000000000000..503c4fb3ffca --- /dev/null +++ b/src/test/interpreters/interpreterVersion.test.ts @@ -0,0 +1,46 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { assert, expect } from 'chai'; +import { execPythonFile } from '../../client/common/utils'; +import { getFirstNonEmptyLineFromMultilineString } from '../../client/interpreter/helpers'; +import { InterpreterVersionService } from '../../client/interpreter/interpreterVersion'; +import { initialize, initializeTest } from '../initialize'; + +suite('Interpreters display version', () => { + const interpreterVersion = new InterpreterVersionService(); + suiteSetup(initialize); + setup(initializeTest); + + test('Must return the Python Version', async () => { + const output = await execPythonFile(undefined, 'python', ['--version'], __dirname, true); + const version = getFirstNonEmptyLineFromMultilineString(output); + const pyVersion = await interpreterVersion.getVersion('python', 'DEFAULT_TEST_VALUE'); + assert.equal(pyVersion, version, 'Incorrect version'); + }); + test('Must return the default value when Python path is invalid', async () => { + const pyVersion = await interpreterVersion.getVersion('INVALID_INTERPRETER', 'DEFAULT_TEST_VALUE'); + assert.equal(pyVersion, 'DEFAULT_TEST_VALUE', 'Incorrect version'); + }); + test('Must return the Pip Version', async () => { + const output = await execPythonFile(undefined, 'python', ['-m', 'pip', '--version'], __dirname, true); + const versionInfo = getFirstNonEmptyLineFromMultilineString(output); + + // Take the second part, see below example. + // pip 9.0.1 from /Users/donjayamanne/anaconda3/lib/python3.6/site-packages (python 3.6). + const parts = versionInfo.split(' '); + + const pipVersionPromise = interpreterVersion.getPipVersion('python'); + // If pip version cannot be identified exception must be thrown. + if (parts.length > 1) { + expect(pipVersionPromise).eventually.to.equal(parts[1].trim(), 'Pip version is not the same'); + } else { + expect(pipVersionPromise).eventually.to.throw(); + } + }); + test('Must throw an exceptionn when Pip version cannot be determine', async () => { + const pipVersionPromise = interpreterVersion.getPipVersion('INVALID_INTERPRETER'); + expect(pipVersionPromise).eventually.to.throw(); + }); +}); From 27701cdd551b5625ab2c8a73cfb223bd0cecc87e Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 10:40:09 -0700 Subject: [PATCH 20/86] missed colon --- src/client/extension.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/extension.ts b/src/client/extension.ts index 42a2d154cc44..5d847b2a4f2b 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -51,7 +51,7 @@ export const activated = activationDeferred.promise; // tslint:disable-next-line:max-func-body-length export async function activate(context: vscode.ExtensionContext) { const pythonSettings = settings.PythonSettings.getInstance(); - sendStartupTelemetry(activated) + sendStartupTelemetry(activated); lintingOutChannel = vscode.window.createOutputChannel(pythonSettings.linting.outputWindow); formatOutChannel = lintingOutChannel; From f40ce2860945bc22f2d6bd33140f68bdb4f4b2da Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 11:07:39 -0700 Subject: [PATCH 21/86] do not stop discovery when running tests --- src/client/unittests/common/baseTestManager.ts | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/client/unittests/common/baseTestManager.ts b/src/client/unittests/common/baseTestManager.ts index b94a8cdc737c..b804d16cdd70 100644 --- a/src/client/unittests/common/baseTestManager.ts +++ b/src/client/unittests/common/baseTestManager.ts @@ -188,7 +188,9 @@ export abstract class BaseTestManager { } this._status = TestStatus.Running; - this.stop(); + if (this.testRunnerCancellationTokenSource) { + this.testRunnerCancellationTokenSource.cancel(); + } // If running failed tests, then don't clear the previously build UnitTests // If we do so, then we end up re-discovering the unit tests and clearing previously cached list of failed tests // Similarly, if running a specific test or test file, don't clear the cache (possible tests have some state information retained) From de928ada910193d609ee4422abbfb5b408385093 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 11:27:34 -0700 Subject: [PATCH 22/86] incorrect telemetry scope for running unittests --- src/client/unittests/common/baseTestManager.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/unittests/common/baseTestManager.ts b/src/client/unittests/common/baseTestManager.ts index b804d16cdd70..a45594728100 100644 --- a/src/client/unittests/common/baseTestManager.ts +++ b/src/client/unittests/common/baseTestManager.ts @@ -158,7 +158,7 @@ export abstract class BaseTestManager { }; const telementryProperties: TestRunTelemetry = { tool: this.testProvider, - scope: 'file', + scope: 'all', debugging: debug === true, trigger: cmdSource, failed: false From 92ec931b88bed869a984c62a1c1f51fb783daf1a Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 13:08:29 -0700 Subject: [PATCH 23/86] fixed unit tests --- .../interpreters/interpreterVersion.test.ts | 14 ++- src/test/unittests/debugger.test.ts | 10 ++- src/test/unittests/mocks.ts | 34 +++++++- src/test/unittests/rediscover.test.ts | 12 ++- .../unittests/stoppingDiscoverAndTest.test.ts | 86 +++++++++++++++++++ tslint.json | 3 +- 6 files changed, 142 insertions(+), 17 deletions(-) create mode 100644 src/test/unittests/stoppingDiscoverAndTest.test.ts diff --git a/src/test/interpreters/interpreterVersion.test.ts b/src/test/interpreters/interpreterVersion.test.ts index 503c4fb3ffca..b1bef874832f 100644 --- a/src/test/interpreters/interpreterVersion.test.ts +++ b/src/test/interpreters/interpreterVersion.test.ts @@ -2,12 +2,15 @@ * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ -import { assert, expect } from 'chai'; +import { assert, expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; import { execPythonFile } from '../../client/common/utils'; import { getFirstNonEmptyLineFromMultilineString } from '../../client/interpreter/helpers'; import { InterpreterVersionService } from '../../client/interpreter/interpreterVersion'; import { initialize, initializeTest } from '../initialize'; +use(chaiAsPromised); + suite('Interpreters display version', () => { const interpreterVersion = new InterpreterVersionService(); suiteSetup(initialize); @@ -32,15 +35,10 @@ suite('Interpreters display version', () => { const parts = versionInfo.split(' '); const pipVersionPromise = interpreterVersion.getPipVersion('python'); - // If pip version cannot be identified exception must be thrown. - if (parts.length > 1) { - expect(pipVersionPromise).eventually.to.equal(parts[1].trim(), 'Pip version is not the same'); - } else { - expect(pipVersionPromise).eventually.to.throw(); - } + await expect(pipVersionPromise).to.eventually.equal(parts[1].trim()); }); test('Must throw an exceptionn when Pip version cannot be determine', async () => { const pipVersionPromise = interpreterVersion.getPipVersion('INVALID_INTERPRETER'); - expect(pipVersionPromise).eventually.to.throw(); + await expect(pipVersionPromise).to.be.rejectedWith(); }); }); diff --git a/src/test/unittests/debugger.test.ts b/src/test/unittests/debugger.test.ts index db750c610275..49d051d4c5fe 100644 --- a/src/test/unittests/debugger.test.ts +++ b/src/test/unittests/debugger.test.ts @@ -84,6 +84,7 @@ suite('Unit Tests Debugging', () => { assert.equal(tests.testSuites.length, 2, 'Incorrect number of test suites'); const testFunction = [tests.testFunctions[0].testFunction]; + // tslint:disable-next-line:no-floating-promises testManager.runTest(CommandSource.commandPalette, { testFunction }, false, true); const launched = await mockDebugLauncher.launched; assert.isTrue(launched, 'Debugger not launched'); @@ -121,9 +122,10 @@ suite('Unit Tests Debugging', () => { const launched = await mockDebugLauncher.launched; assert.isTrue(launched, 'Debugger not launched'); - const discoveryPromise = testManager.discoverTests(CommandSource.commandPalette, true, true, true); + // tslint:disable-next-line:no-floating-promises + testManager.discoverTests(CommandSource.commandPalette, true, true, true); - expect(runningPromise).eventually.throws(CANCELLATION_REASON, 'Incorrect reason for ending the debugger'); + await expect(runningPromise).to.be.rejectedWith(CANCELLATION_REASON, 'Incorrect reason for ending the debugger'); } test('Debugger should stop when user invokes a test discovery (unittest)', async () => { @@ -161,11 +163,15 @@ suite('Unit Tests Debugging', () => { const discoveryPromise = testManager.discoverTests(CommandSource.commandPalette, false, true); const deferred = createDeferred(); + // tslint:disable-next-line:no-floating-promises discoveryPromise + // tslint:disable-next-line:no-unsafe-any .then(() => deferred.resolve('')) + // tslint:disable-next-line:no-unsafe-any .catch(ex => deferred.reject(ex)); // This promise should never resolve nor reject. + // tslint:disable-next-line:no-floating-promises runningPromise .then(() => 'Debugger stopped when it shouldn\'t have') .catch(() => 'Debugger crashed when it shouldn\'t have') diff --git a/src/test/unittests/mocks.ts b/src/test/unittests/mocks.ts index 036c0ffa14d1..fd9741543a78 100644 --- a/src/test/unittests/mocks.ts +++ b/src/test/unittests/mocks.ts @@ -1,13 +1,17 @@ import { CancellationToken, Disposable, OutputChannel } from 'vscode'; import { createDeferred, Deferred } from '../../client/common/helpers'; -import { ITestDebugLauncher, Tests } from '../../client/unittests/common/types'; +import { Product } from '../../client/common/installer'; +import { BaseTestManager } from '../../client/unittests/common/baseTestManager'; +import { CANCELLATION_REASON } from '../../client/unittests/common/constants'; +import { ITestCollectionStorageService, ITestDebugLauncher, ITestResultsService, ITestsHelper, Tests, TestsToRun } from '../../client/unittests/common/types'; export class MockDebugLauncher implements ITestDebugLauncher, Disposable { public get launched(): Promise { return this._launched.promise; } public get debuggerPromise(): Deferred { - return this._promise; + // tslint:disable-next-line:no-non-null-assertion + return this._promise!; } public get cancellationToken(): CancellationToken { return this._token; @@ -38,3 +42,29 @@ export class MockDebugLauncher implements ITestDebugLauncher, Disposable { this._promise = undefined; } } + +export class MockTestManagerWithRunningTests extends BaseTestManager { + // tslint:disable-next-line:no-any + public readonly runnerDeferred = createDeferred(); + // tslint:disable-next-line:no-any + public readonly discoveryDeferred = createDeferred(); + constructor(testRunnerId: 'nosetest' | 'pytest' | 'unittest', product: Product, rootDirectory: string, + outputChannel: OutputChannel, storageService: ITestCollectionStorageService, resultsService: ITestResultsService, testsHelper: ITestsHelper) { + super('nosetest', product, rootDirectory, outputChannel, storageService, resultsService, testsHelper); + } + // tslint:disable-next-line:no-any + protected async runTestImpl(tests: Tests, testsToRun?: TestsToRun, runFailedTests?: boolean, debug?: boolean): Promise { + // tslint:disable-next-line:no-non-null-assertion + this.testRunnerCancellationToken!.onCancellationRequested(() => { + this.runnerDeferred.reject(CANCELLATION_REASON); + }); + return this.runnerDeferred.promise; + } + protected async discoverTestsImpl(ignoreCache: boolean, debug?: boolean): Promise { + // tslint:disable-next-line:no-non-null-assertion + this.testDiscoveryCancellationToken!.onCancellationRequested(() => { + this.discoveryDeferred.reject(CANCELLATION_REASON); + }); + return this.discoveryDeferred.promise; + } +} diff --git a/src/test/unittests/rediscover.test.ts b/src/test/unittests/rediscover.test.ts index d8382a73b0d3..0f106258166f 100644 --- a/src/test/unittests/rediscover.test.ts +++ b/src/test/unittests/rediscover.test.ts @@ -1,13 +1,17 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ import { assert } from 'chai'; import * as fs from 'fs-extra'; import * as path from 'path'; -import { ConfigurationTarget, Position, Range, Uri, window, workspace } from 'vscode'; +import { ConfigurationTarget } from 'vscode'; import { BaseTestManager } from '../../client/unittests/common/baseTestManager'; -import { CANCELLATION_REASON, CommandSource } from '../../client/unittests/common/constants'; +import { CommandSource } from '../../client/unittests/common/constants'; import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; import { TestResultsService } from '../../client/unittests/common/testResultsService'; import { TestsHelper } from '../../client/unittests/common/testUtils'; -import { ITestCollectionStorageService, ITestResultsService, ITestsHelper, TestsToRun } from '../../client/unittests/common/types'; +import { ITestCollectionStorageService, ITestResultsService, ITestsHelper } from '../../client/unittests/common/types'; import { TestResultDisplay } from '../../client/unittests/display/main'; import { TestManager as NosetestManager } from '../../client/unittests/nosetest/main'; import { TestManager as PytestManager } from '../../client/unittests/pytest/main'; @@ -30,7 +34,7 @@ const defaultUnitTestArgs = [ ]; // tslint:disable-next-line:max-func-body-length -suite('Unit Tests Discovery', () => { +suite('Unit Tests re-discovery', () => { let testManager: BaseTestManager; let testResultDisplay: TestResultDisplay; let outChannel: MockOutputChannel; diff --git a/src/test/unittests/stoppingDiscoverAndTest.test.ts b/src/test/unittests/stoppingDiscoverAndTest.test.ts new file mode 100644 index 000000000000..c42788f0d2ee --- /dev/null +++ b/src/test/unittests/stoppingDiscoverAndTest.test.ts @@ -0,0 +1,86 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ +import { expect, use } from 'chai'; +import * as chaiAsPromised from 'chai-as-promised'; +import * as path from 'path'; +import { Product } from '../../client/common/installer'; +import { CANCELLATION_REASON, CommandSource } from '../../client/unittests/common/constants'; +import { TestCollectionStorageService } from '../../client/unittests/common/storageService'; +import { TestResultsService } from '../../client/unittests/common/testResultsService'; +import { TestsHelper } from '../../client/unittests/common/testUtils'; +import { ITestCollectionStorageService, ITestResultsService, ITestsHelper } from '../../client/unittests/common/types'; +import { TestResultDisplay } from '../../client/unittests/display/main'; +import { initialize, initializeTest } from '../initialize'; +import { MockOutputChannel } from '../mockClasses'; +import { MockTestManagerWithRunningTests } from './mocks'; + +use(chaiAsPromised); + +const testFilesPath = path.join(__dirname, '..', '..', '..', 'src', 'test', 'pythonFiles', 'testFiles', 'debuggerTest'); +// tslint:disable-next-line:variable-name +const EmptyTests = { + summary: { + passed: 0, + failures: 0, + errors: 0, + skipped: 0 + }, + testFiles: [], + testFunctions: [], + testSuites: [], + testFolders: [], + rootTestFolders: [] +}; + +// tslint:disable-next-line:max-func-body-length +suite('Unit Tests Stopping Discovery and Runner', () => { + let testResultDisplay: TestResultDisplay; + let outChannel: MockOutputChannel; + let storageService: ITestCollectionStorageService; + let resultsService: ITestResultsService; + let testsHelper: ITestsHelper; + suiteSetup(initialize); + setup(async () => { + outChannel = new MockOutputChannel('Python Test Log'); + testResultDisplay = new TestResultDisplay(outChannel); + await initializeTest(); + }); + teardown(() => { + outChannel.dispose(); + testResultDisplay.dispose(); + }); + + function createTestManagerDepedencies() { + storageService = new TestCollectionStorageService(); + resultsService = new TestResultsService(); + testsHelper = new TestsHelper(); + } + + test('Running tests should not stop existing discovery', async () => { + createTestManagerDepedencies(); + const mockTestManager = new MockTestManagerWithRunningTests('unittest', Product.unittest, testFilesPath, outChannel, storageService, resultsService, testsHelper); + const discoveryPromise = mockTestManager.discoverTests(CommandSource.auto); + mockTestManager.discoveryDeferred.resolve(undefined); + // tslint:disable-next-line:no-floating-promises + mockTestManager.runTest(CommandSource.ui); + + await expect(discoveryPromise).to.eventually.equal(EmptyTests); + }); + + test('Discovering tests should stop running tests', async () => { + createTestManagerDepedencies(); + const mockTestManager = new MockTestManagerWithRunningTests('unittest', Product.unittest, testFilesPath, outChannel, storageService, resultsService, testsHelper); + mockTestManager.discoveryDeferred.resolve(EmptyTests); + await mockTestManager.discoverTests(CommandSource.auto); + const runPromise = mockTestManager.runTest(CommandSource.ui); + // tslint:disable-next-line:no-string-based-set-timeout + await new Promise(resolve => setTimeout(resolve, 1000)); + + // User manually discovering tests will kill the existing test runner. + // tslint:disable-next-line:no-floating-promises + mockTestManager.discoverTests(CommandSource.ui, true, false, true); + await expect(runPromise).to.eventually.be.rejectedWith(CANCELLATION_REASON); + }); +}); diff --git a/tslint.json b/tslint.json index f55dca7c2b4c..7ff727e68b34 100644 --- a/tslint.json +++ b/tslint.json @@ -39,7 +39,8 @@ ], "await-promise": [ true, - "Thenable" + "Thenable", + "PromiseLike" ], "completed-docs": false } From 8a06e989769465ed9403460c7e52a4e5a09c5fb4 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 13:52:33 -0700 Subject: [PATCH 24/86] fixed license headers --- src/client/common/telemetry/constants.ts | 2 +- src/client/common/telemetry/index.ts | 2 +- src/client/common/telemetry/stopWatch.ts | 2 +- src/client/common/telemetry/telemetry.ts | 2 +- src/client/common/telemetry/types.ts | 2 +- src/client/common/telemetry/vscode-extension-telemetry.d.ts | 2 +- src/client/common/utils.ts | 2 +- src/client/debugger/Main.ts | 2 +- src/client/extension.ts | 2 +- src/client/formatters/autoPep8Formatter.ts | 2 +- src/client/formatters/yapfFormatter.ts | 2 +- .../interpreter/configuration/pythonPathUpdaterService.ts | 2 +- .../configuration/pythonPathUpdaterServiceFactory.ts | 2 +- .../interpreter/configuration/services/globalUpdaterService.ts | 2 +- .../configuration/services/workspaceFolderUpdaterService.ts | 2 +- .../configuration/services/workspaceUpdaterService.ts | 2 +- src/client/interpreter/configuration/setInterpreterProvider.ts | 2 +- src/client/interpreter/helpers.ts | 2 +- src/client/interpreter/index.ts | 2 +- src/client/interpreter/interpreterVersion.ts | 2 +- src/client/linters/baseLinter.ts | 2 +- src/client/providers/completionProvider.ts | 2 +- src/client/providers/definitionProvider.ts | 2 +- src/client/providers/execInTerminalProvider.ts | 2 +- src/client/providers/hoverProvider.ts | 2 +- src/client/providers/importSortProvider.ts | 2 +- src/client/providers/lintProvider.ts | 2 +- src/client/providers/objectDefinitionProvider.ts | 2 +- src/client/providers/referenceProvider.ts | 2 +- src/client/providers/renameProvider.ts | 2 +- src/client/providers/replProvider.ts | 2 +- src/client/providers/signatureProvider.ts | 2 +- src/client/providers/simpleRefactorProvider.ts | 2 +- src/client/providers/symbolProvider.ts | 2 +- src/client/providers/updateSparkLibraryProvider.ts | 2 +- src/client/refactor/proxy.ts | 2 +- src/client/unittests/codeLenses/testFiles.ts | 2 +- src/client/unittests/common/baseTestManager.ts | 2 +- src/client/unittests/common/constants.ts | 2 +- src/client/unittests/common/testUtils.ts | 2 +- src/client/unittests/display/picker.ts | 2 +- src/client/unittests/main.ts | 2 +- src/client/unittests/unittest/main.ts | 2 +- src/client/workspaceSymbols/generator.ts | 2 +- src/client/workspaceSymbols/provider.ts | 2 +- src/test/common/common.test.ts | 2 +- src/test/interpreters/condaEnvFileService.test.ts | 2 +- src/test/interpreters/interpreterVersion.test.ts | 2 +- src/test/interpreters/mocks.ts | 2 +- src/test/interpreters/pythonPathUpdater.multiroot.test.ts | 2 +- src/test/interpreters/pythonPathUpdater.test.ts | 2 +- src/test/providers/shebangCodeLenseProvider.test.ts | 2 +- src/test/unittests/debugger.test.ts | 2 +- src/test/unittests/nosetest.test.ts | 2 +- src/test/unittests/pytest.test.ts | 2 +- src/test/unittests/unittest.test.ts | 2 +- 56 files changed, 56 insertions(+), 56 deletions(-) diff --git a/src/client/common/telemetry/constants.ts b/src/client/common/telemetry/constants.ts index b4896a4a5180..b01ca854b7b5 100644 --- a/src/client/common/telemetry/constants.ts +++ b/src/client/common/telemetry/constants.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ export const COMPLETION = 'COMPLETION'; export const DEFINITION = 'DEFINITION'; diff --git a/src/client/common/telemetry/index.ts b/src/client/common/telemetry/index.ts index 6f57fd72990d..07707e944fa8 100644 --- a/src/client/common/telemetry/index.ts +++ b/src/client/common/telemetry/index.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import { StopWatch } from './stopWatch'; import { getTelemetryReporter } from './telemetry'; diff --git a/src/client/common/telemetry/stopWatch.ts b/src/client/common/telemetry/stopWatch.ts index aab19efd0241..17f8713f0b60 100644 --- a/src/client/common/telemetry/stopWatch.ts +++ b/src/client/common/telemetry/stopWatch.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ export class StopWatch { private started: number = Date.now(); diff --git a/src/client/common/telemetry/telemetry.ts b/src/client/common/telemetry/telemetry.ts index 131aa099391e..d86250b08324 100644 --- a/src/client/common/telemetry/telemetry.ts +++ b/src/client/common/telemetry/telemetry.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ // tslint:disable-next-line:no-reference /// diff --git a/src/client/common/telemetry/types.ts b/src/client/common/telemetry/types.ts index 04c102cba76b..a233f23d6991 100644 --- a/src/client/common/telemetry/types.ts +++ b/src/client/common/telemetry/types.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ export type EditorLoadTelemetry = { condaVersion: string; diff --git a/src/client/common/telemetry/vscode-extension-telemetry.d.ts b/src/client/common/telemetry/vscode-extension-telemetry.d.ts index b5ffba6cff5d..143ca92b5002 100644 --- a/src/client/common/telemetry/vscode-extension-telemetry.d.ts +++ b/src/client/common/telemetry/vscode-extension-telemetry.d.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ declare module 'vscode-extension-telemetry' { export default class TelemetryReporter { diff --git a/src/client/common/utils.ts b/src/client/common/utils.ts index 277946f64118..fa544217cc24 100644 --- a/src/client/common/utils.ts +++ b/src/client/common/utils.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; // TODO: Cleanup this place diff --git a/src/client/debugger/Main.ts b/src/client/debugger/Main.ts index 6faab638deee..24158881261b 100644 --- a/src/client/debugger/Main.ts +++ b/src/client/debugger/Main.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ "use strict"; diff --git a/src/client/extension.ts b/src/client/extension.ts index 5d847b2a4f2b..99ce17095fcf 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; import { EDITOR_LOAD } from './common/telemetry/constants'; diff --git a/src/client/formatters/autoPep8Formatter.ts b/src/client/formatters/autoPep8Formatter.ts index d14ae158c790..6ff1b6243852 100644 --- a/src/client/formatters/autoPep8Formatter.ts +++ b/src/client/formatters/autoPep8Formatter.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/formatters/yapfFormatter.ts b/src/client/formatters/yapfFormatter.ts index a668cfce96a2..99100314fa61 100644 --- a/src/client/formatters/yapfFormatter.ts +++ b/src/client/formatters/yapfFormatter.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/interpreter/configuration/pythonPathUpdaterService.ts b/src/client/interpreter/configuration/pythonPathUpdaterService.ts index 41a57bdbbf63..817e52a76622 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterService.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterService.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { ConfigurationTarget, Uri, window } from 'vscode'; diff --git a/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts b/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts index 87f1e4dd8553..8234acf8e0d2 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import { Uri } from 'vscode'; import { GlobalPythonPathUpdaterService } from './services/globalUpdaterService'; diff --git a/src/client/interpreter/configuration/services/globalUpdaterService.ts b/src/client/interpreter/configuration/services/globalUpdaterService.ts index 0bcd084f4cb8..e5bdd7c586e6 100644 --- a/src/client/interpreter/configuration/services/globalUpdaterService.ts +++ b/src/client/interpreter/configuration/services/globalUpdaterService.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import { workspace } from 'vscode'; import { IPythonPathUpdaterService } from '../types'; diff --git a/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts b/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts index 9d465e92dfdc..f09f10a82c0a 100644 --- a/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts +++ b/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { ConfigurationTarget, Uri, workspace } from 'vscode'; diff --git a/src/client/interpreter/configuration/services/workspaceUpdaterService.ts b/src/client/interpreter/configuration/services/workspaceUpdaterService.ts index 56b247399cd9..dbf61bafb24e 100644 --- a/src/client/interpreter/configuration/services/workspaceUpdaterService.ts +++ b/src/client/interpreter/configuration/services/workspaceUpdaterService.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { Uri, workspace } from 'vscode'; diff --git a/src/client/interpreter/configuration/setInterpreterProvider.ts b/src/client/interpreter/configuration/setInterpreterProvider.ts index 5dddff5ff51a..0db4c602a9fb 100644 --- a/src/client/interpreter/configuration/setInterpreterProvider.ts +++ b/src/client/interpreter/configuration/setInterpreterProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; diff --git a/src/client/interpreter/helpers.ts b/src/client/interpreter/helpers.ts index c1b659153552..953c4152ad46 100644 --- a/src/client/interpreter/helpers.ts +++ b/src/client/interpreter/helpers.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as child_process from 'child_process'; import { ConfigurationTarget, window, workspace } from 'vscode'; diff --git a/src/client/interpreter/index.ts b/src/client/interpreter/index.ts index 2a000b7f21fc..76bd665e9b0b 100644 --- a/src/client/interpreter/index.ts +++ b/src/client/interpreter/index.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; diff --git a/src/client/interpreter/interpreterVersion.ts b/src/client/interpreter/interpreterVersion.ts index 2919201dd2f9..63fee232c3e7 100644 --- a/src/client/interpreter/interpreterVersion.ts +++ b/src/client/interpreter/interpreterVersion.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as child_process from 'child_process'; import { getInterpreterVersion } from '../common/utils'; diff --git a/src/client/linters/baseLinter.ts b/src/client/linters/baseLinter.ts index a3f794162b7a..9d7905559d50 100644 --- a/src/client/linters/baseLinter.ts +++ b/src/client/linters/baseLinter.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; diff --git a/src/client/providers/completionProvider.ts b/src/client/providers/completionProvider.ts index 2b1619c5e559..9161cc53c5c2 100644 --- a/src/client/providers/completionProvider.ts +++ b/src/client/providers/completionProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/providers/definitionProvider.ts b/src/client/providers/definitionProvider.ts index 1bab8ebcb3ee..c2747c5f6120 100644 --- a/src/client/providers/definitionProvider.ts +++ b/src/client/providers/definitionProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/providers/execInTerminalProvider.ts b/src/client/providers/execInTerminalProvider.ts index e1405766194b..25643094b1d4 100644 --- a/src/client/providers/execInTerminalProvider.ts +++ b/src/client/providers/execInTerminalProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as fs from 'fs-extra'; diff --git a/src/client/providers/hoverProvider.ts b/src/client/providers/hoverProvider.ts index 180e2a0f99d0..dae2823441f9 100644 --- a/src/client/providers/hoverProvider.ts +++ b/src/client/providers/hoverProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/providers/importSortProvider.ts b/src/client/providers/importSortProvider.ts index bc2858c91dc1..b4481fe65dc8 100644 --- a/src/client/providers/importSortProvider.ts +++ b/src/client/providers/importSortProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as child_process from 'child_process'; diff --git a/src/client/providers/lintProvider.ts b/src/client/providers/lintProvider.ts index 667724f43783..011ec0a69ada 100644 --- a/src/client/providers/lintProvider.ts +++ b/src/client/providers/lintProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/providers/objectDefinitionProvider.ts b/src/client/providers/objectDefinitionProvider.ts index 92545aefd17d..76c48ca7892d 100644 --- a/src/client/providers/objectDefinitionProvider.ts +++ b/src/client/providers/objectDefinitionProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/providers/referenceProvider.ts b/src/client/providers/referenceProvider.ts index 39a38d212190..24523b6dc792 100644 --- a/src/client/providers/referenceProvider.ts +++ b/src/client/providers/referenceProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/providers/renameProvider.ts b/src/client/providers/renameProvider.ts index 148612f7ef49..f7bd7b5d4968 100644 --- a/src/client/providers/renameProvider.ts +++ b/src/client/providers/renameProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/providers/replProvider.ts b/src/client/providers/replProvider.ts index dfeb731c72f6..12accf7c6d71 100644 --- a/src/client/providers/replProvider.ts +++ b/src/client/providers/replProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import { commands, Disposable, window, workspace } from 'vscode'; import { PythonSettings } from '../common/configSettings'; diff --git a/src/client/providers/signatureProvider.ts b/src/client/providers/signatureProvider.ts index 1d28b598ff34..7af1401b7f6c 100644 --- a/src/client/providers/signatureProvider.ts +++ b/src/client/providers/signatureProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/providers/simpleRefactorProvider.ts b/src/client/providers/simpleRefactorProvider.ts index 7a749a7a8c1f..df3070b2231a 100644 --- a/src/client/providers/simpleRefactorProvider.ts +++ b/src/client/providers/simpleRefactorProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/providers/symbolProvider.ts b/src/client/providers/symbolProvider.ts index c7b18c7600e5..2a60288acce5 100644 --- a/src/client/providers/symbolProvider.ts +++ b/src/client/providers/symbolProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/providers/updateSparkLibraryProvider.ts b/src/client/providers/updateSparkLibraryProvider.ts index 4fd1a9907c2d..a715dfe46aa3 100644 --- a/src/client/providers/updateSparkLibraryProvider.ts +++ b/src/client/providers/updateSparkLibraryProvider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; diff --git a/src/client/refactor/proxy.ts b/src/client/refactor/proxy.ts index d9efefb9c392..05d6537df7ce 100644 --- a/src/client/refactor/proxy.ts +++ b/src/client/refactor/proxy.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/unittests/codeLenses/testFiles.ts b/src/client/unittests/codeLenses/testFiles.ts index 47cf8e4d9fe1..2335d2ffe724 100644 --- a/src/client/unittests/codeLenses/testFiles.ts +++ b/src/client/unittests/codeLenses/testFiles.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; diff --git a/src/client/unittests/common/baseTestManager.ts b/src/client/unittests/common/baseTestManager.ts index b94a8cdc737c..7211818456a7 100644 --- a/src/client/unittests/common/baseTestManager.ts +++ b/src/client/unittests/common/baseTestManager.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ // import {TestFolder, TestsToRun, Tests, TestFile, TestSuite, TestFunction, TestStatus, FlattenedTestFunction, FlattenedTestSuite, CANCELLATION_REASON} from './contracts'; import * as vscode from 'vscode'; diff --git a/src/client/unittests/common/constants.ts b/src/client/unittests/common/constants.ts index d79c373ef026..4e9923ccb6e1 100644 --- a/src/client/unittests/common/constants.ts +++ b/src/client/unittests/common/constants.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ export const CANCELLATION_REASON = 'cancelled_user_request'; export enum CommandSource { diff --git a/src/client/unittests/common/testUtils.ts b/src/client/unittests/common/testUtils.ts index e9ecad84df35..777ed96f1055 100644 --- a/src/client/unittests/common/testUtils.ts +++ b/src/client/unittests/common/testUtils.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import * as vscode from 'vscode'; diff --git a/src/client/unittests/display/picker.ts b/src/client/unittests/display/picker.ts index 93cdc73519bb..de7cdb7bfcf8 100644 --- a/src/client/unittests/display/picker.ts +++ b/src/client/unittests/display/picker.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { QuickPickItem, Uri, window } from 'vscode'; diff --git a/src/client/unittests/main.ts b/src/client/unittests/main.ts index cbb2d790e0c5..9977591a3185 100644 --- a/src/client/unittests/main.ts +++ b/src/client/unittests/main.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; import { Uri, window, workspace } from 'vscode'; diff --git a/src/client/unittests/unittest/main.ts b/src/client/unittests/unittest/main.ts index a426ec5ac155..88600310765e 100644 --- a/src/client/unittests/unittest/main.ts +++ b/src/client/unittests/unittest/main.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; diff --git a/src/client/workspaceSymbols/generator.ts b/src/client/workspaceSymbols/generator.ts index e285f3b2d2dd..a8c7ebdcc3c4 100644 --- a/src/client/workspaceSymbols/generator.ts +++ b/src/client/workspaceSymbols/generator.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as child_process from 'child_process'; import * as fs from 'fs'; diff --git a/src/client/workspaceSymbols/provider.ts b/src/client/workspaceSymbols/provider.ts index bc1a4fc12d89..82cfbaafbfaa 100644 --- a/src/client/workspaceSymbols/provider.ts +++ b/src/client/workspaceSymbols/provider.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as _ from 'lodash'; import * as vscode from 'vscode'; diff --git a/src/test/common/common.test.ts b/src/test/common/common.test.ts index 322579cec1ae..ba6cfefd263b 100644 --- a/src/test/common/common.test.ts +++ b/src/test/common/common.test.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import { EOL } from 'os'; diff --git a/src/test/interpreters/condaEnvFileService.test.ts b/src/test/interpreters/condaEnvFileService.test.ts index d153918f6883..0a525e640539 100644 --- a/src/test/interpreters/condaEnvFileService.test.ts +++ b/src/test/interpreters/condaEnvFileService.test.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as fs from 'fs-extra'; diff --git a/src/test/interpreters/interpreterVersion.test.ts b/src/test/interpreters/interpreterVersion.test.ts index 503c4fb3ffca..4823f8a4ee22 100644 --- a/src/test/interpreters/interpreterVersion.test.ts +++ b/src/test/interpreters/interpreterVersion.test.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import { assert, expect } from 'chai'; import { execPythonFile } from '../../client/common/utils'; diff --git a/src/test/interpreters/mocks.ts b/src/test/interpreters/mocks.ts index 64bb01502c5e..a8c00ea3b3ae 100644 --- a/src/test/interpreters/mocks.ts +++ b/src/test/interpreters/mocks.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import { Architecture, Hive, IRegistry } from '../../client/common/registry'; import { IInterpreterLocatorService, PythonInterpreter } from '../../client/interpreter/contracts'; diff --git a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts index a7ac15455e75..3f885c767a21 100644 --- a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts +++ b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as path from 'path'; diff --git a/src/test/interpreters/pythonPathUpdater.test.ts b/src/test/interpreters/pythonPathUpdater.test.ts index 114652587337..3e7505788443 100644 --- a/src/test/interpreters/pythonPathUpdater.test.ts +++ b/src/test/interpreters/pythonPathUpdater.test.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as path from 'path'; diff --git a/src/test/providers/shebangCodeLenseProvider.test.ts b/src/test/providers/shebangCodeLenseProvider.test.ts index d89e0bd230db..bf9f6b9d5b72 100644 --- a/src/test/providers/shebangCodeLenseProvider.test.ts +++ b/src/test/providers/shebangCodeLenseProvider.test.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as child_process from 'child_process'; diff --git a/src/test/unittests/debugger.test.ts b/src/test/unittests/debugger.test.ts index db750c610275..3650b77c0d22 100644 --- a/src/test/unittests/debugger.test.ts +++ b/src/test/unittests/debugger.test.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import { assert, expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; diff --git a/src/test/unittests/nosetest.test.ts b/src/test/unittests/nosetest.test.ts index ee5323a91b68..b047018b1772 100644 --- a/src/test/unittests/nosetest.test.ts +++ b/src/test/unittests/nosetest.test.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as fs from 'fs'; diff --git a/src/test/unittests/pytest.test.ts b/src/test/unittests/pytest.test.ts index bc301f3dea27..7d42f8d014e2 100644 --- a/src/test/unittests/pytest.test.ts +++ b/src/test/unittests/pytest.test.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as path from 'path'; diff --git a/src/test/unittests/unittest.test.ts b/src/test/unittests/unittest.test.ts index 0705395b2cd0..1da28d90eca9 100644 --- a/src/test/unittests/unittest.test.ts +++ b/src/test/unittests/unittest.test.ts @@ -1,6 +1,6 @@ /*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. + * Licensed under the MIT License. *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as fs from 'fs-extra'; From 4b570a58d041b2caff75a731fd8c48aa4d3a629d Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 14:19:04 -0700 Subject: [PATCH 25/86] use regex when extracting version info --- src/client/interpreter/interpreterVersion.ts | 17 ++++++++++------- .../interpreters/interpreterVersion.test.ts | 19 ++++++++++--------- 2 files changed, 20 insertions(+), 16 deletions(-) diff --git a/src/client/interpreter/interpreterVersion.ts b/src/client/interpreter/interpreterVersion.ts index 63fee232c3e7..5f2c4e18fef3 100644 --- a/src/client/interpreter/interpreterVersion.ts +++ b/src/client/interpreter/interpreterVersion.ts @@ -1,7 +1,5 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. import * as child_process from 'child_process'; import { getInterpreterVersion } from '../common/utils'; @@ -10,6 +8,8 @@ export interface IInterpreterVersionService { getPipVersion(pythonPath: string): Promise; } +const PIP_VERSION_REGEX = '\\d\\.\\d(\\.\\d)+'; + export class InterpreterVersionService implements IInterpreterVersionService { public async getVersion(pythonPath: string, defaultValue: string): Promise { return getInterpreterVersion(pythonPath) @@ -20,11 +20,14 @@ export class InterpreterVersionService implements IInterpreterVersionService { return new Promise((resolve, reject) => { child_process.execFile(pythonPath, ['-m', 'pip', '--version'], (error, stdout, stdErr) => { if (stdout && stdout.length > 0) { + // Take the first available version number, see below example. + // pip 9.0.1 from /Users/donjayamanne/anaconda3/lib/python3.6/site-packages (python 3.6). // Take the second part, see below example. // pip 9.0.1 from /Users/donjayamanne/anaconda3/lib/python3.6/site-packages (python 3.6). - const parts = stdout.split(' '); - if (parts.length > 1) { - resolve(parts[1].trim()); + const re = new RegExp(PIP_VERSION_REGEX, 'g'); + const matches = re.exec(stdout); + if (matches && matches.length > 0) { + resolve(matches[0].trim()); return; } } diff --git a/src/test/interpreters/interpreterVersion.test.ts b/src/test/interpreters/interpreterVersion.test.ts index bd3c5dc23e7f..19326b00d7fd 100644 --- a/src/test/interpreters/interpreterVersion.test.ts +++ b/src/test/interpreters/interpreterVersion.test.ts @@ -1,7 +1,5 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. import { assert, expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import { execPythonFile } from '../../client/common/utils'; @@ -28,16 +26,19 @@ suite('Interpreters display version', () => { }); test('Must return the Pip Version', async () => { const output = await execPythonFile(undefined, 'python', ['-m', 'pip', '--version'], __dirname, true); - const versionInfo = getFirstNonEmptyLineFromMultilineString(output); - // Take the second part, see below example. // pip 9.0.1 from /Users/donjayamanne/anaconda3/lib/python3.6/site-packages (python 3.6). - const parts = versionInfo.split(' '); + const re = new RegExp('\\d\\.\\d(\\.\\d)+', 'g'); + const matches = re.exec(output); + assert.isNotNull(matches, 'No matches for version found'); + // tslint:disable-next-line:no-non-null-assertion + assert.isAtLeast(matches!.length, 1, 'Version number not found'); const pipVersionPromise = interpreterVersion.getPipVersion('python'); - await expect(pipVersionPromise).to.eventually.equal(parts[1].trim()); + // tslint:disable-next-line:no-non-null-assertion + await expect(pipVersionPromise).to.eventually.equal(matches![0].trim()); }); - test('Must throw an exceptionn when Pip version cannot be determine', async () => { + test('Must throw an exceptionn when pip version cannot be determine', async () => { const pipVersionPromise = interpreterVersion.getPipVersion('INVALID_INTERPRETER'); await expect(pipVersionPromise).to.be.rejectedWith(); }); From 01562cbcbbecd040332a18b230eadae22b7bc2be Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 14:19:43 -0700 Subject: [PATCH 26/86] removed license header --- src/client/common/utils.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/common/utils.ts b/src/client/common/utils.ts index fa544217cc24..820c81b596da 100644 --- a/src/client/common/utils.ts +++ b/src/client/common/utils.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; // TODO: Cleanup this place // Add options for execPythonFile From be4f35198dfb5eea766c300c4ea9e3bcd279fc18 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 14:22:07 -0700 Subject: [PATCH 27/86] fixed test --- src/test/unittests/stoppingDiscoverAndTest.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/unittests/stoppingDiscoverAndTest.test.ts b/src/test/unittests/stoppingDiscoverAndTest.test.ts index c42788f0d2ee..b69fd40ec7e9 100644 --- a/src/test/unittests/stoppingDiscoverAndTest.test.ts +++ b/src/test/unittests/stoppingDiscoverAndTest.test.ts @@ -62,7 +62,7 @@ suite('Unit Tests Stopping Discovery and Runner', () => { createTestManagerDepedencies(); const mockTestManager = new MockTestManagerWithRunningTests('unittest', Product.unittest, testFilesPath, outChannel, storageService, resultsService, testsHelper); const discoveryPromise = mockTestManager.discoverTests(CommandSource.auto); - mockTestManager.discoveryDeferred.resolve(undefined); + mockTestManager.discoveryDeferred.resolve(EmptyTests); // tslint:disable-next-line:no-floating-promises mockTestManager.runTest(CommandSource.ui); From d62a8a2dabe2a9674a11ae57fc356ffabc866940 Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 14:28:35 -0700 Subject: [PATCH 28/86] fixed typo --- src/test/interpreters/interpreterVersion.test.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/interpreters/interpreterVersion.test.ts b/src/test/interpreters/interpreterVersion.test.ts index 19326b00d7fd..c0d294fee060 100644 --- a/src/test/interpreters/interpreterVersion.test.ts +++ b/src/test/interpreters/interpreterVersion.test.ts @@ -24,7 +24,7 @@ suite('Interpreters display version', () => { const pyVersion = await interpreterVersion.getVersion('INVALID_INTERPRETER', 'DEFAULT_TEST_VALUE'); assert.equal(pyVersion, 'DEFAULT_TEST_VALUE', 'Incorrect version'); }); - test('Must return the Pip Version', async () => { + test('Must return the pip Version', async () => { const output = await execPythonFile(undefined, 'python', ['-m', 'pip', '--version'], __dirname, true); // Take the second part, see below example. // pip 9.0.1 from /Users/donjayamanne/anaconda3/lib/python3.6/site-packages (python 3.6). From d57d9e9f618cf4db50d751f5a698b381377f7dad Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 14:29:18 -0700 Subject: [PATCH 29/86] removed unwanted props --- src/client/providers/execInTerminalProvider.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/client/providers/execInTerminalProvider.ts b/src/client/providers/execInTerminalProvider.ts index 25643094b1d4..367fc9f006e6 100644 --- a/src/client/providers/execInTerminalProvider.ts +++ b/src/client/providers/execInTerminalProvider.ts @@ -210,7 +210,7 @@ function execSelectionInDjangoShell() { terminal.sendText(unix_code); } terminal.show(); - sendTelemetryEvent(EXECUTION_DJANGO, undefined, { scope: 'selection' }); + sendTelemetryEvent(EXECUTION_DJANGO); } class DjangoContextInitializer implements vscode.Disposable { From 04ddb39d823c43e8e9fc7c1c0e311484135f52be Mon Sep 17 00:00:00 2001 From: Don Jayamanne Date: Fri, 3 Nov 2017 14:30:21 -0700 Subject: [PATCH 30/86] fixed typo --- src/client/common/telemetry/index.ts | 10 +++++----- src/client/common/telemetry/stopWatch.ts | 2 +- src/client/extension.ts | 2 +- .../configuration/pythonPathUpdaterService.ts | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/client/common/telemetry/index.ts b/src/client/common/telemetry/index.ts index 07707e944fa8..abc10a6aa527 100644 --- a/src/client/common/telemetry/index.ts +++ b/src/client/common/telemetry/index.ts @@ -41,16 +41,16 @@ export function captureTelemetry(eventName: string) { // tslint:disable-next-line:prefer-type-cast (result as Promise) .then(data => { - sendTelemetryEvent(eventName, stopWatch.elpsedTime); + sendTelemetryEvent(eventName, stopWatch.elapsedTime); return data; }) // tslint:disable-next-line:promise-function-async .catch(ex => { - sendTelemetryEvent(eventName, stopWatch.elpsedTime); + sendTelemetryEvent(eventName, stopWatch.elapsedTime); return Promise.reject(ex); }); } else { - sendTelemetryEvent(eventName, stopWatch.elpsedTime); + sendTelemetryEvent(eventName, stopWatch.elapsedTime); } return result; @@ -69,12 +69,12 @@ export function sendTelemetryWhenDone(eventName: string, promise: Promise | (promise as Promise) .then(data => { // tslint:disable-next-line:no-non-null-assertion - sendTelemetryEvent(eventName, stopWatch!.elpsedTime, properties); + sendTelemetryEvent(eventName, stopWatch!.elapsedTime, properties); return data; // tslint:disable-next-line:promise-function-async }, ex => { // tslint:disable-next-line:no-non-null-assertion - sendTelemetryEvent(eventName, stopWatch!.elpsedTime, properties); + sendTelemetryEvent(eventName, stopWatch!.elapsedTime, properties); return Promise.reject(ex); }); } else { diff --git a/src/client/common/telemetry/stopWatch.ts b/src/client/common/telemetry/stopWatch.ts index 17f8713f0b60..5ff6c15f8608 100644 --- a/src/client/common/telemetry/stopWatch.ts +++ b/src/client/common/telemetry/stopWatch.ts @@ -5,7 +5,7 @@ export class StopWatch { private started: number = Date.now(); private stopped?: number; - public get elpsedTime() { + public get elapsedTime() { return (this.stopped ? this.stopped : Date.now()) - this.started; } public stop() { diff --git a/src/client/extension.ts b/src/client/extension.ts index 99ce17095fcf..7412e0349619 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -155,7 +155,7 @@ export async function activate(context: vscode.ExtensionContext) { async function sendStartupTelemetry(activatedPromise: Promise) { const stopWatch = new StopWatch(); activatedPromise.then(async () => { - const duration = stopWatch.elpsedTime; + const duration = stopWatch.elapsedTime; let condaVersion: string | undefined; try { condaVersion = await getCondaVersion(); diff --git a/src/client/interpreter/configuration/pythonPathUpdaterService.ts b/src/client/interpreter/configuration/pythonPathUpdaterService.ts index 817e52a76622..97dfaa1e8c52 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterService.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterService.ts @@ -27,7 +27,7 @@ export class PythonPathUpdaterService { console.error(reason); } // do not wait for this to complete - this.sendTelemetry(stopWatch.elpsedTime, failed, trigger, pythonPath); + this.sendTelemetry(stopWatch.elapsedTime, failed, trigger, pythonPath); } private async sendTelemetry(duration: number, failed: boolean, trigger: 'ui' | 'shebang' | 'load', pythonPath: string) { let version: string | undefined; From d141205f77f0bef60147ccc6c772c2ebbf95f2b8 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:41:05 -0700 Subject: [PATCH 31/86] Simplify copyright header --- src/client/common/telemetry/types.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/client/common/telemetry/types.ts b/src/client/common/telemetry/types.ts index a233f23d6991..467f0fdd905d 100644 --- a/src/client/common/telemetry/types.ts +++ b/src/client/common/telemetry/types.ts @@ -1,7 +1,5 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. export type EditorLoadTelemetry = { condaVersion: string; }; From 906e43fa5ec7248bc12ee563838f5752a0bd64ce Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:41:27 -0700 Subject: [PATCH 32/86] Simplify copyright header --- src/client/common/telemetry/telemetry.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/client/common/telemetry/telemetry.ts b/src/client/common/telemetry/telemetry.ts index d86250b08324..25db5eddd125 100644 --- a/src/client/common/telemetry/telemetry.ts +++ b/src/client/common/telemetry/telemetry.ts @@ -1,7 +1,6 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + // tslint:disable-next-line:no-reference /// import { extensions } from 'vscode'; From d222c4403744ebb12b2b6788c9aca264ae108328 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:41:48 -0700 Subject: [PATCH 33/86] Simplify copyright header --- src/client/common/telemetry/stopWatch.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/client/common/telemetry/stopWatch.ts b/src/client/common/telemetry/stopWatch.ts index 5ff6c15f8608..221d466754ab 100644 --- a/src/client/common/telemetry/stopWatch.ts +++ b/src/client/common/telemetry/stopWatch.ts @@ -1,7 +1,6 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + export class StopWatch { private started: number = Date.now(); private stopped?: number; From bc321de3ec0b43930b5b746f9d1ff90eedf98ca9 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:42:08 -0700 Subject: [PATCH 34/86] Simplify copyright header --- src/client/common/telemetry/index.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/client/common/telemetry/index.ts b/src/client/common/telemetry/index.ts index abc10a6aa527..74f590f105cf 100644 --- a/src/client/common/telemetry/index.ts +++ b/src/client/common/telemetry/index.ts @@ -1,7 +1,6 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + import { StopWatch } from './stopWatch'; import { getTelemetryReporter } from './telemetry'; import { TelemetryProperties } from './types'; From a3cff53a2da014eee3d2b844720b02333e5de54b Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:42:28 -0700 Subject: [PATCH 35/86] Simplify copyright header --- src/client/common/telemetry/constants.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/client/common/telemetry/constants.ts b/src/client/common/telemetry/constants.ts index b01ca854b7b5..89314e9c712f 100644 --- a/src/client/common/telemetry/constants.ts +++ b/src/client/common/telemetry/constants.ts @@ -1,7 +1,5 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. export const COMPLETION = 'COMPLETION'; export const DEFINITION = 'DEFINITION'; export const HOVER_DEFINITION = 'HOVER_DEFINITION'; From f447ef863aa826115c3bd433ecd967f2242ead48 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:43:50 -0700 Subject: [PATCH 36/86] Remove copyright header --- src/client/common/telemetry/vscode-extension-telemetry.d.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/common/telemetry/vscode-extension-telemetry.d.ts b/src/client/common/telemetry/vscode-extension-telemetry.d.ts index 143ca92b5002..63944bc57471 100644 --- a/src/client/common/telemetry/vscode-extension-telemetry.d.ts +++ b/src/client/common/telemetry/vscode-extension-telemetry.d.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ declare module 'vscode-extension-telemetry' { export default class TelemetryReporter { /** From 612103f01c5a28eccec425d411a70246061bd7b0 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:44:08 -0700 Subject: [PATCH 37/86] Remove copyright header --- src/client/debugger/Main.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/debugger/Main.ts b/src/client/debugger/Main.ts index 24158881261b..dcc276a65c5a 100644 --- a/src/client/debugger/Main.ts +++ b/src/client/debugger/Main.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ "use strict"; import { DebugSession, InitializedEvent, TerminatedEvent, StoppedEvent, OutputEvent, Thread, StackFrame, Scope, Source, Handles } from "vscode-debugadapter"; From 4c160ba42431008c488a2c0c50352d8c24aeabed Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:44:24 -0700 Subject: [PATCH 38/86] Remove copyright header --- src/client/extension.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/extension.ts b/src/client/extension.ts index 7412e0349619..bcb605e732ec 100644 --- a/src/client/extension.ts +++ b/src/client/extension.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import { EDITOR_LOAD } from './common/telemetry/constants'; From 50e3b65efe0c84d0db853e16dd226ff6c866bdbc Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:44:40 -0700 Subject: [PATCH 39/86] Remove copyright header --- src/client/formatters/autoPep8Formatter.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/formatters/autoPep8Formatter.ts b/src/client/formatters/autoPep8Formatter.ts index 6ff1b6243852..1953143618c5 100644 --- a/src/client/formatters/autoPep8Formatter.ts +++ b/src/client/formatters/autoPep8Formatter.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; From f2a806b3e41a0a03fa4762b4994110828aeaf438 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:44:57 -0700 Subject: [PATCH 40/86] Remove copyright header --- src/client/formatters/yapfFormatter.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/formatters/yapfFormatter.ts b/src/client/formatters/yapfFormatter.ts index 99100314fa61..1a221098fe81 100644 --- a/src/client/formatters/yapfFormatter.ts +++ b/src/client/formatters/yapfFormatter.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; From d666edd989b6c94129af7a64a05e0bf423a50b47 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:45:09 -0700 Subject: [PATCH 41/86] Remove copyright header --- .../interpreter/configuration/pythonPathUpdaterService.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/interpreter/configuration/pythonPathUpdaterService.ts b/src/client/interpreter/configuration/pythonPathUpdaterService.ts index 97dfaa1e8c52..ff3e85d04fe0 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterService.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterService.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { ConfigurationTarget, Uri, window } from 'vscode'; import { sendTelemetryEvent } from '../../common/telemetry'; From 3bb4d5068db2fb9a66e34027e34322a1c5af8278 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:45:26 -0700 Subject: [PATCH 42/86] Remove copyright header --- .../configuration/pythonPathUpdaterServiceFactory.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts b/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts index 8234acf8e0d2..c48d20cdac1c 100644 --- a/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts +++ b/src/client/interpreter/configuration/pythonPathUpdaterServiceFactory.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import { Uri } from 'vscode'; import { GlobalPythonPathUpdaterService } from './services/globalUpdaterService'; import { WorkspaceFolderPythonPathUpdaterService } from './services/workspaceFolderUpdaterService'; From 164b27ea2d2bd97c3cf5201e464c630848107e43 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:45:45 -0700 Subject: [PATCH 43/86] Remove copyright header --- .../configuration/services/globalUpdaterService.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/interpreter/configuration/services/globalUpdaterService.ts b/src/client/interpreter/configuration/services/globalUpdaterService.ts index e5bdd7c586e6..d25a866bfbcd 100644 --- a/src/client/interpreter/configuration/services/globalUpdaterService.ts +++ b/src/client/interpreter/configuration/services/globalUpdaterService.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import { workspace } from 'vscode'; import { IPythonPathUpdaterService } from '../types'; From a98b80e6721083cf5cde63755717d04d25f72602 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:45:59 -0700 Subject: [PATCH 44/86] Remove copyright header --- .../configuration/services/workspaceFolderUpdaterService.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts b/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts index f09f10a82c0a..37f45d5cde14 100644 --- a/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts +++ b/src/client/interpreter/configuration/services/workspaceFolderUpdaterService.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { ConfigurationTarget, Uri, workspace } from 'vscode'; import { IPythonPathUpdaterService } from '../types'; From 6d88c7b30e4b4c959e6c1b29172ebe14ef04e851 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:46:14 -0700 Subject: [PATCH 45/86] Remove copyright header --- .../configuration/services/workspaceUpdaterService.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/interpreter/configuration/services/workspaceUpdaterService.ts b/src/client/interpreter/configuration/services/workspaceUpdaterService.ts index dbf61bafb24e..a5a35c3483e5 100644 --- a/src/client/interpreter/configuration/services/workspaceUpdaterService.ts +++ b/src/client/interpreter/configuration/services/workspaceUpdaterService.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { Uri, workspace } from 'vscode'; import { IPythonPathUpdaterService } from '../types'; From 69ea92d23cac9af5c9574fcaf416745ab4a6780f Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:46:32 -0700 Subject: [PATCH 46/86] Remove copyright header --- .../interpreter/configuration/setInterpreterProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/interpreter/configuration/setInterpreterProvider.ts b/src/client/interpreter/configuration/setInterpreterProvider.ts index 0db4c602a9fb..418c12550c5c 100644 --- a/src/client/interpreter/configuration/setInterpreterProvider.ts +++ b/src/client/interpreter/configuration/setInterpreterProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; import { commands, ConfigurationTarget, Disposable, QuickPickItem, QuickPickOptions, Uri, window, workspace } from 'vscode'; From a2b929297714ff4bb177c56794a454ba3fc3b788 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:48:27 -0700 Subject: [PATCH 47/86] Remove copyright header --- src/client/interpreter/helpers.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/interpreter/helpers.ts b/src/client/interpreter/helpers.ts index 953c4152ad46..f78df63a31f8 100644 --- a/src/client/interpreter/helpers.ts +++ b/src/client/interpreter/helpers.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as child_process from 'child_process'; import { ConfigurationTarget, window, workspace } from 'vscode'; import { RegistryImplementation } from '../common/registry'; From 92671f8de7f2f3918d2bf0bddf5dbfce530f4c54 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:48:41 -0700 Subject: [PATCH 48/86] Remove copyright header --- src/client/interpreter/index.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/interpreter/index.ts b/src/client/interpreter/index.ts index 76bd665e9b0b..c00d6b5973e2 100644 --- a/src/client/interpreter/index.ts +++ b/src/client/interpreter/index.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; import { Disposable, StatusBarAlignment, Uri, window, workspace } from 'vscode'; From 9e27b86acb14a500e50eb00721a9aa3c307a4747 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:48:55 -0700 Subject: [PATCH 49/86] Remove copyright header --- src/client/interpreter/interpreterVersion.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/client/interpreter/interpreterVersion.ts b/src/client/interpreter/interpreterVersion.ts index 5f2c4e18fef3..0f7ef485e388 100644 --- a/src/client/interpreter/interpreterVersion.ts +++ b/src/client/interpreter/interpreterVersion.ts @@ -1,5 +1,3 @@ -// Copyright (c) Microsoft Corporation. All rights reserved. -// Licensed under the MIT License. import * as child_process from 'child_process'; import { getInterpreterVersion } from '../common/utils'; From c42d9c495bd1fe9b603160865c4a9faedbfd53b4 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:49:09 -0700 Subject: [PATCH 50/86] Remove copyright header --- src/client/linters/baseLinter.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/linters/baseLinter.ts b/src/client/linters/baseLinter.ts index 9d7905559d50..4b4f1d61541e 100644 --- a/src/client/linters/baseLinter.ts +++ b/src/client/linters/baseLinter.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; import { OutputChannel, Uri } from 'vscode'; From b67f10bad4e010a1e8c5febc0e8a487150bd8d5b Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:49:21 -0700 Subject: [PATCH 51/86] Remove copyright header --- src/client/providers/completionProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/completionProvider.ts b/src/client/providers/completionProvider.ts index 9161cc53c5c2..7d2d67dfdaac 100644 --- a/src/client/providers/completionProvider.ts +++ b/src/client/providers/completionProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; From 638407e65620505e26fd5c8385ade08c5a8f49c5 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:49:35 -0700 Subject: [PATCH 52/86] Remove copyright header --- src/client/providers/definitionProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/definitionProvider.ts b/src/client/providers/definitionProvider.ts index c2747c5f6120..7c9a66aa92ea 100644 --- a/src/client/providers/definitionProvider.ts +++ b/src/client/providers/definitionProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; From d747a2d1df64d98ef11511c8bfe8d388eebc96a0 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:49:50 -0700 Subject: [PATCH 53/86] Remove copyright header --- src/client/providers/execInTerminalProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/execInTerminalProvider.ts b/src/client/providers/execInTerminalProvider.ts index 367fc9f006e6..cd4cc73bab1e 100644 --- a/src/client/providers/execInTerminalProvider.ts +++ b/src/client/providers/execInTerminalProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as fs from 'fs-extra'; import { EOL } from 'os'; From b110d7e2b293f95899bdab92ebe65473bea30285 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:50:03 -0700 Subject: [PATCH 54/86] Remove copyright header --- src/client/providers/hoverProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/hoverProvider.ts b/src/client/providers/hoverProvider.ts index dae2823441f9..05c3e1c0a395 100644 --- a/src/client/providers/hoverProvider.ts +++ b/src/client/providers/hoverProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import { EOL } from 'os'; From 0881e49a605cb2e0f743dd8a1a5a34b868405891 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:50:22 -0700 Subject: [PATCH 55/86] Remove copyright header --- src/client/providers/importSortProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/importSortProvider.ts b/src/client/providers/importSortProvider.ts index b4481fe65dc8..8ec1b2cc0371 100644 --- a/src/client/providers/importSortProvider.ts +++ b/src/client/providers/importSortProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as child_process from 'child_process'; import * as fs from 'fs'; From 0fe0b42acf95d4e92fab53233c9192e1b0c4555f Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:50:37 -0700 Subject: [PATCH 56/86] Remove copyright header --- src/client/providers/lintProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/lintProvider.ts b/src/client/providers/lintProvider.ts index 011ec0a69ada..d1d878d0515f 100644 --- a/src/client/providers/lintProvider.ts +++ b/src/client/providers/lintProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as fs from 'fs'; From 3095f8bb7b03515cccc40927bdb61816fed62874 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:50:51 -0700 Subject: [PATCH 57/86] Remove copyright header --- src/client/providers/objectDefinitionProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/objectDefinitionProvider.ts b/src/client/providers/objectDefinitionProvider.ts index 76c48ca7892d..2caf816b555f 100644 --- a/src/client/providers/objectDefinitionProvider.ts +++ b/src/client/providers/objectDefinitionProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; From e750ff74e799e71aaa416895f2dbd7e8787f4a37 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:51:04 -0700 Subject: [PATCH 58/86] Remove copyright header --- src/client/providers/referenceProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/referenceProvider.ts b/src/client/providers/referenceProvider.ts index 24523b6dc792..afb5ec7c148a 100644 --- a/src/client/providers/referenceProvider.ts +++ b/src/client/providers/referenceProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; From 31343c00d041ae2c9967db5f9102770f1cae0073 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:51:18 -0700 Subject: [PATCH 59/86] Remove copyright header --- src/client/providers/renameProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/renameProvider.ts b/src/client/providers/renameProvider.ts index f7bd7b5d4968..4f1270e5a423 100644 --- a/src/client/providers/renameProvider.ts +++ b/src/client/providers/renameProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; From 75ec627d6642b9229b1e0875aeb37358c80933b0 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:51:34 -0700 Subject: [PATCH 60/86] Remove copyright header --- src/client/providers/replProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/replProvider.ts b/src/client/providers/replProvider.ts index 12accf7c6d71..60dc4f040d3d 100644 --- a/src/client/providers/replProvider.ts +++ b/src/client/providers/replProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import { commands, Disposable, window, workspace } from 'vscode'; import { PythonSettings } from '../common/configSettings'; import { Commands } from '../common/constants'; From bbd89151261ece103818da2dfa076d80ce4318bc Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:54:00 -0700 Subject: [PATCH 61/86] Remove copyright header --- src/client/providers/signatureProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/signatureProvider.ts b/src/client/providers/signatureProvider.ts index 7af1401b7f6c..135886a528d8 100644 --- a/src/client/providers/signatureProvider.ts +++ b/src/client/providers/signatureProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; From f36a1d5639004a803bddc383f4a0ffe38836edc5 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:54:15 -0700 Subject: [PATCH 62/86] Remove copyright header --- src/client/providers/simpleRefactorProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/simpleRefactorProvider.ts b/src/client/providers/simpleRefactorProvider.ts index df3070b2231a..bc9cced0c019 100644 --- a/src/client/providers/simpleRefactorProvider.ts +++ b/src/client/providers/simpleRefactorProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; From e1147889f61cd9a5bf4779cde41a847423a0f5cb Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:54:31 -0700 Subject: [PATCH 63/86] Remove copyright header --- src/client/providers/symbolProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/symbolProvider.ts b/src/client/providers/symbolProvider.ts index 2a60288acce5..8c4ba6f42aa6 100644 --- a/src/client/providers/symbolProvider.ts +++ b/src/client/providers/symbolProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; From a7f3e52669387e612f3016ab0113a663852687b2 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:54:46 -0700 Subject: [PATCH 64/86] Remove copyright header --- src/client/providers/updateSparkLibraryProvider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/providers/updateSparkLibraryProvider.ts b/src/client/providers/updateSparkLibraryProvider.ts index a715dfe46aa3..cc2f1616fcc7 100644 --- a/src/client/providers/updateSparkLibraryProvider.ts +++ b/src/client/providers/updateSparkLibraryProvider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as path from 'path'; import * as vscode from 'vscode'; From 21b924faadda0405cc5690c086e3ef3f526df575 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:54:59 -0700 Subject: [PATCH 65/86] Remove copyright header --- src/client/refactor/proxy.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/refactor/proxy.ts b/src/client/refactor/proxy.ts index 05d6537df7ce..2511c99450d9 100644 --- a/src/client/refactor/proxy.ts +++ b/src/client/refactor/proxy.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as child_process from 'child_process'; From da8571026d3b7ce9a4dd7a3ad7f364bede73a070 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:55:12 -0700 Subject: [PATCH 66/86] Remove copyright header --- src/client/unittests/codeLenses/testFiles.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/unittests/codeLenses/testFiles.ts b/src/client/unittests/codeLenses/testFiles.ts index 2335d2ffe724..10f115148594 100644 --- a/src/client/unittests/codeLenses/testFiles.ts +++ b/src/client/unittests/codeLenses/testFiles.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import { CancellationToken, CancellationTokenSource, CodeLens, CodeLensProvider, Event, EventEmitter, Position, Range, SymbolInformation, SymbolKind, TextDocument, workspace } from 'vscode'; From f2d31f61492a3b37349360e1e0f82662ee557103 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:55:32 -0700 Subject: [PATCH 67/86] Remove copyright header --- src/client/unittests/common/baseTestManager.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/unittests/common/baseTestManager.ts b/src/client/unittests/common/baseTestManager.ts index c1e9e303a030..633fbb3ad14d 100644 --- a/src/client/unittests/common/baseTestManager.ts +++ b/src/client/unittests/common/baseTestManager.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ // import {TestFolder, TestsToRun, Tests, TestFile, TestSuite, TestFunction, TestStatus, FlattenedTestFunction, FlattenedTestSuite, CANCELLATION_REASON} from './contracts'; import * as vscode from 'vscode'; import { Uri, workspace } from 'vscode'; From 74ae430793fd7e87bb3ce5ddef9b4c2155df2e9f Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:55:50 -0700 Subject: [PATCH 68/86] Remove copyright header --- src/client/unittests/common/constants.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/unittests/common/constants.ts b/src/client/unittests/common/constants.ts index 4e9923ccb6e1..9bd66948c6e3 100644 --- a/src/client/unittests/common/constants.ts +++ b/src/client/unittests/common/constants.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ export const CANCELLATION_REASON = 'cancelled_user_request'; export enum CommandSource { auto = 'auto', From 93600b7162ce45e08383646299adef8f678ec384 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:56:04 -0700 Subject: [PATCH 69/86] Remove copyright header --- src/client/unittests/common/testUtils.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/unittests/common/testUtils.ts b/src/client/unittests/common/testUtils.ts index 777ed96f1055..b552b4c82b7e 100644 --- a/src/client/unittests/common/testUtils.ts +++ b/src/client/unittests/common/testUtils.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import * as vscode from 'vscode'; import { Uri, workspace } from 'vscode'; From 4e923af05fd1b344429dcb8564a68d75d64bfa7d Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:56:18 -0700 Subject: [PATCH 70/86] Remove copyright header --- src/client/unittests/display/picker.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/unittests/display/picker.ts b/src/client/unittests/display/picker.ts index de7cdb7bfcf8..2b3d47652abf 100644 --- a/src/client/unittests/display/picker.ts +++ b/src/client/unittests/display/picker.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as path from 'path'; import { QuickPickItem, Uri, window } from 'vscode'; import * as vscode from 'vscode'; From a89fd8eb1ca042e60ad4e4b90c740421eae89cb4 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:56:34 -0700 Subject: [PATCH 71/86] Remove copyright header --- src/client/unittests/main.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/unittests/main.ts b/src/client/unittests/main.ts index 9977591a3185..f7e0b0978f0a 100644 --- a/src/client/unittests/main.ts +++ b/src/client/unittests/main.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import { Uri, window, workspace } from 'vscode'; import * as vscode from 'vscode'; From d6241ef939bd9cb85be4c9d9436f912289effc41 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:56:48 -0700 Subject: [PATCH 72/86] Remove copyright header --- src/client/unittests/unittest/main.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/unittests/unittest/main.ts b/src/client/unittests/unittest/main.ts index 88600310765e..09e96e307fa5 100644 --- a/src/client/unittests/unittest/main.ts +++ b/src/client/unittests/unittest/main.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ 'use strict'; import * as vscode from 'vscode'; import { Product } from '../../common/installer'; From f7360068e2104d6ff2b342c60c9533a98cd5cd3b Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:57:02 -0700 Subject: [PATCH 73/86] Remove copyright header --- src/client/workspaceSymbols/generator.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/workspaceSymbols/generator.ts b/src/client/workspaceSymbols/generator.ts index a8c7ebdcc3c4..acbc3b5354cc 100644 --- a/src/client/workspaceSymbols/generator.ts +++ b/src/client/workspaceSymbols/generator.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as child_process from 'child_process'; import * as fs from 'fs'; import * as path from 'path'; From 78c0d19057ae958be867313a85a1762b4e51b15c Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:57:16 -0700 Subject: [PATCH 74/86] Remove copyright header --- src/client/workspaceSymbols/provider.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/client/workspaceSymbols/provider.ts b/src/client/workspaceSymbols/provider.ts index 82cfbaafbfaa..736c6ff0f750 100644 --- a/src/client/workspaceSymbols/provider.ts +++ b/src/client/workspaceSymbols/provider.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as _ from 'lodash'; import * as vscode from 'vscode'; import { Commands } from '../common/constants'; From e330ef010f70d8cd8f22f5b6e62acaebde3e02d6 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:57:30 -0700 Subject: [PATCH 75/86] Remove copyright header --- src/test/common/common.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/common/common.test.ts b/src/test/common/common.test.ts index ba6cfefd263b..aeccb54166da 100644 --- a/src/test/common/common.test.ts +++ b/src/test/common/common.test.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import { EOL } from 'os'; import * as vscode from 'vscode'; From 5168eb23940940680bef3c48ed0275716d9fa587 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:57:43 -0700 Subject: [PATCH 76/86] Remove copyright header --- src/test/interpreters/condaEnvFileService.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/interpreters/condaEnvFileService.test.ts b/src/test/interpreters/condaEnvFileService.test.ts index 0a525e640539..88f3ae8934e3 100644 --- a/src/test/interpreters/condaEnvFileService.test.ts +++ b/src/test/interpreters/condaEnvFileService.test.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as fs from 'fs-extra'; import { EOL } from 'os'; From 258a381ef7a2c8fe4df4bc8fc14011766c198467 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:58:03 -0700 Subject: [PATCH 77/86] Remove copyright header --- src/test/interpreters/mocks.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/interpreters/mocks.ts b/src/test/interpreters/mocks.ts index a8c00ea3b3ae..db4cfed0c474 100644 --- a/src/test/interpreters/mocks.ts +++ b/src/test/interpreters/mocks.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import { Architecture, Hive, IRegistry } from '../../client/common/registry'; import { IInterpreterLocatorService, PythonInterpreter } from '../../client/interpreter/contracts'; import { IInterpreterVersionService } from '../../client/interpreter/interpreterVersion'; From 4247d9bad945a219d4b1c530cee6f27d454d3b87 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:58:16 -0700 Subject: [PATCH 78/86] Remove copyright header --- src/test/interpreters/pythonPathUpdater.multiroot.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts index 3f885c767a21..05025376fe3d 100644 --- a/src/test/interpreters/pythonPathUpdater.multiroot.test.ts +++ b/src/test/interpreters/pythonPathUpdater.multiroot.test.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as path from 'path'; import { ConfigurationTarget, Uri, workspace } from 'vscode'; From bb2826e639fe68a93999151228c350e1891bf49d Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:58:30 -0700 Subject: [PATCH 79/86] Remove copyright header --- src/test/interpreters/pythonPathUpdater.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/interpreters/pythonPathUpdater.test.ts b/src/test/interpreters/pythonPathUpdater.test.ts index 3e7505788443..c74aba47ec07 100644 --- a/src/test/interpreters/pythonPathUpdater.test.ts +++ b/src/test/interpreters/pythonPathUpdater.test.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as path from 'path'; import { ConfigurationTarget, Uri, workspace } from 'vscode'; From 93c6561dbaae3096f53719f77dd0dbcfe3d3974b Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:58:45 -0700 Subject: [PATCH 80/86] Remove copyright header --- src/test/providers/shebangCodeLenseProvider.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/providers/shebangCodeLenseProvider.test.ts b/src/test/providers/shebangCodeLenseProvider.test.ts index bf9f6b9d5b72..158f6e6db987 100644 --- a/src/test/providers/shebangCodeLenseProvider.test.ts +++ b/src/test/providers/shebangCodeLenseProvider.test.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as child_process from 'child_process'; import * as path from 'path'; From c653c0608b96d4c6909a37c2e02975685c0f3bc0 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:58:59 -0700 Subject: [PATCH 81/86] Remove copyright header --- src/test/unittests/debugger.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/unittests/debugger.test.ts b/src/test/unittests/debugger.test.ts index 7f50e322ac9a..e02fd63422e1 100644 --- a/src/test/unittests/debugger.test.ts +++ b/src/test/unittests/debugger.test.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import { assert, expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import * as path from 'path'; From e55c15e335bc8793554843bce2ab0cf5e611a0e8 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:59:14 -0700 Subject: [PATCH 82/86] Remove copyright header --- src/test/unittests/nosetest.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/unittests/nosetest.test.ts b/src/test/unittests/nosetest.test.ts index b047018b1772..c932a1950332 100644 --- a/src/test/unittests/nosetest.test.ts +++ b/src/test/unittests/nosetest.test.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as fs from 'fs'; import * as path from 'path'; From a1b9b26ff664c7d8dde6a494d027237697374a88 Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:59:28 -0700 Subject: [PATCH 83/86] Remove copyright header --- src/test/unittests/pytest.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/unittests/pytest.test.ts b/src/test/unittests/pytest.test.ts index 7d42f8d014e2..1b016f4228cc 100644 --- a/src/test/unittests/pytest.test.ts +++ b/src/test/unittests/pytest.test.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as path from 'path'; import * as vscode from 'vscode'; From 7c56f5a34a7ee48e345f84b94a247854604bc8bd Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 15:59:47 -0700 Subject: [PATCH 84/86] Remove copyright header --- src/test/unittests/rediscover.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/unittests/rediscover.test.ts b/src/test/unittests/rediscover.test.ts index 0f106258166f..ade46afcbfd5 100644 --- a/src/test/unittests/rediscover.test.ts +++ b/src/test/unittests/rediscover.test.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ import { assert } from 'chai'; import * as fs from 'fs-extra'; import * as path from 'path'; From ef467e21367752f0fe4df85169d7a8700a47c6ee Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 16:00:23 -0700 Subject: [PATCH 85/86] Simplify copyright header --- src/test/unittests/stoppingDiscoverAndTest.test.ts | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/test/unittests/stoppingDiscoverAndTest.test.ts b/src/test/unittests/stoppingDiscoverAndTest.test.ts index b69fd40ec7e9..eba6a358aa8d 100644 --- a/src/test/unittests/stoppingDiscoverAndTest.test.ts +++ b/src/test/unittests/stoppingDiscoverAndTest.test.ts @@ -1,7 +1,6 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. See License.txt in the project root for license information. - *--------------------------------------------------------------------------------------------*/ +// Copyright (c) Microsoft Corporation. All rights reserved. +// Licensed under the MIT License. + import { expect, use } from 'chai'; import * as chaiAsPromised from 'chai-as-promised'; import * as path from 'path'; From b7100a72f2467c1e0c53f64aa86a942fdd778b5e Mon Sep 17 00:00:00 2001 From: Brett Cannon Date: Fri, 3 Nov 2017 16:00:54 -0700 Subject: [PATCH 86/86] Remove copyright header --- src/test/unittests/unittest.test.ts | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/test/unittests/unittest.test.ts b/src/test/unittests/unittest.test.ts index 1da28d90eca9..d333ed32fa9c 100644 --- a/src/test/unittests/unittest.test.ts +++ b/src/test/unittests/unittest.test.ts @@ -1,7 +1,3 @@ -/*--------------------------------------------------------------------------------------------- - * Copyright (c) Microsoft Corporation. All rights reserved. - * Licensed under the MIT License. - *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import * as fs from 'fs-extra'; import * as path from 'path';