Skip to content

Commit bdacd43

Browse files
arajkumarrgrunber
authored andcommitted
feat: Add dependency analytics extension recommendation
Signed-off-by: Arunprasad Rajkumar <[email protected]>
1 parent 496e6f3 commit bdacd43

File tree

5 files changed

+115
-0
lines changed

5 files changed

+115
-0
lines changed

src/extension.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import { ExecuteCommandParams, ExecuteCommandRequest, LanguageClient, LanguageCl
99
import { collectJavaExtensions } from './plugin';
1010
import { prepareExecutable } from './javaServerStarter';
1111
import * as requirements from './requirements';
12+
import { initialize as initializeRecommendation } from './recommendation';
1213
import { Commands } from './commands';
1314
import { ExtensionAPI, ClientStatus } from './extension.api';
1415
import { getJavaConfiguration, deleteDirectory, getBuildFilePatterns, getInclusionPatternsFromNegatedExclusion, convertToGlob, getExclusionBlob } from './utils';
@@ -127,6 +128,8 @@ export function activate(context: ExtensionContext): Promise<ExtensionAPI> {
127128

128129
enableJavadocSymbols();
129130

131+
initializeRecommendation(context);
132+
130133
return requirements.resolveRequirements(context).catch(error => {
131134
// show error
132135
window.showErrorMessage(error.message, error.label).then((selection) => {
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
3+
'use strict';
4+
5+
import * as vscode from "vscode";
6+
import { IHandler } from "./handler";
7+
8+
const EXTENSION_NAME = "redhat.fabric8-analytics";
9+
const GH_ORG_URL = `https://github.com/fabric8-analytics`;
10+
const RECOMMENDATION_MESSAGE = `[Dependency Analytics](${GH_ORG_URL}) extension is recommended to get security insights about pom.xml.`;
11+
12+
function isPomDotXml(uri: vscode.Uri) {
13+
return !!uri.path && uri.path.toLowerCase().endsWith("pom.xml");
14+
}
15+
16+
export function initialize (context: vscode.ExtensionContext, handler: IHandler): void {
17+
if (!handler.canRecommendExtension(EXTENSION_NAME)) {
18+
return;
19+
}
20+
context.subscriptions.push(vscode.workspace.onDidOpenTextDocument(e => {
21+
if (isPomDotXml(e.uri)) {
22+
handler.handle(EXTENSION_NAME, RECOMMENDATION_MESSAGE);
23+
}
24+
}));
25+
26+
const isPomDotXmlOpened = vscode.workspace.textDocuments.findIndex(doc => isPomDotXml(doc.uri)) !== -1;
27+
if (isPomDotXmlOpened) {
28+
handler.handle(EXTENSION_NAME, RECOMMENDATION_MESSAGE);
29+
}
30+
}

src/recommendation/handler.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
'use strict';
2+
3+
export interface IHandler {
4+
handle(extName: string, message: string): Promise<void>;
5+
canRecommendExtension(extName: string): boolean;
6+
}

src/recommendation/handlerImpl.ts

Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
3+
'use strict';
4+
5+
import * as vscode from "vscode";
6+
import { IHandler } from "./handler";
7+
8+
const KEY_RECOMMENDATION_USER_CHOICE_MAP = "recommendationUserChoice";
9+
10+
async function installExtensionCmdHandler(extensionName: string, displayName: string) {
11+
return vscode.window.withProgress({ location: vscode.ProgressLocation.Notification, title: `Installing ${displayName||extensionName}...`}, progress => {
12+
return vscode.commands.executeCommand("workbench.extensions.installExtension", extensionName);
13+
}).then(() => {
14+
vscode.window.showInformationMessage(`Successfully installed ${displayName||extensionName}.`);
15+
});
16+
}
17+
18+
enum UserChoice {
19+
Install = "Install",
20+
Never = "Never",
21+
Later = "Later",
22+
}
23+
24+
export class HandlerImpl implements IHandler {
25+
userChoice: any;
26+
storeUserChoice: any;
27+
constructor(context: vscode.ExtensionContext) {
28+
this.userChoice = () => {
29+
return context.globalState.get(KEY_RECOMMENDATION_USER_CHOICE_MAP, {});
30+
};
31+
32+
this.storeUserChoice = (choice: object) => {
33+
context.globalState.update(KEY_RECOMMENDATION_USER_CHOICE_MAP, choice);
34+
};
35+
}
36+
37+
isExtensionInstalled(extName: string): boolean {
38+
return !!vscode.extensions.getExtension(extName);
39+
}
40+
41+
canRecommendExtension(extName: string): boolean {
42+
return this.userChoice()[extName] !== UserChoice.Never && !this.isExtensionInstalled(extName);
43+
}
44+
45+
async handle(extName: string, message: string): Promise<void> {
46+
if (this.isExtensionInstalled(extName)) {
47+
return;
48+
}
49+
50+
const choice = this.userChoice();
51+
if (choice[extName] === UserChoice.Never) {
52+
return;
53+
}
54+
55+
const actions: Array<string> = Object.keys(UserChoice);
56+
const answer = await vscode.window.showInformationMessage(message, ...actions);
57+
if (answer === UserChoice.Install) {
58+
await installExtensionCmdHandler(extName, extName);
59+
}
60+
61+
choice[extName] = answer;
62+
this.storeUserChoice(choice);
63+
}
64+
}

src/recommendation/index.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
3+
'use strict';
4+
5+
import * as vscode from "vscode";
6+
import { HandlerImpl } from "./handlerImpl";
7+
import { initialize as initDependencyAnalytics } from "./dependencyAnalytics";
8+
9+
export function initialize (context: vscode.ExtensionContext) {
10+
const handler = new HandlerImpl(context);
11+
initDependencyAnalytics(context, handler);
12+
}

0 commit comments

Comments
 (0)