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
5 changes: 5 additions & 0 deletions extensions/ql-vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -470,6 +470,11 @@
"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"
},
"codeQL.model.packName": {
"type": "string",
"default": "${owner}/${name}-${language}",
"markdownDescription": "Name of newly created CodeQL model packs. If the result is not a valid pack name, it will be converted to a valid pack name.\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"
}
}
},
Expand Down
14 changes: 14 additions & 0 deletions extensions/ql-vscode/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -736,6 +736,7 @@ const LLM_GENERATION_DEV_ENDPOINT = new Setting(
);
const MODEL_EVALUATION = new Setting("evaluation", MODEL_SETTING);
const MODEL_PACK_LOCATION = new Setting("packLocation", MODEL_SETTING);
const MODEL_PACK_NAME = new Setting("packName", MODEL_SETTING);
const ENABLE_PYTHON = new Setting("enablePython", MODEL_SETTING);
const ENABLE_ACCESS_PATH_SUGGESTIONS = new Setting(
"enableAccessPathSuggestions",
Expand All @@ -757,6 +758,7 @@ export interface ModelConfig {
languageId: string,
variables: ModelConfigPackVariables,
): string;
getPackName(languageId: string, variables: ModelConfigPackVariables): string;
enablePython: boolean;
enableAccessPathSuggestions: boolean;
}
Expand Down Expand Up @@ -810,6 +812,18 @@ export class ModelConfigListener extends ConfigListener implements ModelConfig {
);
}

public getPackName(
languageId: string,
variables: ModelConfigPackVariables,
): string {
return substituteConfigVariables(
MODEL_PACK_NAME.getValue<string>({
languageId,
}),
variables,
);
}

public get enablePython(): boolean {
return !!ENABLE_PYTHON.getValue<boolean>();
}
Expand Down
18 changes: 13 additions & 5 deletions extensions/ql-vscode/src/model-editor/extension-pack-name.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,11 +15,19 @@ export function formatPackName(packName: ExtensionPackName): string {
return `${packName.scope}/${packName.name}`;
}

export function autoNameExtensionPack(
name: string,
language: string,
): ExtensionPackName | undefined {
let packName = `${name}-${language}`;
export function sanitizePackName(userPackName: string): ExtensionPackName {
let packName = userPackName;

packName = packName.trim();

while (packName.startsWith("/")) {
packName = packName.slice(1);
}

while (packName.endsWith("/")) {
packName = packName.slice(0, -1);
}

if (!packName.includes("/")) {
packName = `pack/${packName}`;
}
Expand Down
21 changes: 15 additions & 6 deletions extensions/ql-vscode/src/model-editor/extension-pack-picker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ import type { NotificationLogger } from "../common/logging";
import { showAndLogErrorMessage } from "../common/logging";
import type { ModelConfig, ModelConfigPackVariables } from "../config";
import type { ExtensionPackName } from "./extension-pack-name";
import { autoNameExtensionPack, formatPackName } from "./extension-pack-name";
import {
validatePackName,
sanitizePackName,
formatPackName,
} from "./extension-pack-name";
import {
ensurePackLocationIsInWorkspaceFolder,
packLocationToAbsolute,
Expand Down Expand Up @@ -80,15 +84,20 @@ export async function pickExtensionPack(

await ensurePackLocationIsInWorkspaceFolder(packPath, modelConfig, logger);

// Generate the name of the extension pack
const packName = autoNameExtensionPack(
databaseItem.name,
const userPackName = modelConfig.getPackName(
databaseItem.language,
getModelConfigPackVariables(databaseItem),
);
if (!packName) {

// Generate the name of the extension pack
const packName = sanitizePackName(userPackName);

// Validate that the name isn't too long etc.
const packNameError = validatePackName(formatPackName(packName));
if (packNameError) {
void showAndLogErrorMessage(
logger,
`Could not automatically name extension pack for database ${databaseItem.name}`,
`Invalid model pack name '${formatPackName(packName)}' for database ${databaseItem.name}: ${packNameError}`,
);

return undefined;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,82 +1,81 @@
import {
autoNameExtensionPack,
sanitizePackName,
formatPackName,
parsePackName,
validatePackName,
} from "../../../src/model-editor/extension-pack-name";

describe("autoNameExtensionPack", () => {
describe("sanitizePackName", () => {
const testCases: Array<{
name: string;
language: string;
expected: string;
}> = [
{
name: "github/vscode-codeql",
language: "javascript",
name: "github/vscode-codeql-javascript",
expected: "github/vscode-codeql-javascript",
},
{
name: "vscode-codeql",
language: "a",
name: "vscode-codeql-a",
expected: "pack/vscode-codeql-a",
},
{
name: "b",
language: "java",
name: "b-java",
expected: "pack/b-java",
},
{
name: "a/b",
language: "csharp",
name: "a/b-csharp",
expected: "a/b-csharp",
},
{
name: "-/b",
language: "csharp",
name: "-/b-csharp",
expected: "pack/b-csharp",
},
{
name: "a/b/c/d",
language: "csharp",
name: "a/b/c/d-csharp",
expected: "a/b-c-d-csharp",
},
{
name: "JAVA/CodeQL",
language: "csharp",
name: "JAVA/CodeQL-csharp",
expected: "java/codeql-csharp",
},
{
name: "my new pack",
language: "swift",
name: "my new pack-swift",
expected: "pack/my-new-pack-swift",
},
{
name: "gïthub/vscode-codeql",
language: "javascript",
name: "gïthub/vscode-codeql-javascript",
expected: "gthub/vscode-codeql-javascript",
},
{
name: "a/b-",
language: "csharp",
name: "a/b-csharp",
expected: "a/b-csharp",
},
{
name: "-a-/b",
language: "ruby",
name: "-a-/b-ruby",
expected: "a/b-ruby",
},
{
name: "a/b--d--e-d-",
language: "csharp",
name: "a/b--d--e-d-csharp",
expected: "a/b-d-e-d-csharp",
},
{
name: "/github/vscode-codeql",
expected: "github/vscode-codeql",
},
{
name: "github/vscode-codeql/",
expected: "github/vscode-codeql",
},
{
name: "///github/vscode-codeql///",
expected: "github/vscode-codeql",
},
];

test.each(testCases)(
"$name with $language = $expected",
({ name, language, expected }) => {
const result = autoNameExtensionPack(name, language);
({ name, expected }) => {
const result = sanitizePackName(name);
expect(result).not.toBeUndefined();
if (!result) {
return;
Expand Down
Loading