Skip to content

Commit dd1bdf5

Browse files
committed
Add integrity check for commands in package.json
Attempt to enforce some regularity in how we name commands, and fix one command that was showing up improperly in the command palette.
1 parent c017728 commit dd1bdf5

File tree

2 files changed

+105
-0
lines changed

2 files changed

+105
-0
lines changed

extensions/ql-vscode/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -460,6 +460,10 @@
460460
"command": "codeQLDatabases.chooseDatabaseInternet",
461461
"when": "false"
462462
},
463+
{
464+
"command": "codeQLDatabases.upgradeDatabase",
465+
"when": "false"
466+
},
463467
{
464468
"command": "codeQLQueryHistory.openQuery",
465469
"when": "false"
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
import { expect } from 'chai';
2+
import * as path from 'path';
3+
import * as fs from 'fs-extra';
4+
5+
type CmdDecl = {
6+
command: string;
7+
when?: string;
8+
title?: string;
9+
}
10+
11+
describe('commands declared in package.json', function() {
12+
const manifest = fs.readJsonSync(path.join(__dirname, '../../package.json'));
13+
const commands = manifest.contributes.commands;
14+
const menus = manifest.contributes.menus;
15+
16+
const disabledInPalette: Set<string> = new Set<string>();
17+
18+
// These commands should appear in the command palette, and so
19+
// should be prefixed with 'CodeQL: '.
20+
const paletteCmds: Set<string> = new Set<string>();
21+
22+
// These commands arising on context menus in non-CodeQL controlled
23+
// panels, (e.g. file browser) and so should be prefixed with 'CodeQL: '.
24+
const contribContextMenuCmds: Set<string> = new Set<string>();
25+
26+
// These are commands used in CodeQL controlled panels, and so don't need any prefixing in their title.
27+
const scopedCmds: Set<string> = new Set<string>();
28+
const commandTitles: { [cmd: string]: string } = {};
29+
30+
commands.forEach((commandDecl: CmdDecl) => {
31+
const { command, title } = commandDecl;
32+
if (command.match(/^codeQL\./)
33+
|| command.match(/^codeQLQueryResults\./)
34+
|| command.match(/^codeQLTests\./)) {
35+
paletteCmds.add(command);
36+
expect(title).not.to.be.undefined;
37+
commandTitles[command] = title!;
38+
}
39+
else if (command.match(/^codeQLDatabases\./)
40+
|| command.match(/^codeQLQueryHistory\./)) {
41+
scopedCmds.add(command);
42+
expect(title).not.to.be.undefined;
43+
commandTitles[command] = title!;
44+
}
45+
else {
46+
expect.fail(`Unexpected command name ${command}`);
47+
}
48+
});
49+
50+
menus['explorer/context'].forEach((commandDecl: CmdDecl) => {
51+
const { command } = commandDecl;
52+
paletteCmds.delete(command);
53+
contribContextMenuCmds.add(command);
54+
});
55+
56+
menus['editor/context'].forEach((commandDecl: CmdDecl) => {
57+
const { command } = commandDecl;
58+
paletteCmds.delete(command);
59+
contribContextMenuCmds.add(command);
60+
});
61+
62+
menus.commandPalette.forEach((commandDecl: CmdDecl) => {
63+
if (commandDecl.when === 'false')
64+
disabledInPalette.add(commandDecl.command);
65+
});
66+
67+
68+
69+
it('should have commands appropriately prefixed', function() {
70+
paletteCmds.forEach(command => {
71+
expect(commandTitles[command], `command ${command} should be prefixed with 'CodeQL: ', since it is accessible from the command palette`).to.match(/^CodeQL: /);
72+
});
73+
74+
contribContextMenuCmds.forEach(command => {
75+
expect(commandTitles[command], `command ${command} should be prefixed with 'CodeQL: ', since it is accessible from a context menu in a non-extension-controlled context`).to.match(/^CodeQL: /);
76+
});
77+
78+
scopedCmds.forEach(command => {
79+
expect(commandTitles[command], `command ${command} should not be prefixed with 'CodeQL: ', since it is accessible from an extension-controlled context`).not.to.match(/^CodeQL: /);
80+
});
81+
});
82+
83+
it('should have the right commands accessible from the command palette', function() {
84+
paletteCmds.forEach(command => {
85+
expect(disabledInPalette.has(command), `command ${command} should be enabled in the command palette`).to.be.false;
86+
});
87+
88+
// Commands in contribContextMenuCmds may reasonbly be enabled or
89+
// disabled in the command palette; for example, codeQL.runQuery
90+
// is available there, since we heuristically figure out which
91+
// query to run, but codeQL.setCurrentDatabase is not.
92+
93+
scopedCmds.forEach(command => {
94+
expect(disabledInPalette.has(command), `command ${command} should be disabled in the command palette`).to.be.true;
95+
});
96+
});
97+
98+
99+
});
100+
101+

0 commit comments

Comments
 (0)