Skip to content

Commit

Permalink
Avoid clobbering quick-query file when re-opened
Browse files Browse the repository at this point in the history
Only recreate the qlpack.yml file.

Also, add an integration test for quick-query creation.
  • Loading branch information
aeisenberg committed Feb 8, 2021
1 parent 27529bf commit bb270a0
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 23 deletions.
37 changes: 16 additions & 21 deletions extensions/ql-vscode/src/quick-query.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,10 @@ import { CancellationToken, ExtensionContext, window as Window, workspace, Uri }
import { ErrorCodes, ResponseError } from 'vscode-languageclient';
import { CodeQLCliServer } from './cli';
import { DatabaseUI } from './databases-ui';
import { logger } from './logging';
import {
getInitialQueryContents,
getPrimaryDbscheme,
getQlPackForDbscheme,
showAndLogErrorMessage,
showBinaryChoiceDialog,
} from './helpers';
import {
Expand All @@ -21,6 +19,7 @@ import {
const QUICK_QUERIES_DIR_NAME = 'quick-queries';
const QUICK_QUERY_QUERY_NAME = 'quick-query.ql';
const QUICK_QUERY_WORKSPACE_FOLDER_NAME = 'Quick Queries';
const QLPACK_FILE_HEADER = '# This is an automatically generated file.\n\n';

export function isQuickQueryPath(queryPath: string): boolean {
return path.basename(queryPath) === QUICK_QUERY_QUERY_NAME;
Expand All @@ -36,9 +35,6 @@ function getQuickQueriesDir(ctx: ExtensionContext): string {
return queriesPath;
}




/**
* Show a buffer the user can enter a simple query into.
*/
Expand Down Expand Up @@ -88,10 +84,11 @@ export async function displayQuickQuery(
}

const index = workspaceFolders.findIndex(folder => folder.name === QUICK_QUERY_WORKSPACE_FOLDER_NAME);
if (index === -1)
if (index === -1) {
updateQuickQueryDir(queriesDir, workspaceFolders.length, 0);
else
} else {
updateQuickQueryDir(queriesDir, index, 1);
}

// We're going to infer which qlpack to use from the current database
const dbItem = await databaseUI.getDatabaseItem(progress, token);
Expand All @@ -109,24 +106,22 @@ export async function displayQuickQuery(
libraryPathDependencies: [qlpack]
};

// Only recreate the query file if it doesn't already exist.
// Always recreate the qlpack file because the file will change when database languages change
const qlFile = path.join(queriesDir, QUICK_QUERY_QUERY_NAME);
if (!await fs.pathExists(qlFile)) {
await fs.writeFile(qlFile, getInitialQueryContents(dbItem.language, dbscheme), 'utf8');
}

const qlPackFile = path.join(queriesDir, 'qlpack.yml');
await fs.writeFile(qlFile, getInitialQueryContents(dbItem.language, dbscheme), 'utf8');
await fs.writeFile(qlPackFile, yaml.safeDump(quickQueryQlpackYaml), 'utf8');
await fs.writeFile(qlPackFile, QLPACK_FILE_HEADER + yaml.safeDump(quickQueryQlpackYaml), 'utf8');
Window.showTextDocument(await workspace.openTextDocument(qlFile));
}

// TODO: clean up error handling for top-level commands like this
catch (e) {
if (e instanceof UserCancellationException) {
logger.log(e.message);
}
else if (e instanceof ResponseError && e.code == ErrorCodes.RequestCancelled) {
logger.log(e.message);
}
else if (e instanceof Error)
showAndLogErrorMessage(e.message);
else
} catch (e) {
if (e instanceof ResponseError && e.code == ErrorCodes.RequestCancelled) {
throw new UserCancellationException(e.message);
} else {
throw e;
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { fail } from 'assert';
import { CancellationToken, commands, extensions, Uri } from 'vscode';
import { CancellationToken, commands, ExtensionContext, extensions, Uri } from 'vscode';
import * as sinon from 'sinon';
import * as path from 'path';
import * as fs from 'fs-extra';
import 'mocha';
import { expect } from 'chai';
import * as yaml from 'js-yaml';

import { DatabaseItem, DatabaseManager } from '../../databases';
import { CodeQLExtensionInterface } from '../../extension';
Expand All @@ -21,7 +22,7 @@ import { QueryResultType } from '../../pure/messages';
* Integration tests for queries
*/
describe('Queries', function() {
this.timeout(20000);
this.timeout(20000000);

before(function() {
skipIfNoCodeQL(this);
Expand All @@ -34,6 +35,7 @@ describe('Queries', function() {
let sandbox: sinon.SinonSandbox;
let progress: sinon.SinonSpy;
let token: CancellationToken;
let ctx: ExtensionContext;

beforeEach(async () => {
sandbox = sinon.createSandbox();
Expand All @@ -45,6 +47,7 @@ describe('Queries', function() {
cli = extension.cliServer;
qs = extension.qs;
cli.quiet = true;
ctx = extension.ctx;
} else {
throw new Error('Extension not initialized. Make sure cli is downloaded and installed properly.');
}
Expand Down Expand Up @@ -126,4 +129,24 @@ describe('Queries', function() {
fail(e);
}
});

it('should create a quick query', async () => {
const qlpackFile = `${ctx.storagePath}/quick-queries/qlpack.yml`;
const qlFile = `${ctx.storagePath}/quick-queries/quick-query.ql`;

if (fs.existsSync(`${ctx.storagePath}/quick-queries`)) {
fs.rmdirSync(`${ctx.storagePath}/quick-queries`);
}
await commands.executeCommand('codeQL.quickQuery');

// should have created the quick query file and query pack file
expect(fs.pathExistsSync(qlFile));
expect(fs.pathExistsSync(qlpackFile));

const qlpackContents: any = await yaml.safeLoad(
fs.readFileSync(qlpackFile, 'utf8')
);
// Should have chosen the js libraries
expect(qlpackContents.libraryPathDependencies[0]).to.eq('codeql-javascript');
});
});

0 comments on commit bb270a0

Please sign in to comment.