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

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 14 additions & 2 deletions extensions/ql-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -463,8 +463,20 @@
},
{
"type": "object",
"title": "Log insights",
"title": "Model Editor",
"order": 9,
"properties": {
"codeQL.model.packLocation": {
"type": "string",
"default": ".github/codeql/extensions/${name}-${language}",
"markdownDescription": "Location for newly created CodeQL model packs. The location can be either absolute or relative. If relative, it is relative to the workspace root.\n\nThe following variables are supported:\n* **${database}** - the name of the database\n* **${language}** - the name of the language\n* **${name}** - the name of the GitHub repository, or the name of the database if the database was not downloaded from GitHub\n* **${owner}** - the owner of the GitHub repository, or an empty string if the database was not downloaded from GitHub"
}
}
},
{
"type": "object",
"title": "Log insights",
"order": 10,
"properties": {
"codeQL.logInsights.joinOrderWarningThreshold": {
"type": "number",
Expand All @@ -478,7 +490,7 @@
{
"type": "object",
"title": "Telemetry",
"order": 10,
"order": 11,
"properties": {
"codeQL.telemetry.enableTelemetry": {
"type": "boolean",
Expand Down
29 changes: 23 additions & 6 deletions extensions/ql-vscode/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import {
FilterKey,
SortKey,
} from "./variant-analysis/shared/variant-analysis-filter-sort";
import { substituteConfigVariables } from "./common/config-template";

export const ALL_SETTINGS: Setting[] = [];

Expand Down Expand Up @@ -734,18 +735,28 @@ const LLM_GENERATION_DEV_ENDPOINT = new Setting(
MODEL_SETTING,
);
const MODEL_EVALUATION = new Setting("evaluation", MODEL_SETTING);
const EXTENSIONS_DIRECTORY = new Setting("extensionsDirectory", MODEL_SETTING);
const MODEL_PACK_LOCATION = new Setting("packLocation", MODEL_SETTING);
const ENABLE_PYTHON = new Setting("enablePython", MODEL_SETTING);
const ENABLE_ACCESS_PATH_SUGGESTIONS = new Setting(
"enableAccessPathSuggestions",
MODEL_SETTING,
);

export type ModelConfigPackVariables = {
database: string;
owner: string;
name: string;
language: string;
};

export interface ModelConfig {
flowGeneration: boolean;
llmGeneration: boolean;
showTypeModels: boolean;
getExtensionsDirectory(languageId: string): string | undefined;
getPackLocation(
languageId: string,
variables: ModelConfigPackVariables,
): string;
enablePython: boolean;
enableAccessPathSuggestions: boolean;
}
Expand Down Expand Up @@ -787,10 +798,16 @@ export class ModelConfigListener extends ConfigListener implements ModelConfig {
return !!MODEL_EVALUATION.getValue<boolean>();
}

public getExtensionsDirectory(languageId: string): string | undefined {
return EXTENSIONS_DIRECTORY.getValue<string>({
languageId,
});
public getPackLocation(
languageId: string,
variables: ModelConfigPackVariables,
): string {
return substituteConfigVariables(
MODEL_PACK_LOCATION.getValue<string>({
languageId,
}),
variables,
);
}

public get enablePython(): boolean {
Expand Down
54 changes: 37 additions & 17 deletions extensions/ql-vscode/src/model-editor/extension-pack-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import { join } from "path";
import { outputFile, pathExists, readFile } from "fs-extra";
import { dump as dumpYaml, load as loadYaml } from "js-yaml";
import type { CancellationToken } from "vscode";
import { Uri } from "vscode";
import Ajv from "ajv";
import type { CodeQLCliServer } from "../codeql-cli/cli";
import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
Expand All @@ -14,10 +13,13 @@ import { getErrorMessage } from "../common/helpers-pure";
import type { ExtensionPack } from "./shared/extension-pack";
import type { NotificationLogger } from "../common/logging";
import { showAndLogErrorMessage } from "../common/logging";
import type { ModelConfig } from "../config";
import type { ModelConfig, ModelConfigPackVariables } from "../config";
import type { ExtensionPackName } from "./extension-pack-name";
import { autoNameExtensionPack, formatPackName } from "./extension-pack-name";
import { autoPickExtensionsDirectory } from "./extensions-workspace-folder";
import {
ensurePackLocationIsInWorkspaceFolder,
packLocationToAbsolute,
} from "./extensions-workspace-folder";

import type { ExtensionPackMetadata } from "./extension-pack-metadata";
import extensionPackMetadataSchemaJson from "./extension-pack-metadata.schema.json";
Expand All @@ -27,7 +29,7 @@ const extensionPackValidate = ajv.compile(extensionPackMetadataSchemaJson);

export async function pickExtensionPack(
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">,
databaseItem: Pick<DatabaseItem, "name" | "language">,
databaseItem: Pick<DatabaseItem, "name" | "language" | "origin">,
modelConfig: ModelConfig,
logger: NotificationLogger,
progress: ProgressCallback,
Expand Down Expand Up @@ -64,20 +66,20 @@ export async function pickExtensionPack(
maxStep,
});

// Get the `codeQL.model.extensionsDirectory` setting for the language
const userExtensionsDirectory = modelConfig.getExtensionsDirectory(
databaseItem.language,
// The default is .github/codeql/extensions/${name}-${language}
const packPath = await packLocationToAbsolute(
modelConfig.getPackLocation(
databaseItem.language,
getModelConfigPackVariables(databaseItem),
),
logger,
);

// If the setting is not set, automatically pick a suitable directory
const extensionsDirectory = userExtensionsDirectory
? Uri.file(userExtensionsDirectory)
: await autoPickExtensionsDirectory(logger);

if (!extensionsDirectory) {
if (!packPath) {
return undefined;
}

await ensurePackLocationIsInWorkspaceFolder(packPath, modelConfig, logger);

// Generate the name of the extension pack
const packName = autoNameExtensionPack(
databaseItem.name,
Expand Down Expand Up @@ -139,14 +141,12 @@ export async function pickExtensionPack(
return undefined;
}

const packPath = join(extensionsDirectory.fsPath, packName.name);

if (await pathExists(packPath)) {
void showAndLogErrorMessage(
logger,
`Directory ${packPath} already exists for extension pack ${formatPackName(
packName,
)}`,
)}, but wasn't returned by codeql resolve qlpacks --kind extension --no-recursive`,
);

return undefined;
Expand All @@ -155,6 +155,26 @@ export async function pickExtensionPack(
return writeExtensionPack(packPath, packName, databaseItem.language);
}

function getModelConfigPackVariables(
databaseItem: Pick<DatabaseItem, "name" | "language" | "origin">,
): ModelConfigPackVariables {
const database = databaseItem.name;
const language = databaseItem.language;
let name = databaseItem.name;
let owner = "";

if (databaseItem.origin?.type === "github") {
[owner, name] = databaseItem.origin.repository.split("/");
}

return {
database,
language,
name,
owner,
};
}

async function writeExtensionPack(
packPath: string,
packName: ExtensionPackName,
Expand Down
Loading