Skip to content

Commit e9574d3

Browse files
authored
Merge pull request #985 from github/qc-packs
Remote Queries: Create packs for remote queries
2 parents 848869e + 4a65b6a commit e9574d3

File tree

16 files changed

+591
-67
lines changed

16 files changed

+591
-67
lines changed

extensions/ql-vscode/src/cli.ts

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -806,6 +806,39 @@ export class CodeQLCliServer implements Disposable {
806806
);
807807
}
808808

809+
async packInstall(dir: string) {
810+
return this.runJsonCodeQlCliCommand(['pack', 'install'], [dir], 'Installing pack dependencies');
811+
}
812+
813+
async packBundle(dir: string, workspaceFolders: string[], outputPath: string, precompile = true): Promise<void> {
814+
const args = [
815+
'-o',
816+
outputPath,
817+
dir,
818+
'--additional-packs',
819+
workspaceFolders.join(path.delimiter)
820+
];
821+
if (!precompile && await this.cliConstraints.supportsNoPrecompile()) {
822+
args.push('--no-precompile');
823+
}
824+
825+
return this.runJsonCodeQlCliCommand(['pack', 'bundle'], args, 'Bundling pack');
826+
}
827+
828+
async packPacklist(dir: string, includeQueries: boolean): Promise<string[]> {
829+
const args = includeQueries ? [dir] : ['--no-include-queries', dir];
830+
// since 2.7.1, packlist returns an object with a "paths" property that is a list of packs.
831+
// previous versions return a list of packs.
832+
const results: { paths: string[] } | string[] = await this.runJsonCodeQlCliCommand(['pack', 'packlist'], args, 'Generating the pack list');
833+
834+
// Once we no longer need to support 2.7.0 or earlier, we can remove this and assume all versions return an object.
835+
if ('paths' in results) {
836+
return results.paths;
837+
} else {
838+
return results;
839+
}
840+
}
841+
809842
async generateDil(qloFile: string, outFile: string): Promise<void> {
810843
const extraArgs = await this.cliConstraints.supportsDecompileDil()
811844
? ['--kind', 'dil', '-o', outFile, qloFile]
@@ -1099,6 +1132,16 @@ export class CliVersionConstraint {
10991132
*/
11001133
public static CLI_VERSION_WITH_DATABASE_UNBUNDLE = new SemVer('2.6.0');
11011134

1135+
/**
1136+
* CLI version where the `--no-precompile` option for pack creation was introduced.
1137+
*/
1138+
public static CLI_VERSION_WITH_NO_PRECOMPILE = new SemVer('2.7.1');
1139+
1140+
/**
1141+
* CLI version where remote queries are supported.
1142+
*/
1143+
public static CLI_VERSION_REMOTE_QUERIES = new SemVer('2.6.3');
1144+
11021145
constructor(private readonly cli: CodeQLCliServer) {
11031146
/**/
11041147
}
@@ -1135,4 +1178,12 @@ export class CliVersionConstraint {
11351178
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_DATABASE_UNBUNDLE);
11361179
}
11371180

1181+
async supportsNoPrecompile() {
1182+
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_WITH_NO_PRECOMPILE);
1183+
}
1184+
1185+
async supportsRemoteQueries() {
1186+
return this.isVersionAtLeast(CliVersionConstraint.CLI_VERSION_REMOTE_QUERIES);
1187+
}
1188+
11381189
}

extensions/ql-vscode/src/config.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -304,7 +304,7 @@ const REMOTE_QUERIES_SETTING = new Setting('remoteQueries', ROOT_SETTING);
304304
/**
305305
* Lists of GitHub repositories that you want to query remotely via the "Run Remote query" command.
306306
* Note: This command is only available for internal users.
307-
*
307+
*
308308
* This setting should be a JSON object where each key is a user-specified name (string),
309309
* and the value is an array of GitHub repositories (of the form `<owner>/<repo>`).
310310
*/
@@ -314,6 +314,10 @@ export function getRemoteRepositoryLists(): Record<string, string[]> | undefined
314314
return REMOTE_REPO_LISTS.getValue<Record<string, string[]>>() || undefined;
315315
}
316316

317+
export async function setRemoteRepositoryLists(lists: Record<string, string[]> | undefined) {
318+
await REMOTE_REPO_LISTS.updateValue(lists, ConfigurationTarget.Global);
319+
}
320+
317321
/**
318322
* The name of the "controller" repository that you want to use with the "Run Remote query" command.
319323
* Note: This command is only available for internal users.

extensions/ql-vscode/src/extension.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -718,13 +718,25 @@ async function activateWithInstalledDistribution(
718718
);
719719
// The "runRemoteQuery" command is internal-only.
720720
ctx.subscriptions.push(
721-
commandRunner('codeQL.runRemoteQuery', async (
721+
commandRunnerWithProgress('codeQL.runRemoteQuery', async (
722+
progress: ProgressCallback,
723+
token: CancellationToken,
722724
uri: Uri | undefined
723725
) => {
724726
if (isCanary()) {
727+
progress({
728+
maxStep: 5,
729+
step: 0,
730+
message: 'Getting credentials'
731+
});
725732
const credentials = await Credentials.initialize(ctx);
726-
await runRemoteQuery(cliServer, credentials, uri || window.activeTextEditor?.document.uri);
733+
await runRemoteQuery(cliServer, credentials, uri || window.activeTextEditor?.document.uri, false, progress, token);
734+
} else {
735+
throw new Error('Remote queries require the CodeQL Canary version to run.');
727736
}
737+
}, {
738+
title: 'Run Remote Query',
739+
cancellable: true
728740
})
729741
);
730742
ctx.subscriptions.push(

extensions/ql-vscode/src/helpers.ts

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
env
1111
} from 'vscode';
1212
import { CodeQLCliServer, QlpacksInfo } from './cli';
13+
import { UserCancellationException } from './commandRunner';
1314
import { logger } from './logging';
1415

1516
/**
@@ -494,14 +495,25 @@ export async function findLanguage(
494495
void logger.log('Could not autodetect query language. Select language manually.');
495496
}
496497
}
497-
const availableLanguages = Object.keys(await cliServer.resolveLanguages());
498+
499+
// will be undefined if user cancels the quick pick.
500+
return await askForLanguage(cliServer, false);
501+
}
502+
503+
504+
export async function askForLanguage(cliServer: CodeQLCliServer, throwOnEmpty = true): Promise<string | undefined> {
505+
const availableLanguages = Object.keys(await cliServer.resolveLanguages()).sort();
498506
const language = await Window.showQuickPick(
499507
availableLanguages,
500508
{ placeHolder: 'Select target language for your query', ignoreFocusOut: true }
501509
);
502510
if (!language) {
503511
// This only happens if the user cancels the quick pick.
504-
void showAndLogErrorMessage('Language not found. Language must be specified manually.');
512+
if (throwOnEmpty) {
513+
throw new UserCancellationException('Cancelled.');
514+
} else {
515+
void showAndLogErrorMessage('Language not found. Language must be specified manually.');
516+
}
505517
}
506518
return language;
507519
}

extensions/ql-vscode/src/quick-query.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,7 @@ export async function displayQuickQuery(
118118
// Only rewrite the qlpack file if the database has changed
119119
if (shouldRewrite) {
120120
const quickQueryQlpackYaml: any = {
121-
name: 'quick-query',
121+
name: 'vscode/quick-query',
122122
version: '1.0.0',
123123
libraryPathDependencies: [qlpack]
124124
};

0 commit comments

Comments
 (0)