Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion src/client/common/application/applicationEnvironment.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import { inject, injectable } from 'inversify';
import * as path from 'path';
import { parse } from 'semver';
import * as vscode from 'vscode';
import { Channel } from '../constants';
import { IPlatformService } from '../platform/types';
import { ICurrentProcess, IPathUtils } from '../types';
import { OSType } from '../utils/platform';
import { Channel, IApplicationEnvironment } from './types';
import { IApplicationEnvironment } from './types';

@injectable()
export class ApplicationEnvironment implements IApplicationEnvironment {
Expand Down
25 changes: 8 additions & 17 deletions src/client/common/application/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,11 @@

'use strict';

import { CancellationToken, Disposable, Position, TextDocument, Uri } from 'vscode';
import { CancellationToken, Position, TextDocument, Uri } from 'vscode';
import { Commands as LSCommands } from '../../activation/commands';
import { TensorBoardEntrypoint, TensorBoardEntrypointTrigger } from '../../tensorBoard/constants';
import { TestDataItem, TestFunction, TestsToRun, TestWorkspaceFolder } from '../../testing/common/types';
import { Commands } from '../constants';
import { Channel, CommandSource, ICommandManager } from './types';
import { Channel, Commands, CommandSource } from '../constants';

export type CommandsWithoutArgs = keyof ICommandNameWithoutArgumentTypeMapping;

Expand Down Expand Up @@ -48,10 +47,15 @@ interface ICommandNameWithoutArgumentTypeMapping {
[Commands.Tests_Discovering]: [];
[Commands.PickLocalProcess]: [];
[Commands.OpenStartPage]: [];
[Commands.ClearStorage]: [];
[Commands.ReportIssue]: [];
[Commands.RefreshTensorBoard]: [];
[LSCommands.ClearAnalyisCache]: [];
[LSCommands.RestartLS]: [];
}

export type AllCommands = keyof ICommandNameArgumentTypeMapping;

/**
* Mapping between commands and list of arguments.
* Used to provide strong typing for command & args.
Expand Down Expand Up @@ -83,6 +87,7 @@ export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgu
['jupyter.opennotebook']: [undefined | Uri, undefined | CommandSource];
['jupyter.runallcells']: [Uri];
['extension.open']: [string];
['workbench.action.openIssueReporter']: [{ extensionId: string; issueBody: string }];
[Commands.GetSelectedInterpreterPath]: [{ workspaceFolder: string } | string[]];
[Commands.Build_Workspace_Symbols]: [boolean, CancellationToken];
[Commands.Sort_Imports]: [undefined, Uri];
Expand Down Expand Up @@ -127,17 +132,3 @@ export interface ICommandNameArgumentTypeMapping extends ICommandNameWithoutArgu
[Commands.navigateToTestSuite]: [Uri, TestDataItem, boolean];
[Commands.LaunchTensorBoard]: [TensorBoardEntrypoint, TensorBoardEntrypointTrigger];
}

//export const IPythonCommandManager = Symbol('IPythonCommandManager');
export interface IPythonCommandManager extends ICommandManager {
registerCommand<E extends keyof ICommandNameArgumentTypeMapping, U extends ICommandNameArgumentTypeMapping[E]>(
command: E,
callback: (...args: U) => any,
thisArg?: any,
): Disposable;

executeCommand<T, E extends keyof ICommandNameArgumentTypeMapping, U extends ICommandNameArgumentTypeMapping[E]>(
command: E,
...rest: U
): Thenable<T | undefined>;
}
3 changes: 2 additions & 1 deletion src/client/common/application/commands/reportIssueCommand.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { EXTENSION_ROOT_DIR } from '../../../constants';
import { IInterpreterService, IInterpreterVersionService } from '../../../interpreter/contracts';
import { identifyEnvironment } from '../../../pythonEnvironments/common/environmentIdentifier';
import { getPythonOutputChannelContent } from '../../../logging';
import { Commands } from '../../constants';

/**
* Allows the user to report an issue related to the Python extension using our template.
Expand All @@ -26,7 +27,7 @@ export class ReportIssueCommandHandler implements IExtensionSingleActivationServ
) {}

public async activate(): Promise<void> {
this.commandManager.registerCommand('python.reportIssue', this.openReportIssue, this);
this.commandManager.registerCommand(Commands.ReportIssue, this.openReportIssue, this);
}

private templatePath = path.join(EXTENSION_ROOT_DIR, 'resources', 'report_issue_template.md');
Expand Down
23 changes: 11 additions & 12 deletions src/client/common/application/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -60,15 +60,9 @@ import {
} from 'vscode';
import type { NotebookConcatTextDocument, NotebookDocument } from 'vscode-proposed';

import { Channel } from '../constants';
import { IAsyncDisposable, Resource } from '../types';

export enum CommandSource {
auto = 'auto',
ui = 'ui',
codelens = 'codelens',
commandPalette = 'commandpalette',
testExplorer = 'testExplorer',
}
import { ICommandNameArgumentTypeMapping } from './commands';

export const IApplicationShell = Symbol('IApplicationShell');
export interface IApplicationShell {
Expand Down Expand Up @@ -437,7 +431,11 @@ export interface ICommandManager {
* @param thisArg The `this` context used when invoking the handler function.
* @return Disposable which unregisters this command on disposal.
*/
registerCommand(command: string, callback: (...args: any[]) => any, thisArg?: any): Disposable;
registerCommand<E extends keyof ICommandNameArgumentTypeMapping, U extends ICommandNameArgumentTypeMapping[E]>(
command: E,
callback: (...args: U) => any,
thisArg?: any,
): Disposable;

/**
* Registers a text editor command that can be invoked via a keyboard shortcut,
Expand Down Expand Up @@ -473,7 +471,10 @@ export interface ICommandManager {
* @return A thenable that resolves to the returned value of the given command. `undefined` when
* the command handler function doesn't return anything.
*/
executeCommand<T>(command: string, ...rest: any[]): Thenable<T | undefined>;
executeCommand<T, E extends keyof ICommandNameArgumentTypeMapping, U extends ICommandNameArgumentTypeMapping[E]>(
command: E,
...rest: U
): Thenable<T | undefined>;

/**
* Retrieve the list of all available commands. Commands starting an underscore are
Expand Down Expand Up @@ -1164,8 +1165,6 @@ export interface ILanguageService {
): Disposable;
}

export type Channel = 'stable' | 'insiders';

/**
* Wraps the `ActiveResourceService` API class. Created for injecting and mocking class methods in testing
*/
Expand Down
11 changes: 11 additions & 0 deletions src/client/common/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,16 @@ export const PYLANCE_EXTENSION_ID = 'ms-python.vscode-pylance';
export const JUPYTER_EXTENSION_ID = 'ms-toolsai.jupyter';
export const AppinsightsKey = 'AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217';

export type Channel = 'stable' | 'insiders';

export enum CommandSource {
auto = 'auto',
ui = 'ui',
codelens = 'codelens',
commandPalette = 'commandpalette',
testExplorer = 'testExplorer',
}

export namespace Commands {
export const Set_Interpreter = 'python.setInterpreter';
export const Set_ShebangInterpreter = 'python.setShebangInterpreter';
Expand Down Expand Up @@ -69,6 +79,7 @@ export namespace Commands {
export const OpenStartPage = 'python.startPage.open';
export const LaunchTensorBoard = 'python.launchTensorBoard';
export const RefreshTensorBoard = 'python.refreshTensorBoard';
export const ReportIssue = 'python.reportIssue';
}
export namespace Octicons {
export const Test_Pass = '$(check)';
Expand Down
3 changes: 1 addition & 2 deletions src/client/common/serviceRegistry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ import { ApplicationEnvironment } from './application/applicationEnvironment';
import { ApplicationShell } from './application/applicationShell';
import { ClipboardService } from './application/clipboard';
import { CommandManager } from './application/commandManager';
import { IPythonCommandManager } from './application/commands';
import { ReloadVSCodeCommandHandler } from './application/commands/reloadCommand';
import { ReportIssueCommandHandler } from './application/commands/reportIssueCommand';
import { DebugService } from './application/debugService';
Expand Down Expand Up @@ -141,7 +140,7 @@ export function registerTypes(serviceManager: IServiceManager) {
IJupyterExtensionDependencyManager,
JupyterExtensionDependencyManager,
);
serviceManager.addSingleton<IPythonCommandManager>(ICommandManager, CommandManager);
serviceManager.addSingleton<ICommandManager>(ICommandManager, CommandManager);
serviceManager.addSingleton<IConfigurationService>(IConfigurationService, ConfigurationService);
serviceManager.addSingleton<IWorkspaceService>(IWorkspaceService, WorkspaceService);
serviceManager.addSingleton<IProcessLogger>(IProcessLogger, ProcessLogger);
Expand Down
2 changes: 1 addition & 1 deletion src/client/common/startPage/startPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,14 @@ import { IExtensionSingleActivationService } from '../../activation/types';
import { EXTENSION_ROOT_DIR } from '../../constants';
import { sendTelemetryEvent } from '../../telemetry';
import {
CommandSource,
IApplicationEnvironment,
IApplicationShell,
ICommandManager,
IDocumentManager,
IWebviewPanelProvider,
IWorkspaceService,
} from '../application/types';
import { CommandSource } from '../constants';
import { IFileSystem } from '../platform/types';
import { IConfigurationService, IExtensionContext, Resource } from '../types';
import * as localize from '../utils/localize';
Expand Down
23 changes: 16 additions & 7 deletions src/client/testing/codeLenses/testFiles.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,6 @@ import {
TextDocument,
Uri,
} from 'vscode';
import { CommandSource } from '../../common/application/types';
import { IWorkspaceService } from '../../../client/common/application/types';
import { IFileSystem } from '../../../client/common/platform/types';
import { IServiceContainer } from '../../../client/ioc/types';
Expand Down Expand Up @@ -167,12 +166,22 @@ export class TestFileCodeLensProvider implements CodeLensProvider {
new CodeLens(range, {
title: getTestStatusIcon(cls.status) + constants.Text.CodeLensRunUnitTest,
command: constants.Commands.Tests_Run,
arguments: [undefined, CommandSource.codelens, file, <TestsToRun>{ testSuite: [cls] }],
arguments: [
undefined,
constants.CommandSource.codelens,
file,
<TestsToRun>{ testSuite: [cls] },
],
}),
new CodeLens(range, {
title: getTestStatusIcon(cls.status) + constants.Text.CodeLensDebugUnitTest,
command: constants.Commands.Tests_Debug,
arguments: [undefined, CommandSource.codelens, file, <TestsToRun>{ testSuite: [cls] }],
arguments: [
undefined,
constants.CommandSource.codelens,
file,
<TestsToRun>{ testSuite: [cls] },
],
}),
];
}
Expand Down Expand Up @@ -251,12 +260,12 @@ function getFunctionCodeLens(
new CodeLens(range, {
title: getTestStatusIcon(fn.status) + constants.Text.CodeLensRunUnitTest,
command: constants.Commands.Tests_Run,
arguments: [undefined, CommandSource.codelens, file, <TestsToRun>{ testFunction: [fn] }],
arguments: [undefined, constants.CommandSource.codelens, file, <TestsToRun>{ testFunction: [fn] }],
}),
new CodeLens(range, {
title: getTestStatusIcon(fn.status) + constants.Text.CodeLensDebugUnitTest,
command: constants.Commands.Tests_Debug,
arguments: [undefined, CommandSource.codelens, file, <TestsToRun>{ testFunction: [fn] }],
arguments: [undefined, constants.CommandSource.codelens, file, <TestsToRun>{ testFunction: [fn] }],
}),
];
}
Expand All @@ -275,12 +284,12 @@ function getFunctionCodeLens(
new CodeLens(range, {
title: `${getTestStatusIcons(functions)} ${constants.Text.CodeLensRunUnitTest} (Multiple)`,
command: constants.Commands.Tests_Picker_UI,
arguments: [undefined, CommandSource.codelens, file, functions],
arguments: [undefined, constants.CommandSource.codelens, file, functions],
}),
new CodeLens(range, {
title: `${getTestStatusIcons(functions)} ${constants.Text.CodeLensDebugUnitTest} (Multiple)`,
command: constants.Commands.Tests_Picker_UI_Debug,
arguments: [undefined, CommandSource.codelens, file, functions],
arguments: [undefined, constants.CommandSource.codelens, file, functions],
}),
];
}
Expand Down
3 changes: 2 additions & 1 deletion src/client/testing/common/managers/baseTestManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import {
OutputChannel,
Uri,
} from 'vscode';
import { CommandSource, ICommandManager, IWorkspaceService } from '../../../common/application/types';
import { ICommandManager, IWorkspaceService } from '../../../common/application/types';
import '../../../common/extensions';
import { isNotInstalledError } from '../../../common/helpers';
import { traceError } from '../../../common/logger';
Expand Down Expand Up @@ -50,6 +50,7 @@ import {
TestsToRun,
WorkspaceTestStatus,
} from '../types';
import { CommandSource } from '../../../common/constants';

enum CancellationTokenType {
testDiscovery,
Expand Down
7 changes: 5 additions & 2 deletions src/client/testing/common/testUtils.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import { inject, injectable, named } from 'inversify';
import * as path from 'path';
import { Uri, workspace } from 'vscode';
import { CommandSource } from '../../common/application/types';
import { IApplicationShell, ICommandManager } from '../../common/application/types';
import * as constants from '../../common/constants';
import { Product } from '../../common/types';
Expand Down Expand Up @@ -230,7 +229,11 @@ export class TestsHelper implements ITestsHelper {
public displayTestErrorMessage(message: string) {
this.appShell.showErrorMessage(message, constants.Button_Text_Tests_View_Output).then((action) => {
if (action === constants.Button_Text_Tests_View_Output) {
this.commandManager.executeCommand(constants.Commands.Tests_ViewOutput, undefined, CommandSource.ui);
this.commandManager.executeCommand(
constants.Commands.Tests_ViewOutput,
undefined,
constants.CommandSource.ui,
);
}
});
}
Expand Down
2 changes: 1 addition & 1 deletion src/client/testing/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,12 @@ import {
Uri,
WorkspaceFolder,
} from 'vscode';
import { CommandSource } from '../../common/application/types';
import { Product } from '../../common/types';
import { DebuggerTypeName } from '../../debugger/constants';
import { ConsoleType } from '../../debugger/types';
import { TestProvider } from '../types';
import { TestSettingsPropertyNames } from '../configuration/types';
import { CommandSource } from '../../common/constants';

export type UnitTestProduct = Product.nosetest | Product.pytest | Product.unittest;

Expand Down
8 changes: 4 additions & 4 deletions src/client/testing/display/picker.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { inject, injectable } from 'inversify';
import * as path from 'path';
import { QuickPickItem, Uri } from 'vscode';
import { CommandSource, IApplicationShell, ICommandManager } from '../../common/application/types';
import { IApplicationShell, ICommandManager } from '../../common/application/types';
import * as constants from '../../common/constants';
import { IFileSystem } from '../../common/platform/types';
import { IServiceContainer } from '../../ioc/types';
Expand Down Expand Up @@ -34,7 +34,7 @@ export class TestDisplay implements ITestDisplay {
}
});
}
public displayTestUI(cmdSource: CommandSource, wkspace: Uri) {
public displayTestUI(cmdSource: constants.CommandSource, wkspace: Uri) {
const tests = this.testCollectionStorage.getTests(wkspace);
this.appShell
.showQuickPick(buildItems(tests), { matchOnDescription: true, matchOnDetail: true })
Expand Down Expand Up @@ -73,7 +73,7 @@ export class TestDisplay implements ITestDisplay {
});
}
public displayFunctionTestPickerUI(
cmdSource: CommandSource,
cmdSource: constants.CommandSource,
wkspace: Uri,
rootDirectory: string,
file: Uri,
Expand Down Expand Up @@ -276,7 +276,7 @@ function buildItemsForTestFiles(rootDirectory: string, testFiles: TestFile[]): T
}
export function onItemSelected(
commandManager: ICommandManager,
cmdSource: CommandSource,
cmdSource: constants.CommandSource,
wkspace: Uri,
selection: TestItem,
debug?: boolean,
Expand Down
4 changes: 2 additions & 2 deletions src/client/testing/explorer/commandHandlers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@
'use strict';

import { inject, injectable } from 'inversify';
import { CommandSource, ICommandManager } from '../../common/application/types';
import { Commands } from '../../common/constants';
import { ICommandManager } from '../../common/application/types';
import { Commands, CommandSource } from '../../common/constants';
import { traceDecorators } from '../../common/logger';
import { IDisposable } from '../../common/types';
import { swallowExceptions } from '../../common/utils/decorators';
Expand Down
4 changes: 2 additions & 2 deletions src/client/testing/explorer/testTreeViewProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@

import { inject, injectable } from 'inversify';
import { Event, EventEmitter, TreeItem, TreeItemCollapsibleState, Uri } from 'vscode';
import { CommandSource, ICommandManager, IWorkspaceService } from '../../common/application/types';
import { Commands } from '../../common/constants';
import { ICommandManager, IWorkspaceService } from '../../common/application/types';
import { Commands, CommandSource } from '../../common/constants';
import { IDisposable, IDisposableRegistry } from '../../common/types';
import { sendTelemetryEvent } from '../../telemetry';
import { EventName } from '../../telemetry/constants';
Expand Down
Loading