Skip to content

Commit f377bb9

Browse files
Merge pull request #2250 from github/elena/yer-a-wizard-query
Adapt skeleton pack generation to work with new queries panel
2 parents b3ff1ed + e4406f4 commit f377bb9

File tree

10 files changed

+775
-59
lines changed

10 files changed

+775
-59
lines changed

extensions/ql-vscode/package.json

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -361,6 +361,10 @@
361361
"command": "codeQL.quickQuery",
362362
"title": "CodeQL: Quick Query"
363363
},
364+
{
365+
"command": "codeQL.createSkeletonQuery",
366+
"title": "CodeQL: Create Query"
367+
},
364368
{
365369
"command": "codeQL.openDocumentation",
366370
"title": "CodeQL: Open Documentation"

extensions/ql-vscode/src/common/commands.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -99,6 +99,7 @@ export type LocalQueryCommands = {
9999
"codeQL.quickEvalContextEditor": (uri: Uri) => Promise<void>;
100100
"codeQL.codeLensQuickEval": (uri: Uri, range: Range) => Promise<void>;
101101
"codeQL.quickQuery": () => Promise<void>;
102+
"codeQL.createSkeletonQuery": () => Promise<void>;
102103
};
103104

104105
export type ResultsViewCommands = {

extensions/ql-vscode/src/databaseFetcher.ts

Lines changed: 61 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -78,6 +78,10 @@ export async function promptImportInternetDatabase(
7878
*
7979
* @param databaseManager the DatabaseManager
8080
* @param storagePath where to store the unzipped database.
81+
* @param credentials the credentials to use to authenticate with GitHub
82+
* @param progress the progress callback
83+
* @param token the cancellation token
84+
* @param cli the CodeQL CLI server
8185
*/
8286
export async function promptImportGithubDatabase(
8387
commandManager: AppCommandManager,
@@ -103,6 +107,49 @@ export async function promptImportGithubDatabase(
103107
return;
104108
}
105109

110+
const databaseItem = await downloadGitHubDatabase(
111+
githubRepo,
112+
databaseManager,
113+
storagePath,
114+
credentials,
115+
progress,
116+
token,
117+
cli,
118+
);
119+
120+
if (databaseItem) {
121+
await commandManager.execute("codeQLDatabases.focus");
122+
void showAndLogInformationMessage(
123+
"Database downloaded and imported successfully.",
124+
);
125+
return databaseItem;
126+
}
127+
128+
return;
129+
}
130+
131+
/**
132+
* Downloads a database from GitHub
133+
*
134+
* @param githubRepo the GitHub repository to download the database from
135+
* @param databaseManager the DatabaseManager
136+
* @param storagePath where to store the unzipped database.
137+
* @param credentials the credentials to use to authenticate with GitHub
138+
* @param progress the progress callback
139+
* @param token the cancellation token
140+
* @param cli the CodeQL CLI server
141+
* @param language the language to download. If undefined, the user will be prompted to choose a language.
142+
**/
143+
export async function downloadGitHubDatabase(
144+
githubRepo: string,
145+
databaseManager: DatabaseManager,
146+
storagePath: string,
147+
credentials: Credentials | undefined,
148+
progress: ProgressCallback,
149+
token: CancellationToken,
150+
cli?: CodeQLCliServer,
151+
language?: string,
152+
): Promise<DatabaseItem | undefined> {
106153
const nwo = getNwoFromGitHubUrl(githubRepo) || githubRepo;
107154
if (!isValidGitHubNwo(nwo)) {
108155
throw new Error(`Invalid GitHub repository: ${githubRepo}`);
@@ -112,7 +159,12 @@ export async function promptImportGithubDatabase(
112159
? await credentials.getOctokit()
113160
: new Octokit.Octokit({ retry });
114161

115-
const result = await convertGithubNwoToDatabaseUrl(nwo, octokit, progress);
162+
const result = await convertGithubNwoToDatabaseUrl(
163+
nwo,
164+
octokit,
165+
progress,
166+
language,
167+
);
116168
if (!result) {
117169
return;
118170
}
@@ -130,7 +182,7 @@ export async function promptImportGithubDatabase(
130182
* We only need the actual token string.
131183
*/
132184
const octokitToken = ((await octokit.auth()) as { token: string })?.token;
133-
const item = await databaseArchiveFetcher(
185+
return await databaseArchiveFetcher(
134186
databaseUrl,
135187
{
136188
Accept: "application/zip",
@@ -143,14 +195,6 @@ export async function promptImportGithubDatabase(
143195
token,
144196
cli,
145197
);
146-
if (item) {
147-
await commandManager.execute("codeQLDatabases.focus");
148-
void showAndLogInformationMessage(
149-
"Database downloaded and imported successfully.",
150-
);
151-
return item;
152-
}
153-
return;
154198
}
155199

156200
/**
@@ -450,6 +494,7 @@ export async function convertGithubNwoToDatabaseUrl(
450494
nwo: string,
451495
octokit: Octokit.Octokit,
452496
progress: ProgressCallback,
497+
language?: string,
453498
): Promise<
454499
| {
455500
databaseUrl: string;
@@ -468,9 +513,11 @@ export async function convertGithubNwoToDatabaseUrl(
468513

469514
const languages = response.data.map((db: any) => db.language);
470515

471-
const language = await promptForLanguage(languages, progress);
472-
if (!language) {
473-
return;
516+
if (!language || !languages.includes(language)) {
517+
language = await promptForLanguage(languages, progress);
518+
if (!language) {
519+
return;
520+
}
474521
}
475522

476523
return {
@@ -484,7 +531,7 @@ export async function convertGithubNwoToDatabaseUrl(
484531
}
485532
}
486533

487-
async function promptForLanguage(
534+
export async function promptForLanguage(
488535
languages: string[],
489536
progress: ProgressCallback,
490537
): Promise<string | undefined> {

extensions/ql-vscode/src/local-databases.ts

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -897,6 +897,20 @@ export class DatabaseManager extends DisposableObject {
897897
}
898898
}
899899

900+
public async digForDatabaseItem(
901+
language: string,
902+
databaseNwo: string,
903+
): Promise<DatabaseItem | undefined> {
904+
const dbItems = this.databaseItems || [];
905+
const dbs = dbItems.filter(
906+
(db) => db.language === language && db.name === databaseNwo,
907+
);
908+
if (dbs.length === 0) {
909+
return undefined;
910+
}
911+
return dbs[0];
912+
}
913+
900914
/**
901915
* Returns the index of the workspace folder that corresponds to the source archive of `item`
902916
* if there is one, and -1 otherwise.

extensions/ql-vscode/src/local-queries.ts

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ import {
88
window,
99
} from "vscode";
1010
import { BaseLogger, extLogger, Logger, TeeLogger } from "./common";
11-
import { MAX_QUERIES } from "./config";
11+
import { isCanary, MAX_QUERIES } from "./config";
1212
import { gatherQlFiles } from "./pure/files";
1313
import { basename } from "path";
1414
import {
@@ -51,6 +51,7 @@ import { App } from "./common/app";
5151
import { DisposableObject } from "./pure/disposable-object";
5252
import { QueryResultType } from "./pure/new-messages";
5353
import { redactableError } from "./pure/errors";
54+
import { SkeletonQueryWizard } from "./skeleton-query-wizard";
5455

5556
interface DatabaseQuickPickItem extends QuickPickItem {
5657
databaseItem: DatabaseItem;
@@ -237,6 +238,7 @@ export class LocalQueries extends DisposableObject {
237238
"codeQL.quickEvalContextEditor": this.quickEval.bind(this),
238239
"codeQL.codeLensQuickEval": this.codeLensQuickEval.bind(this),
239240
"codeQL.quickQuery": this.quickQuery.bind(this),
241+
"codeQL.createSkeletonQuery": this.createSkeletonQuery.bind(this),
240242
};
241243
}
242244

@@ -375,6 +377,26 @@ export class LocalQueries extends DisposableObject {
375377
);
376378
}
377379

380+
private async createSkeletonQuery(): Promise<void> {
381+
await withProgress(
382+
async (progress: ProgressCallback, token: CancellationToken) => {
383+
const credentials = isCanary() ? this.app.credentials : undefined;
384+
const skeletonQueryWizard = new SkeletonQueryWizard(
385+
this.cliServer,
386+
progress,
387+
credentials,
388+
extLogger,
389+
this.databaseManager,
390+
token,
391+
);
392+
await skeletonQueryWizard.execute();
393+
},
394+
{
395+
title: "Create Query",
396+
},
397+
);
398+
}
399+
378400
/**
379401
* Creates a new `LocalQueryRun` object to track a query evaluation. This creates a timestamp
380402
* file in the query's output directory, creates a `LocalQueryInfo` object, and registers that

extensions/ql-vscode/src/qlpack-generator.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -66,8 +66,8 @@ export class QlPackGenerator {
6666
await writeFile(qlPackFilePath, this.header + dump(qlPackYml), "utf8");
6767
}
6868

69-
private async createExampleQlFile() {
70-
const exampleQlFilePath = join(this.folderUri.fsPath, "example.ql");
69+
public async createExampleQlFile(fileName = "example.ql") {
70+
const exampleQlFilePath = join(this.folderUri.fsPath, fileName);
7171

7272
const exampleQl = `
7373
/**

0 commit comments

Comments
 (0)