Skip to content

Commit b4a9ef0

Browse files
authored
Merge pull request #3400 from github/koesie10/refactor-yaml-save
Extract saving of model extension YAML file
2 parents f4a866b + 5468aef commit b4a9ef0

File tree

3 files changed

+77
-56
lines changed

3 files changed

+77
-56
lines changed

extensions/ql-vscode/src/model-editor/model-extension-file.schema.json

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -8,36 +8,39 @@
88
"extensions": {
99
"type": "array",
1010
"items": {
11-
"type": "object",
12-
"properties": {
13-
"addsTo": {
14-
"type": "object",
15-
"properties": {
16-
"pack": {
17-
"type": "string"
18-
},
19-
"extensible": {
20-
"type": "string"
21-
}
22-
},
23-
"required": ["pack", "extensible"]
24-
},
25-
"data": {
26-
"type": "array",
27-
"items": {
28-
"type": "array",
29-
"items": {
30-
"$ref": "#/definitions/DataTuple"
31-
}
32-
}
33-
}
34-
},
35-
"required": ["addsTo", "data"]
11+
"$ref": "#/definitions/ModelExtension"
3612
}
3713
}
3814
},
3915
"required": ["extensions"]
4016
},
17+
"ModelExtension": {
18+
"type": "object",
19+
"properties": {
20+
"addsTo": {
21+
"type": "object",
22+
"properties": {
23+
"pack": {
24+
"type": "string"
25+
},
26+
"extensible": {
27+
"type": "string"
28+
}
29+
},
30+
"required": ["pack", "extensible"]
31+
},
32+
"data": {
33+
"type": "array",
34+
"items": {
35+
"type": "array",
36+
"items": {
37+
"$ref": "#/definitions/DataTuple"
38+
}
39+
}
40+
}
41+
},
42+
"required": ["addsTo", "data"]
43+
},
4144
"DataTuple": {
4245
"type": ["boolean", "number", "string"]
4346
}

extensions/ql-vscode/src/model-editor/model-extension-file.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ export type DataTuple = boolean | number | string;
77

88
type DataRow = DataTuple[];
99

10-
type ModelExtension = {
10+
export type ModelExtension = {
1111
addsTo: ExtensibleReference;
1212
data: DataRow[];
1313
};

extensions/ql-vscode/src/model-editor/yaml.ts

Lines changed: 48 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -16,46 +16,33 @@ import type {
1616
import { getModelsAsDataLanguage } from "./languages";
1717
import { Mode } from "./shared/mode";
1818
import { assertNever } from "../common/helpers-pure";
19-
import type { ModelExtensionFile } from "./model-extension-file";
19+
import type {
20+
ModelExtension,
21+
ModelExtensionFile,
22+
} from "./model-extension-file";
2023
import type { QueryLanguage } from "../common/query-language";
2124

2225
import modelExtensionFileSchema from "./model-extension-file.schema.json";
2326

2427
const ajv = new Ajv({ allErrors: true, allowUnionTypes: true });
2528
const modelExtensionFileSchemaValidate = ajv.compile(modelExtensionFileSchema);
2629

27-
function createDataProperty<T>(
28-
methods: readonly T[],
29-
definition: ModelsAsDataLanguagePredicate<T>,
30-
) {
31-
if (methods.length === 0) {
32-
return " []";
33-
}
34-
35-
return `\n${methods
36-
.map(
37-
(method) =>
38-
` - ${JSON.stringify(
39-
definition.generateMethodDefinition(method),
40-
)}`,
41-
)
42-
.join("\n")}`;
43-
}
44-
4530
function createExtensions<T>(
4631
language: QueryLanguage,
4732
methods: readonly T[],
4833
definition: ModelsAsDataLanguagePredicate<T> | undefined,
49-
) {
34+
): ModelExtension | undefined {
5035
if (!definition) {
51-
return "";
36+
return undefined;
5237
}
5338

54-
return ` - addsTo:
55-
pack: codeql/${language}-all
56-
extensible: ${definition.extensiblePredicate}
57-
data:${createDataProperty(methods, definition)}
58-
`;
39+
return {
40+
addsTo: {
41+
pack: `codeql/${language}-all`,
42+
extensible: definition.extensiblePredicate,
43+
},
44+
data: methods.map((method) => definition.generateMethodDefinition(method)),
45+
};
5946
}
6047

6148
export function createDataExtensionYaml(
@@ -99,7 +86,7 @@ export function createDataExtensionYaml(
9986
}
10087

10188
const extensions = Object.keys(methodsByType)
102-
.map((typeKey) => {
89+
.map((typeKey): ModelExtension | undefined => {
10390
const type = typeKey as keyof ModelsAsDataLanguagePredicates;
10491

10592
switch (type) {
@@ -137,10 +124,11 @@ export function createDataExtensionYaml(
137124
assertNever(type);
138125
}
139126
})
140-
.filter((extensions) => extensions !== "");
127+
.filter(
128+
(extension): extension is ModelExtension => extension !== undefined,
129+
);
141130

142-
return `extensions:
143-
${extensions.join("\n")}`;
131+
return modelExtensionFileToYaml({ extensions });
144132
}
145133

146134
export function createDataExtensionYamls(
@@ -341,6 +329,36 @@ function validateModelExtensionFile(data: unknown): data is ModelExtensionFile {
341329
return true;
342330
}
343331

332+
/**
333+
* Creates a string for the data extension YAML file from the
334+
* structure of the data extension file. This should be used
335+
* instead of creating a JSON string directly or dumping the
336+
* YAML directly to ensure that the file is formatted correctly.
337+
*
338+
* @param data The data extension file
339+
*/
340+
function modelExtensionFileToYaml(data: ModelExtensionFile) {
341+
const extensions = data.extensions
342+
.map((extension) => {
343+
const data =
344+
extension.data.length === 0
345+
? " []"
346+
: `\n${extension.data
347+
.map((row) => ` - ${JSON.stringify(row)}`)
348+
.join("\n")}`;
349+
350+
return ` - addsTo:
351+
pack: ${extension.addsTo.pack}
352+
extensible: ${extension.addsTo.extensible}
353+
data:${data}
354+
`;
355+
})
356+
.filter((extensions) => extensions !== "");
357+
358+
return `extensions:
359+
${extensions.join("\n")}`;
360+
}
361+
344362
export function loadDataExtensionYaml(
345363
data: unknown,
346364
language: QueryLanguage,

0 commit comments

Comments
 (0)