Run eslint --fix on the extension

This commit is contained in:
Andrew Eisenberg 2020-06-15 13:25:20 -07:00
Родитель 45dc2a29cf
Коммит ff8e72a318
33 изменённых файлов: 511 добавлений и 511 удалений

Просмотреть файл

@ -1,4 +1,4 @@
import { DecodedBqrsChunk, ResultSetSchema, ColumnKind, Column, ColumnValue } from "./bqrs-cli-types";
import { DecodedBqrsChunk, ResultSetSchema, ColumnKind, Column, ColumnValue } from './bqrs-cli-types';
import { LocationValue, ResultSetSchema as AdaptedSchema, ColumnSchema, ColumnType, LocationStyle } from 'semmle-bqrs';
// FIXME: This is a temporary bit of impedance matching to convert

Просмотреть файл

@ -8,12 +8,12 @@ export const PAGE_SIZE = 1000;
*/
// eslint-disable-next-line @typescript-eslint/no-namespace
export namespace ColumnKindCode {
export const FLOAT = "f";
export const INTEGER = "i";
export const STRING = "s";
export const BOOLEAN = "b";
export const DATE = "d";
export const ENTITY = "e";
export const FLOAT = 'f';
export const INTEGER = 'i';
export const STRING = 's';
export const BOOLEAN = 'b';
export const DATE = 'd';
export const ENTITY = 'e';
}
export type ColumnKind =
@ -37,7 +37,7 @@ export interface ResultSetSchema {
}
export function getResultSetSchema(resultSetName: string, resultSets: BQRSInfo): ResultSetSchema | undefined {
for (const schema of resultSets["result-sets"]) {
for (const schema of resultSets['result-sets']) {
if (schema.name === resultSetName) {
return schema;
}
@ -45,12 +45,12 @@ export function getResultSetSchema(resultSetName: string, resultSets: BQRSInfo):
return undefined;
}
export interface PaginationInfo {
"step-size": number;
'step-size': number;
offsets: number[];
}
export interface BQRSInfo {
"result-sets": ResultSetSchema[];
'result-sets': ResultSetSchema[];
}
export interface EntityValue {

Просмотреть файл

@ -1,6 +1,6 @@
import * as semver from "semver";
import { runCodeQlCliCommand } from "./cli";
import { Logger } from "./logging";
import * as semver from 'semver';
import { runCodeQlCliCommand } from './cli';
import { Logger } from './logging';
/**
* Get the version of a CodeQL CLI.
@ -9,9 +9,9 @@ export async function getCodeQlCliVersion(codeQlPath: string, logger: Logger): P
try {
const output: string = await runCodeQlCliCommand(
codeQlPath,
["version"],
["--format=terse"],
"Checking CodeQL version",
['version'],
['--format=terse'],
'Checking CodeQL version',
logger
);
return semver.parse(output.trim()) || undefined;

Просмотреть файл

@ -9,16 +9,16 @@ import { StringDecoder } from 'string_decoder';
import * as tk from 'tree-kill';
import * as util from 'util';
import { CancellationToken, Disposable } from 'vscode';
import { BQRSInfo, DecodedBqrsChunk } from "./bqrs-cli-types";
import { DistributionProvider } from "./distribution";
import { assertNever } from "./helpers-pure";
import { QueryMetadata, SortDirection } from "./interface-types";
import { Logger, ProgressReporter } from "./logging";
import { BQRSInfo, DecodedBqrsChunk } from './bqrs-cli-types';
import { DistributionProvider } from './distribution';
import { assertNever } from './helpers-pure';
import { QueryMetadata, SortDirection } from './interface-types';
import { Logger, ProgressReporter } from './logging';
/**
* The version of the SARIF format that we are using.
*/
const SARIF_FORMAT = "sarifv2.1.0";
const SARIF_FORMAT = 'sarifv2.1.0';
/**
* Flags to pass to all cli commands.
@ -131,7 +131,7 @@ export class CodeQLCliServer implements Disposable {
// Tell the Java CLI server process to shut down.
this.logger.log('Sending shutdown request');
try {
this.process.stdin.write(JSON.stringify(["shutdown"]), "utf8");
this.process.stdin.write(JSON.stringify(['shutdown']), 'utf8');
this.process.stdin.write(this.nullBuffer);
this.logger.log('Sent shutdown request');
} catch (e) {
@ -188,13 +188,13 @@ export class CodeQLCliServer implements Disposable {
*/
private async launchProcess(): Promise<child_process.ChildProcessWithoutNullStreams> {
const config = await this.getCodeQlPath();
return spawnServer(config, "CodeQL CLI Server", ["execute", "cli-server"], [], this.logger, _data => { /**/ });
return spawnServer(config, 'CodeQL CLI Server', ['execute', 'cli-server'], [], this.logger, _data => { /**/ });
}
private async runCodeQlCliInternal(command: string[], commandArgs: string[], description: string): Promise<string> {
const stderrBuffers: Buffer[] = [];
if (this.commandInProcess) {
throw new Error("runCodeQlCliInternal called while cli was running");
throw new Error('runCodeQlCliInternal called while cli was running');
}
this.commandInProcess = true;
try {
@ -209,7 +209,7 @@ export class CodeQLCliServer implements Disposable {
// Compute the full args array
const args = command.concat(LOGGING_FLAGS).concat(commandArgs);
const argsString = args.join(" ");
const argsString = args.join(' ');
this.logger.log(`${description} using CodeQL CLI: ${argsString}...`);
try {
await new Promise((resolve, reject) => {
@ -228,16 +228,16 @@ export class CodeQLCliServer implements Disposable {
stderrBuffers.push(newData);
});
// Listen for process exit.
process.addListener("close", (code) => reject(code));
process.addListener('close', (code) => reject(code));
// Write the command followed by a null terminator.
process.stdin.write(JSON.stringify(args), "utf8");
process.stdin.write(JSON.stringify(args), 'utf8');
process.stdin.write(this.nullBuffer);
});
// Join all the data together
const fullBuffer = Buffer.concat(stdoutBuffers);
// Make sure we remove the terminator;
const data = fullBuffer.toString("utf8", 0, fullBuffer.length - 1);
this.logger.log(`CLI command succeeded.`);
const data = fullBuffer.toString('utf8', 0, fullBuffer.length - 1);
this.logger.log('CLI command succeeded.');
return data;
} catch (err) {
// Kill the process if it isn't already dead.
@ -246,15 +246,15 @@ export class CodeQLCliServer implements Disposable {
const newError =
stderrBuffers.length == 0
? new Error(`${description} failed: ${err}`)
: new Error(`${description} failed: ${Buffer.concat(stderrBuffers).toString("utf8")}`);
: new Error(`${description} failed: ${Buffer.concat(stderrBuffers).toString('utf8')}`);
newError.stack += (err.stack || '');
throw newError;
} finally {
this.logger.log(Buffer.concat(stderrBuffers).toString("utf8"));
this.logger.log(Buffer.concat(stderrBuffers).toString('utf8'));
// Remove the listeners we set up.
process.stdout.removeAllListeners('data');
process.stderr.removeAllListeners('data');
process.removeAllListeners("close");
process.removeAllListeners('close');
}
} finally {
this.commandInProcess = false;
@ -413,10 +413,10 @@ export class CodeQLCliServer implements Disposable {
async resolveLibraryPath(workspaces: string[], queryPath: string): Promise<QuerySetup> {
const subcommandArgs = [
'--query', queryPath,
"--additional-packs",
'--additional-packs',
workspaces.join(path.delimiter)
];
return await this.runJsonCodeQlCliCommand<QuerySetup>(['resolve', 'library-path'], subcommandArgs, "Resolving library paths");
return await this.runJsonCodeQlCliCommand<QuerySetup>(['resolve', 'library-path'], subcommandArgs, 'Resolving library paths');
}
/**
@ -458,7 +458,7 @@ export class CodeQLCliServer implements Disposable {
* @param queryPath The path to the query.
*/
async resolveMetadata(queryPath: string): Promise<QueryMetadata> {
return await this.runJsonCodeQlCliCommand<QueryMetadata>(['resolve', 'metadata'], [queryPath], "Resolving query metadata");
return await this.runJsonCodeQlCliCommand<QueryMetadata>(['resolve', 'metadata'], [queryPath], 'Resolving query metadata');
}
/**
@ -474,7 +474,7 @@ export class CodeQLCliServer implements Disposable {
if (queryMemoryMb !== undefined) {
args.push('--ram', queryMemoryMb.toString());
}
return await this.runJsonCodeQlCliCommand<string[]>(['resolve', 'ram'], args, "Resolving RAM settings", progressReporter);
return await this.runJsonCodeQlCliCommand<string[]>(['resolve', 'ram'], args, 'Resolving RAM settings', progressReporter);
}
/**
* Gets the headers (and optionally pagination info) of a bqrs.
@ -483,11 +483,11 @@ export class CodeQLCliServer implements Disposable {
*/
async bqrsInfo(bqrsPath: string, pageSize?: number): Promise<BQRSInfo> {
const subcommandArgs = (
pageSize ? ["--paginate-rows", pageSize.toString()] : []
pageSize ? ['--paginate-rows', pageSize.toString()] : []
).concat(
bqrsPath
);
return await this.runJsonCodeQlCliCommand<BQRSInfo>(['bqrs', 'info'], subcommandArgs, "Reading bqrs header");
return await this.runJsonCodeQlCliCommand<BQRSInfo>(['bqrs', 'info'], subcommandArgs, 'Reading bqrs header');
}
/**
@ -499,14 +499,14 @@ export class CodeQLCliServer implements Disposable {
*/
async bqrsDecode(bqrsPath: string, resultSet: string, pageSize?: number, offset?: number): Promise<DecodedBqrsChunk> {
const subcommandArgs = [
"--entities=url,string",
"--result-set", resultSet,
'--entities=url,string',
'--result-set', resultSet,
].concat(
pageSize ? ["--rows", pageSize.toString()] : []
pageSize ? ['--rows', pageSize.toString()] : []
).concat(
offset ? ["--start-at", offset.toString()] : []
offset ? ['--start-at', offset.toString()] : []
).concat([bqrsPath]);
return await this.runJsonCodeQlCliCommand<DecodedBqrsChunk>(['bqrs', 'decode'], subcommandArgs, "Reading bqrs data");
return await this.runJsonCodeQlCliCommand<DecodedBqrsChunk>(['bqrs', 'decode'], subcommandArgs, 'Reading bqrs data');
}
@ -514,22 +514,22 @@ export class CodeQLCliServer implements Disposable {
const args = [
`-t=kind=${metadata.kind}`,
`-t=id=${metadata.id}`,
"--output", interpretedResultsPath,
"--format", SARIF_FORMAT,
'--output', interpretedResultsPath,
'--format', SARIF_FORMAT,
// TODO: This flag means that we don't group interpreted results
// by primary location. We may want to revisit whether we call
// interpretation with and without this flag, or do some
// grouping client-side.
"--no-group-results",
'--no-group-results',
];
if (sourceInfo !== undefined) {
args.push(
"--source-archive", sourceInfo.sourceArchive,
"--source-location-prefix", sourceInfo.sourceLocationPrefix
'--source-archive', sourceInfo.sourceArchive,
'--source-location-prefix', sourceInfo.sourceLocationPrefix
);
}
args.push(resultsPath);
await this.runCodeQlCliCommand(['bqrs', 'interpret'], args, "Interpreting query results");
await this.runCodeQlCliCommand(['bqrs', 'interpret'], args, 'Interpreting query results');
let output: string;
try {
@ -549,9 +549,9 @@ export class CodeQLCliServer implements Disposable {
const sortDirectionStrings = sortDirections.map(direction => {
switch (direction) {
case SortDirection.asc:
return "asc";
return 'asc';
case SortDirection.desc:
return "desc";
return 'desc';
default:
return assertNever(direction);
}
@ -559,14 +559,14 @@ export class CodeQLCliServer implements Disposable {
await this.runCodeQlCliCommand(['bqrs', 'decode'],
[
"--format=bqrs",
'--format=bqrs',
`--result-set=${resultSet}`,
`--output=${sortedResultsPath}`,
`--sort-key=${sortKeys.join(",")}`,
`--sort-direction=${sortDirectionStrings.join(",")}`,
`--sort-key=${sortKeys.join(',')}`,
`--sort-direction=${sortDirectionStrings.join(',')}`,
resultsPath
],
"Sorting query results");
'Sorting query results');
}
@ -576,7 +576,7 @@ export class CodeQLCliServer implements Disposable {
*/
resolveDatabase(databasePath: string): Promise<DbInfo> {
return this.runJsonCodeQlCliCommand(['resolve', 'database'], [databasePath],
"Resolving database");
'Resolving database');
}
/**
@ -591,7 +591,7 @@ export class CodeQLCliServer implements Disposable {
return this.runJsonCodeQlCliCommand<UpgradesInfo>(
['resolve', 'upgrades'],
args,
"Resolving database upgrade scripts",
'Resolving database upgrade scripts',
);
}
@ -611,7 +611,7 @@ export class CodeQLCliServer implements Disposable {
return this.runJsonCodeQlCliCommand<QlpacksInfo>(
['resolve', 'qlpacks'],
args,
"Resolving qlpack information",
'Resolving qlpack information',
);
}
@ -632,7 +632,7 @@ export class CodeQLCliServer implements Disposable {
return this.runJsonCodeQlCliCommand<string[]>(
['resolve', 'queries'],
args,
"Resolving queries",
'Resolving queries',
);
}
}
@ -666,7 +666,7 @@ export function spawnServer(
// Start the server process.
const base = codeqlPath;
const argsString = args.join(" ");
const argsString = args.join(' ');
if (progressReporter !== undefined) {
progressReporter.report({ message: `Starting ${name}` });
}
@ -703,7 +703,7 @@ export function spawnServer(
export async function runCodeQlCliCommand(codeQlPath: string, command: string[], commandArgs: string[], description: string, logger: Logger, progressReporter?: ProgressReporter): Promise<string> {
// Add logging arguments first, in case commandArgs contains positional parameters.
const args = command.concat(LOGGING_FLAGS).concat(commandArgs);
const argsString = args.join(" ");
const argsString = args.join(' ');
try {
if (progressReporter !== undefined) {
progressReporter.report({ message: description });
@ -711,7 +711,7 @@ export async function runCodeQlCliCommand(codeQlPath: string, command: string[],
logger.log(`${description} using CodeQL CLI: ${codeQlPath} ${argsString}...`);
const result = await util.promisify(child_process.execFile)(codeQlPath, args);
logger.log(result.stderr);
logger.log(`CLI command succeeded.`);
logger.log('CLI command succeeded.');
return result.stdout;
} catch (err) {
throw new Error(`${description} failed: ${err.stderr || err}`);

Просмотреть файл

@ -1,22 +1,22 @@
import fetch, { Response } from "node-fetch";
import * as unzipper from "unzipper";
import fetch, { Response } from 'node-fetch';
import * as unzipper from 'unzipper';
import {
Uri,
ProgressOptions,
ProgressLocation,
commands,
window,
} from "vscode";
import * as fs from "fs-extra";
import * as path from "path";
import { DatabaseManager, DatabaseItem } from "./databases";
} from 'vscode';
import * as fs from 'fs-extra';
import * as path from 'path';
import { DatabaseManager, DatabaseItem } from './databases';
import {
ProgressCallback,
showAndLogErrorMessage,
withProgress,
showAndLogInformationMessage,
} from "./helpers";
import { logger } from "./logging";
} from './helpers';
import { logger } from './logging';
/**
* Prompts a user to fetch a database from a remote location. Database is assumed to be an archive file.
@ -32,14 +32,14 @@ export async function promptImportInternetDatabase(
try {
const databaseUrl = await window.showInputBox({
prompt: "Enter URL of zipfile of database to download",
prompt: 'Enter URL of zipfile of database to download',
});
if (databaseUrl) {
validateHttpsUrl(databaseUrl);
const progressOptions: ProgressOptions = {
location: ProgressLocation.Notification,
title: "Adding database from URL",
title: 'Adding database from URL',
cancellable: false,
};
await withProgress(
@ -52,10 +52,10 @@ export async function promptImportInternetDatabase(
progress
))
);
commands.executeCommand("codeQLDatabases.focus");
commands.executeCommand('codeQLDatabases.focus');
}
showAndLogInformationMessage(
"Database downloaded and imported successfully."
'Database downloaded and imported successfully.'
);
} catch (e) {
showAndLogErrorMessage(e.message);
@ -81,7 +81,7 @@ export async function promptImportLgtmDatabase(
try {
const lgtmUrl = await window.showInputBox({
prompt:
"Enter the project URL on LGTM (e.g., https://lgtm.com/projects/g/github/codeql)",
'Enter the project URL on LGTM (e.g., https://lgtm.com/projects/g/github/codeql)',
});
if (!lgtmUrl) {
return;
@ -91,7 +91,7 @@ export async function promptImportLgtmDatabase(
if (databaseUrl) {
const progressOptions: ProgressOptions = {
location: ProgressLocation.Notification,
title: "Adding database from LGTM",
title: 'Adding database from LGTM',
cancellable: false,
};
await withProgress(
@ -104,14 +104,14 @@ export async function promptImportLgtmDatabase(
progress
))
);
commands.executeCommand("codeQLDatabases.focus");
commands.executeCommand('codeQLDatabases.focus');
}
} else {
throw new Error(`Invalid LGTM URL: ${lgtmUrl}`);
}
if (item) {
showAndLogInformationMessage(
"Database downloaded and imported successfully."
'Database downloaded and imported successfully.'
);
}
} catch (e) {
@ -137,7 +137,7 @@ export async function importArchiveDatabase(
try {
const progressOptions: ProgressOptions = {
location: ProgressLocation.Notification,
title: "Importing database from archive",
title: 'Importing database from archive',
cancellable: false,
};
await withProgress(
@ -150,16 +150,16 @@ export async function importArchiveDatabase(
progress
))
);
commands.executeCommand("codeQLDatabases.focus");
commands.executeCommand('codeQLDatabases.focus');
if (item) {
showAndLogInformationMessage(
"Database unzipped and imported successfully."
'Database unzipped and imported successfully.'
);
}
} catch (e) {
if (e.message.includes("unexpected end of file")) {
showAndLogErrorMessage("Database is corrupt or too large. Try unzipping outside of VS Code and importing the unzipped folder instead.");
if (e.message.includes('unexpected end of file')) {
showAndLogErrorMessage('Database is corrupt or too large. Try unzipping outside of VS Code and importing the unzipped folder instead.');
} else {
showAndLogErrorMessage(e.message);
}
@ -184,11 +184,11 @@ async function databaseArchiveFetcher(
): Promise<DatabaseItem> {
progressCallback?.({
maxStep: 3,
message: "Getting database",
message: 'Getting database',
step: 1,
});
if (!storagePath) {
throw new Error("No storage path specified.");
throw new Error('No storage path specified.');
}
await fs.ensureDir(storagePath);
const unzipPath = await getStorageFolder(storagePath, databaseUrl);
@ -201,22 +201,22 @@ async function databaseArchiveFetcher(
progressCallback?.({
maxStep: 3,
message: "Opening database",
message: 'Opening database',
step: 3,
});
// find the path to the database. The actual database might be in a sub-folder
const dbPath = await findDirWithFile(
unzipPath,
".dbinfo",
"codeql-database.yml"
'.dbinfo',
'codeql-database.yml'
);
if (dbPath) {
const item = await databasesManager.openDatabase(Uri.file(dbPath));
databasesManager.setCurrentDatabaseItem(item);
return item;
} else {
throw new Error("Database not found in archive.");
throw new Error('Database not found in archive.');
}
}
@ -228,7 +228,7 @@ async function getStorageFolder(storagePath: string, urlStr: string) {
// MacOS has a max filename length of 255
// and remove a few extra chars in case we need to add a counter at the end.
let lastName = path.basename(url.path).substring(0, 250);
if (lastName.endsWith(".zip")) {
if (lastName.endsWith('.zip')) {
lastName = lastName.substring(0, lastName.length - 4);
}
@ -241,7 +241,7 @@ async function getStorageFolder(storagePath: string, urlStr: string) {
counter++;
folderName = path.join(realpath, `${lastName}-${counter}`);
if (counter > 100) {
throw new Error("Could not find a unique name for downloaded database.");
throw new Error('Could not find a unique name for downloaded database.');
}
}
return folderName;
@ -255,8 +255,8 @@ function validateHttpsUrl(databaseUrl: string) {
throw new Error(`Invalid url: ${databaseUrl}`);
}
if (uri.scheme !== "https") {
throw new Error("Must use https for downloading a database.");
if (uri.scheme !== 'https') {
throw new Error('Must use https for downloading a database.');
}
}
@ -269,9 +269,9 @@ async function readAndUnzip(databaseUrl: string, unzipPath: string) {
// we already know this is a file scheme
const databaseFile = Uri.parse(databaseUrl).fsPath;
const stream = fs.createReadStream(databaseFile);
stream.on("error", reject);
unzipStream.on("error", reject);
unzipStream.on("close", resolve);
stream.on('error', reject);
unzipStream.on('error', reject);
unzipStream.on('close', resolve);
stream.pipe(unzipStream);
});
}
@ -290,7 +290,7 @@ async function fetchAndUnzip(
});
progressCallback?.({
maxStep: 3,
message: "Unzipping database",
message: 'Unzipping database',
step: 2,
});
await new Promise((resolve, reject) => {
@ -301,9 +301,9 @@ async function fetchAndUnzip(
reject(err);
}
};
response.body.on("error", handler);
unzipStream.on("error", handler);
unzipStream.on("close", resolve);
response.body.on('error', handler);
unzipStream.on('error', handler);
unzipStream.on('close', resolve);
response.body.pipe(unzipStream);
});
}
@ -326,7 +326,7 @@ async function checkForFailingResponse(response: Response): Promise<void | never
}
function isFile(databaseUrl: string) {
return Uri.parse(databaseUrl).scheme === "file";
return Uri.parse(databaseUrl).scheme === 'file';
}
/**
@ -381,16 +381,16 @@ export function looksLikeLgtmUrl(lgtmUrl: string | undefined): lgtmUrl is string
try {
const uri = Uri.parse(lgtmUrl, true);
if (uri.scheme !== "https") {
if (uri.scheme !== 'https') {
return false;
}
if (uri.authority !== "lgtm.com" && uri.authority !== "www.lgtm.com") {
if (uri.authority !== 'lgtm.com' && uri.authority !== 'www.lgtm.com') {
return false;
}
const paths = uri.path.split("/").filter((segment) => segment);
return paths.length >= 4 && paths[0] === "projects";
const paths = uri.path.split('/').filter((segment) => segment);
return paths.length >= 4 && paths[0] === 'projects';
} catch (e) {
return false;
}
@ -400,10 +400,10 @@ export function looksLikeLgtmUrl(lgtmUrl: string | undefined): lgtmUrl is string
export async function convertToDatabaseUrl(lgtmUrl: string) {
try {
const uri = Uri.parse(lgtmUrl, true);
const paths = ["api", "v1.0"].concat(
uri.path.split("/").filter((segment) => segment)
const paths = ['api', 'v1.0'].concat(
uri.path.split('/').filter((segment) => segment)
).slice(0, 6);
const projectUrl = `https://lgtm.com/${paths.join("/")}`;
const projectUrl = `https://lgtm.com/${paths.join('/')}`;
const projectResponse = await fetch(projectUrl);
const projectJson = await projectResponse.json();
@ -416,12 +416,12 @@ export async function convertToDatabaseUrl(lgtmUrl: string) {
return;
}
return `https://lgtm.com/${[
"api",
"v1.0",
"snapshots",
'api',
'v1.0',
'snapshots',
projectJson.id,
language,
].join("/")}`;
].join('/')}`;
} catch (e) {
logger.log(`Error: ${e.message}`);
throw new Error(`Invalid LGTM URL: ${lgtmUrl}`);
@ -440,7 +440,7 @@ async function promptForLanguage(
return await window.showQuickPick(
projectJson.languages.map((lang: { language: string }) => lang.language), {
placeHolder: "Select the database language to download:"
placeHolder: 'Select the database language to download:'
}
);
}

Просмотреть файл

@ -670,7 +670,7 @@ export class DatabaseManager extends DisposableObject {
// Delete folder from file system only if it is controlled by the extension
if (this.isExtensionControlledLocation(item.databaseUri)) {
logger.log(`Deleting database from filesystem.`);
logger.log('Deleting database from filesystem.');
fs.remove(item.databaseUri.path).then(
() => logger.log(`Deleted '${item.databaseUri.path}'`),
e => logger.log(`Failed to delete '${item.databaseUri.path}'. Reason: ${e.message}`));

Просмотреть файл

@ -1,16 +1,16 @@
import * as fs from 'fs-extra';
import * as yaml from 'js-yaml';
import * as tmp from 'tmp';
import * as vscode from "vscode";
import { decodeSourceArchiveUri, zipArchiveScheme } from "./archive-filesystem-provider";
import { ColumnKindCode, EntityValue, getResultSetSchema, LineColumnLocation, UrlValue } from "./bqrs-cli-types";
import { CodeQLCliServer } from "./cli";
import { DatabaseItem, DatabaseManager } from "./databases";
import * as vscode from 'vscode';
import { decodeSourceArchiveUri, zipArchiveScheme } from './archive-filesystem-provider';
import { ColumnKindCode, EntityValue, getResultSetSchema, LineColumnLocation, UrlValue } from './bqrs-cli-types';
import { CodeQLCliServer } from './cli';
import { DatabaseItem, DatabaseManager } from './databases';
import * as helpers from './helpers';
import { CachedOperation } from './helpers';
import * as messages from "./messages";
import { QueryServerClient } from "./queryserver-client";
import { compileAndRunQueryAgainstDatabase, QueryWithResults } from "./run-queries";
import * as messages from './messages';
import { QueryServerClient } from './queryserver-client';
import { compileAndRunQueryAgainstDatabase, QueryWithResults } from './run-queries';
/**
* Run templated CodeQL queries to find definitions and references in
@ -19,8 +19,8 @@ import { compileAndRunQueryAgainstDatabase, QueryWithResults } from "./run-queri
* or from a selected identifier.
*/
const TEMPLATE_NAME = "selectedSourceFile";
const SELECT_QUERY_NAME = "#select";
const TEMPLATE_NAME = 'selectedSourceFile';
const SELECT_QUERY_NAME = '#select';
enum KeyType {
DefinitionQuery = 'DefinitionQuery',
@ -29,15 +29,15 @@ enum KeyType {
function tagOfKeyType(keyType: KeyType): string {
switch (keyType) {
case KeyType.DefinitionQuery: return "ide-contextual-queries/local-definitions";
case KeyType.ReferenceQuery: return "ide-contextual-queries/local-references";
case KeyType.DefinitionQuery: return 'ide-contextual-queries/local-definitions';
case KeyType.ReferenceQuery: return 'ide-contextual-queries/local-references';
}
}
function nameOfKeyType(keyType: KeyType): string {
switch (keyType) {
case KeyType.DefinitionQuery: return "definitions";
case KeyType.ReferenceQuery: return "references";
case KeyType.DefinitionQuery: return 'definitions';
case KeyType.ReferenceQuery: return 'references';
}
}
@ -166,7 +166,7 @@ async function getLinksForUriString(
if (db) {
const qlpack = await qlpackOfDatabase(cli, db);
if (qlpack === undefined) {
throw new Error("Can't infer qlpack from database source archive");
throw new Error('Can\'t infer qlpack from database source archive');
}
const links: FullLocationLink[] = [];
for (const query of await resolveQueries(cli, qlpack, keyType)) {
@ -191,7 +191,7 @@ async function getLinksForUriString(
}
function fileRangeFromURI(uri: UrlValue, db: DatabaseItem): FileRange | undefined {
if (typeof uri === "string") {
if (typeof uri === 'string') {
return undefined;
} else if ('startOffset' in uri) {
return undefined;
@ -203,7 +203,7 @@ function fileRangeFromURI(uri: UrlValue, db: DatabaseItem): FileRange | undefine
Math.max(0, loc.endColumn));
try {
const parsed = vscode.Uri.parse(uri.uri, true);
if (parsed.scheme === "file") {
if (parsed.scheme === 'file') {
return { file: db.resolveSourceFile(parsed.fsPath), range };
}
return undefined;

Просмотреть файл

@ -1,16 +1,16 @@
import * as fetch from "node-fetch";
import * as fs from "fs-extra";
import * as os from "os";
import * as path from "path";
import * as semver from "semver";
import * as unzipper from "unzipper";
import * as url from "url";
import { ExtensionContext, Event } from "vscode";
import { DistributionConfig } from "./config";
import { InvocationRateLimiter, InvocationRateLimiterResultKind, showAndLogErrorMessage } from "./helpers";
import { logger } from "./logging";
import * as helpers from "./helpers";
import { getCodeQlCliVersion } from "./cli-version";
import * as fetch from 'node-fetch';
import * as fs from 'fs-extra';
import * as os from 'os';
import * as path from 'path';
import * as semver from 'semver';
import * as unzipper from 'unzipper';
import * as url from 'url';
import { ExtensionContext, Event } from 'vscode';
import { DistributionConfig } from './config';
import { InvocationRateLimiter, InvocationRateLimiterResultKind, showAndLogErrorMessage } from './helpers';
import { logger } from './logging';
import * as helpers from './helpers';
import { getCodeQlCliVersion } from './cli-version';
/**
* distribution.ts
@ -25,7 +25,7 @@ import { getCodeQlCliVersion } from "./cli-version";
* We set the default here rather than as a default config value so that this default is invoked
* upon blanking the setting.
*/
const DEFAULT_DISTRIBUTION_OWNER_NAME = "github";
const DEFAULT_DISTRIBUTION_OWNER_NAME = 'github';
/**
* Default value for the repository name of the extension-managed distribution on GitHub.
@ -33,14 +33,14 @@ const DEFAULT_DISTRIBUTION_OWNER_NAME = "github";
* We set the default here rather than as a default config value so that this default is invoked
* upon blanking the setting.
*/
const DEFAULT_DISTRIBUTION_REPOSITORY_NAME = "codeql-cli-binaries";
const DEFAULT_DISTRIBUTION_REPOSITORY_NAME = 'codeql-cli-binaries';
/**
* Range of versions of the CLI that are compatible with the extension.
*
* This applies to both extension-managed and CLI distributions.
*/
export const DEFAULT_DISTRIBUTION_VERSION_RANGE: semver.Range = new semver.Range("2.x");
export const DEFAULT_DISTRIBUTION_VERSION_RANGE: semver.Range = new semver.Range('2.x');
export interface DistributionProvider {
getCodeQlPathWithoutVersionCheck(): Promise<string | undefined>;
@ -54,7 +54,7 @@ export class DistributionManager implements DistributionProvider {
this._onDidChangeDistribution = config.onDidChangeDistributionConfiguration;
this._updateCheckRateLimiter = new InvocationRateLimiter(
extensionContext,
"extensionSpecificDistributionUpdateCheck",
'extensionSpecificDistributionUpdateCheck',
() => this._extensionSpecificDistributionManager.checkForUpdatesToDistribution()
);
this._versionRange = versionRange;
@ -128,8 +128,8 @@ export class DistributionManager implements DistributionProvider {
if (this._config.customCodeQlPath) {
if (!await fs.pathExists(this._config.customCodeQlPath)) {
showAndLogErrorMessage(`The CodeQL executable path is specified as "${this._config.customCodeQlPath}" ` +
"by a configuration setting, but a CodeQL executable could not be found at that path. Please check " +
"that a CodeQL executable exists at the specified path or remove the setting.");
'by a configuration setting, but a CodeQL executable could not be found at that path. Please check ' +
'that a CodeQL executable exists at the specified path or remove the setting.');
return undefined;
}
@ -165,7 +165,7 @@ export class DistributionManager implements DistributionProvider {
};
}
}
logger.log("INFO: Could not find CodeQL on path.");
logger.log('INFO: Could not find CodeQL on path.');
}
return undefined;
@ -248,7 +248,7 @@ class ExtensionSpecificDistributionManager {
try {
await this.removeDistribution();
} catch (e) {
logger.log("WARNING: Tried to remove corrupted CodeQL CLI at " +
logger.log('WARNING: Tried to remove corrupted CodeQL CLI at ' +
`${this.getDistributionStoragePath()} but encountered an error: ${e}.`);
}
}
@ -309,13 +309,13 @@ class ExtensionSpecificDistributionManager {
}
const assetStream = await this.createReleasesApiConsumer().streamBinaryContentOfAsset(assets[0]);
const tmpDirectory = await fs.mkdtemp(path.join(os.tmpdir(), "vscode-codeql"));
const tmpDirectory = await fs.mkdtemp(path.join(os.tmpdir(), 'vscode-codeql'));
try {
const archivePath = path.join(tmpDirectory, "distributionDownload.zip");
const archivePath = path.join(tmpDirectory, 'distributionDownload.zip');
const archiveFile = fs.createWriteStream(archivePath);
const contentLength = assetStream.headers.get("content-length");
const contentLength = assetStream.headers.get('content-length');
let numBytesDownloaded = 0;
if (progressCallback && contentLength !== null) {
@ -332,7 +332,7 @@ class ExtensionSpecificDistributionManager {
// Display the progress straight away rather than waiting for the first chunk.
updateProgress();
assetStream.body.on("data", data => {
assetStream.body.on('data', data => {
numBytesDownloaded += data.length;
updateProgress();
});
@ -340,8 +340,8 @@ class ExtensionSpecificDistributionManager {
await new Promise((resolve, reject) =>
assetStream.body.pipe(archiveFile)
.on("finish", resolve)
.on("error", reject)
.on('finish', resolve)
.on('error', reject)
);
await this.bumpDistributionFolderIndex();
@ -413,7 +413,7 @@ class ExtensionSpecificDistributionManager {
private getDistributionStoragePath(): string {
// Use an empty string for the initial distribution for backwards compatibility.
const distributionFolderIndex = this._extensionContext.globalState.get(
ExtensionSpecificDistributionManager._currentDistributionFolderIndexStateKey, 0) || "";
ExtensionSpecificDistributionManager._currentDistributionFolderIndexStateKey, 0) || '';
return path.join(this._extensionContext.globalStoragePath,
ExtensionSpecificDistributionManager._currentDistributionFolderBaseName + distributionFolderIndex);
}
@ -435,19 +435,19 @@ class ExtensionSpecificDistributionManager {
private readonly _extensionContext: ExtensionContext;
private readonly _versionRange: semver.Range;
private static readonly _currentDistributionFolderBaseName = "distribution";
private static readonly _currentDistributionFolderIndexStateKey = "distributionFolderIndex";
private static readonly _installedReleaseStateKey = "distributionRelease";
private static readonly _codeQlExtractedFolderName = "codeql";
private static readonly _currentDistributionFolderBaseName = 'distribution';
private static readonly _currentDistributionFolderIndexStateKey = 'distributionFolderIndex';
private static readonly _installedReleaseStateKey = 'distributionRelease';
private static readonly _codeQlExtractedFolderName = 'codeql';
}
export class ReleasesApiConsumer {
constructor(ownerName: string, repoName: string, personalAccessToken?: string) {
// Specify version of the GitHub API
this._defaultHeaders["accept"] = "application/vnd.github.v3+json";
this._defaultHeaders['accept'] = 'application/vnd.github.v3+json';
if (personalAccessToken) {
this._defaultHeaders["authorization"] = `token ${personalAccessToken}`;
this._defaultHeaders['authorization'] = `token ${personalAccessToken}`;
}
this._ownerName = ownerName;
@ -475,11 +475,11 @@ export class ReleasesApiConsumer {
if (versionComparison !== 0) {
return versionComparison;
}
return b.created_at.localeCompare(a.created_at, "en-US");
return b.created_at.localeCompare(a.created_at, 'en-US');
})[0];
if (latestRelease === undefined) {
throw new Error("No compatible CodeQL CLI releases were found. " +
"Please check that the CodeQL extension is up to date.");
throw new Error('No compatible CodeQL CLI releases were found. ' +
'Please check that the CodeQL extension is up to date.');
}
const assets: ReleaseAsset[] = latestRelease.assets.map(asset => {
return {
@ -501,7 +501,7 @@ export class ReleasesApiConsumer {
const apiPath = `/repos/${this._ownerName}/${this._repoName}/releases/assets/${asset.id}`;
return await this.makeApiCall(apiPath, {
"accept": "application/octet-stream"
'accept': 'application/octet-stream'
});
}
@ -511,7 +511,7 @@ export class ReleasesApiConsumer {
if (!response.ok) {
// Check for rate limiting
const rateLimitResetValue = response.headers.get("X-RateLimit-Reset");
const rateLimitResetValue = response.headers.get('X-RateLimit-Reset');
if (response.status === 403 && rateLimitResetValue) {
const secondsToMillisecondsFactor = 1000;
const rateLimitResetDate = new Date(parseInt(rateLimitResetValue, 10) * secondsToMillisecondsFactor);
@ -528,21 +528,21 @@ export class ReleasesApiConsumer {
redirectCount = 0): Promise<fetch.Response> {
const response = await fetch.default(requestUrl, {
headers,
redirect: "manual"
redirect: 'manual'
});
const redirectUrl = response.headers.get("location");
const redirectUrl = response.headers.get('location');
if (isRedirectStatusCode(response.status) && redirectUrl && redirectCount < ReleasesApiConsumer._maxRedirects) {
const parsedRedirectUrl = url.parse(redirectUrl);
if (parsedRedirectUrl.protocol != "https:") {
throw new Error("Encountered a non-https redirect, rejecting");
if (parsedRedirectUrl.protocol != 'https:') {
throw new Error('Encountered a non-https redirect, rejecting');
}
if (parsedRedirectUrl.host != "api.github.com") {
if (parsedRedirectUrl.host != 'api.github.com') {
// Remove authorization header if we are redirected outside of the GitHub API.
//
// This is necessary to stream release assets since AWS fails if more than one auth
// mechanism is provided.
delete headers["authorization"];
delete headers['authorization'];
}
return await this.makeRawRequest(redirectUrl, headers, redirectCount + 1);
}
@ -554,7 +554,7 @@ export class ReleasesApiConsumer {
private readonly _ownerName: string;
private readonly _repoName: string;
private static readonly _apiBase = "https://api.github.com";
private static readonly _apiBase = 'https://api.github.com';
private static readonly _maxRedirects = 20;
}
@ -576,11 +576,11 @@ export async function extractZipArchive(archivePath: string, outPath: string): P
}
function codeQlLauncherName(): string {
return (os.platform() === "win32") ? "codeql.exe" : "codeql";
return (os.platform() === 'win32') ? 'codeql.exe' : 'codeql';
}
function deprecatedCodeQlLauncherName(): string | undefined {
return (os.platform() === "win32") ? "codeql.cmd" : undefined;
return (os.platform() === 'win32') ? 'codeql.cmd' : undefined;
}
function isRedirectStatusCode(statusCode: number): boolean {
@ -713,7 +713,7 @@ export async function getExecutableFromDirectory(directory: string, warnWhenNotF
}
if (warnWhenNotFound) {
logger.log(`WARNING: Expected to find a CodeQL CLI executable at ${expectedLauncherPath} but one was not found. ` +
"Will try PATH.");
'Will try PATH.');
}
return undefined;
}

Просмотреть файл

@ -95,7 +95,7 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
const codeQlVersionRange = DEFAULT_DISTRIBUTION_VERSION_RANGE;
const distributionManager = new DistributionManager(ctx, distributionConfigListener, codeQlVersionRange);
const shouldUpdateOnNextActivationKey = "shouldUpdateOnNextActivation";
const shouldUpdateOnNextActivationKey = 'shouldUpdateOnNextActivation';
registerErrorStubs([checkForUpdatesCommand], command => () => {
helpers.showAndLogErrorMessage(`Can't execute ${command}: waiting to finish loading CodeQL CLI.`);
@ -118,7 +118,7 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
switch (result.kind) {
case DistributionUpdateCheckResultKind.AlreadyCheckedRecentlyResult:
logger.log("Didn't perform CodeQL CLI update check since a check was already performed within the previous " +
logger.log('Didn\'t perform CodeQL CLI update check since a check was already performed within the previous ' +
`${minSecondsSinceLastUpdateCheck} seconds.`);
break;
case DistributionUpdateCheckResultKind.AlreadyUpToDate:
@ -155,16 +155,16 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
async function installOrUpdateDistribution(config: DistributionUpdateConfig): Promise<void> {
if (isInstallingOrUpdatingDistribution) {
throw new Error("Already installing or updating CodeQL CLI");
throw new Error('Already installing or updating CodeQL CLI');
}
isInstallingOrUpdatingDistribution = true;
const codeQlInstalled = await distributionManager.getCodeQlPathWithoutVersionCheck() !== undefined;
const willUpdateCodeQl = ctx.globalState.get(shouldUpdateOnNextActivationKey);
const messageText = willUpdateCodeQl
? "Updating CodeQL CLI"
? 'Updating CodeQL CLI'
: codeQlInstalled
? "Checking for updates to CodeQL CLI"
: "Installing CodeQL CLI";
? 'Checking for updates to CodeQL CLI'
: 'Installing CodeQL CLI';
try {
await installOrUpdateDistributionWithProgressTitle(messageText, config);
@ -173,8 +173,8 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
// or updating the distribution.
const alertFunction = (codeQlInstalled && !config.isUserInitiated) ?
helpers.showAndLogWarningMessage : helpers.showAndLogErrorMessage;
const taskDescription = (willUpdateCodeQl ? "update" :
codeQlInstalled ? "check for updates to" : "install") + " CodeQL CLI";
const taskDescription = (willUpdateCodeQl ? 'update' :
codeQlInstalled ? 'check for updates to' : 'install') + ' CodeQL CLI';
if (e instanceof GithubRateLimitedError) {
alertFunction(`Rate limited while trying to ${taskDescription}. Please try again after ` +
@ -198,7 +198,7 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
const fixGuidanceMessage = (() => {
switch (result.distribution.kind) {
case DistributionKind.ExtensionManaged:
return "Please update the CodeQL CLI by running the \"CodeQL: Check for CLI Updates\" command.";
return 'Please update the CodeQL CLI by running the "CodeQL: Check for CLI Updates" command.';
case DistributionKind.CustomPathConfig:
return `Please update the \"CodeQL CLI Executable Path\" setting to point to a CLI in the version range ${codeQlVersionRange}.`;
case DistributionKind.PathEnvironmentVariable:
@ -208,15 +208,15 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
})();
helpers.showAndLogWarningMessage(`The current version of the CodeQL CLI (${result.version.raw}) ` +
"is incompatible with this extension. " + fixGuidanceMessage);
'is incompatible with this extension. ' + fixGuidanceMessage);
break;
}
case FindDistributionResultKind.UnknownCompatibilityDistribution:
helpers.showAndLogWarningMessage("Compatibility with the configured CodeQL CLI could not be determined. " +
"You may experience problems using the extension.");
helpers.showAndLogWarningMessage('Compatibility with the configured CodeQL CLI could not be determined. ' +
'You may experience problems using the extension.');
break;
case FindDistributionResultKind.NoDistribution:
helpers.showAndLogErrorMessage("The CodeQL CLI could not be found.");
helpers.showAndLogErrorMessage('The CodeQL CLI could not be found.');
break;
default:
assertNever(result);
@ -234,7 +234,7 @@ export async function activate(ctx: ExtensionContext): Promise<void> {
await activateWithInstalledDistribution(ctx, distributionManager);
} else if (distributionResult.kind === FindDistributionResultKind.NoDistribution) {
registerErrorStubs([checkForUpdatesCommand], command => async () => {
const installActionName = "Install CodeQL CLI";
const installActionName = 'Install CodeQL CLI';
const chosenAction = await helpers.showAndLogErrorMessage(`Can't execute ${command}: missing CodeQL CLI.`, {
items: [installActionName]
});

Просмотреть файл

@ -10,7 +10,7 @@
*/
class ExhaustivityCheckingError extends Error {
constructor(public expectedExhaustiveValue: never) {
super("Internal error: exhaustivity checking failure");
super('Internal error: exhaustivity checking failure');
}
}

Просмотреть файл

@ -139,7 +139,7 @@ export function getOnDiskWorkspaceFolders() {
const workspaceFolders = workspace.workspaceFolders || [];
const diskWorkspaceFolders: string[] = [];
for (const workspaceFolder of workspaceFolders) {
if (workspaceFolder.uri.scheme === "file")
if (workspaceFolder.uri.scheme === 'file')
diskWorkspaceFolders.push(workspaceFolder.uri.fsPath);
}
return diskWorkspaceFolders;
@ -213,7 +213,7 @@ export class InvocationRateLimiter<T> {
private readonly _func: () => Promise<T>;
private readonly _funcIdentifier: string;
private static readonly _invocationRateLimiterPrefix = "invocationRateLimiter_lastInvocationDate_";
private static readonly _invocationRateLimiterPrefix = 'invocationRateLimiter_lastInvocationDate_';
}
export enum InvocationRateLimiterResultKind {

Просмотреть файл

@ -1,6 +1,6 @@
import { RawResultSet } from "./adapt";
import { ResultSetSchema } from "semmle-bqrs";
import { Interpretation } from "./interface-types";
import { RawResultSet } from './adapt';
import { ResultSetSchema } from 'semmle-bqrs';
import { Interpretation } from './interface-types';
export const SELECT_TABLE_NAME = '#select';
export const ALERTS_TABLE_NAME = 'alerts';

Просмотреть файл

@ -129,7 +129,7 @@ export class InterfaceManager extends DisposableObject {
private _panelLoadedCallBacks: (() => void)[] = [];
private readonly _diagnosticCollection = languages.createDiagnosticCollection(
`codeql-query-results`
'codeql-query-results'
);
constructor(
@ -148,20 +148,20 @@ export class InterfaceManager extends DisposableObject {
logger.log('Registering path-step navigation commands.');
this.push(
vscode.commands.registerCommand(
"codeQLQueryResults.nextPathStep",
'codeQLQueryResults.nextPathStep',
this.navigatePathStep.bind(this, 1)
)
);
this.push(
vscode.commands.registerCommand(
"codeQLQueryResults.previousPathStep",
'codeQLQueryResults.previousPathStep',
this.navigatePathStep.bind(this, -1)
)
);
}
navigatePathStep(direction: number): void {
this.postMessage({ t: "navigatePath", direction });
this.postMessage({ t: 'navigatePath', direction });
}
// Returns the webview panel, creating it if it doesn't already
@ -170,8 +170,8 @@ export class InterfaceManager extends DisposableObject {
if (this._panel == undefined) {
const { ctx } = this;
const panel = (this._panel = Window.createWebviewPanel(
"resultsView", // internal name
"CodeQL Query Results", // user-visible name
'resultsView', // internal name
'CodeQL Query Results', // user-visible name
{ viewColumn: vscode.ViewColumn.Beside, preserveFocus: true },
{
enableScripts: true,
@ -179,7 +179,7 @@ export class InterfaceManager extends DisposableObject {
retainContextWhenHidden: true,
localResourceRoots: [
vscode.Uri.file(tmpDir.name),
vscode.Uri.file(path.join(this.ctx.extensionPath, "out"))
vscode.Uri.file(path.join(this.ctx.extensionPath, 'out'))
]
}
));
@ -191,10 +191,10 @@ export class InterfaceManager extends DisposableObject {
ctx.subscriptions
);
const scriptPathOnDisk = vscode.Uri.file(
ctx.asAbsolutePath("out/resultsView.js")
ctx.asAbsolutePath('out/resultsView.js')
);
const stylesheetPathOnDisk = vscode.Uri.file(
ctx.asAbsolutePath("out/resultsView.css")
ctx.asAbsolutePath('out/resultsView.css')
);
getHtmlForWebview(
panel.webview,
@ -215,12 +215,12 @@ export class InterfaceManager extends DisposableObject {
): Promise<void> {
if (this._displayedQuery === undefined) {
showAndLogErrorMessage(
"Failed to sort results since evaluation info was unknown."
'Failed to sort results since evaluation info was unknown.'
);
return;
}
// Notify the webview that it should expect new results.
await this.postMessage({ t: "resultsUpdating" });
await this.postMessage({ t: 'resultsUpdating' });
await update(this._displayedQuery);
await this.showResults(
this._displayedQuery,
@ -233,7 +233,7 @@ export class InterfaceManager extends DisposableObject {
msg: FromResultsViewMsg
): Promise<void> {
switch (msg.t) {
case "viewSourceFile": {
case 'viewSourceFile': {
const databaseItem = this.databaseManager.findDatabaseItem(
Uri.parse(msg.databaseUri)
);
@ -244,7 +244,7 @@ export class InterfaceManager extends DisposableObject {
if (e instanceof Error) {
if (e.message.match(/File not found/)) {
vscode.window.showErrorMessage(
`Original file of this result is not in the database's source archive.`
'Original file of this result is not in the database\'s source archive.'
);
} else {
this.logger.log(
@ -258,7 +258,7 @@ export class InterfaceManager extends DisposableObject {
}
break;
}
case "toggleDiagnostics": {
case 'toggleDiagnostics': {
if (msg.visible) {
const databaseItem = this.databaseManager.findDatabaseItem(
Uri.parse(msg.databaseUri)
@ -276,12 +276,12 @@ export class InterfaceManager extends DisposableObject {
}
break;
}
case "resultViewLoaded":
case 'resultViewLoaded':
this._panelLoaded = true;
this._panelLoadedCallBacks.forEach(cb => cb());
this._panelLoadedCallBacks = [];
break;
case "changeSort":
case 'changeSort':
await this.changeSortState(query =>
query.updateSortState(
this.cliServer,
@ -290,12 +290,12 @@ export class InterfaceManager extends DisposableObject {
)
);
break;
case "changeInterpretedSort":
case 'changeInterpretedSort':
await this.changeSortState(query =>
query.updateInterpretedSortState(this.cliServer, msg.sortState)
);
break;
case "changePage":
case 'changePage':
await this.showPageOfResults(msg.selectedTable, msg.pageNumber);
break;
default:
@ -360,10 +360,10 @@ export class InterfaceManager extends DisposableObject {
// is not visible; it's in a not-currently-viewed tab. Show a
// more asynchronous message to not so abruptly interrupt
// user's workflow by immediately revealing the panel.
const showButton = "View Results";
const showButton = 'View Results';
const queryName = results.queryName;
const resultPromise = vscode.window.showInformationMessage(
`Finished running query ${queryName.length > 0 ? ` "${queryName}"` : ""}.`,
`Finished running query ${queryName.length > 0 ? ` "${queryName}"` : ''}.`,
showButton
);
// Address this click asynchronously so we still update the
@ -379,12 +379,12 @@ export class InterfaceManager extends DisposableObject {
if (EXPERIMENTAL_BQRS_SETTING.getValue()) {
const schemas = await this.cliServer.bqrsInfo(results.query.resultsPaths.resultsPath, RAW_RESULTS_PAGE_SIZE);
const resultSetNames = schemas["result-sets"].map(resultSet => resultSet.name);
const resultSetNames = schemas['result-sets'].map(resultSet => resultSet.name);
// This may not wind up being the page we actually show, if there are interpreted results,
// but speculatively send it anyway.
const selectedTable = getDefaultResultSetName(resultSetNames);
const schema = schemas["result-sets"].find(resultSet => resultSet.name == selectedTable)!;
const schema = schemas['result-sets'].find(resultSet => resultSet.name == selectedTable)!;
if (schema === undefined) {
return { t: 'WebviewParsed' };
}
@ -408,7 +408,7 @@ export class InterfaceManager extends DisposableObject {
};
await this.postMessage({
t: "setState",
t: 'setState',
interpretation,
origResultsPaths: results.query.resultsPaths,
resultsPath: this.convertPathToWebviewUri(
@ -441,9 +441,9 @@ export class InterfaceManager extends DisposableObject {
const schemas = await this.cliServer.bqrsInfo(results.query.resultsPaths.resultsPath, RAW_RESULTS_PAGE_SIZE);
const resultSetNames = schemas["result-sets"].map(resultSet => resultSet.name);
const resultSetNames = schemas['result-sets'].map(resultSet => resultSet.name);
const schema = schemas["result-sets"].find(resultSet => resultSet.name == selectedTable)!;
const schema = schemas['result-sets'].find(resultSet => resultSet.name == selectedTable)!;
if (schema === undefined)
throw new Error(`Query result set '${selectedTable}' not found.`);
@ -461,7 +461,7 @@ export class InterfaceManager extends DisposableObject {
};
await this.postMessage({
t: "setState",
t: 'setState',
interpretation: this._interpretation,
origResultsPaths: results.query.resultsPaths,
resultsPath: this.convertPathToWebviewUri(
@ -602,7 +602,7 @@ export class InterfaceManager extends DisposableObject {
if (!sarif.runs || !sarif.runs[0].results) {
this.logger.log(
"Didn't find a run in the sarif results. Error processing sarif?"
'Didn\'t find a run in the sarif results. Error processing sarif?'
);
return;
}
@ -612,11 +612,11 @@ export class InterfaceManager extends DisposableObject {
for (const result of sarif.runs[0].results) {
const message = result.message.text;
if (message === undefined) {
this.logger.log("Sarif had result without plaintext message");
this.logger.log('Sarif had result without plaintext message');
continue;
}
if (!result.locations) {
this.logger.log("Sarif had result without location");
this.logger.log('Sarif had result without location');
continue;
}
@ -624,12 +624,12 @@ export class InterfaceManager extends DisposableObject {
result.locations[0],
sourceLocationPrefix
);
if (sarifLoc.t == "NoLocation") {
if (sarifLoc.t == 'NoLocation') {
continue;
}
const resultLocation = tryResolveLocation(sarifLoc, databaseItem);
if (!resultLocation) {
this.logger.log("Sarif location was not resolvable " + sarifLoc);
this.logger.log('Sarif location was not resolvable ' + sarifLoc);
continue;
}
const parsedMessage = parseSarifPlainTextMessage(message);
@ -641,7 +641,7 @@ export class InterfaceManager extends DisposableObject {
}
const resultMessageChunks: string[] = [];
for (const section of parsedMessage) {
if (typeof section === "string") {
if (typeof section === 'string') {
resultMessageChunks.push(section);
} else {
resultMessageChunks.push(section.text);
@ -649,7 +649,7 @@ export class InterfaceManager extends DisposableObject {
relatedLocationsById[section.dest],
sourceLocationPrefix
);
if (sarifChunkLoc.t == "NoLocation") {
if (sarifChunkLoc.t == 'NoLocation') {
continue;
}
const referenceLocation = tryResolveLocation(
@ -668,7 +668,7 @@ export class InterfaceManager extends DisposableObject {
}
const diagnostic = new Diagnostic(
resultLocation.range,
resultMessageChunks.join(""),
resultMessageChunks.join(''),
DiagnosticSeverity.Warning
);
diagnostic.relatedInformation = relatedInformation;

Просмотреть файл

@ -1,4 +1,4 @@
import { IndentAction, languages } from "vscode";
import { IndentAction, languages } from 'vscode';
/**
@ -18,9 +18,9 @@ export function install() {
langConfig.wordPattern = new RegExp(langConfig.wordPattern);
langConfig.onEnterRules = onEnterRules;
langConfig.indentationRules = {
decreaseIndentPattern: /^((?!.*?\/\*).*\*\/)?\s*[\}\]].*$/,
increaseIndentPattern: /^((?!\/\/).)*(\{[^}"'`]*|\([^)"'`]*|\[[^\]"'`]*)$/
};
decreaseIndentPattern: /^((?!.*?\/\*).*\*\/)?\s*[\}\]].*$/,
increaseIndentPattern: /^((?!\/\/).)*(\{[^}"'`]*|\([^)"'`]*|\[[^\]"'`]*)$/
};
languages.setLanguageConfiguration('ql', langConfig);
languages.setLanguageConfiguration('qll', langConfig);

Просмотреть файл

@ -352,9 +352,9 @@ export class QueryHistoryManager {
} catch (e) {
if (
e.message.includes(
"Files above 50MB cannot be synchronized with extensions"
'Files above 50MB cannot be synchronized with extensions'
) ||
e.message.includes("too large to open")
e.message.includes('too large to open')
) {
const res = await helpers.showBinaryChoiceDialog(
`VS Code does not allow extensions to open files >50MB. This file
@ -365,7 +365,7 @@ the file in the file explorer and dragging it into the workspace.`
);
if (res) {
try {
await vscode.commands.executeCommand("revealFileInOS", uri);
await vscode.commands.executeCommand('revealFileInOS', uri);
} catch (e) {
helpers.showAndLogErrorMessage(e.message);
}

Просмотреть файл

@ -1,15 +1,15 @@
import { env } from 'vscode';
import { QueryWithResults, tmpDir, QueryInfo } from "./run-queries";
import { QueryWithResults, tmpDir, QueryInfo } from './run-queries';
import * as messages from './messages';
import * as helpers from './helpers';
import * as cli from './cli';
import * as sarif from 'sarif';
import * as fs from 'fs-extra';
import * as path from 'path';
import { RawResultsSortState, SortedResultSetInfo, DatabaseInfo, QueryMetadata, InterpretedResultsSortState, ResultsPaths } from "./interface-types";
import { QueryHistoryConfig } from "./config";
import { QueryHistoryItemOptions } from "./query-history";
import { RawResultsSortState, SortedResultSetInfo, DatabaseInfo, QueryMetadata, InterpretedResultsSortState, ResultsPaths } from './interface-types';
import { QueryHistoryConfig } from './config';
import { QueryHistoryItemOptions } from './query-history';
export class CompletedQuery implements QueryWithResults {
readonly time: string;
@ -61,7 +61,7 @@ export class CompletedQuery implements QueryWithResults {
case messages.QueryResultType.CANCELLATION:
return `cancelled after ${this.result.evaluationTime / 1000} seconds`;
case messages.QueryResultType.OOM:
return `out of memory`;
return 'out of memory';
case messages.QueryResultType.SUCCESS:
return `finished in ${this.result.evaluationTime / 1000} seconds`;
case messages.QueryResultType.TIMEOUT:
@ -140,7 +140,7 @@ export async function interpretResults(server: cli.CodeQLCliServer, metadata: Qu
if (id === undefined) {
// Interpretation per se doesn't really require an id, but the
// SARIF format does, so in the absence of one, we use a dummy id.
id = "dummy-id";
id = 'dummy-id';
}
return await server.interpretBqrs({ kind, id }, resultsPath, interpretedResultsPath, sourceInfo);
}

Просмотреть файл

@ -102,8 +102,8 @@ export async function displayQuickQuery(ctx: ExtensionContext, cliServer: CodeQL
const datasetFolder = await dbItem.getDatasetFolder(cliServer);
const { qlpack, dbscheme } = await helpers.resolveDatasetFolder(cliServer, datasetFolder);
const quickQueryQlpackYaml: any = {
name: "quick-query",
version: "1.0.0",
name: 'quick-query',
version: '1.0.0',
libraryPathDependencies: [qlpack]
};

Просмотреть файл

@ -100,7 +100,7 @@ export class QueryInfo {
try {
await helpers.withProgress({
location: vscode.ProgressLocation.Notification,
title: "Running Query",
title: 'Running Query',
cancellable: true,
}, (progress, token) => {
return qs.sendRequest(messages.runQueries, params, token, progress);
@ -110,7 +110,7 @@ export class QueryInfo {
}
return result || {
evaluationTime: 0,
message: "No result from server",
message: 'No result from server',
queryId: -1,
runId: callbackId,
resultType: messages.QueryResultType.OTHER_ERROR
@ -145,13 +145,13 @@ export class QueryInfo {
compiled = await helpers.withProgress({
location: vscode.ProgressLocation.Notification,
title: "Compiling Query",
title: 'Compiling Query',
cancellable: true,
}, (progress, token) => {
return qs.sendRequest(messages.compileQuery, params, token, progress);
});
} finally {
qs.logger.log(" - - - COMPILATION DONE - - - ");
qs.logger.log(' - - - COMPILATION DONE - - - ');
}
return (compiled?.messages || []).filter(msg => msg.severity === messages.Severity.ERROR);
}
@ -162,7 +162,7 @@ export class QueryInfo {
async canHaveInterpretedResults(): Promise<boolean> {
const hasMetadataFile = await this.dbItem.hasMetadataFile();
if (!hasMetadataFile) {
logger.log("Cannot produce interpreted results since the database does not have a .dbinfo or codeql-database.yml file.");
logger.log('Cannot produce interpreted results since the database does not have a .dbinfo or codeql-database.yml file.');
}
return hasMetadataFile;
}
@ -203,7 +203,7 @@ export async function clearCacheInDatabase(
return helpers.withProgress({
location: vscode.ProgressLocation.Notification,
title: "Clearing Cache",
title: 'Clearing Cache',
cancellable: false,
}, (progress, token) =>
qs.sendRequest(messages.clearCache, params, token, progress)
@ -216,7 +216,7 @@ export async function clearCacheInDatabase(
*
*/
async function convertToQlPath(filePath: string): Promise<string> {
if (process.platform === "win32") {
if (process.platform === 'win32') {
if (path.parse(filePath).root === filePath) {
// Java assumes uppercase drive letters are canonical.
@ -234,7 +234,7 @@ async function convertToQlPath(filePath: string): Promise<string> {
}
}
}
throw new Error("Can't convert path to form suitable for QL:" + filePath);
throw new Error('Can\'t convert path to form suitable for QL:' + filePath);
} else {
return filePath;
}
@ -517,18 +517,18 @@ export async function compileAndRunQueryAgainstDatabase(
const formattedMessages: string[] = [];
for (const error of errors) {
const message = error.message || "[no error message available]";
const message = error.message || '[no error message available]';
const formatted = `ERROR: ${message} (${error.position.fileName}:${error.position.line}:${error.position.column}:${error.position.endLine}:${error.position.endColumn})`;
formattedMessages.push(formatted);
qs.logger.log(formatted);
}
if (quickEval && formattedMessages.length <= 3) {
helpers.showAndLogErrorMessage("Quick evaluation compilation failed: \n" + formattedMessages.join("\n"));
helpers.showAndLogErrorMessage('Quick evaluation compilation failed: \n' + formattedMessages.join('\n'));
} else {
helpers.showAndLogErrorMessage((quickEval ? "Quick evaluation" : "Query") +
" compilation failed. Please make sure there are no errors in the query, the database is up to date," +
" and the query and database use the same target language. For more details on the error, go to View > Output," +
" and choose CodeQL Query Server from the dropdown.");
helpers.showAndLogErrorMessage((quickEval ? 'Quick evaluation' : 'Query') +
' compilation failed. Please make sure there are no errors in the query, the database is up to date,' +
' and the query and database use the same target language. For more details on the error, go to View > Output,' +
' and choose CodeQL Query Server from the dropdown.');
}
return createSyntheticResult(query, db, historyItemOptions, 'Query had compilation errors', messages.QueryResultType.OTHER_ERROR);

Просмотреть файл

@ -1,6 +1,6 @@
import * as Sarif from "sarif";
import * as path from "path";
import { LocationStyle, ResolvableLocationValue } from "semmle-bqrs";
import * as Sarif from 'sarif';
import * as path from 'path';
import { LocationStyle, ResolvableLocationValue } from 'semmle-bqrs';
export interface SarifLink {
dest: number;
@ -23,7 +23,7 @@ export type SarifMessageComponent = string | SarifLink
* Unescape "[", "]" and "\\" like in sarif plain text messages
*/
export function unescapeSarifText(message: string): string {
return message.replace(/\\\[/g, "[").replace(/\\\]/g, "]").replace(/\\\\/, "\\");
return message.replace(/\\\[/g, '[').replace(/\\\]/g, ']').replace(/\\\\/, '\\');
}
export function parseSarifPlainTextMessage(message: string): SarifMessageComponent[] {
@ -38,8 +38,8 @@ export function parseSarifPlainTextMessage(message: string): SarifMessageCompone
let curIndex = 0;
while ((result = linkRegex.exec(message)) !== null) {
results.push(unescapeSarifText(message.substring(curIndex, result.index)));
const linkText = result.groups!["linkText"];
const linkTarget = +result.groups!["linkTarget"];
const linkText = result.groups!['linkText'];
const linkTarget = +result.groups!['linkTarget'];
results.push({ dest: linkTarget, text: unescapeSarifText(linkText) });
curIndex = result.index + result[0].length;
}

Просмотреть файл

@ -23,7 +23,7 @@ async function checkAndConfirmDatabaseUpgrade(
qs: qsClient.QueryServerClient, db: DatabaseItem, targetDbScheme: vscode.Uri, upgradesDirectories: vscode.Uri[]
): Promise<messages.UpgradeParams | undefined> {
if (db.contents === undefined || db.contents.dbSchemeUri === undefined) {
helpers.showAndLogErrorMessage("Database is invalid, and cannot be upgraded.");
helpers.showAndLogErrorMessage('Database is invalid, and cannot be upgraded.');
return;
}
const params: messages.UpgradeParams = {
@ -86,11 +86,11 @@ async function checkAndConfirmDatabaseUpgrade(
let messageLines = descriptionMessage.split('\n');
if (messageLines.length > MAX_UPGRADE_MESSAGE_LINES) {
messageLines = messageLines.slice(0, MAX_UPGRADE_MESSAGE_LINES);
messageLines.push(`The list of upgrades was truncated, click "No, Show Changes" to see the full list.`);
messageLines.push('The list of upgrades was truncated, click "No, Show Changes" to see the full list.');
dialogOptions.push(showLogItem);
}
const message = `Should the database ${db.databaseUri.fsPath} be upgraded?\n\n${messageLines.join("\n")}`;
const message = `Should the database ${db.databaseUri.fsPath} be upgraded?\n\n${messageLines.join('\n')}`;
const chosenItem = await vscode.window.showInformationMessage(message, { modal: true }, ...dialogOptions);
if (chosenItem === showLogItem) {
@ -157,7 +157,7 @@ async function checkDatabaseUpgrade(
): Promise<messages.CheckUpgradeResult> {
return helpers.withProgress({
location: vscode.ProgressLocation.Notification,
title: "Checking for database upgrades",
title: 'Checking for database upgrades',
cancellable: true,
}, (progress, token) => qs.sendRequest(messages.checkUpgrade, upgradeParams, token, progress));
}
@ -172,7 +172,7 @@ async function compileDatabaseUpgrade(
return helpers.withProgress({
location: vscode.ProgressLocation.Notification,
title: "Compiling database upgrades",
title: 'Compiling database upgrades',
cancellable: true,
}, (progress, token) => qs.sendRequest(messages.compileUpgrade, params, token, progress));
}
@ -197,7 +197,7 @@ async function runDatabaseUpgrade(
return helpers.withProgress({
location: vscode.ProgressLocation.Notification,
title: "Running database upgrades",
title: 'Running database upgrades',
cancellable: true,
}, (progress, token) => qs.sendRequest(messages.runUpgrade, params, token, progress));
}

Просмотреть файл

@ -103,7 +103,7 @@ export class PathTable extends React.Component<PathTableProps, PathTableState> {
for (const part of parts) {
if (typeof part === "string") {
if (typeof part === 'string') {
result.push(<span>{part} </span>);
} else {
const renderedLocation = renderSarifLocationWithText(part.text, relatedLocationsById[part.dest],
@ -149,7 +149,7 @@ export class PathTable extends React.Component<PathTableProps, PathTableState> {
let shortLocation, longLocation: string;
switch (parsedLoc.t) {
case 'NoLocation':
return renderNonLocation("[no location]", parsedLoc.hint);
return renderNonLocation('[no location]', parsedLoc.hint);
case LocationStyle.WholeFile:
shortLocation = `${path.basename(parsedLoc.userVisibleFile)}`;
longLocation = `${parsedLoc.userVisibleFile}`;

Просмотреть файл

@ -1,4 +1,4 @@
import * as React from "react";
import * as React from 'react';
/**
* These icons come from https://github.com/microsoft/vscode-icons

Просмотреть файл

@ -1,9 +1,9 @@
import * as React from "react";
import { renderLocation, ResultTableProps, zebraStripe, className, nextSortDirection } from "./result-table-utils";
import { vscode } from "./results";
import { ResultValue } from "../adapt";
import { SortDirection, RAW_RESULTS_LIMIT, RawResultsSortState } from "../interface-types";
import { RawTableResultSet } from "../interface-utils";
import * as React from 'react';
import { renderLocation, ResultTableProps, zebraStripe, className, nextSortDirection } from './result-table-utils';
import { vscode } from './results';
import { ResultValue } from '../adapt';
import { SortDirection, RAW_RESULTS_LIMIT, RawResultsSortState } from '../interface-types';
import { RawTableResultSet } from '../interface-utils';
export type RawTableProps = ResultTableProps & {
resultSet: RawTableResultSet;
@ -58,7 +58,7 @@ export class RawTable extends React.Component<RawTableProps, {}> {
...resultSet.schema.columns.map((col, index) => {
const displayName = col.name || `[${index}]`;
const sortDirection = this.props.sortState && index === this.props.sortState.columnIndex ? this.props.sortState.sortDirection : undefined;
return <th className={"sort-" + (sortDirection !== undefined ? SortDirection[sortDirection] : "none")} key={index} onClick={() => this.toggleSortStateForColumn(index)}><b>{displayName}</b></th>;
return <th className={'sort-' + (sortDirection !== undefined ? SortDirection[sortDirection] : 'none')} key={index} onClick={() => this.toggleSortStateForColumn(index)}><b>{displayName}</b></th>;
})
]
}

Просмотреть файл

@ -31,7 +31,7 @@ interface ResultTablesState {
selectedPage: string; // stringified selected page
}
const UPDATING_RESULTS_TEXT_CLASS_NAME = "vscode-codeql__result-tables-updating-text";
const UPDATING_RESULTS_TEXT_CLASS_NAME = 'vscode-codeql__result-tables-updating-text';
function getResultCount(resultSet: ResultSet): number {
switch (resultSet.t) {

Просмотреть файл

@ -336,4 +336,4 @@ Rdom.render(
document.getElementById('root')
);
vscode.postMessage({ t: "resultViewLoaded" });
vscode.postMessage({ t: 'resultViewLoaded' });

Просмотреть файл

@ -5,31 +5,31 @@ import { encodeSourceArchiveUri, ArchiveFileSystemProvider, decodeSourceArchiveU
import { FileType, FileSystemError } from 'vscode';
describe('archive-filesystem-provider', () => {
it("reads empty file correctly", async () => {
it('reads empty file correctly', async () => {
const archiveProvider = new ArchiveFileSystemProvider();
const uri = encodeSourceArchiveUri({
sourceArchiveZipPath: path.resolve(__dirname, "data/archive-filesystem-provider-test/single_file.zip"),
pathWithinSourceArchive: "/aFileName.txt"
sourceArchiveZipPath: path.resolve(__dirname, 'data/archive-filesystem-provider-test/single_file.zip'),
pathWithinSourceArchive: '/aFileName.txt'
});
const data = await archiveProvider.readFile(uri);
expect(data.length).to.equal(0);
});
it("read non-empty file correctly", async () => {
it('read non-empty file correctly', async () => {
const archiveProvider = new ArchiveFileSystemProvider();
const uri = encodeSourceArchiveUri({
sourceArchiveZipPath: path.resolve(__dirname, "data/archive-filesystem-provider-test/zip_with_folder.zip"),
pathWithinSourceArchive: "folder1/textFile.txt"
sourceArchiveZipPath: path.resolve(__dirname, 'data/archive-filesystem-provider-test/zip_with_folder.zip'),
pathWithinSourceArchive: 'folder1/textFile.txt'
});
const data = await archiveProvider.readFile(uri);
expect(Buffer.from(data).toString('utf8')).to.be.equal('I am a text\n');
});
it("read a directory", async () => {
it('read a directory', async () => {
const archiveProvider = new ArchiveFileSystemProvider();
const uri = encodeSourceArchiveUri({
sourceArchiveZipPath: path.resolve(__dirname, "data/archive-filesystem-provider-test/zip_with_folder.zip"),
pathWithinSourceArchive: "folder1"
sourceArchiveZipPath: path.resolve(__dirname, 'data/archive-filesystem-provider-test/zip_with_folder.zip'),
pathWithinSourceArchive: 'folder1'
});
const files = await archiveProvider.readDirectory(uri);
expect(files).to.be.deep.equal([
@ -42,8 +42,8 @@ describe('archive-filesystem-provider', () => {
it('should handle a missing directory', async () => {
const archiveProvider = new ArchiveFileSystemProvider();
const uri = encodeSourceArchiveUri({
sourceArchiveZipPath: path.resolve(__dirname, "data/archive-filesystem-provider-test/zip_with_folder.zip"),
pathWithinSourceArchive: "folder1/not-here"
sourceArchiveZipPath: path.resolve(__dirname, 'data/archive-filesystem-provider-test/zip_with_folder.zip'),
pathWithinSourceArchive: 'folder1/not-here'
});
try {
await archiveProvider.readDirectory(uri);
@ -56,8 +56,8 @@ describe('archive-filesystem-provider', () => {
it('should handle a missing file', async () => {
const archiveProvider = new ArchiveFileSystemProvider();
const uri = encodeSourceArchiveUri({
sourceArchiveZipPath: path.resolve(__dirname, "data/archive-filesystem-provider-test/zip_with_folder.zip"),
pathWithinSourceArchive: "folder1/not-here"
sourceArchiveZipPath: path.resolve(__dirname, 'data/archive-filesystem-provider-test/zip_with_folder.zip'),
pathWithinSourceArchive: 'folder1/not-here'
});
try {
await archiveProvider.readFile(uri);
@ -70,8 +70,8 @@ describe('archive-filesystem-provider', () => {
it('should handle reading a file as a directory', async () => {
const archiveProvider = new ArchiveFileSystemProvider();
const uri = encodeSourceArchiveUri({
sourceArchiveZipPath: path.resolve(__dirname, "data/archive-filesystem-provider-test/zip_with_folder.zip"),
pathWithinSourceArchive: "folder1/textFile.txt"
sourceArchiveZipPath: path.resolve(__dirname, 'data/archive-filesystem-provider-test/zip_with_folder.zip'),
pathWithinSourceArchive: 'folder1/textFile.txt'
});
try {
await archiveProvider.readDirectory(uri);
@ -84,8 +84,8 @@ describe('archive-filesystem-provider', () => {
it('should handle reading a directory as a file', async () => {
const archiveProvider = new ArchiveFileSystemProvider();
const uri = encodeSourceArchiveUri({
sourceArchiveZipPath: path.resolve(__dirname, "data/archive-filesystem-provider-test/zip_with_folder.zip"),
pathWithinSourceArchive: "folder1/folder2"
sourceArchiveZipPath: path.resolve(__dirname, 'data/archive-filesystem-provider-test/zip_with_folder.zip'),
pathWithinSourceArchive: 'folder1/folder2'
});
try {
await archiveProvider.readFile(uri);
@ -95,11 +95,11 @@ describe('archive-filesystem-provider', () => {
}
});
it("read a nested directory", async () => {
it('read a nested directory', async () => {
const archiveProvider = new ArchiveFileSystemProvider();
const uri = encodeSourceArchiveUri({
sourceArchiveZipPath: path.resolve(__dirname, "data/archive-filesystem-provider-test/zip_with_folder.zip"),
pathWithinSourceArchive: "folder1/folder2"
sourceArchiveZipPath: path.resolve(__dirname, 'data/archive-filesystem-provider-test/zip_with_folder.zip'),
pathWithinSourceArchive: 'folder1/folder2'
});
const files = await archiveProvider.readDirectory(uri);
expect(files).to.be.deep.equal([
@ -112,15 +112,15 @@ describe('source archive uri encoding', function() {
const testCases: { name: string; input: ZipFileReference }[] = [
{
name: 'mixed case and unicode',
input: { sourceArchiveZipPath: "/I-\u2665-codeql.zip", pathWithinSourceArchive: "/foo/bar" }
input: { sourceArchiveZipPath: '/I-\u2665-codeql.zip', pathWithinSourceArchive: '/foo/bar' }
},
{
name: 'Windows path',
input: { sourceArchiveZipPath: "C:/Users/My Name/folder/src.zip", pathWithinSourceArchive: "/foo/bar.ext" }
input: { sourceArchiveZipPath: 'C:/Users/My Name/folder/src.zip', pathWithinSourceArchive: '/foo/bar.ext' }
},
{
name: 'Unix path',
input: { sourceArchiveZipPath: "/home/folder/src.zip", pathWithinSourceArchive: "/foo/bar.ext" }
input: { sourceArchiveZipPath: '/home/folder/src.zip', pathWithinSourceArchive: '/foo/bar.ext' }
}
];
for (const testCase of testCases) {

Просмотреть файл

@ -1,131 +1,131 @@
import "vscode-test";
import "mocha";
import * as chaiAsPromised from "chai-as-promised";
import * as sinon from "sinon";
import 'vscode-test';
import 'mocha';
import * as chaiAsPromised from 'chai-as-promised';
import * as sinon from 'sinon';
// import * as sinonChai from 'sinon-chai';
import * as path from "path";
import * as fs from "fs-extra";
import * as tmp from "tmp";
import * as chai from "chai";
import { window } from "vscode";
import * as path from 'path';
import * as fs from 'fs-extra';
import * as tmp from 'tmp';
import * as chai from 'chai';
import { window } from 'vscode';
import {
convertToDatabaseUrl,
looksLikeLgtmUrl,
findDirWithFile,
} from "../../databaseFetcher";
} from '../../databaseFetcher';
chai.use(chaiAsPromised);
const expect = chai.expect;
describe("databaseFetcher", () => {
describe("convertToDatabaseUrl", () => {
describe('databaseFetcher', () => {
describe('convertToDatabaseUrl', () => {
let quickPickSpy: sinon.SinonStub;
beforeEach(() => {
quickPickSpy = sinon.stub(window, "showQuickPick");
quickPickSpy = sinon.stub(window, 'showQuickPick');
});
afterEach(() => {
(window.showQuickPick as sinon.SinonStub).restore();
});
it("should convert a project url to a database url", async () => {
quickPickSpy.returns("javascript" as any);
const lgtmUrl = "https://lgtm.com/projects/g/github/codeql";
it('should convert a project url to a database url', async () => {
quickPickSpy.returns('javascript' as any);
const lgtmUrl = 'https://lgtm.com/projects/g/github/codeql';
const dbUrl = await convertToDatabaseUrl(lgtmUrl);
expect(dbUrl).to.equal(
"https://lgtm.com/api/v1.0/snapshots/1506465042581/javascript"
'https://lgtm.com/api/v1.0/snapshots/1506465042581/javascript'
);
expect(quickPickSpy.firstCall.args[0]).to.contain("javascript");
expect(quickPickSpy.firstCall.args[0]).to.contain("python");
expect(quickPickSpy.firstCall.args[0]).to.contain('javascript');
expect(quickPickSpy.firstCall.args[0]).to.contain('python');
});
it("should convert a project url to a database url with extra path segments", async () => {
quickPickSpy.returns("python" as any);
it('should convert a project url to a database url with extra path segments', async () => {
quickPickSpy.returns('python' as any);
const lgtmUrl =
"https://lgtm.com/projects/g/github/codeql/subpage/subpage2?query=xxx";
'https://lgtm.com/projects/g/github/codeql/subpage/subpage2?query=xxx';
const dbUrl = await convertToDatabaseUrl(lgtmUrl);
expect(dbUrl).to.equal(
"https://lgtm.com/api/v1.0/snapshots/1506465042581/python"
'https://lgtm.com/api/v1.0/snapshots/1506465042581/python'
);
});
it("should fail on a nonexistant prohect", async () => {
quickPickSpy.returns("javascript" as any);
const lgtmUrl = "https://lgtm.com/projects/g/github/hucairz";
it('should fail on a nonexistant prohect', async () => {
quickPickSpy.returns('javascript' as any);
const lgtmUrl = 'https://lgtm.com/projects/g/github/hucairz';
expect(convertToDatabaseUrl(lgtmUrl)).to.rejectedWith(/Invalid LGTM URL/);
});
});
describe("looksLikeLgtmUrl", () => {
it("should handle invalid urls", () => {
expect(looksLikeLgtmUrl("")).to.be.false;
expect(looksLikeLgtmUrl("http://lgtm.com/projects/g/github/codeql")).to.be
describe('looksLikeLgtmUrl', () => {
it('should handle invalid urls', () => {
expect(looksLikeLgtmUrl('')).to.be.false;
expect(looksLikeLgtmUrl('http://lgtm.com/projects/g/github/codeql')).to.be
.false;
expect(looksLikeLgtmUrl("https://ww.lgtm.com/projects/g/github/codeql"))
expect(looksLikeLgtmUrl('https://ww.lgtm.com/projects/g/github/codeql'))
.to.be.false;
expect(looksLikeLgtmUrl("https://ww.lgtm.com/projects/g/github")).to.be
expect(looksLikeLgtmUrl('https://ww.lgtm.com/projects/g/github')).to.be
.false;
});
it("should handle valid urls", () => {
expect(looksLikeLgtmUrl("https://lgtm.com/projects/g/github/codeql")).to
it('should handle valid urls', () => {
expect(looksLikeLgtmUrl('https://lgtm.com/projects/g/github/codeql')).to
.be.true;
expect(looksLikeLgtmUrl("https://www.lgtm.com/projects/g/github/codeql"))
expect(looksLikeLgtmUrl('https://www.lgtm.com/projects/g/github/codeql'))
.to.be.true;
expect(
looksLikeLgtmUrl("https://lgtm.com/projects/g/github/codeql/sub/pages")
looksLikeLgtmUrl('https://lgtm.com/projects/g/github/codeql/sub/pages')
).to.be.true;
expect(
looksLikeLgtmUrl(
"https://lgtm.com/projects/g/github/codeql/sub/pages?query=string"
'https://lgtm.com/projects/g/github/codeql/sub/pages?query=string'
)
).to.be.true;
});
});
describe("findDirWithFile", () => {
describe('findDirWithFile', () => {
let dir: tmp.DirResult;
beforeEach(() => {
dir = tmp.dirSync({ unsafeCleanup: true });
createFile("a");
createFile("b");
createFile("c");
createFile('a');
createFile('b');
createFile('c');
createDir("dir1");
createFile("dir1", "d");
createFile("dir1", "e");
createFile("dir1", "f");
createDir('dir1');
createFile('dir1', 'd');
createFile('dir1', 'e');
createFile('dir1', 'f');
createDir("dir2");
createFile("dir2", "g");
createFile("dir2", "h");
createFile("dir2", "i");
createDir('dir2');
createFile('dir2', 'g');
createFile('dir2', 'h');
createFile('dir2', 'i');
createDir("dir2", "dir3");
createFile("dir2", "dir3", "j");
createFile("dir2", "dir3", "k");
createFile("dir2", "dir3", "l");
createDir('dir2', 'dir3');
createFile('dir2', 'dir3', 'j');
createFile('dir2', 'dir3', 'k');
createFile('dir2', 'dir3', 'l');
});
it("should find files", async () => {
expect(await findDirWithFile(dir.name, "k")).to.equal(
path.join(dir.name, "dir2", "dir3")
it('should find files', async () => {
expect(await findDirWithFile(dir.name, 'k')).to.equal(
path.join(dir.name, 'dir2', 'dir3')
);
expect(await findDirWithFile(dir.name, "h")).to.equal(
path.join(dir.name, "dir2")
expect(await findDirWithFile(dir.name, 'h')).to.equal(
path.join(dir.name, 'dir2')
);
expect(await findDirWithFile(dir.name, "z", "a")).to.equal(dir.name);
expect(await findDirWithFile(dir.name, 'z', 'a')).to.equal(dir.name);
// there's some slight indeterminism when more than one name exists
// but in general, this will find files in the current directory before
// finding files in sub-dirs
expect(await findDirWithFile(dir.name, "k", "a")).to.equal(dir.name);
expect(await findDirWithFile(dir.name, 'k', 'a')).to.equal(dir.name);
});
it("should not find files", async () => {
expect(await findDirWithFile(dir.name, "x", "y", "z")).to.be.undefined;
it('should not find files', async () => {
expect(await findDirWithFile(dir.name, 'x', 'y', 'z')).to.be.undefined;
});

Просмотреть файл

@ -1,71 +1,71 @@
import * as chai from "chai";
import * as path from "path";
import * as fetch from "node-fetch";
import "chai/register-should";
import * as semver from "semver";
import * as sinonChai from "sinon-chai";
import * as sinon from "sinon";
import * as pq from "proxyquire";
import "mocha";
import * as chai from 'chai';
import * as path from 'path';
import * as fetch from 'node-fetch';
import 'chai/register-should';
import * as semver from 'semver';
import * as sinonChai from 'sinon-chai';
import * as sinon from 'sinon';
import * as pq from 'proxyquire';
import 'mocha';
import { GithubRelease, GithubReleaseAsset, ReleasesApiConsumer } from "../../distribution";
import { GithubRelease, GithubReleaseAsset, ReleasesApiConsumer } from '../../distribution';
const proxyquire = pq.noPreserveCache();
chai.use(sinonChai);
const expect = chai.expect;
describe("Releases API consumer", () => {
const owner = "someowner";
const repo = "somerepo";
const unconstrainedVersionRange = new semver.Range("*");
describe('Releases API consumer', () => {
const owner = 'someowner';
const repo = 'somerepo';
const unconstrainedVersionRange = new semver.Range('*');
describe("picking the latest release", () => {
describe('picking the latest release', () => {
const sampleReleaseResponse: GithubRelease[] = [
{
"assets": [],
"created_at": "2019-09-01T00:00:00Z",
"id": 1,
"name": "",
"prerelease": false,
"tag_name": "v2.1.0"
'assets': [],
'created_at': '2019-09-01T00:00:00Z',
'id': 1,
'name': '',
'prerelease': false,
'tag_name': 'v2.1.0'
},
{
"assets": [],
"created_at": "2019-08-10T00:00:00Z",
"id": 2,
"name": "",
"prerelease": false,
"tag_name": "v3.1.1"
'assets': [],
'created_at': '2019-08-10T00:00:00Z',
'id': 2,
'name': '',
'prerelease': false,
'tag_name': 'v3.1.1'
},
{
"assets": [{
'assets': [{
id: 1,
name: "exampleAsset.txt",
name: 'exampleAsset.txt',
size: 1
}],
"created_at": "2019-09-05T00:00:00Z",
"id": 3,
"name": "",
"prerelease": false,
"tag_name": "v2.0.0"
'created_at': '2019-09-05T00:00:00Z',
'id': 3,
'name': '',
'prerelease': false,
'tag_name': 'v2.0.0'
},
{
"assets": [],
"created_at": "2019-08-11T00:00:00Z",
"id": 4,
"name": "",
"prerelease": true,
"tag_name": "v3.1.2-pre-1.1"
'assets': [],
'created_at': '2019-08-11T00:00:00Z',
'id': 4,
'name': '',
'prerelease': true,
'tag_name': 'v3.1.2-pre-1.1'
},
// Release ID 5 is older than release ID 4 but its version has a higher precedence, so release
// ID 5 should be picked over release ID 4.
{
"assets": [],
"created_at": "2019-08-09T00:00:00Z",
"id": 5,
"name": "",
"prerelease": true,
"tag_name": "v3.1.2-pre-2.0"
'assets': [],
'created_at': '2019-08-09T00:00:00Z',
'id': 5,
'name': '',
'prerelease': true,
'tag_name': 'v3.1.2-pre-2.0'
},
];
@ -78,50 +78,50 @@ describe("Releases API consumer", () => {
}
}
it("picked release has version with the highest precedence", async () => {
it('picked release has version with the highest precedence', async () => {
const consumer = new MockReleasesApiConsumer(owner, repo);
const latestRelease = await consumer.getLatestRelease(unconstrainedVersionRange);
expect(latestRelease.id).to.equal(2);
});
it("version of picked release is within the version range", async () => {
it('version of picked release is within the version range', async () => {
const consumer = new MockReleasesApiConsumer(owner, repo);
const latestRelease = await consumer.getLatestRelease(new semver.Range("2.*.*"));
const latestRelease = await consumer.getLatestRelease(new semver.Range('2.*.*'));
expect(latestRelease.id).to.equal(1);
});
it("fails if none of the releases are within the version range", async () => {
it('fails if none of the releases are within the version range', async () => {
const consumer = new MockReleasesApiConsumer(owner, repo);
await chai.expect(
consumer.getLatestRelease(new semver.Range("5.*.*"))
consumer.getLatestRelease(new semver.Range('5.*.*'))
).to.be.rejectedWith(Error);
});
it("picked release passes additional compatibility test if an additional compatibility test is specified", async () => {
it('picked release passes additional compatibility test if an additional compatibility test is specified', async () => {
const consumer = new MockReleasesApiConsumer(owner, repo);
const latestRelease = await consumer.getLatestRelease(
new semver.Range("2.*.*"),
new semver.Range('2.*.*'),
true,
release => release.assets.some(asset => asset.name === "exampleAsset.txt")
release => release.assets.some(asset => asset.name === 'exampleAsset.txt')
);
expect(latestRelease.id).to.equal(3);
});
it("fails if none of the releases pass the additional compatibility test", async () => {
it('fails if none of the releases pass the additional compatibility test', async () => {
const consumer = new MockReleasesApiConsumer(owner, repo);
await chai.expect(consumer.getLatestRelease(
new semver.Range("2.*.*"),
new semver.Range('2.*.*'),
true,
release => release.assets.some(asset => asset.name === "otherExampleAsset.txt")
release => release.assets.some(asset => asset.name === 'otherExampleAsset.txt')
)).to.be.rejectedWith(Error);
});
it("picked release is the most recent prerelease when includePrereleases is set", async () => {
it('picked release is the most recent prerelease when includePrereleases is set', async () => {
const consumer = new MockReleasesApiConsumer(owner, repo);
const latestRelease = await consumer.getLatestRelease(unconstrainedVersionRange, true);
@ -129,17 +129,17 @@ describe("Releases API consumer", () => {
});
});
it("gets correct assets for a release", async () => {
it('gets correct assets for a release', async () => {
const expectedAssets: GithubReleaseAsset[] = [
{
"id": 1,
"name": "firstAsset",
"size": 11
'id': 1,
'name': 'firstAsset',
'size': 11
},
{
"id": 2,
"name": "secondAsset",
"size": 12
'id': 2,
'name': 'secondAsset',
'size': 12
}
];
@ -147,12 +147,12 @@ describe("Releases API consumer", () => {
protected async makeApiCall(apiPath: string): Promise<fetch.Response> {
if (apiPath === `/repos/${owner}/${repo}/releases`) {
const responseBody: GithubRelease[] = [{
"assets": expectedAssets,
"created_at": "2019-09-01T00:00:00Z",
"id": 1,
"name": "Release 1",
"prerelease": false,
"tag_name": "v2.0.0"
'assets': expectedAssets,
'created_at': '2019-09-01T00:00:00Z',
'id': 1,
'name': 'Release 1',
'prerelease': false,
'tag_name': 'v2.0.0'
}];
return Promise.resolve(new fetch.Response(JSON.stringify(responseBody)));

Просмотреть файл

@ -1,9 +1,9 @@
import { expect } from "chai";
import "mocha";
import { ExtensionContext, Memento } from "vscode";
import { InvocationRateLimiter } from "../../helpers";
import { expect } from 'chai';
import 'mocha';
import { ExtensionContext, Memento } from 'vscode';
import { InvocationRateLimiter } from '../../helpers';
describe("Invocation rate limiter", () => {
describe('Invocation rate limiter', () => {
// 1 January 2020
let currentUnixTime = 1577836800;
@ -19,18 +19,18 @@ describe("Invocation rate limiter", () => {
return new InvocationRateLimiter(new MockExtensionContext(), funcIdentifier, func, s => createDate(s));
}
it("initially invokes function", async () => {
it('initially invokes function', async () => {
let numTimesFuncCalled = 0;
const invocationRateLimiter = createInvocationRateLimiter("funcid", async () => {
const invocationRateLimiter = createInvocationRateLimiter('funcid', async () => {
numTimesFuncCalled++;
});
await invocationRateLimiter.invokeFunctionIfIntervalElapsed(100);
expect(numTimesFuncCalled).to.equal(1);
});
it("doesn't invoke function again if no time has passed", async () => {
it('doesn\'t invoke function again if no time has passed', async () => {
let numTimesFuncCalled = 0;
const invocationRateLimiter = createInvocationRateLimiter("funcid", async () => {
const invocationRateLimiter = createInvocationRateLimiter('funcid', async () => {
numTimesFuncCalled++;
});
await invocationRateLimiter.invokeFunctionIfIntervalElapsed(100);
@ -38,9 +38,9 @@ describe("Invocation rate limiter", () => {
expect(numTimesFuncCalled).to.equal(1);
});
it("doesn't invoke function again if requested time since last invocation hasn't passed", async () => {
it('doesn\'t invoke function again if requested time since last invocation hasn\'t passed', async () => {
let numTimesFuncCalled = 0;
const invocationRateLimiter = createInvocationRateLimiter("funcid", async () => {
const invocationRateLimiter = createInvocationRateLimiter('funcid', async () => {
numTimesFuncCalled++;
});
await invocationRateLimiter.invokeFunctionIfIntervalElapsed(100);
@ -49,9 +49,9 @@ describe("Invocation rate limiter", () => {
expect(numTimesFuncCalled).to.equal(1);
});
it("invokes function again immediately if requested time since last invocation is 0 seconds", async () => {
it('invokes function again immediately if requested time since last invocation is 0 seconds', async () => {
let numTimesFuncCalled = 0;
const invocationRateLimiter = createInvocationRateLimiter("funcid", async () => {
const invocationRateLimiter = createInvocationRateLimiter('funcid', async () => {
numTimesFuncCalled++;
});
await invocationRateLimiter.invokeFunctionIfIntervalElapsed(0);
@ -59,9 +59,9 @@ describe("Invocation rate limiter", () => {
expect(numTimesFuncCalled).to.equal(2);
});
it("invokes function again after requested time since last invocation has elapsed", async () => {
it('invokes function again after requested time since last invocation has elapsed', async () => {
let numTimesFuncCalled = 0;
const invocationRateLimiter = createInvocationRateLimiter("funcid", async () => {
const invocationRateLimiter = createInvocationRateLimiter('funcid', async () => {
numTimesFuncCalled++;
});
await invocationRateLimiter.invokeFunctionIfIntervalElapsed(1);
@ -70,13 +70,13 @@ describe("Invocation rate limiter", () => {
expect(numTimesFuncCalled).to.equal(2);
});
it("invokes functions with different rate limiters", async () => {
it('invokes functions with different rate limiters', async () => {
let numTimesFuncACalled = 0;
const invocationRateLimiterA = createInvocationRateLimiter("funcid", async () => {
const invocationRateLimiterA = createInvocationRateLimiter('funcid', async () => {
numTimesFuncACalled++;
});
let numTimesFuncBCalled = 0;
const invocationRateLimiterB = createInvocationRateLimiter("funcid", async () => {
const invocationRateLimiterB = createInvocationRateLimiter('funcid', async () => {
numTimesFuncBCalled++;
});
await invocationRateLimiterA.invokeFunctionIfIntervalElapsed(100);
@ -90,13 +90,13 @@ class MockExtensionContext implements ExtensionContext {
subscriptions: { dispose(): unknown }[] = [];
workspaceState: Memento = new MockMemento();
globalState: Memento = new MockMemento();
extensionPath = "";
extensionPath = '';
asAbsolutePath(_relativePath: string): string {
throw new Error("Method not implemented.");
throw new Error('Method not implemented.');
}
storagePath = "";
globalStoragePath = "";
logPath = "";
storagePath = '';
globalStoragePath = '';
logPath = '';
}
class MockMemento implements Memento {

Просмотреть файл

@ -1,11 +1,11 @@
import * as chai from "chai";
import "mocha";
import * as vscode from "vscode";
import * as sinon from "sinon";
import * as chai from 'chai';
import 'mocha';
import * as vscode from 'vscode';
import * as sinon from 'sinon';
// import * as sinonChai from 'sinon-chai';
import * as chaiAsPromised from "chai-as-promised";
import { logger } from "../../logging";
import { QueryHistoryManager } from "../../query-history";
import * as chaiAsPromised from 'chai-as-promised';
import { logger } from '../../logging';
import { QueryHistoryManager } from '../../query-history';
chai.use(chaiAsPromised);
const expect = chai.expect;
@ -14,7 +14,7 @@ const expect = chai.expect;
describe('query-history', () => {
describe("tryOpenExternalFile", () => {
describe('tryOpenExternalFile', () => {
let showTextDocumentSpy: sinon.SinonStub;
let showInformationMessageSpy: sinon.SinonStub;
let executeCommandSpy: sinon.SinonStub;
@ -23,13 +23,13 @@ describe('query-history', () => {
let tryOpenExternalFile: Function;
beforeEach(() => {
showTextDocumentSpy = sinon.stub(vscode.window, "showTextDocument");
showTextDocumentSpy = sinon.stub(vscode.window, 'showTextDocument');
showInformationMessageSpy = sinon.stub(
vscode.window,
"showInformationMessage"
'showInformationMessage'
);
executeCommandSpy = sinon.stub(vscode.commands, "executeCommand");
logSpy = sinon.stub(logger, "log");
executeCommandSpy = sinon.stub(vscode.commands, 'executeCommand');
logSpy = sinon.stub(logger, 'log');
tryOpenExternalFile = (QueryHistoryManager.prototype as any).tryOpenExternalFile;
logSpy;
executeCommandSpy;
@ -42,7 +42,7 @@ describe('query-history', () => {
(vscode.window.showInformationMessage as sinon.SinonStub).restore();
});
it("should open an external file", async () => {
it('should open an external file', async () => {
await tryOpenExternalFile('xxx');
expect(showTextDocumentSpy).to.have.been.calledOnceWith(
vscode.Uri.file('xxx')
@ -51,30 +51,30 @@ describe('query-history', () => {
});
[
"too large to open",
"Files above 50MB cannot be synchronized with extensions",
'too large to open',
'Files above 50MB cannot be synchronized with extensions',
].forEach(msg => {
it(`should fail to open a file because "${msg}" and open externally`, async () => {
showTextDocumentSpy.throws(new Error(msg));
showInformationMessageSpy.returns({ title: "Yes" });
showInformationMessageSpy.returns({ title: 'Yes' });
await tryOpenExternalFile("xxx");
const uri = vscode.Uri.file("xxx");
await tryOpenExternalFile('xxx');
const uri = vscode.Uri.file('xxx');
expect(showTextDocumentSpy).to.have.been.calledOnceWith(
uri
);
expect(executeCommandSpy).to.have.been.calledOnceWith(
"revealFileInOS",
'revealFileInOS',
uri
);
});
it(`should fail to open a file because "${msg}" and NOT open externally`, async () => {
showTextDocumentSpy.throws(new Error(msg));
showInformationMessageSpy.returns({ title: "No" });
showInformationMessageSpy.returns({ title: 'No' });
await tryOpenExternalFile("xxx");
const uri = vscode.Uri.file("xxx");
await tryOpenExternalFile('xxx');
const uri = vscode.Uri.file('xxx');
expect(showTextDocumentSpy).to.have.been.calledOnceWith(uri);
expect(showInformationMessageSpy).to.have.been.called;
expect(executeCommandSpy).not.to.have.been.called;

Просмотреть файл

@ -1,39 +1,39 @@
import 'mocha';
import { expect } from "chai";
import { expect } from 'chai';
import { parseSarifPlainTextMessage } from '../../sarif-utils';
describe('parsing sarif', () => {
it('should be able to parse a simple message from the spec', async function() {
const message = "Tainted data was used. The data came from [here](3).";
const message = 'Tainted data was used. The data came from [here](3).';
const results = parseSarifPlainTextMessage(message);
expect(results).to.deep.equal([
"Tainted data was used. The data came from ",
{ dest: 3, text: "here" }, "."
'Tainted data was used. The data came from ',
{ dest: 3, text: 'here' }, '.'
]);
});
it('should be able to parse a complex message from the spec', async function() {
const message = "Prohibited term used in [para\\[0\\]\\\\spans\\[2\\]](1).";
const message = 'Prohibited term used in [para\\[0\\]\\\\spans\\[2\\]](1).';
const results = parseSarifPlainTextMessage(message);
expect(results).to.deep.equal([
"Prohibited term used in ",
{ dest: 1, text: "para[0]\\spans[2]" }, "."
'Prohibited term used in ',
{ dest: 1, text: 'para[0]\\spans[2]' }, '.'
]);
});
it('should be able to parse a broken complex message from the spec', async function() {
const message = "Prohibited term used in [para\\[0\\]\\\\spans\\[2\\](1).";
const message = 'Prohibited term used in [para\\[0\\]\\\\spans\\[2\\](1).';
const results = parseSarifPlainTextMessage(message);
expect(results).to.deep.equal([
"Prohibited term used in [para[0]\\spans[2](1)."
'Prohibited term used in [para[0]\\spans[2](1).'
]);
});
it('should be able to parse a message with extra escaping the spec', async function() {
const message = "Tainted data was used. The data came from \\[here](3).";
const message = 'Tainted data was used. The data came from \\[here](3).';
const results = parseSarifPlainTextMessage(message);
expect(results).to.deep.equal([
"Tainted data was used. The data came from [here](3)."
'Tainted data was used. The data came from [here](3).'
]);
});
});

Просмотреть файл

@ -1,7 +1,7 @@
import { expect } from "chai";
import * as path from "path";
import * as tmp from "tmp";
import { window, ViewColumn, Uri } from "vscode";
import { expect } from 'chai';
import * as path from 'path';
import * as tmp from 'tmp';
import { window, ViewColumn, Uri } from 'vscode';
import { fileUriToWebviewUri, webviewUriToFileUri } from '../../interface';
describe('webview uri conversion', function() {
@ -27,7 +27,7 @@ describe('webview uri conversion', function() {
});
// CSP allowing nothing, to prevent warnings.
const html = `<html><head><meta http-equiv="Content-Security-Policy" content="default-src 'none';"></head></html>`;
const html = '<html><head><meta http-equiv="Content-Security-Policy" content="default-src \'none\';"></head></html>';
panel.webview.html = html;
return {
fileUriOnDisk,
@ -42,7 +42,7 @@ describe('webview uri conversion', function() {
expect(reconstructedFileUri.toString(true)).to.equal(fileUriOnDisk.toString(true));
});
it("does not double-encode # in URIs", function() {
it('does not double-encode # in URIs', function() {
const { fileUriOnDisk, panel } = setupWebview('#');
const webviewUri = fileUriToWebviewUri(panel, fileUriOnDisk);
const parsedUri = Uri.parse(webviewUri);

Просмотреть файл

@ -13,7 +13,7 @@ import * as cli from '../../src/cli';
import { ProgressReporter, Logger } from '../../src/logging';
declare module "url" {
declare module 'url' {
export function pathToFileURL(urlStr: string): Url;
}
@ -63,21 +63,21 @@ const queryTestCases: QueryTestCase[] = [
{
queryPath: path.join(__dirname, '../data/query.ql'),
expectedResultSets: {
'#select': [[42, 3.14159, "hello world", true]]
'#select': [[42, 3.14159, 'hello world', true]]
}
},
{
queryPath: path.join(__dirname, '../data/multiple-result-sets.ql'),
expectedResultSets: {
'edges': [[1, 2], [2, 3]],
'#select': [["s"]]
'#select': [['s']]
}
}
];
describe('using the query server', function() {
before(function() {
if (process.env["CODEQL_PATH"] === undefined) {
if (process.env['CODEQL_PATH'] === undefined) {
console.log('The environment variable CODEQL_PATH is not set. The query server tests, which require the CodeQL CLI, will be skipped.');
this.skip();
}
@ -87,7 +87,7 @@ describe('using the query server', function() {
// ensure they are all written with standard anonymous functions.
this.timeout(10000);
const codeQlPath = process.env["CODEQL_PATH"]!;
const codeQlPath = process.env['CODEQL_PATH']!;
let qs: qsClient.QueryServerClient;
let cliServer: cli.CodeQLCliServer;
const queryServerStarted = new Checkpoint<void>();