diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 863deb963a1..3a89e5a9e2f 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -151,7 +151,7 @@ jobs: strategy: matrix: os: [ubuntu-latest, windows-latest] - version: ['v2.2.6', 'v2.3.3', 'v2.4.6', 'v2.5.9', 'v2.6.1', 'nightly'] + version: ['v2.3.3', 'v2.4.6', 'v2.5.9', 'v2.6.1', 'nightly'] env: CLI_VERSION: ${{ matrix.version }} NIGHTLY_URL: ${{ needs.find-nightly.outputs.url }} diff --git a/extensions/ql-vscode/CHANGELOG.md b/extensions/ql-vscode/CHANGELOG.md index e82b018883b..53dfffb72f2 100644 --- a/extensions/ql-vscode/CHANGELOG.md +++ b/extensions/ql-vscode/CHANGELOG.md @@ -3,6 +3,7 @@ ## [UNRELEASED] - Fix bug where a query is sometimes run before the file is saved. [#947](https://github.com/github/vscode-codeql/pull/947) +- Fix broken contextual queries, including _View AST_. [#949](https://github.com/github/vscode-codeql/pull/949) ## 1.5.4 - 02 September 2021 diff --git a/extensions/ql-vscode/src/contextual/queryResolver.ts b/extensions/ql-vscode/src/contextual/queryResolver.ts index 99c4c42050b..17f21b0a89d 100644 --- a/extensions/ql-vscode/src/contextual/queryResolver.ts +++ b/extensions/ql-vscode/src/contextual/queryResolver.ts @@ -31,26 +31,24 @@ export async function qlpackOfDatabase(cli: CodeQLCliServer, db: DatabaseItem): * @returns The found queries from the first pack in which any matching queries were found. */ async function resolveQueriesFromPacks(cli: CodeQLCliServer, qlpacks: string[], keyType: KeyType): Promise { + const suiteFile = (await tmp.file({ + postfix: '.qls' + })).path; + const suiteYaml = []; for (const qlpack of qlpacks) { - const suiteFile = (await tmp.file({ - postfix: '.qls' - })).path; - const suiteYaml = { - qlpack, + suiteYaml.push({ + from: qlpack, + queries: '.', include: { kind: kindOfKeyType(keyType), 'tags contain': tagOfKeyType(keyType) } - }; - await fs.writeFile(suiteFile, yaml.safeDump(suiteYaml), 'utf8'); - - const queries = await cli.resolveQueriesInSuite(suiteFile, helpers.getOnDiskWorkspaceFolders()); - if (queries.length > 0) { - return queries; - } + }); } + await fs.writeFile(suiteFile, yaml.safeDump(suiteYaml), 'utf8'); - return []; + const queries = await cli.resolveQueriesInSuite(suiteFile, helpers.getOnDiskWorkspaceFolders()); + return queries; } export async function resolveQueries(cli: CodeQLCliServer, qlpacks: QlPacksForLanguage, keyType: KeyType): Promise { diff --git a/extensions/ql-vscode/src/helpers.ts b/extensions/ql-vscode/src/helpers.ts index 65eb3b29ffa..9caf7991b67 100644 --- a/extensions/ql-vscode/src/helpers.ts +++ b/extensions/ql-vscode/src/helpers.ts @@ -423,6 +423,12 @@ const dbSchemeToLanguage = { 'go.dbscheme': 'go' }; +export const languageToDbScheme = Object.entries(dbSchemeToLanguage).reduce((acc, [k, v]) => { + acc[v] = k; + return acc; +}, {} as { [k: string]: string }); + + /** * Returns the initial contents for an empty query, based on the language of the selected * databse. diff --git a/extensions/ql-vscode/src/vscode-tests/cli-integration/run-cli.test.ts b/extensions/ql-vscode/src/vscode-tests/cli-integration/run-cli.test.ts index 7429cd21a03..3c04b3ae6c3 100644 --- a/extensions/ql-vscode/src/vscode-tests/cli-integration/run-cli.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/cli-integration/run-cli.test.ts @@ -6,12 +6,16 @@ import { SemVer } from 'semver'; import { CodeQLCliServer, QueryInfoByLanguage } from '../../cli'; import { CodeQLExtensionInterface } from '../../extension'; import { skipIfNoCodeQL } from '../ensureCli'; -import { getOnDiskWorkspaceFolders } from '../../helpers'; +import { getOnDiskWorkspaceFolders, getQlPackForDbscheme, languageToDbScheme } from '../../helpers'; +import { resolveQueries } from '../../contextual/queryResolver'; +import { KeyType } from '../../contextual/keyType'; /** * Perform proper integration tests by running the CLI */ describe('Use cli', function() { + const supportedLanguages = ['cpp', 'csharp', 'go', 'java', 'javascript', 'python']; + this.timeout(60000); let cli: CodeQLCliServer; @@ -49,7 +53,7 @@ describe('Use cli', function() { // Depending on the version of the CLI, the qlpacks may have different names // (e.g. "codeql/javascript-all" vs "codeql-javascript"), // so we just check that the expected languages are included. - for (const expectedLanguage of ['cpp', 'csharp', 'go', 'java', 'javascript', 'python']) { + for (const expectedLanguage of supportedLanguages) { expect((Object.keys(qlpacks)).includes(expectedLanguage)); } }); @@ -57,7 +61,7 @@ describe('Use cli', function() { it('should resolve languages', async function() { skipIfNoCodeQL(this); const languages = await cli.resolveLanguages(); - for (const expectedLanguage of ['cpp', 'csharp', 'go', 'java', 'javascript', 'python']) { + for (const expectedLanguage of supportedLanguages) { expect(languages).to.have.property(expectedLanguage).that.is.not.undefined; } }); @@ -68,4 +72,27 @@ describe('Use cli', function() { const queryInfo: QueryInfoByLanguage = await cli.resolveQueryByLanguage(getOnDiskWorkspaceFolders(), Uri.file(queryPath)); expect((Object.keys(queryInfo.byLanguage))[0]).to.eql('javascript'); }); + + + supportedLanguages.forEach(lang => { + if (lang === 'go') { + // The codeql-go submodule is not available in the integration tests. + return; + } + it(`should resolve printAST queries for ${lang}`, async function() { + skipIfNoCodeQL(this); + + const pack = await getQlPackForDbscheme(cli, languageToDbScheme[lang]); + expect(pack.dbschemePack).to.contain(lang); + if (pack.dbschemePackIsLibraryPack) { + expect(pack.queryPack).to.contain(lang); + } + + const result = await resolveQueries(cli, pack, KeyType.PrintAstQuery); + + // It doesn't matter what the name or path of the query is, only + // that we have found exactly one query. + expect(result.length).to.eq(1); + }); + }); }); diff --git a/extensions/ql-vscode/src/vscode-tests/no-workspace/contextual/queryResolver.test.ts b/extensions/ql-vscode/src/vscode-tests/no-workspace/contextual/queryResolver.test.ts index 09ac5cad78f..71a463785be 100644 --- a/extensions/ql-vscode/src/vscode-tests/no-workspace/contextual/queryResolver.test.ts +++ b/extensions/ql-vscode/src/vscode-tests/no-workspace/contextual/queryResolver.test.ts @@ -30,19 +30,19 @@ describe('queryResolver', () => { }); describe('resolveQueries', () => { - it('should resolve a query', async () => { mockCli.resolveQueriesInSuite.returns(['a', 'b']); const result = await module.resolveQueries(mockCli, { dbschemePack: 'my-qlpack' }, KeyType.DefinitionQuery); expect(result).to.deep.equal(['a', 'b']); expect(writeFileSpy.getCall(0).args[0]).to.match(/.qls$/); - expect(yaml.safeLoad(writeFileSpy.getCall(0).args[1])).to.deep.equal({ - qlpack: 'my-qlpack', + expect(yaml.safeLoad(writeFileSpy.getCall(0).args[1])).to.deep.equal([{ + from: 'my-qlpack', + queries: '.', include: { kind: 'definitions', 'tags contain': 'ide-contextual-queries/local-definitions' } - }); + }]); }); it('should resolve a query from the queries pack if this is an old CLI', async () => { @@ -52,13 +52,14 @@ describe('queryResolver', () => { const result = await module.resolveQueries(mockCli, { dbschemePackIsLibraryPack: true, dbschemePack: 'my-qlpack', queryPack: 'my-qlpack2' }, KeyType.DefinitionQuery); expect(result).to.deep.equal(['a', 'b']); expect(writeFileSpy.getCall(0).args[0]).to.match(/.qls$/); - expect(yaml.safeLoad(writeFileSpy.getCall(0).args[1])).to.deep.equal({ - qlpack: 'my-qlpack2', + expect(yaml.safeLoad(writeFileSpy.getCall(0).args[1])).to.deep.equal([{ + from: 'my-qlpack2', + queries: '.', include: { kind: 'definitions', 'tags contain': 'ide-contextual-queries/local-definitions' } - }); + }]); }); it('should throw an error when there are no queries found', async () => {