Skip to content

Commit

Permalink
Merge pull request #405 from redhat-developer/notify-if-ansible
Browse files Browse the repository at this point in the history
Implement a way to determine if an extension is conflicting with VSCo…
  • Loading branch information
JPinkney authored Mar 9, 2021
2 parents 8663b4d + 90718fa commit f3c0efe
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 0 deletions.
15 changes: 15 additions & 0 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { CUSTOM_SCHEMA_REQUEST, CUSTOM_CONTENT_REQUEST, SchemaExtensionAPI } fro
import { joinPath } from './paths';
import { getJsonSchemaContent, JSONSchemaDocumentContentProvider } from './json-schema-content-provider';
import { JSONSchemaCache } from './json-schema-cache';
import { getConflictingExtensions, showUninstallConflictsNotification } from './extensionConflicts';

export interface ISchemaAssociations {
[pattern: string]: string[];
Expand Down Expand Up @@ -104,13 +105,15 @@ export function activate(context: ExtensionContext): SchemaExtensionAPI {
workspace.registerTextDocumentContentProvider('json-schema', new JSONSchemaDocumentContentProvider(schemaCache))
);

findConflicts();
client.onReady().then(() => {
// Send a notification to the server with any YAML schema associations in all extensions
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations());

// If the extensions change, fire this notification again to pick up on any association changes
extensions.onDidChange(() => {
client.sendNotification(SchemaAssociationNotification.type, getSchemaAssociations());
findConflicts();
});
// Tell the server that the client is ready to provide custom schema content
client.sendNotification(DynamicCustomSchemaRequestRegistration.type);
Expand All @@ -131,6 +134,18 @@ export function activate(context: ExtensionContext): SchemaExtensionAPI {
return schemaExtensionAPI;
}

/**
* Finds extensions that conflict with VSCode-YAML.
* If one or more conflicts are found then show an uninstall notification
* If no conflicts are found then do nothing
*/
function findConflicts(): void {
const conflictingExtensions = getConflictingExtensions();
if (conflictingExtensions.length > 0) {
showUninstallConflictsNotification(conflictingExtensions);
}
}

function getSchemaAssociations(): ISchemaAssociation[] {
const associations: ISchemaAssociation[] = [];
extensions.all.forEach((extension) => {
Expand Down
70 changes: 70 additions & 0 deletions src/extensionConflicts.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Red Hat, Inc. All rights reserved..
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { commands, Extension, extensions, window } from 'vscode';

// A set of VSCode extension ID's that conflict with VSCode-YAML
const azureDeploy = 'ms-vscode-deploy-azure.azure-deploy';
const conflictingIDs = new Set(['vscoss.vscode-ansible', azureDeploy, 'sysninja.vscode-ansible-mod', 'haaaad.ansible']);

// A set of VSCode extension ID's that are currently uninstalling
const uninstallingIDs = new Set();

/**
* Get all of the installed extensions that currently conflict with VSCode-YAML
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function getConflictingExtensions(): Extension<any>[] {
const conflictingExtensions = [];
conflictingIDs.forEach((extension) => {
const ext = extensions.getExtension(extension);
if (ext && !uninstallingIDs.has(ext.id)) {
conflictingExtensions.push(ext);
}
});
return conflictingExtensions;
}

/**
* Display the uninstall conflicting extension notification if there are any conflicting extensions currently installed
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export function showUninstallConflictsNotification(conflictingExts: Extension<any>[]): void {
// Add all available conflicting extensions to the uninstalling IDs map
for (const extIndex in conflictingExts) {
const ext = conflictingExts[extIndex];
uninstallingIDs.add(ext.id);
}

const uninstallMsg = 'Uninstall';

// Gather all the conflicting display names
let conflictMsg = '';
if (conflictingExts.length === 1) {
conflictMsg = `${conflictingExts[0].packageJSON.displayName} extension is incompatible with VSCode-YAML. Please uninstall it.`;
} else {
const extNames = [];
conflictingExts.forEach((ext) => {
extNames.push(ext.packageJSON.displayName);
});
conflictMsg = `The ${extNames.join(', ')} extensions are incompatible with VSCode-YAML. Please uninstall them.`;
}

if (conflictingExts.length > 0) {
window.showInformationMessage(conflictMsg, uninstallMsg).then((clickedMsg) => {
if (clickedMsg === uninstallMsg) {
conflictingExts.forEach((ext) => {
commands.executeCommand('workbench.extensions.uninstallExtension', ext.id);
uninstallingIDs.delete(ext.id);
});

// The azure deploy extension must be reloaded in order to be completely uninstalled
// eslint-disable-next-line @typescript-eslint/no-explicit-any
if (conflictingExts.findIndex((ext: any) => ext.id === azureDeploy) !== -1) {
commands.executeCommand('workbench.action.reloadWindow');
}
}
});
}
}

0 comments on commit f3c0efe

Please sign in to comment.