diff --git a/extensions/ql-vscode/src/config.ts b/extensions/ql-vscode/src/config.ts index d54c1a040..c35fcd07d 100644 --- a/extensions/ql-vscode/src/config.ts +++ b/extensions/ql-vscode/src/config.ts @@ -569,6 +569,7 @@ export async function setRemoteControllerRepo(repo: string | undefined) { export interface VariantAnalysisConfig { controllerRepo: string | undefined; + showSystemDefinedRepositoryLists: boolean; onDidChangeConfiguration?: Event; } @@ -578,7 +579,7 @@ export class VariantAnalysisConfigListener { protected handleDidChangeConfiguration(e: ConfigurationChangeEvent): void { this.handleDidChangeConfigurationForRelevantSettings( - [VARIANT_ANALYSIS_SETTING], + [VARIANT_ANALYSIS_SETTING, VSCODE_GITHUB_ENTERPRISE_URI_SETTING], e, ); } @@ -586,6 +587,10 @@ export class VariantAnalysisConfigListener public get controllerRepo(): string | undefined { return getRemoteControllerRepo(); } + + public get showSystemDefinedRepositoryLists(): boolean { + return !hasEnterpriseUri(); + } } const VARIANT_ANALYSIS_FILTER_RESULTS = new Setting( diff --git a/extensions/ql-vscode/src/databases/db-manager.ts b/extensions/ql-vscode/src/databases/db-manager.ts index fd5ba5d1b..7d9013d31 100644 --- a/extensions/ql-vscode/src/databases/db-manager.ts +++ b/extensions/ql-vscode/src/databases/db-manager.ts @@ -16,6 +16,7 @@ import { } from "./db-item-selection"; import { createRemoteTree } from "./db-tree-creator"; import type { DbConfigValidationError } from "./db-validation-errors"; +import type { VariantAnalysisConfig } from "../config"; export class DbManager extends DisposableObject { public readonly onDbItemsChanged: AppEvent; @@ -25,6 +26,7 @@ export class DbManager extends DisposableObject { constructor( private readonly app: App, private readonly dbConfigStore: DbConfigStore, + private readonly variantAnalysisConfigListener: VariantAnalysisConfig, ) { super(); @@ -36,6 +38,10 @@ export class DbManager extends DisposableObject { this.dbConfigStore.onDidChangeConfig(() => { this.onDbItemsChangesEventEmitter.fire(); }); + + this.variantAnalysisConfigListener.onDidChangeConfiguration?.(() => { + this.onDbItemsChangesEventEmitter.fire(); + }); } public getSelectedDbItem(): DbItem | undefined { @@ -56,7 +62,11 @@ export class DbManager extends DisposableObject { const expandedItems = this.getExpandedItems(); - const remoteTree = createRemoteTree(configResult.value, expandedItems); + const remoteTree = createRemoteTree( + configResult.value, + this.variantAnalysisConfigListener, + expandedItems, + ); return ValueResult.ok(remoteTree.children); } diff --git a/extensions/ql-vscode/src/databases/db-module.ts b/extensions/ql-vscode/src/databases/db-module.ts index f8fb7ccd4..54cb2b976 100644 --- a/extensions/ql-vscode/src/databases/db-module.ts +++ b/extensions/ql-vscode/src/databases/db-module.ts @@ -7,6 +7,7 @@ import { DbManager } from "./db-manager"; import { DbPanel } from "./ui/db-panel"; import { DbSelectionDecorationProvider } from "./ui/db-selection-decoration-provider"; import type { DatabasePanelCommands } from "../common/commands"; +import { VariantAnalysisConfigListener } from "../config"; export class DbModule extends DisposableObject { public readonly dbManager: DbManager; @@ -17,7 +18,13 @@ export class DbModule extends DisposableObject { super(); this.dbConfigStore = new DbConfigStore(app); - this.dbManager = this.push(new DbManager(app, this.dbConfigStore)); + this.dbManager = this.push( + new DbManager( + app, + this.dbConfigStore, + new VariantAnalysisConfigListener(), + ), + ); } public static async initialize(app: App): Promise { diff --git a/extensions/ql-vscode/src/databases/db-tree-creator.ts b/extensions/ql-vscode/src/databases/db-tree-creator.ts index 0bc5a7f8e..c77ebacf7 100644 --- a/extensions/ql-vscode/src/databases/db-tree-creator.ts +++ b/extensions/ql-vscode/src/databases/db-tree-creator.ts @@ -1,3 +1,4 @@ +import type { VariantAnalysisConfig } from "../config"; import type { DbConfig, RemoteRepositoryList } from "./config/db-config"; import { SelectedDbItemKind } from "./config/db-config"; import type { @@ -13,13 +14,17 @@ import { ExpandedDbItemKind } from "./db-item-expansion"; export function createRemoteTree( dbConfig: DbConfig, + variantAnalysisConfig: VariantAnalysisConfig, expandedItems: ExpandedDbItem[], ): RootRemoteDbItem { - const systemDefinedLists = [ - createSystemDefinedList(10, dbConfig), - createSystemDefinedList(100, dbConfig), - createSystemDefinedList(1000, dbConfig), - ]; + const systemDefinedLists = + variantAnalysisConfig.showSystemDefinedRepositoryLists + ? [ + createSystemDefinedList(10, dbConfig), + createSystemDefinedList(100, dbConfig), + createSystemDefinedList(1000, dbConfig), + ] + : []; const userDefinedRepoLists = dbConfig.databases.variantAnalysis.repositoryLists.map((r) => diff --git a/extensions/ql-vscode/test/factories/config.ts b/extensions/ql-vscode/test/factories/config.ts new file mode 100644 index 000000000..9a7060871 --- /dev/null +++ b/extensions/ql-vscode/test/factories/config.ts @@ -0,0 +1,9 @@ +import type { VariantAnalysisConfig } from "../../src/config"; + +export function createMockVariantAnalysisConfig(): VariantAnalysisConfig { + return { + controllerRepo: "foo/bar", + showSystemDefinedRepositoryLists: true, + onDidChangeConfiguration: jest.fn(), + }; +} diff --git a/extensions/ql-vscode/test/unit-tests/databases/db-manager.test.ts b/extensions/ql-vscode/test/unit-tests/databases/db-manager.test.ts index e9fc6a41f..66aca44bc 100644 --- a/extensions/ql-vscode/test/unit-tests/databases/db-manager.test.ts +++ b/extensions/ql-vscode/test/unit-tests/databases/db-manager.test.ts @@ -24,6 +24,7 @@ import { DbManager } from "../../../src/databases/db-manager"; import { createDbConfig } from "../../factories/db-config-factories"; import { createRemoteUserDefinedListDbItem } from "../../factories/db-item-factories"; import { createMockApp } from "../../__mocks__/appMock"; +import { createMockVariantAnalysisConfig } from "../../factories/config"; // Note: Although these are "unit tests" (i.e. not integrating with VS Code), they do // test the interaction/"integration" between the DbManager and the DbConfigStore. @@ -46,7 +47,11 @@ describe("db manager", () => { // We don't need to watch changes to the config file in these tests, so we // pass `false` to the dbConfigStore constructor. dbConfigStore = new DbConfigStore(app, false); - dbManager = new DbManager(app, dbConfigStore); + dbManager = new DbManager( + app, + dbConfigStore, + createMockVariantAnalysisConfig(), + ); await ensureDir(tempWorkspaceStoragePath); dbConfigFilePath = join( diff --git a/extensions/ql-vscode/test/unit-tests/databases/db-tree-creator.test.ts b/extensions/ql-vscode/test/unit-tests/databases/db-tree-creator.test.ts index bdda21890..6e4f0555b 100644 --- a/extensions/ql-vscode/test/unit-tests/databases/db-tree-creator.test.ts +++ b/extensions/ql-vscode/test/unit-tests/databases/db-tree-creator.test.ts @@ -10,13 +10,20 @@ import type { ExpandedDbItem } from "../../../src/databases/db-item-expansion"; import { ExpandedDbItemKind } from "../../../src/databases/db-item-expansion"; import { createRemoteTree } from "../../../src/databases/db-tree-creator"; import { createDbConfig } from "../../factories/db-config-factories"; +import { createMockVariantAnalysisConfig } from "../../factories/config"; describe("db tree creator", () => { + const defaultVariantAnalysisConfig = createMockVariantAnalysisConfig(); + describe("createRemoteTree", () => { it("should build root node and system defined lists", () => { const dbConfig = createDbConfig(); - const dbTreeRoot = createRemoteTree(dbConfig, []); + const dbTreeRoot = createRemoteTree( + dbConfig, + defaultVariantAnalysisConfig, + [], + ); expect(dbTreeRoot).toBeTruthy(); expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); @@ -45,6 +52,24 @@ describe("db tree creator", () => { }); }); + it("displays empty list when no remote user defined list nodes and system defined lists are disabled", () => { + const dbConfig = createDbConfig(); + + const dbTreeRoot = createRemoteTree( + dbConfig, + { + ...defaultVariantAnalysisConfig, + showSystemDefinedRepositoryLists: false, + }, + [], + ); + + expect(dbTreeRoot).toBeTruthy(); + expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); + expect(dbTreeRoot.expanded).toBe(false); + expect(dbTreeRoot.children.length).toBe(0); + }); + it("should create remote user defined list nodes", () => { const dbConfig = createDbConfig({ remoteLists: [ @@ -59,10 +84,15 @@ describe("db tree creator", () => { ], }); - const dbTreeRoot = createRemoteTree(dbConfig, []); + const dbTreeRoot = createRemoteTree( + dbConfig, + defaultVariantAnalysisConfig, + [], + ); expect(dbTreeRoot).toBeTruthy(); expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); + expect(dbTreeRoot.children.length).toBe(5); const repositoryListNodes = dbTreeRoot.children.filter( isRemoteUserDefinedListDbItem, ); @@ -102,12 +132,76 @@ describe("db tree creator", () => { }); }); + it("shows only user defined list nodes when system defined lists are disabled", () => { + const dbConfig = createDbConfig({ + remoteLists: [ + { + name: "my-list-1", + repositories: ["owner1/repo1", "owner1/repo2", "owner2/repo1"], + }, + { + name: "my-list-2", + repositories: ["owner3/repo1", "owner3/repo2", "owner4/repo1"], + }, + ], + }); + + const dbTreeRoot = createRemoteTree( + dbConfig, + { + ...defaultVariantAnalysisConfig, + showSystemDefinedRepositoryLists: false, + }, + [], + ); + + expect(dbTreeRoot).toBeTruthy(); + expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); + expect(dbTreeRoot.children.length).toBe(2); + expect(dbTreeRoot.children[0]).toEqual({ + kind: DbItemKind.RemoteUserDefinedList, + selected: false, + expanded: false, + listName: dbConfig.databases.variantAnalysis.repositoryLists[0].name, + repos: + dbConfig.databases.variantAnalysis.repositoryLists[0].repositories.map( + (repo) => ({ + kind: DbItemKind.RemoteRepo, + selected: false, + repoFullName: repo, + parentListName: + dbConfig.databases.variantAnalysis.repositoryLists[0].name, + }), + ), + }); + expect(dbTreeRoot.children[1]).toEqual({ + kind: DbItemKind.RemoteUserDefinedList, + selected: false, + expanded: false, + listName: dbConfig.databases.variantAnalysis.repositoryLists[1].name, + repos: + dbConfig.databases.variantAnalysis.repositoryLists[1].repositories.map( + (repo) => ({ + kind: DbItemKind.RemoteRepo, + selected: false, + repoFullName: repo, + parentListName: + dbConfig.databases.variantAnalysis.repositoryLists[1].name, + }), + ), + }); + }); + it("should create remote owner nodes", () => { const dbConfig: DbConfig = createDbConfig({ remoteOwners: ["owner1", "owner2"], }); - const dbTreeRoot = createRemoteTree(dbConfig, []); + const dbTreeRoot = createRemoteTree( + dbConfig, + defaultVariantAnalysisConfig, + [], + ); expect(dbTreeRoot).toBeTruthy(); expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); @@ -131,7 +225,11 @@ describe("db tree creator", () => { remoteRepos: ["owner1/repo1", "owner1/repo2", "owner2/repo1"], }); - const dbTreeRoot = createRemoteTree(dbConfig, []); + const dbTreeRoot = createRemoteTree( + dbConfig, + defaultVariantAnalysisConfig, + [], + ); expect(dbTreeRoot).toBeTruthy(); expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); @@ -170,7 +268,11 @@ describe("db tree creator", () => { }, }); - const dbTreeRoot = createRemoteTree(dbConfig, []); + const dbTreeRoot = createRemoteTree( + dbConfig, + defaultVariantAnalysisConfig, + [], + ); expect(dbTreeRoot).toBeTruthy(); expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); @@ -191,7 +293,11 @@ describe("db tree creator", () => { }, }); - const dbTreeRoot = createRemoteTree(dbConfig, []); + const dbTreeRoot = createRemoteTree( + dbConfig, + defaultVariantAnalysisConfig, + [], + ); expect(dbTreeRoot).toBeTruthy(); expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); @@ -213,7 +319,11 @@ describe("db tree creator", () => { }, }); - const dbTreeRoot = createRemoteTree(dbConfig, []); + const dbTreeRoot = createRemoteTree( + dbConfig, + defaultVariantAnalysisConfig, + [], + ); expect(dbTreeRoot).toBeTruthy(); expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); @@ -240,7 +350,11 @@ describe("db tree creator", () => { }, }); - const dbTreeRoot = createRemoteTree(dbConfig, []); + const dbTreeRoot = createRemoteTree( + dbConfig, + defaultVariantAnalysisConfig, + [], + ); expect(dbTreeRoot).toBeTruthy(); @@ -265,7 +379,11 @@ describe("db tree creator", () => { }, ]; - const dbTreeRoot = createRemoteTree(dbConfig, expanded); + const dbTreeRoot = createRemoteTree( + dbConfig, + defaultVariantAnalysisConfig, + expanded, + ); expect(dbTreeRoot).toBeTruthy(); expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); @@ -291,7 +409,11 @@ describe("db tree creator", () => { }, ]; - const dbTreeRoot = createRemoteTree(dbConfig, expanded); + const dbTreeRoot = createRemoteTree( + dbConfig, + defaultVariantAnalysisConfig, + expanded, + ); expect(dbTreeRoot).toBeTruthy(); expect(dbTreeRoot.kind).toBe(DbItemKind.RootRemote); diff --git a/extensions/ql-vscode/test/vscode-tests/activated-extension/variant-analysis/variant-analysis-manager.test.ts b/extensions/ql-vscode/test/vscode-tests/activated-extension/variant-analysis/variant-analysis-manager.test.ts index a38ab4c30..79a9c201b 100644 --- a/extensions/ql-vscode/test/vscode-tests/activated-extension/variant-analysis/variant-analysis-manager.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/activated-extension/variant-analysis/variant-analysis-manager.test.ts @@ -49,6 +49,7 @@ import { writeRepoStates, } from "../../../../src/variant-analysis/repo-states-store"; import { permissiveFilterSortState } from "../../../unit-tests/variant-analysis-filter-sort.test"; +import { createMockVariantAnalysisConfig } from "../../../factories/config"; // up to 3 minutes per test jest.setTimeout(3 * 60 * 1000); @@ -72,7 +73,11 @@ describe("Variant Analysis Manager", () => { const extension = await getActivatedExtension(); const cli = mockedObject({}); app = new ExtensionApp(extension.ctx); - const dbManager = new DbManager(app, new DbConfigStore(app)); + const dbManager = new DbManager( + app, + new DbConfigStore(app), + createMockVariantAnalysisConfig(), + ); variantAnalysisResultsManager = new VariantAnalysisResultsManager( cli, extLogger, diff --git a/extensions/ql-vscode/test/vscode-tests/cli-integration/variant-analysis/variant-analysis-manager.test.ts b/extensions/ql-vscode/test/vscode-tests/cli-integration/variant-analysis/variant-analysis-manager.test.ts index 7a7403275..dbbc60023 100644 --- a/extensions/ql-vscode/test/vscode-tests/cli-integration/variant-analysis/variant-analysis-manager.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/cli-integration/variant-analysis/variant-analysis-manager.test.ts @@ -36,6 +36,7 @@ import type { QlPackLockFile } from "../../../../src/packaging/qlpack-lock-file" //import { expect } from "@jest/globals"; import "../../../matchers/toExistInCodeQLPack"; import type { QlPackDetails } from "../../../../src/variant-analysis/ql-pack-details"; +import { createMockVariantAnalysisConfig } from "../../../factories/config"; describe("Variant Analysis Manager", () => { let cli: CodeQLCliServer; @@ -50,7 +51,11 @@ describe("Variant Analysis Manager", () => { const extension = await getActivatedExtension(); cli = extension.cliServer; const app = new ExtensionApp(extension.ctx); - const dbManager = new DbManager(app, new DbConfigStore(app)); + const dbManager = new DbManager( + app, + new DbConfigStore(app), + createMockVariantAnalysisConfig(), + ); const variantAnalysisResultsManager = new VariantAnalysisResultsManager( cli, extLogger, diff --git a/extensions/ql-vscode/test/vscode-tests/minimal-workspace/databases/db-panel-rendering.test.ts b/extensions/ql-vscode/test/vscode-tests/minimal-workspace/databases/db-panel-rendering.test.ts index 25b5728cd..c1dd5855e 100644 --- a/extensions/ql-vscode/test/vscode-tests/minimal-workspace/databases/db-panel-rendering.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/minimal-workspace/databases/db-panel-rendering.test.ts @@ -11,6 +11,7 @@ import { ExtensionApp } from "../../../../src/common/vscode/extension-app"; import { createMockExtensionContext } from "../../../factories/extension-context"; import { createDbConfig } from "../../../factories/db-config-factories"; import { setRemoteControllerRepo } from "../../../../src/config"; +import { createMockVariantAnalysisConfig } from "../../../factories/config"; describe("db panel rendering nodes", () => { const workspaceStoragePath = join(__dirname, "test-workspace-storage"); @@ -35,7 +36,11 @@ describe("db panel rendering nodes", () => { const app = new ExtensionApp(extensionContext); dbConfigStore = new DbConfigStore(app, false); - dbManager = new DbManager(app, dbConfigStore); + dbManager = new DbManager( + app, + dbConfigStore, + createMockVariantAnalysisConfig(), + ); }); beforeEach(async () => { diff --git a/extensions/ql-vscode/test/vscode-tests/minimal-workspace/databases/db-panel.test.ts b/extensions/ql-vscode/test/vscode-tests/minimal-workspace/databases/db-panel.test.ts index 92262220b..2670c70d6 100644 --- a/extensions/ql-vscode/test/vscode-tests/minimal-workspace/databases/db-panel.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/minimal-workspace/databases/db-panel.test.ts @@ -10,6 +10,7 @@ import { ExtensionApp } from "../../../../src/common/vscode/extension-app"; import { createMockExtensionContext } from "../../../factories/extension-context"; import { createDbConfig } from "../../../factories/db-config-factories"; import { setRemoteControllerRepo } from "../../../../src/config"; +import { createMockVariantAnalysisConfig } from "../../../factories/config"; describe("db panel", () => { const workspaceStoragePath = join(__dirname, "test-workspace-storage"); @@ -34,7 +35,11 @@ describe("db panel", () => { const app = new ExtensionApp(extensionContext); dbConfigStore = new DbConfigStore(app, false); - dbManager = new DbManager(app, dbConfigStore); + dbManager = new DbManager( + app, + dbConfigStore, + createMockVariantAnalysisConfig(), + ); }); beforeEach(async () => { diff --git a/extensions/ql-vscode/test/vscode-tests/no-workspace/databases/db-panel-selection.test.ts b/extensions/ql-vscode/test/vscode-tests/no-workspace/databases/db-panel-selection.test.ts index 53b987af0..e53900119 100644 --- a/extensions/ql-vscode/test/vscode-tests/no-workspace/databases/db-panel-selection.test.ts +++ b/extensions/ql-vscode/test/vscode-tests/no-workspace/databases/db-panel-selection.test.ts @@ -12,6 +12,7 @@ import { ExtensionApp } from "../../../../src/common/vscode/extension-app"; import { createMockExtensionContext } from "../../../factories/extension-context"; import { createDbConfig } from "../../../factories/db-config-factories"; import { setRemoteControllerRepo } from "../../../../src/config"; +import { createMockVariantAnalysisConfig } from "../../../factories/config"; describe("db panel selection", () => { const workspaceStoragePath = join(__dirname, "test-workspace-storage"); @@ -36,7 +37,11 @@ describe("db panel selection", () => { const app = new ExtensionApp(extensionContext); dbConfigStore = new DbConfigStore(app, false); - dbManager = new DbManager(app, dbConfigStore); + dbManager = new DbManager( + app, + dbConfigStore, + createMockVariantAnalysisConfig(), + ); }); beforeEach(async () => {