-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathimplementations-update.ts
More file actions
93 lines (86 loc) · 3.05 KB
/
implementations-update.ts
File metadata and controls
93 lines (86 loc) · 3.05 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
import * as fs from "node:fs";
import * as path from "node:path";
import * as yaml from "js-yaml";
import { getActImplementationReport } from "./map-implementation/get-act-implementation-report";
import { loadJson } from "./utils/load-json";
import {
ActImplementationReport,
TestCaseJson,
} from "./map-implementation/types";
import { Implementation } from "./types";
import { createFile, filenameEscape } from "./utils";
import { createRuleImplementation } from "./implementation-update/create-rule-implementation";
export interface CliArgs {
testCaseJson: string;
implementations: string;
outDir: string;
tableFilePattern: string;
}
export async function cliProgram({
tableFilePattern,
testCaseJson: testCasePath,
implementations: implementationPath,
outDir,
}: CliArgs): Promise<void> {
const testCaseJson = (await loadJson(testCasePath)) as TestCaseJson;
const implementationMappings = await createImplementationMappings(
implementationPath,
outDir,
testCaseJson,
);
for (const ruleId of getRuleIds(testCaseJson)) {
const filePath = tableFilePattern.replace("{ruleId}", ruleId);
const fileText = createRuleImplementation(ruleId, implementationMappings);
await createFile(filePath, fileText);
}
}
async function createImplementationMappings(
implementationPath: string,
outDir: string,
testCasesJson: TestCaseJson,
): Promise<ActImplementationReport[]> {
const implementations = loadImplementations(implementationPath);
const implementationMappings: ActImplementationReport[] = [];
for (const { name, vendor, report } of implementations) {
const jsonLd = await loadJson(report);
const mapping = await getActImplementationReport(
jsonLd,
testCasesJson.testcases,
{
name,
vendor,
},
);
const filePath = path.resolve(outDir, `${filenameEscape(name)}.json`);
console.log(`Writing file ${filePath}`);
await createFile(filePath, mapping);
implementationMappings.push(mapping);
}
return implementationMappings;
}
function loadImplementations(implementationPath: string): Implementation[] {
const yamlData = yaml.load(fs.readFileSync(implementationPath, "utf8"));
if (typeof yamlData !== "object" || yamlData === null) {
return [];
}
const yamlRecord = yamlData as Record<string, unknown>;
const implementations: Implementation[] = [];
Object.entries(yamlRecord).forEach(([name, entry]) => {
if (typeof entry !== "object" || entry === null) {
console.warn(`Failed to load ${name}. Properties missing or invalid`);
return;
}
const { vendor, report } = entry as Record<string, unknown>;
if (typeof vendor === "string" && typeof report === "string") {
implementations.push({ name, vendor, report });
} else {
console.warn(`Failed to load ${name}. Properties missing or invalid`);
}
});
return implementations;
}
function getRuleIds({ testcases }: TestCaseJson): string[] {
const uniqueIds = new Set<string>();
testcases.forEach((testcase) => uniqueIds.add(testcase.ruleId));
return Array.from(uniqueIds);
}