Skip to content

Commit

Permalink
Extension IDs listed for 'unwantedRecommendations' should be ignored.
Browse files Browse the repository at this point in the history
- Support 'unwantedRecommendations' in .vscode/extensions.json and in
  the '.code-workspace' (multi-root) files

Signed-off-by: Roland Grunberg <[email protected]>
  • Loading branch information
rgrunber committed Sep 11, 2024
1 parent 018eeaf commit c5946a5
Showing 1 changed file with 41 additions and 1 deletion.
42 changes: 41 additions & 1 deletion src/vscode/impl/recommendationServiceImpl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import { IRecommendationService } from "../recommendationService";
import { IStorageService } from "../storageService";
import { StorageServiceImpl } from "./storageServiceImpl";
import { getInstalledExtensionName, isExtensionInstalled, promptUserUtil, installExtensionUtil } from "./vscodeUtil";
import { existsSync } from "fs";
import { readFile } from "./util/fsUtil";

export const filterUnique = (value: any, index: number, self: any[]): boolean => self.indexOf(value) === index;

Expand Down Expand Up @@ -40,6 +42,23 @@ export class RecommendationServiceImpl implements IRecommendationService {
return path.resolve(context.globalStorageUri.fsPath, '..', 'vscode-extension-recommender');
}

protected getExtensionConfiguration(): string | undefined {
if (workspace.workspaceFolders !== undefined) {
if (workspace.workspaceFolders.length == 1) {
const file = path.resolve(workspace.workspaceFolders[0].uri.path, '.vscode', 'extensions.json');
if (existsSync(file)) {
return file;
}
} else {
const file = workspace.workspaceFile?.path;
if (file !== undefined && existsSync(file)) {
return file;
}
}
}
return undefined;
}

public async register(toAdd: Recommendation[]): Promise<void> {
const newSession: boolean = await this.addRecommendationsToModel(toAdd);
if( newSession ) {
Expand All @@ -56,6 +75,26 @@ export class RecommendationServiceImpl implements IRecommendationService {
return false;
}

protected async isUnwantedRecommendation(toExtension: string): Promise<boolean> {
const extensionConfigFile = this.getExtensionConfiguration();
if (extensionConfigFile !== undefined) {
try {
const jsonData = await readFile(extensionConfigFile);
if (jsonData) {
let json = JSON.parse(jsonData);
if (workspace.workspaceFile?.path !== undefined) {
json = json['extensions'];
}
const unwantedRecommendations = json['unwantedRecommendations'];
return !!unwantedRecommendations && unwantedRecommendations.length > 0 && unwantedRecommendations.includes(toExtension);
}
} catch (err) {
// continue
}
}
return false;
}

public create(extensionId: string,
extensionDisplayName: string,
description: string,
Expand Down Expand Up @@ -114,7 +153,7 @@ export class RecommendationServiceImpl implements IRecommendationService {
// Show a single recommendation immediately, if certain conditions are met
// Specifically, if the recommender is installed, and the recommended is not installed,
// and the recommended has not been timelocked in this session or ignored by user previously
if( this.ignoreRecommendations()) {
if( this.ignoreRecommendations() || await this.isUnwantedRecommendation(toExtension)) {
return;
}

Expand Down Expand Up @@ -154,6 +193,7 @@ export class RecommendationServiceImpl implements IRecommendationService {
const recommendedExtension: string[] = model.recommendations
.map((x) => x.extensionId)
.filter(filterUnique)
.filter((x) => !this.isUnwantedRecommendation(x))
.filter((x) => !isExtensionInstalled(x));
for( let i = 0; i < recommendedExtension.length; i++ ) {
this.showStartupRecommendationsForSingleExtension(model, recommendedExtension[i]);
Expand Down

0 comments on commit c5946a5

Please sign in to comment.