Skip to content

Commit 4dc126d

Browse files
authored
Merge pull request #3539 from github/koesie10/pack-location-config
Add `codeQL.model.packLocation` setting
2 parents 9e729ba + 6146d7d commit 4dc126d

File tree

6 files changed

+665
-202
lines changed

6 files changed

+665
-202
lines changed

extensions/ql-vscode/package.json

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -463,8 +463,20 @@
463463
},
464464
{
465465
"type": "object",
466-
"title": "Log insights",
466+
"title": "Model Editor",
467467
"order": 9,
468+
"properties": {
469+
"codeQL.model.packLocation": {
470+
"type": "string",
471+
"default": ".github/codeql/extensions/${name}-${language}",
472+
"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"
473+
}
474+
}
475+
},
476+
{
477+
"type": "object",
478+
"title": "Log insights",
479+
"order": 10,
468480
"properties": {
469481
"codeQL.logInsights.joinOrderWarningThreshold": {
470482
"type": "number",
@@ -478,7 +490,7 @@
478490
{
479491
"type": "object",
480492
"title": "Telemetry",
481-
"order": 10,
493+
"order": 11,
482494
"properties": {
483495
"codeQL.telemetry.enableTelemetry": {
484496
"type": "boolean",

extensions/ql-vscode/src/config.ts

Lines changed: 23 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ import {
1313
FilterKey,
1414
SortKey,
1515
} from "./variant-analysis/shared/variant-analysis-filter-sort";
16+
import { substituteConfigVariables } from "./common/config-template";
1617

1718
export const ALL_SETTINGS: Setting[] = [];
1819

@@ -734,18 +735,28 @@ const LLM_GENERATION_DEV_ENDPOINT = new Setting(
734735
MODEL_SETTING,
735736
);
736737
const MODEL_EVALUATION = new Setting("evaluation", MODEL_SETTING);
737-
const EXTENSIONS_DIRECTORY = new Setting("extensionsDirectory", MODEL_SETTING);
738+
const MODEL_PACK_LOCATION = new Setting("packLocation", MODEL_SETTING);
738739
const ENABLE_PYTHON = new Setting("enablePython", MODEL_SETTING);
739740
const ENABLE_ACCESS_PATH_SUGGESTIONS = new Setting(
740741
"enableAccessPathSuggestions",
741742
MODEL_SETTING,
742743
);
743744

745+
export type ModelConfigPackVariables = {
746+
database: string;
747+
owner: string;
748+
name: string;
749+
language: string;
750+
};
751+
744752
export interface ModelConfig {
745753
flowGeneration: boolean;
746754
llmGeneration: boolean;
747755
showTypeModels: boolean;
748-
getExtensionsDirectory(languageId: string): string | undefined;
756+
getPackLocation(
757+
languageId: string,
758+
variables: ModelConfigPackVariables,
759+
): string;
749760
enablePython: boolean;
750761
enableAccessPathSuggestions: boolean;
751762
}
@@ -787,10 +798,16 @@ export class ModelConfigListener extends ConfigListener implements ModelConfig {
787798
return !!MODEL_EVALUATION.getValue<boolean>();
788799
}
789800

790-
public getExtensionsDirectory(languageId: string): string | undefined {
791-
return EXTENSIONS_DIRECTORY.getValue<string>({
792-
languageId,
793-
});
801+
public getPackLocation(
802+
languageId: string,
803+
variables: ModelConfigPackVariables,
804+
): string {
805+
return substituteConfigVariables(
806+
MODEL_PACK_LOCATION.getValue<string>({
807+
languageId,
808+
}),
809+
variables,
810+
);
794811
}
795812

796813
public get enablePython(): boolean {

extensions/ql-vscode/src/model-editor/extension-pack-picker.ts

Lines changed: 37 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import { join } from "path";
22
import { outputFile, pathExists, readFile } from "fs-extra";
33
import { dump as dumpYaml, load as loadYaml } from "js-yaml";
44
import type { CancellationToken } from "vscode";
5-
import { Uri } from "vscode";
65
import Ajv from "ajv";
76
import type { CodeQLCliServer } from "../codeql-cli/cli";
87
import { getOnDiskWorkspaceFolders } from "../common/vscode/workspace-folders";
@@ -14,10 +13,13 @@ import { getErrorMessage } from "../common/helpers-pure";
1413
import type { ExtensionPack } from "./shared/extension-pack";
1514
import type { NotificationLogger } from "../common/logging";
1615
import { showAndLogErrorMessage } from "../common/logging";
17-
import type { ModelConfig } from "../config";
16+
import type { ModelConfig, ModelConfigPackVariables } from "../config";
1817
import type { ExtensionPackName } from "./extension-pack-name";
1918
import { autoNameExtensionPack, formatPackName } from "./extension-pack-name";
20-
import { autoPickExtensionsDirectory } from "./extensions-workspace-folder";
19+
import {
20+
ensurePackLocationIsInWorkspaceFolder,
21+
packLocationToAbsolute,
22+
} from "./extensions-workspace-folder";
2123

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

2830
export async function pickExtensionPack(
2931
cliServer: Pick<CodeQLCliServer, "resolveQlpacks">,
30-
databaseItem: Pick<DatabaseItem, "name" | "language">,
32+
databaseItem: Pick<DatabaseItem, "name" | "language" | "origin">,
3133
modelConfig: ModelConfig,
3234
logger: NotificationLogger,
3335
progress: ProgressCallback,
@@ -64,20 +66,20 @@ export async function pickExtensionPack(
6466
maxStep,
6567
});
6668

67-
// Get the `codeQL.model.extensionsDirectory` setting for the language
68-
const userExtensionsDirectory = modelConfig.getExtensionsDirectory(
69-
databaseItem.language,
69+
// The default is .github/codeql/extensions/${name}-${language}
70+
const packPath = await packLocationToAbsolute(
71+
modelConfig.getPackLocation(
72+
databaseItem.language,
73+
getModelConfigPackVariables(databaseItem),
74+
),
75+
logger,
7076
);
71-
72-
// If the setting is not set, automatically pick a suitable directory
73-
const extensionsDirectory = userExtensionsDirectory
74-
? Uri.file(userExtensionsDirectory)
75-
: await autoPickExtensionsDirectory(logger);
76-
77-
if (!extensionsDirectory) {
77+
if (!packPath) {
7878
return undefined;
7979
}
8080

81+
await ensurePackLocationIsInWorkspaceFolder(packPath, modelConfig, logger);
82+
8183
// Generate the name of the extension pack
8284
const packName = autoNameExtensionPack(
8385
databaseItem.name,
@@ -139,14 +141,12 @@ export async function pickExtensionPack(
139141
return undefined;
140142
}
141143

142-
const packPath = join(extensionsDirectory.fsPath, packName.name);
143-
144144
if (await pathExists(packPath)) {
145145
void showAndLogErrorMessage(
146146
logger,
147147
`Directory ${packPath} already exists for extension pack ${formatPackName(
148148
packName,
149-
)}`,
149+
)}, but wasn't returned by codeql resolve qlpacks --kind extension --no-recursive`,
150150
);
151151

152152
return undefined;
@@ -155,6 +155,26 @@ export async function pickExtensionPack(
155155
return writeExtensionPack(packPath, packName, databaseItem.language);
156156
}
157157

158+
function getModelConfigPackVariables(
159+
databaseItem: Pick<DatabaseItem, "name" | "language" | "origin">,
160+
): ModelConfigPackVariables {
161+
const database = databaseItem.name;
162+
const language = databaseItem.language;
163+
let name = databaseItem.name;
164+
let owner = "";
165+
166+
if (databaseItem.origin?.type === "github") {
167+
[owner, name] = databaseItem.origin.repository.split("/");
168+
}
169+
170+
return {
171+
database,
172+
language,
173+
name,
174+
owner,
175+
};
176+
}
177+
158178
async function writeExtensionPack(
159179
packPath: string,
160180
packName: ExtensionPackName,

0 commit comments

Comments
 (0)