Skip to content

Commit 3743895

Browse files
mgsiumshati-patel
authored andcommitted
Add "Preview Query Help" command
1 parent c590e2f commit 3743895

File tree

4 files changed

+72
-0
lines changed

4 files changed

+72
-0
lines changed

extensions/ql-vscode/CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
- Fix a bug with importing large databases. Databases over 4GB can now be imported directly from LGTM or from a zip file. This functionality is only available when using CodeQL CLI version 2.6.0 or later. [#971](https://github.com/github/vscode-codeql/pull/971)
88
- Replace certain control codes (`U+0000` - `U+001F`) with their corresponding control labels (`U+2400` - `U+241F`) in the results view. [#963](https://github.com/github/vscode-codeql/pull/963)
99
- Allow case-insensitive project slugs for GitHub repositories when adding a CodeQL database from LGTM. [#978](https://github.com/github/vscode-codeql/pull/961)
10+
- Add a _CodeQL: Preview Query Help_ command to generate Markdown previews of `.qhelp` query help files. This command should only be run in trusted workspaces. See https://codeql.github.com/docs/codeql-cli/testing-query-help-files for more information about query help. [#988](https://github.com/github/vscode-codeql/pull/988)
1011
- Make "Open Referenced File" command accessible from the active editor menu. [#989](https://github.com/github/vscode-codeql/pull/989)
1112
- Allow query result locations with 0 as the end column value. These are treated as the first column in the line. [#1002](https://github.com/github/vscode-codeql/pull/1002)
1213

extensions/ql-vscode/package.json

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,7 @@
4646
"onCommand:codeQL.setCurrentDatabase",
4747
"onCommand:codeQL.viewAst",
4848
"onCommand:codeQL.openReferencedFile",
49+
"onCommand:codeQL.previewQueryHelp",
4950
"onCommand:codeQL.chooseDatabaseFolder",
5051
"onCommand:codeQL.chooseDatabaseArchive",
5152
"onCommand:codeQL.chooseDatabaseInternet",
@@ -295,6 +296,10 @@
295296
"command": "codeQL.openReferencedFile",
296297
"title": "CodeQL: Open Referenced File"
297298
},
299+
{
300+
"command": "codeQL.previewQueryHelp",
301+
"title": "CodeQL: Preview Query Help"
302+
},
298303
{
299304
"command": "codeQL.quickQuery",
300305
"title": "CodeQL: Quick Query"
@@ -681,6 +686,11 @@
681686
"group": "9_qlCommands",
682687
"when": "view == codeQLQueryHistory"
683688
},
689+
{
690+
"command": "codeQL.previewQueryHelp",
691+
"group": "9_qlCommands",
692+
"when": "view == codeQLQueryHistory && resourceScheme == .qhelp && isWorkspaceTrusted"
693+
},
684694
{
685695
"command": "codeQLTests.showOutputDifferences",
686696
"group": "qltest@1",
@@ -712,6 +722,11 @@
712722
"command": "codeQL.openReferencedFile",
713723
"group": "9_qlCommands",
714724
"when": "resourceExtname == .qlref"
725+
},
726+
{
727+
"command": "codeQL.previewQueryHelp",
728+
"group": "9_qlCommands",
729+
"when": "resourceExtname == .qhelp && isWorkspaceTrusted"
715730
}
716731
],
717732
"commandPalette": [
@@ -743,6 +758,10 @@
743758
"command": "codeQL.openReferencedFile",
744759
"when": "resourceExtname == .qlref"
745760
},
761+
{
762+
"command": "codeQL.previewQueryHelp",
763+
"when": "resourceExtname == .qhelp && isWorkspaceTrusted"
764+
},
746765
{
747766
"command": "codeQL.setCurrentDatabase",
748767
"when": "false"
@@ -900,6 +919,10 @@
900919
{
901920
"command": "codeQL.openReferencedFile",
902921
"when": "resourceExtname == .qlref"
922+
},
923+
{
924+
"command": "codeQL.previewQueryHelp",
925+
"when": "resourceExtname == .qhelp && isWorkspaceTrusted"
903926
}
904927
]
905928
},

extensions/ql-vscode/src/cli.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -621,6 +621,20 @@ export class CodeQLCliServer implements Disposable {
621621

622622
return await this.runCodeQlCliCommand(['database', 'unbundle'], subcommandArgs, `Extracting ${archivePath} to directory ${target}`);
623623
}
624+
625+
/**
626+
* Uses a .qhelp file to generate Query Help documentation in a specified format.
627+
* @param pathToQhelp The path to the .qhelp file
628+
* @param format The format in which the query help should be generated {@link https://codeql.github.com/docs/codeql-cli/manual/generate-query-help/#cmdoption-codeql-generate-query-help-format}
629+
* @param outputDirectory The output directory for the generated file
630+
*/
631+
async generateQueryHelp(pathToQhelp:string, outputDirectory?: string): Promise<string> {
632+
const subcommandArgs = ['--format=markdown'];
633+
if(outputDirectory) subcommandArgs.push('--output', outputDirectory);
634+
subcommandArgs.push(pathToQhelp);
635+
636+
return await this.runCodeQlCliCommand(['generate', 'query-help'], subcommandArgs, `Generating qhelp in markdown format at ${outputDirectory}`);
637+
}
624638

625639
/**
626640
* Gets the results from a bqrs.

extensions/ql-vscode/src/extension.ts

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@ import {
1616
import { LanguageClient } from 'vscode-languageclient';
1717
import * as os from 'os';
1818
import * as path from 'path';
19+
import * as tmp from 'tmp-promise';
1920
import { testExplorerExtensionId, TestHub } from 'vscode-test-adapter-api';
2021

2122
import { AstViewer } from './astViewer';
@@ -493,6 +494,32 @@ async function activateWithInstalledDistribution(
493494
}
494495
}
495496

497+
const qhelpTmpDir = tmp.dirSync({ prefix: 'qhelp_', keep: false, unsafeCleanup: true });
498+
ctx.subscriptions.push({ dispose: qhelpTmpDir.removeCallback });
499+
500+
async function previewQueryHelp(
501+
selectedQuery: Uri
502+
): Promise<void> {
503+
// selectedQuery is unpopulated when executing through the command palette
504+
const pathToQhelp = selectedQuery ? selectedQuery.fsPath : window.activeTextEditor?.document.uri.fsPath;
505+
if(pathToQhelp) {
506+
// Create temporary directory
507+
const relativePathToMd = path.basename(pathToQhelp, '.qhelp') + '.md';
508+
const absolutePathToMd = path.join(qhelpTmpDir.name, relativePathToMd);
509+
const uri = Uri.file(absolutePathToMd);
510+
try {
511+
await cliServer.generateQueryHelp(pathToQhelp , absolutePathToMd);
512+
await commands.executeCommand('markdown.showPreviewToSide', uri);
513+
} catch (err) {
514+
const errorMessage = err.message.includes('Generating qhelp in markdown') ? (
515+
`Could not generate markdown from ${pathToQhelp}: Bad formatting in .qhelp file.`
516+
) : `Could not open a preview of the generated file (${absolutePathToMd}).`;
517+
void helpers.showAndLogErrorMessage(errorMessage, { fullMessage: `${errorMessage}\n${err}` });
518+
}
519+
}
520+
521+
}
522+
496523
async function openReferencedFile(
497524
selectedQuery: Uri
498525
): Promise<void> {
@@ -746,6 +773,13 @@ async function activateWithInstalledDistribution(
746773
)
747774
);
748775

776+
ctx.subscriptions.push(
777+
commandRunner(
778+
'codeQL.previewQueryHelp',
779+
previewQueryHelp
780+
)
781+
);
782+
749783
ctx.subscriptions.push(
750784
commandRunnerWithProgress('codeQL.restartQueryServer', async (
751785
progress: ProgressCallback,

0 commit comments

Comments
 (0)