Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions extensions/ql-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ import {
import { CodeQlStatusBarHandler } from './status-bar';

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

/**
* extension.ts
Expand Down Expand Up @@ -576,7 +576,7 @@ async function activateWithInstalledDistribution(
return;
}
// If possible, only show databases with the right language (otherwise show all databases).
const queryLanguage = await findLanguage(cliServer, uri);
const queryLanguage = await helpers.findLanguage(cliServer, uri);
if (queryLanguage) {
filteredDBs = dbm.databaseItems.filter(db => db.language === queryLanguage);
if (filteredDBs.length === 0) {
Expand Down
31 changes: 31 additions & 0 deletions extensions/ql-vscode/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -424,3 +424,34 @@ export async function isLikelyDatabaseRoot(maybeRoot: string) {
export function isLikelyDbLanguageFolder(dbPath: string) {
return !!path.basename(dbPath).startsWith('db-');
}

/**
* Finds the language that a query targets.
* If it can't be autodetected, prompt the user to specify the language manually.
*/
export async function findLanguage(
cliServer: CodeQLCliServer,
queryUri: Uri | undefined
): Promise<string | undefined> {
const uri = queryUri || Window.activeTextEditor?.document.uri;
if (uri !== undefined) {
try {
const queryInfo = await cliServer.resolveQueryByLanguage(getOnDiskWorkspaceFolders(), uri);
const language = (Object.keys(queryInfo.byLanguage))[0];
void logger.log(`Detected query language: ${language}`);
return language;
} catch (e) {
void logger.log('Could not autodetect query language. Select language manually.');
}
}
const availableLanguages = Object.keys(await cliServer.resolveLanguages());
const language = await Window.showQuickPick(
availableLanguages,
{ placeHolder: 'Select target language for your query', ignoreFocusOut: true }
);
if (!language) {
// This only happens if the user cancels the quick pick.
void showAndLogErrorMessage('Language not found. Language must be specified manually.');
}
return language;
}
33 changes: 1 addition & 32 deletions extensions/ql-vscode/src/run-remote-query.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { QuickPickItem, Uri, window } from 'vscode';
import * as yaml from 'js-yaml';
import * as fs from 'fs-extra';
import { getOnDiskWorkspaceFolders, showAndLogErrorMessage, showAndLogInformationMessage } from './helpers';
import { findLanguage, showAndLogErrorMessage, showAndLogInformationMessage } from './helpers';
import { Credentials } from './authentication';
import * as cli from './cli';
import { logger } from './logging';
Expand All @@ -16,37 +16,6 @@ interface Config {
const OWNER = 'dsp-testing';
const REPO = 'qc-controller';

/**
* Finds the language that a query targets.
* If it can't be autodetected, prompt the user to specify the language manually.
*/
export async function findLanguage(
cliServer: cli.CodeQLCliServer,
queryUri: Uri | undefined
): Promise<string | undefined> {
const uri = queryUri || window.activeTextEditor?.document.uri;
if (uri !== undefined) {
try {
const queryInfo = await cliServer.resolveQueryByLanguage(getOnDiskWorkspaceFolders(), uri);
const language = (Object.keys(queryInfo.byLanguage))[0];
void logger.log(`Detected query language: ${language}`);
return language;
} catch (e) {
void logger.log('Could not autodetect query language. Select language manually.');
}
}
const availableLanguages = Object.keys(await cliServer.resolveLanguages());
const language = await window.showQuickPick(
availableLanguages,
{ placeHolder: 'Select target language for your query', ignoreFocusOut: true }
);
if (!language) {
// This only happens if the user cancels the quick pick.
void showAndLogErrorMessage('Language not found. Language must be specified manually.');
}
return language;
}

interface RepoListQuickPickItem extends QuickPickItem {
repoList: string[];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -52,4 +52,15 @@ describe('Use cli', function() {
expect(qlpacks['codeql-javascript']).not.to.be.undefined;
expect(qlpacks['codeql-python']).not.to.be.undefined;
});

it('should resolve languages', async function() {
skipIfNoCodeQL(this);
const languages = await cli.resolveLanguages();
// should have a bunch of languages. just check that a few known ones exist
expect(languages['cpp']).not.to.be.undefined;
expect(languages['csharp']).not.to.be.undefined;
expect(languages['java']).not.to.be.undefined;
expect(languages['javascript']).not.to.be.undefined;
expect(languages['python']).not.to.be.undefined;
Copy link
Copy Markdown
Contributor

@adityasharad adityasharad Aug 31, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reading the Chai docs, I think there's an equivalent way of writing what we had before, with the added advantage of giving a more helpful message if the key is missing. Does this work?

for (const expectedLanguage of ['cpp', 'csharp', 'go', 'java', 'javascript', 'python']) {
  expect(languages).to.have.property(expectedLanguage).that.is.not.undefined;
}

I also added Go since we can expect that to exist, might as well test all supported languages.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you, that looks nicer! (and also works 😄)

I'll merge this and start looking at more interesting tests in a follow-up PR.

});
});