Skip to content

Commit

Permalink
Merge pull request #3163 from github/koesie10/queries-panel-no-cli-se…
Browse files Browse the repository at this point in the history
…rver

Do not use the CLI server to determine query pack language
  • Loading branch information
koesie10 authored Jan 3, 2024
2 parents 870874d + ed4b296 commit 1ad20fa
Show file tree
Hide file tree
Showing 15 changed files with 418 additions and 174 deletions.
10 changes: 10 additions & 0 deletions extensions/ql-vscode/scripts/generate-schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,16 @@ import { format, resolveConfig } from "prettier";
const extensionDirectory = resolve(__dirname, "..");

const schemas = [
{
path: join(extensionDirectory, "src", "packaging", "qlpack-file.ts"),
type: "QlPackFile",
schemaPath: join(
extensionDirectory,
"src",
"packaging",
"qlpack-file.schema.json",
),
},
{
path: join(
extensionDirectory,
Expand Down
23 changes: 0 additions & 23 deletions extensions/ql-vscode/src/codeql-cli/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -738,29 +738,6 @@ export class CodeQLCliServer implements Disposable {
);
}

/**
* Resolve the library path and dbscheme for a query.
* @param workspaces The current open workspaces
* @param queryPath The path to the query
*/
async resolveLibraryPath(
workspaces: string[],
queryPath: string,
silent = false,
): Promise<QuerySetup> {
const subcommandArgs = [
"--query",
queryPath,
...this.getAdditionalPacksArg(workspaces),
];
return await this.runJsonCodeQlCliCommand<QuerySetup>(
["resolve", "library-path"],
subcommandArgs,
"Resolving library paths",
{ silent },
);
}

/**
* Resolves the language for a query.
* @param queryUri The URI of the query
Expand Down
4 changes: 2 additions & 2 deletions extensions/ql-vscode/src/common/discovery.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import { DisposableObject } from "./disposable-object";
import { getErrorMessage } from "./helpers-pure";
import { Logger } from "./logging";
import { BaseLogger } from "./logging";

/**
* Base class for "discovery" operations, which scan the file system to find specific kinds of
Expand All @@ -13,7 +13,7 @@ export abstract class Discovery extends DisposableObject {

constructor(
protected readonly name: string,
private readonly logger: Logger,
protected readonly logger: BaseLogger,
) {
super();
}
Expand Down
26 changes: 26 additions & 0 deletions extensions/ql-vscode/src/common/qlpack-language.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
import { QueryLanguage } from "./query-language";
import { loadQlpackFile } from "../packaging/qlpack-file-loader";

/**
* @param qlpackPath The path to the `qlpack.yml` or `codeql-pack.yml` file.
* @return the language of the given qlpack file, or undefined if the file is
* not a valid qlpack file or does not contain exactly one language.
*/
export async function getQlPackLanguage(
qlpackPath: string,
): Promise<QueryLanguage | undefined> {
const qlPack = await loadQlpackFile(qlpackPath);
const dependencies = qlPack?.dependencies;
if (!dependencies) {
return;
}

const matchingLanguages = Object.values(QueryLanguage).filter(
(language) => `codeql/${language}-all` in dependencies,
);
if (matchingLanguages.length !== 1) {
return undefined;
}

return matchingLanguages[0];
}
6 changes: 1 addition & 5 deletions extensions/ql-vscode/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -800,11 +800,7 @@ async function activateWithInstalledDistribution(
);
ctx.subscriptions.push(databaseUI);

const queriesModule = QueriesModule.initialize(
app,
languageContext,
cliServer,
);
const queriesModule = QueriesModule.initialize(app, languageContext);

void extLogger.log("Initializing evaluator log viewer.");
const evalLogViewer = new EvalLogViewer();
Expand Down
25 changes: 6 additions & 19 deletions extensions/ql-vscode/src/local-queries/skeleton-query-wizard.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,16 +28,15 @@ import {
isCodespacesTemplate,
setQlPackLocation,
} from "../config";
import { lstat, pathExists, readFile } from "fs-extra";
import { lstat, pathExists } from "fs-extra";
import { askForLanguage } from "../codeql-cli/query-language";
import { showInformationMessageWithAction } from "../common/vscode/dialog";
import { redactableError } from "../common/errors";
import { App } from "../common/app";
import { QueryTreeViewItem } from "../queries-panel/query-tree-view-item";
import { containsPath, pathsEqual } from "../common/files";
import { getQlPackPath } from "../common/ql";
import { load } from "js-yaml";
import { QlPackFile } from "../packaging/qlpack-file";
import { getQlPackLanguage } from "../common/qlpack-language";

type QueryLanguagesToDatabaseMap = Record<string, string>;

Expand Down Expand Up @@ -253,24 +252,12 @@ export class SkeletonQueryWizard {
return undefined;
}

const qlPack = load(await readFile(qlPackPath, "utf8")) as
| QlPackFile
| undefined;
const dependencies = qlPack?.dependencies;
if (!dependencies || typeof dependencies !== "object") {
return;
}

const matchingLanguages = Object.values(QueryLanguage).filter(
(language) => `codeql/${language}-all` in dependencies,
);
if (matchingLanguages.length !== 1) {
return undefined;
const language = await getQlPackLanguage(qlPackPath);
if (language) {
this.qlPackStoragePath = matchingQueryPackPath;
}

this.qlPackStoragePath = matchingQueryPackPath;

return matchingLanguages[0];
return language;
}

private async chooseLanguage() {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,24 @@
"ExtensionPackMetadata": {
"type": "object",
"properties": {
"name": {
"type": ["string", "null"]
},
"version": {
"type": ["string", "null"]
},
"extensionTargets": {
"type": "object",
"additionalProperties": {
"type": "string"
}
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
]
},
"dataExtensions": {
"anyOf": [
Expand All @@ -21,35 +34,46 @@
},
{
"type": "string"
},
{
"type": "null"
}
]
},
"name": {
"type": "string"
},
"version": {
"type": "string"
},
"dependencies": {
"type": "object",
"additionalProperties": {
"type": "string"
}
"anyOf": [
{
"type": "object",
"additionalProperties": {
"type": "string"
}
},
{
"type": "null"
}
]
},
"dbscheme": {
"type": "string"
"type": ["string", "null"]
},
"library": {
"type": "boolean"
"type": ["boolean", "null"]
},
"defaultSuite": {
"type": "array",
"items": {
"$ref": "#/definitions/SuiteInstruction"
}
"anyOf": [
{
"type": "array",
"items": {
"$ref": "#/definitions/SuiteInstruction"
}
},
{
"type": "null"
}
]
},
"defaultSuiteFile": {
"type": "string"
"type": ["string", "null"]
}
},
"required": ["dataExtensions", "extensionTargets", "name", "version"]
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
import { QlPackFile } from "../packaging/qlpack-file";

export type ExtensionPackMetadata = QlPackFile & {
// Make both extensionTargets and dataExtensions required
// Make name, version, extensionTargets, and dataExtensions required
name: string;
version: string;
extensionTargets: Record<string, string>;
dataExtensions: string[] | string;
};
32 changes: 32 additions & 0 deletions extensions/ql-vscode/src/packaging/qlpack-file-loader.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import Ajv from "ajv";
import * as qlpackFileSchemaJson from "./qlpack-file.schema.json";
import { QlPackFile } from "./qlpack-file";
import { load } from "js-yaml";
import { readFile } from "fs-extra";

const ajv = new Ajv({ allErrors: true });
const qlpackFileValidate = ajv.compile(qlpackFileSchemaJson);

export async function loadQlpackFile(path: string): Promise<QlPackFile> {
const qlpackFileText = await readFile(path, "utf8");

let qlPack = load(qlpackFileText) as QlPackFile | undefined;

if (qlPack === undefined || qlPack === null) {
// An empty file is not valid according to the schema since it's not an object,
// but it is equivalent to an empty object.
qlPack = {};
}

qlpackFileValidate(qlPack);

if (qlpackFileValidate.errors) {
throw new Error(
`Invalid extension pack YAML: ${qlpackFileValidate.errors
.map((error) => `${error.instancePath} ${error.message}`)
.join(", ")}`,
);
}

return qlPack;
}
Loading

0 comments on commit 1ad20fa

Please sign in to comment.