Skip to content
Draft
Show file tree
Hide file tree
Changes from all 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
10 changes: 10 additions & 0 deletions src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -201,6 +201,16 @@ class Config {
// process.env['VSCEXT_EXHORT_SNYK_TOKEN'] = token;
}

/**
* Adds a path to the workspace-local redHatDependencyAnalytics.exclude list.
* @param path The path to add
*/
async addFileToExcludeList(path: string) {
const original = vscode.workspace.getConfiguration('redHatDependencyAnalytics').inspect('exclude');
const newValues = [...((original?.workspaceValue as string[] | undefined) || []), path];
await vscode.workspace.getConfiguration('redHatDependencyAnalytics').update('exclude', newValues);
}

/**
* Authorizes the RHDA (Red Hat Dependency Analytics) service.
* @param context The extension context for authorization.
Expand Down
1 change: 1 addition & 0 deletions src/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ export enum StatusMessages {
export enum PromptText {
FULL_STACK_PROMPT_TEXT = `Open Red Hat Dependency Analytics Report`,
LSP_FAILURE_TEXT = `Open the output window`,
IGNORE_FILE = 'Ignore this file',
}

export enum Titles {
Expand Down
36 changes: 23 additions & 13 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { applySettingNameMappings, buildLogErrorMessage } from './utils';
import { clearCodeActionsMap, getDiagnosticsCodeActions } from './codeActionHandler';
import { AnalysisMatcher } from './fileHandler';
import { EventEmitter } from 'node:events';
import { AbstractDiagnosticsPipeline } from './diagnosticsPipeline';

export let outputChannelDep: DepOutputChannel;

Expand Down Expand Up @@ -105,10 +106,16 @@ export async function activate(context: vscode.ExtensionContext) {

const showVulnerabilityFoundPrompt = async (msg: string, filePath: vscode.Uri) => {
const fileName = path.basename(filePath.fsPath);
const selection = await vscode.window.showWarningMessage(`${msg}`, PromptText.FULL_STACK_PROMPT_TEXT);
const selection = await vscode.window.showWarningMessage(`${msg}`, PromptText.FULL_STACK_PROMPT_TEXT as string, PromptText.IGNORE_FILE);
if (selection === PromptText.FULL_STACK_PROMPT_TEXT) {
record(context, TelemetryActions.vulnerabilityReportPopupOpened, { manifest: fileName, fileName: fileName });
vscode.commands.executeCommand(commands.STACK_ANALYSIS_COMMAND, filePath.fsPath);
} else if (selection === PromptText.IGNORE_FILE) {
outputChannelDep.info(`Added "${filePath.fsPath}" to workspace exclude list`);
await globalConfig.addFileToExcludeList(filePath.fsPath);
AbstractDiagnosticsPipeline.diagnosticsCollection.delete(filePath);
clearCodeActionsMap(filePath);
// TODO: need to clear status bar
} else {
record(context, TelemetryActions.vulnerabilityReportPopupIgnored, { manifest: fileName, fileName: fileName });
}
Expand All @@ -123,12 +130,19 @@ export async function activate(context: vscode.ExtensionContext) {
}
});

notifications.on('caError', (errorData: CANotificationData) => {
notifications.on('caError', async (errorData: CANotificationData) => {
const notification = new CANotification(errorData);
caStatusBarProvider.setError();

// Since CA is an automated feature, only warning message will be shown on failure
vscode.window.showWarningMessage(`RHDA error while analyzing ${errorData.uri.fsPath}: ${notification.errorMsg()}`);
const selection = await vscode.window.showWarningMessage(`RHDA error while analyzing ${errorData.uri.fsPath}: ${notification.errorMsg()}`, PromptText.IGNORE_FILE);
if (selection === PromptText.IGNORE_FILE) {
outputChannelDep.info(`Added "${errorData.uri.fsPath}" to workspace exclude list`);
await globalConfig.addFileToExcludeList(errorData.uri.fsPath);
AbstractDiagnosticsPipeline.diagnosticsCollection.delete(errorData.uri);
clearCodeActionsMap(errorData.uri);
// TODO: need to clear status bar
}

// Record telemetry event
record(context, TelemetryActions.componentAnalysisFailed, { manifest: path.basename(notification.origin().fsPath), fileName: path.basename(notification.origin().fsPath), error: notification.errorMsg() });
Expand All @@ -151,6 +165,7 @@ export async function activate(context: vscode.ExtensionContext) {

vscode.workspace.onDidChangeConfiguration(() => {
globalConfig.loadData();
outputChannelDep.debug(`configuration updated`);
});
}

Expand Down Expand Up @@ -213,8 +228,11 @@ function showRHRepositoryRecommendationNotification() {
* @param context - The extension context.
*/
function registerStackAnalysisCommands(context: vscode.ExtensionContext) {

const invokeFullStackReport = async (filePath: string) => {
const recordAndInvoke = async (origin: string, uri: vscode.Uri) => {
// TODO: vscode.window.activeTextEditor may be null
const fileUri = uri || vscode.window.activeTextEditor!.document.uri;
const filePath = fileUri.fsPath;
record(context, origin, { manifest: path.basename(filePath), fileName: path.basename(filePath) });
const fileName = path.basename(filePath);
try {
await generateRHDAReport(context, filePath, outputChannelDep);
Expand All @@ -227,14 +245,6 @@ function registerStackAnalysisCommands(context: vscode.ExtensionContext) {
}
};

const recordAndInvoke = (origin: string, uri: vscode.Uri) => {
// TODO: vscode.window.activeTextEditor may be null
const fileUri = uri || vscode.window.activeTextEditor!.document.uri;
const filePath = fileUri.fsPath;
record(context, origin, { manifest: path.basename(filePath), fileName: path.basename(filePath) });
invokeFullStackReport(filePath);
};

const registerCommand = (cmd: string, action: TelemetryActions) => {
return vscode.commands.registerCommand(cmd, recordAndInvoke.bind(null, action));
};
Expand Down