Skip to content

Commit f78f535

Browse files
committed
Merge remote-tracking branch 'origin/main' into koesie10/data-extension-editor-generate-flow-model
2 parents 80cbaf9 + 20e9370 commit f78f535

13 files changed

Lines changed: 114 additions & 94 deletions

File tree

.github/workflows/main.yml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,11 @@ jobs:
100100
run: |
101101
npm run lint
102102
103+
- name: Lint Markdown
104+
working-directory: extensions/ql-vscode
105+
run: |
106+
npm run lint:markdown
107+
103108
- name: Lint scenarios
104109
working-directory: extensions/ql-vscode
105110
run: |

extensions/ql-vscode/package-lock.json

Lines changed: 9 additions & 9 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

extensions/ql-vscode/src/data-extensions-editor/data-extensions-editor-view.ts

Lines changed: 34 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@ import { CoreCompletedQuery, QueryRunner } from "../queryRunner";
1616
import { qlpackOfDatabase } from "../contextual/queryResolver";
1717
import { file } from "tmp-promise";
1818
import { readFile, writeFile } from "fs-extra";
19-
import { dump, load } from "js-yaml";
19+
import { dump as dumpYaml, load as loadYaml } from "js-yaml";
2020
import {
2121
getOnDiskWorkspaceFolders,
2222
showAndLogExceptionWithTelemetry,
23+
showAndLogWarningMessage,
2324
} from "../helpers";
2425
import { DatabaseItem, DatabaseManager } from "../local-databases";
2526
import { CodeQLCliServer } from "../cli";
@@ -29,6 +30,8 @@ import { promptImportGithubDatabase } from "../databaseFetcher";
2930
import { App } from "../common/app";
3031
import { decodeBqrsToExternalApiUsages } from "./bqrs";
3132
import { redactableError } from "../pure/errors";
33+
import { createDataExtensionYaml, loadDataExtensionYaml } from "./yaml";
34+
import { ExternalApiUsage } from "./external-api-usage";
3235
import { ModeledMethod } from "./modeled-method";
3336

3437
export class DataExtensionsEditorView extends AbstractWebview<
@@ -76,8 +79,11 @@ export class DataExtensionsEditorView extends AbstractWebview<
7679
await this.onWebViewLoaded();
7780

7881
break;
79-
case "applyDataExtensionYaml":
80-
await this.saveYaml(msg.yaml);
82+
case "saveModeledMethods":
83+
await this.saveModeledMethods(
84+
msg.externalApiUsages,
85+
msg.modeledMethods,
86+
);
8187
await this.loadExternalApiUsages();
8288

8389
break;
@@ -93,36 +99,51 @@ export class DataExtensionsEditorView extends AbstractWebview<
9399
protected async onWebViewLoaded() {
94100
super.onWebViewLoaded();
95101

96-
await Promise.all([this.loadExternalApiUsages(), this.readExistingYaml()]);
102+
await Promise.all([
103+
this.loadExternalApiUsages(),
104+
this.loadExistingModeledMethods(),
105+
]);
97106
}
98107

99-
protected async saveYaml(yaml: string): Promise<void> {
100-
const modelFilename = this.modelFileName;
108+
protected async saveModeledMethods(
109+
externalApiUsages: ExternalApiUsage[],
110+
modeledMethods: Record<string, ModeledMethod>,
111+
): Promise<void> {
112+
const modelFilename = this.calculateModelFilename();
101113
if (!modelFilename) {
102114
return;
103115
}
104116

117+
const yaml = createDataExtensionYaml(externalApiUsages, modeledMethods);
118+
105119
await writeFile(modelFilename, yaml);
106120

107121
void extLogger.log(`Saved data extension YAML to ${modelFilename}`);
108122
}
109123

110-
protected async readExistingYaml(): Promise<void> {
111-
const modelFilename = this.modelFileName;
124+
protected async loadExistingModeledMethods(): Promise<void> {
125+
const modelFilename = this.calculateModelFilename();
112126
if (!modelFilename) {
113127
return;
114128
}
115129

116130
try {
117131
const yaml = await readFile(modelFilename, "utf8");
118132

119-
const data = load(yaml, {
133+
const data = loadYaml(yaml, {
120134
filename: modelFilename,
121135
});
122136

137+
const existingModeledMethods = loadDataExtensionYaml(data);
138+
139+
if (!existingModeledMethods) {
140+
void showAndLogWarningMessage("Failed to parse data extension YAML.");
141+
return;
142+
}
143+
123144
await this.postMessage({
124-
t: "setExistingYamlData",
125-
data,
145+
t: "setExistingModeledMethods",
146+
existingModeledMethods,
126147
});
127148
} catch (e: unknown) {
128149
void extLogger.log(`Unable to read data extension YAML: ${e}`);
@@ -275,7 +296,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
275296
},
276297
});
277298
}
278-
await writeFile(suiteFile, dump(suiteYaml), "utf8");
299+
await writeFile(suiteFile, dumpYaml(suiteYaml), "utf8");
279300

280301
const queries = await this.cliServer.resolveQueriesInSuite(
281302
suiteFile,
@@ -354,7 +375,7 @@ export class DataExtensionsEditorView extends AbstractWebview<
354375
});
355376
}
356377

357-
private get modelFileName(): string | undefined {
378+
private calculateModelFilename(): string | undefined {
358379
const workspaceFolder = workspace.workspaceFolders?.find(
359380
(folder) => folder.name === "ql",
360381
);

extensions/ql-vscode/src/pure/interface-types.ts

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -493,19 +493,20 @@ export interface ShowProgressMessage {
493493
message: string;
494494
}
495495

496-
export interface SetExistingYamlDataMessage {
497-
t: "setExistingYamlData";
498-
data: any;
496+
export interface SetExistingModeledMethods {
497+
t: "setExistingModeledMethods";
498+
existingModeledMethods: Record<string, ModeledMethod>;
499499
}
500500

501501
export interface AddModeledMethodsMessage {
502502
t: "addModeledMethods";
503503
modeledMethods: Record<string, ModeledMethod>;
504504
}
505505

506-
export interface ApplyDataExtensionYamlMessage {
507-
t: "applyDataExtensionYaml";
508-
yaml: string;
506+
export interface SaveModeledMethods {
507+
t: "saveModeledMethods";
508+
externalApiUsages: ExternalApiUsage[];
509+
modeledMethods: Record<string, ModeledMethod>;
509510
}
510511

511512
export interface GenerateExternalApiMessage {
@@ -515,10 +516,10 @@ export interface GenerateExternalApiMessage {
515516
export type ToDataExtensionsEditorMessage =
516517
| SetExternalApiUsagesMessage
517518
| ShowProgressMessage
518-
| SetExistingYamlDataMessage
519+
| SetExistingModeledMethods
519520
| AddModeledMethodsMessage;
520521

521522
export type FromDataExtensionsEditorMessage =
522523
| ViewLoadedMsg
523-
| ApplyDataExtensionYamlMessage
524+
| SaveModeledMethods
524525
| GenerateExternalApiMessage;

extensions/ql-vscode/src/variant-analysis/markdown-generation.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,7 @@ export function generateVariantAnalysisMarkdownSummary(
112112
lines.push(`### Results for "${query.name}"`, "");
113113

114114
// Expandable section containing query text
115-
const queryCodeBlock = ["```ql", ...query.text.split("\n"), "```"];
115+
const queryCodeBlock = ["```ql", ...query.text.split("\n"), "```", ""];
116116
lines.push(...buildExpandableMarkdownSection("Query", queryCodeBlock));
117117

118118
// Padding between sections
@@ -128,6 +128,9 @@ export function generateVariantAnalysisMarkdownSummary(
128128
lines.push(`| ${fullName} | [${summary.resultCount} result(s)](${link}) |`);
129129
}
130130

131+
// Add a trailing newline
132+
lines.push("");
133+
131134
return {
132135
fileName: "_summary",
133136
content: lines,
@@ -279,8 +282,8 @@ function generateMarkdownForPathResults(
279282
);
280283
// Indent the snippet to fit with the numbered list.
281284
// The indentation is "n + 2" where the list number is an n-digit number.
282-
const codeSnippetIndented = codeSnippet.map(
283-
(line) => " ".repeat(listNumber.toString().length + 2) + line,
285+
const codeSnippetIndented = codeSnippet.map((line) =>
286+
(" ".repeat(listNumber.toString().length + 2) + line).trimEnd(),
284287
);
285288
pathLines.push(`${listNumber}. ${link}`, ...codeSnippetIndented);
286289
}
@@ -382,7 +385,6 @@ function buildExpandableMarkdownSection(
382385
`<summary>${title}</summary>`,
383386
"",
384387
...contents,
385-
"",
386388
"</details>",
387389
"",
388390
);

extensions/ql-vscode/src/view/data-extensions-editor/DataExtensionsEditor.tsx

Lines changed: 4 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,6 @@ import { ModeledMethod } from "../../data-extensions-editor/modeled-method";
1616
import { MethodRow } from "./MethodRow";
1717
import { assertNever } from "../../pure/helpers-pure";
1818
import { vscode } from "../vscode-api";
19-
import {
20-
createDataExtensionYaml,
21-
loadDataExtensionYaml,
22-
} from "../../data-extensions-editor/yaml";
2319
import { calculateSupportedPercentage } from "./supported";
2420

2521
export const DataExtensionsEditorContainer = styled.div`
@@ -61,12 +57,10 @@ export function DataExtensionsEditor(): JSX.Element {
6157
case "showProgress":
6258
setProgress(msg);
6359
break;
64-
case "setExistingYamlData":
60+
case "setExistingModeledMethods":
6561
setModeledMethods((oldModeledMethods) => {
66-
const existingModeledMethods = loadDataExtensionYaml(msg.data);
67-
6862
return {
69-
...existingModeledMethods,
63+
...msg.existingModeledMethods,
7064
...oldModeledMethods,
7165
};
7266
});
@@ -120,14 +114,10 @@ export function DataExtensionsEditor(): JSX.Element {
120114
);
121115

122116
const onApplyClick = useCallback(() => {
123-
const yamlString = createDataExtensionYaml(
117+
vscode.postMessage({
118+
t: "saveModeledMethods",
124119
externalApiUsages,
125120
modeledMethods,
126-
);
127-
128-
vscode.postMessage({
129-
t: "applyDataExtensionYaml",
130-
yaml: yamlString,
131121
});
132122
}, [externalApiUsages, modeledMethods]);
133123

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
{
2+
"extends": "../../../../../../.markdownlint.json",
3+
"MD010": false, // Hard tabs are from the original snippet in the SARIF file
4+
"MD024": false, // Duplicate headings
5+
"MD033": false, // Inline HTML for <details> and <summary>
6+
"MD051": false // Link fragments are used in Gist to link to other files
7+
}

0 commit comments

Comments
 (0)