-
Notifications
You must be signed in to change notification settings - Fork 1.6k
fix #1229 disable installer prompts via do not show again option #1243
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -1,8 +1,8 @@ | ||
| import * as vscode from 'vscode'; | ||
| import * as settings from './configSettings'; | ||
| import { createDeferred, isNotInstalledError } from './helpers'; | ||
| import { execPythonFile, getFullyQualifiedPythonInterpreterPath } from './utils'; | ||
| import * as os from 'os'; | ||
| import { isNotInstalledError } from './helpers'; | ||
| import { execPythonFile, getFullyQualifiedPythonInterpreterPath } from './utils'; | ||
| import { Documentation } from './constants'; | ||
|
|
||
| export enum Product { | ||
|
|
@@ -86,9 +86,6 @@ export const Linters: Product[] = [ | |
| Product.pydocstyle | ||
| ]; | ||
|
|
||
| const Formatters: Product[] = [Product.autopep8, Product.yapf]; | ||
| const TestFrameworks: Product[] = [Product.pytest, Product.nosetest, Product.unittest]; | ||
|
|
||
| const ProductNames = new Map<Product, string>(); | ||
| ProductNames.set(Product.autopep8, 'autopep8'); | ||
| ProductNames.set(Product.flake8, 'flake8'); | ||
|
|
@@ -146,9 +143,9 @@ ProductTypes.set(Product.yapf, ProductType.Formatter); | |
| ProductTypes.set(Product.rope, ProductType.RefactoringLibrary); | ||
|
|
||
| export class Installer implements vscode.Disposable { | ||
| private static terminal: vscode.Terminal; | ||
| private static terminal: vscode.Terminal | undefined | null; | ||
| private disposables: vscode.Disposable[] = []; | ||
| constructor(private outputChannel: vscode.OutputChannel = null) { | ||
| constructor(private outputChannel?: vscode.OutputChannel) { | ||
| this.disposables.push(vscode.window.onDidCloseTerminal(term => { | ||
| if (term === Installer.terminal) { | ||
| Installer.terminal = null; | ||
|
|
@@ -158,46 +155,65 @@ export class Installer implements vscode.Disposable { | |
| public dispose() { | ||
| this.disposables.forEach(d => d.dispose()); | ||
| } | ||
| public shouldDisplayPrompt(product: Product) { | ||
| const productName = ProductNames.get(product)!; | ||
| return settings.PythonSettings.getInstance().disablePromptForFeatures.indexOf(productName) === -1; | ||
| } | ||
|
|
||
| promptToInstall(product: Product): Thenable<any> { | ||
| const productType = ProductTypes.get(product); | ||
| async promptToInstall(product: Product) { | ||
| const productType = ProductTypes.get(product)!; | ||
| const productTypeName = ProductTypeNames.get(productType); | ||
| const productName = ProductNames.get(product); | ||
| const productName = ProductNames.get(product)!; | ||
|
|
||
| if (!this.shouldDisplayPrompt(product)) { | ||
| const message = `${productTypeName} '${productName}' not installed.`; | ||
| if (this.outputChannel) { | ||
| this.outputChannel.appendLine(message); | ||
| } | ||
| else { | ||
| console.warn(message); | ||
| } | ||
| return; | ||
| } | ||
|
|
||
| const installOption = 'Install ' + productName; | ||
| const disableOption = 'Disable ' + productTypeName; | ||
| const disableOptionGlobally = `Disable ${productTypeName} globally`; | ||
| const dontShowAgain = `Don't show this prompt again`; | ||
| const alternateFormatter = product === Product.autopep8 ? 'yapf' : 'autopep8'; | ||
| const useOtherFormatter = `Use '${alternateFormatter}' formatter`; | ||
| const options = []; | ||
| options.push(installOption); | ||
| if (productType === ProductType.Formatter) { | ||
| options.push(...[installOption, useOtherFormatter]); | ||
| options.push(...[useOtherFormatter]); | ||
| } | ||
| if (SettingToDisableProduct.has(product)) { | ||
| options.push(...[disableOption, disableOptionGlobally]); | ||
| options.push(...[disableOption, dontShowAgain]); | ||
| } | ||
| return vscode.window.showErrorMessage(`${productTypeName} ${productName} is not installed`, ...options).then(item => { | ||
| switch (item) { | ||
| case installOption: { | ||
| return this.install(product); | ||
| } | ||
| case disableOptionGlobally: | ||
| case disableOption: { | ||
| const global = item === disableOptionGlobally; | ||
| if (Linters.indexOf(product) >= 0) { | ||
| return disableLinter(product, global); | ||
| return disableLinter(product); | ||
| } | ||
| else { | ||
| const pythonConfig = vscode.workspace.getConfiguration('python'); | ||
| const settingToDisable = SettingToDisableProduct.get(product); | ||
| return pythonConfig.update(settingToDisable, false, global); | ||
| const settingToDisable = SettingToDisableProduct.get(product)!; | ||
| return pythonConfig.update(settingToDisable, false); | ||
| } | ||
| } | ||
| case useOtherFormatter: { | ||
| const pythonConfig = vscode.workspace.getConfiguration('python'); | ||
| return pythonConfig.update('formatting.provider', alternateFormatter); | ||
| } | ||
| case dontShowAgain: { | ||
| const pythonConfig = vscode.workspace.getConfiguration('python'); | ||
| const features = pythonConfig.get('disablePromptForFeatures', [] as string[]); | ||
| features.push(productName); | ||
| return pythonConfig.update('disablePromptForFeatures', features, true); | ||
| } | ||
| case 'Help': { | ||
| return Promise.resolve(); | ||
| } | ||
|
|
@@ -215,7 +231,7 @@ export class Installer implements vscode.Disposable { | |
| return Promise.resolve(); | ||
| } | ||
|
|
||
| let installArgs = ProductInstallScripts.get(product); | ||
| let installArgs = ProductInstallScripts.get(product)!; | ||
| let pipIndex = installArgs.indexOf('pip'); | ||
| if (pipIndex > 0) { | ||
| installArgs = installArgs.slice(); | ||
|
|
@@ -228,8 +244,8 @@ export class Installer implements vscode.Disposable { | |
| if (this.outputChannel && installArgs[0] === '-m') { | ||
| // Errors are just displayed to the user | ||
| this.outputChannel.show(); | ||
| return execPythonFile(settings.PythonSettings.getInstance().pythonPath, installArgs, vscode.workspace.rootPath, true, (data) => { | ||
| this.outputChannel.append(data); | ||
| return execPythonFile(settings.PythonSettings.getInstance().pythonPath, installArgs, vscode.workspace.rootPath!, true, (data) => { | ||
| this.outputChannel!.append(data); | ||
| }); | ||
| } | ||
| else { | ||
|
|
@@ -249,8 +265,8 @@ export class Installer implements vscode.Disposable { | |
| installScript = `${pythonPath} ${installScript}`; | ||
| } | ||
| } | ||
| Installer.terminal.sendText(installScript); | ||
| Installer.terminal.show(false); | ||
| Installer.terminal!.sendText(installScript); | ||
| Installer.terminal!.show(false); | ||
| }); | ||
| } | ||
| } | ||
|
|
@@ -266,7 +282,7 @@ export class Installer implements vscode.Disposable { | |
|
|
||
| export function disableLinter(product: Product, global?: boolean) { | ||
| const pythonConfig = vscode.workspace.getConfiguration('python'); | ||
| const settingToDisable = SettingToDisableProduct.get(product); | ||
| const settingToDisable = SettingToDisableProduct.get(product)!; | ||
| if (vscode.workspace.rootPath) { | ||
| return pythonConfig.update(settingToDisable, false, global); | ||
| } | ||
|
|
@@ -275,12 +291,12 @@ export function disableLinter(product: Product, global?: boolean) { | |
| } | ||
| } | ||
|
|
||
| function isProductInstalled(product: Product): Promise<boolean | undefined> { | ||
| async function isProductInstalled(product: Product): Promise<boolean | undefined> { | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To help me learn, what are the rules for when to use
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lol,
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Figures. Wasn't sure if there was a move towards just
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. e.g. if you declare a variable or call a function without passing in a value, the default value of those variables or parameters is |
||
| if (!ProductExecutableAndArgs.has(product)) { | ||
| return; | ||
| } | ||
| const prodExec = ProductExecutableAndArgs.get(product); | ||
| return execPythonFile(prodExec.executable, prodExec.args.concat(['--version']), vscode.workspace.rootPath, false) | ||
| const prodExec = ProductExecutableAndArgs.get(product)!; | ||
| return execPythonFile(prodExec.executable, prodExec.args.concat(['--version']), vscode.workspace.rootPath!, false) | ||
| .then(() => { | ||
| return true; | ||
| }).catch(reason => { | ||
|
|
@@ -289,6 +305,6 @@ function isProductInstalled(product: Product): Promise<boolean | undefined> { | |
| } | ||
|
|
||
| function uninstallproduct(product: Product): Promise<any> { | ||
| const uninstallArgs = ProductUninstallScripts.get(product); | ||
| return execPythonFile('python', uninstallArgs, vscode.workspace.rootPath, false); | ||
| } | ||
| const uninstallArgs = ProductUninstallScripts.get(product)!; | ||
| return execPythonFile('python', uninstallArgs, vscode.workspace.rootPath!, false); | ||
| } | ||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of curiosity, what does this pattern do?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Allow it to be nullable (i'm slowly introducing some strict checks.
I don't want to turn this on globally, else we'll have 100s of errors.
New --strict master option
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is the errors from dependencies or just old code that needs an update?