Skip to content

Commit b2a6263

Browse files
committed
Send a query pack
1 parent 20cdca7 commit b2a6263

File tree

2 files changed

+38
-9
lines changed

2 files changed

+38
-9
lines changed

extensions/ql-vscode/src/cli.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -801,6 +801,14 @@ export class CodeQLCliServer implements Disposable {
801801
);
802802
}
803803

804+
async packInstall(dir: string) {
805+
return this.runJsonCodeQlCliCommand(['pack', 'install'], [dir], 'Installing pack dependencies');
806+
}
807+
808+
async packBundle(dir: string, outputPath: string): Promise<void> {
809+
return this.runJsonCodeQlCliCommand(['pack', 'bundle'], ['-o', outputPath, dir], 'Bundling pack');
810+
}
811+
804812
async generateDil(qloFile: string, outFile: string): Promise<void> {
805813
const extraArgs = await this.cliConstraints.supportsDecompileDil()
806814
? ['--kind', 'dil', '-o', outFile, qloFile]

extensions/ql-vscode/src/run-remote-query.ts

Lines changed: 30 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
import { QuickPickItem, Uri, window } from 'vscode';
2+
import * as path from 'path';
23
import * as yaml from 'js-yaml';
34
import * as fs from 'fs-extra';
5+
import * as tmp from 'tmp-promise';
46
import { findLanguage, showAndLogErrorMessage, showAndLogInformationMessage, showInformationMessageWithAction } from './helpers';
57
import { Credentials } from './authentication';
68
import * as cli from './cli';
@@ -68,6 +70,22 @@ export async function getRepositories(): Promise<string[] | undefined> {
6870
}
6971
}
7072

73+
async function generateQueryPack(cliServer: cli.CodeQLCliServer, queryFile: string): Promise<string> {
74+
75+
const packRoot = path.dirname(queryFile);
76+
77+
const bundlePath = await tmp.tmpName({
78+
postfix: '.tgz',
79+
prefix: 'qlpack-',
80+
});
81+
82+
await cliServer.packBundle(packRoot, bundlePath);
83+
const base64Pack = (await fs.readFile(bundlePath)).toString('base64');
84+
85+
await fs.unlink(bundlePath);
86+
return base64Pack;
87+
}
88+
7189
export async function runRemoteQuery(cliServer: cli.CodeQLCliServer, credentials: Credentials, uri?: Uri) {
7290
if (!uri?.fsPath.endsWith('.ql')) {
7391
return;
@@ -81,6 +99,7 @@ export async function runRemoteQuery(cliServer: cli.CodeQLCliServer, credentials
8199
let language: string | undefined;
82100
let repositories: string[] | undefined;
83101

102+
await cliServer.packInstall(path.dirname(queryFile));
84103
// If the user has an explicit `.repositories` file, use that.
85104
// Otherwise, prompt user to select repositories from the `codeQL.remoteQueries.repositoryLists` setting.
86105
if (await fs.pathExists(repositoriesFile)) {
@@ -130,10 +149,11 @@ export async function runRemoteQuery(cliServer: cli.CodeQLCliServer, credentials
130149
void logger.log(`Using controller repository: ${controllerRepo}`);
131150
const [owner, repo] = controllerRepo.split('/');
132151

133-
await runRemoteQueriesApiRequest(credentials, ref, language, repositories, query, owner, repo);
152+
const queryPackBase64 = await generateQueryPack(cliServer, queryFile);
153+
await runRemoteQueriesApiRequest(credentials, ref, language, repositories, query, owner, repo, queryPackBase64);
134154
}
135155

136-
async function runRemoteQueriesApiRequest(credentials: Credentials, ref: string, language: string, repositories: string[], query: string, owner: string, repo: string) {
156+
async function runRemoteQueriesApiRequest(credentials: Credentials, ref: string, language: string, repositories: string[], query: string, owner: string, repo: string, queryPackBase64: string): Promise<void> {
137157
const octokit = await credentials.getOctokit();
138158

139159
try {
@@ -143,22 +163,23 @@ async function runRemoteQueriesApiRequest(credentials: Credentials, ref: string,
143163
owner,
144164
repo,
145165
data: {
146-
ref: ref,
147-
language: language,
148-
repositories: repositories,
149-
query: query,
166+
ref,
167+
language,
168+
repositories,
169+
query,
170+
queryPack: queryPackBase64,
150171
}
151172
}
152173
);
153174
void showAndLogInformationMessage(`Successfully scheduled runs. [Click here to see the progress](https://github.com/${owner}/${repo}/actions).`);
154175

155176
} catch (error) {
156-
await attemptRerun(error, credentials, ref, language, repositories, query, owner, repo);
177+
await attemptRerun(error, credentials, ref, language, repositories, query, owner, repo, queryPackBase64);
157178
}
158179
}
159180

160181
/** Attempts to rerun the query on only the valid repositories */
161-
export async function attemptRerun(error: any, credentials: Credentials, ref: string, language: string, repositories: string[], query: string, owner: string, repo: string) {
182+
export async function attemptRerun(error: any, credentials: Credentials, ref: string, language: string, repositories: string[], query: string, owner: string, repo: string, queryPackBase64: string) {
162183
if (typeof error.message === 'string' && error.message.includes('Some repositories were invalid')) {
163184
const invalidRepos = error?.response?.data?.invalid_repos || [];
164185
const reposWithoutDbUploads = error?.response?.data?.repos_without_db_uploads || [];
@@ -181,7 +202,7 @@ export async function attemptRerun(error: any, credentials: Credentials, ref: st
181202
if (rerunQuery) {
182203
const validRepositories = repositories.filter(r => !invalidRepos.includes(r) && !reposWithoutDbUploads.includes(r));
183204
void logger.log(`Rerunning query on set of valid repositories: ${JSON.stringify(validRepositories)}`);
184-
await runRemoteQueriesApiRequest(credentials, ref, language, validRepositories, query, owner, repo);
205+
await runRemoteQueriesApiRequest(credentials, ref, language, validRepositories, query, owner, repo, queryPackBase64);
185206
}
186207

187208
} else {

0 commit comments

Comments
 (0)