Skip to content

Commit b8a90b7

Browse files
committed
Use "findLanguage" in relevant places
- When running on multiple databases - When running a remote query
1 parent af7bc8e commit b8a90b7

3 files changed

Lines changed: 58 additions & 32 deletions

File tree

extensions/ql-vscode/src/cli.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,11 @@ export interface UpgradesInfo {
8181
*/
8282
export type QlpacksInfo = { [name: string]: string[] };
8383

84+
/**
85+
* The expected output of `codeql resolve languages`.
86+
*/
87+
export type LanguagesInfo = { [name: string]: string[] };
88+
8489
/**
8590
* The expected output of `codeql resolve qlref`.
8691
*/
@@ -748,6 +753,14 @@ export class CodeQLCliServer implements Disposable {
748753
);
749754
}
750755

756+
/**
757+
* Gets information about the available languages.
758+
* @returns A dictionary mapping language name to the directory it comes from
759+
*/
760+
async resolveLanguages(): Promise<LanguagesInfo> {
761+
return await this.runJsonCodeQlCliCommand<LanguagesInfo>(['resolve', 'languages'], [], 'Resolving languages');
762+
}
763+
751764
/**
752765
* Gets information about queries in a query suite.
753766
* @param suite The suite to resolve.

extensions/ql-vscode/src/extension.ts

Lines changed: 9 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ import {
7373
import { CodeQlStatusBarHandler } from './status-bar';
7474

7575
import { Credentials } from './authentication';
76-
import runRemoteQuery from './run-remote-query';
76+
import { runRemoteQuery, findLanguage } from './run-remote-query';
7777

7878
/**
7979
* extension.ts
@@ -559,30 +559,6 @@ async function activateWithInstalledDistribution(
559559
}
560560
)
561561
);
562-
/**
563-
* Finds the language that a query targets.
564-
* If it can't be autodetected, prompt the user to specify the language manually.
565-
*/
566-
async function findLanguage(
567-
queryUri: Uri
568-
): Promise<string> {
569-
let language = '';
570-
try {
571-
const queryInfo = await cliServer.resolveQueryByLanguage(helpers.getOnDiskWorkspaceFolders(), queryUri || window.activeTextEditor?.document.uri);
572-
language = (Object.keys(queryInfo.byLanguage))[0];
573-
} catch (e) {
574-
// Add an option to manually specify the language, in case automatic language detection fails.
575-
void logger.log('Could not autodetect query language. Select language manually.');
576-
language = await window.showQuickPick(
577-
['cpp', 'csharp', 'go', 'java', 'javascript', 'ruby', 'python'],
578-
{ placeHolder: 'Select target language for your query', ignoreFocusOut: true }
579-
) || '';
580-
}
581-
if (language === '') {
582-
throw new Error('Language not found');
583-
}
584-
return language;
585-
}
586562
interface DatabaseQuickPickItem extends QuickPickItem {
587563
databaseItem: DatabaseItem;
588564
}
@@ -594,7 +570,13 @@ async function activateWithInstalledDistribution(
594570
token: CancellationToken,
595571
uri: Uri | undefined
596572
) => {
597-
const quickPickItems = dbm.databaseItems.map<DatabaseQuickPickItem>(dbItem => (
573+
const queryLanguage = await findLanguage(cliServer, uri);
574+
const filteredDBs = dbm.databaseItems.filter(db => db.language === queryLanguage);
575+
if (filteredDBs.length === 0) {
576+
void helpers.showAndLogErrorMessage(`No databases found for language ${queryLanguage}`);
577+
return;
578+
}
579+
const quickPickItems = filteredDBs.map<DatabaseQuickPickItem>(dbItem => (
598580
{
599581
databaseItem: dbItem,
600582
label: dbItem.name,
@@ -731,7 +713,7 @@ async function activateWithInstalledDistribution(
731713
) => {
732714
if (isCanary()) {
733715
const credentials = await Credentials.initialize(ctx);
734-
await runRemoteQuery(credentials, uri || window.activeTextEditor?.document.uri);
716+
await runRemoteQuery(cliServer, credentials, uri || window.activeTextEditor?.document.uri);
735717
}
736718
})
737719
);

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

Lines changed: 36 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,51 @@
1-
import { Uri } from 'vscode';
1+
import { Uri, window } from 'vscode';
22
import * as yaml from 'js-yaml';
33
import * as fs from 'fs-extra';
4-
import { showAndLogErrorMessage, showAndLogInformationMessage } from './helpers';
4+
import { getOnDiskWorkspaceFolders, showAndLogErrorMessage, showAndLogInformationMessage } from './helpers';
55
import { Credentials } from './authentication';
6+
import * as cli from './cli';
7+
import { logger } from './logging';
68

79
interface Config {
810
repositories: string[];
911
ref?: string;
10-
language: string;
12+
language?: string;
1113
}
1214

1315
// Test "controller" repository and workflow.
1416
const OWNER = 'dsp-testing';
1517
const REPO = 'qc-controller';
1618

17-
export default async function runRemoteQuery(credentials: Credentials, uri?: Uri) {
19+
/**
20+
* Finds the language that a query targets.
21+
* If it can't be autodetected, prompt the user to specify the language manually.
22+
*/
23+
export async function findLanguage(
24+
cliServer: cli.CodeQLCliServer,
25+
queryUri: Uri | undefined
26+
): Promise<string> {
27+
const uri = queryUri || window.activeTextEditor?.document.uri;
28+
if (uri !== undefined) {
29+
try {
30+
const queryInfo = await cliServer.resolveQueryByLanguage(getOnDiskWorkspaceFolders(), uri);
31+
return (Object.keys(queryInfo.byLanguage))[0];
32+
} catch (e) {
33+
void logger.log('Could not autodetect query language. Select language manually.');
34+
}
35+
}
36+
const availableLanguages = Object.keys(await cliServer.resolveLanguages());
37+
const language = await window.showQuickPick(
38+
availableLanguages,
39+
{ placeHolder: 'Select target language for your query', ignoreFocusOut: true }
40+
) || '';
41+
if (language === '') {
42+
// This only happens if the user cancels the quick pick.
43+
void showAndLogErrorMessage('Language not found. Language must be specified manually.');
44+
}
45+
return language;
46+
}
47+
48+
export async function runRemoteQuery(cliServer: cli.CodeQLCliServer, credentials: Credentials, uri?: Uri) {
1849
if (!uri?.fsPath.endsWith('.ql')) {
1950
return;
2051
}
@@ -34,7 +65,7 @@ export default async function runRemoteQuery(credentials: Credentials, uri?: Uri
3465
const config = yaml.safeLoad(await fs.readFile(repositoriesFile, 'utf8')) as Config;
3566

3667
const ref = config.ref || 'main';
37-
const language = config.language;
68+
const language = config.language || await findLanguage(cliServer, uri);
3869
const repositories = config.repositories;
3970

4071
try {

0 commit comments

Comments
 (0)