80 lines
3.4 KiB
TypeScript
80 lines
3.4 KiB
TypeScript
import fs from 'fs';
|
|
import path from 'path';
|
|
import { LanguageSupport } from '../types/RuleMetadata';
|
|
|
|
import { getRulesDirectories, listSupportedLanguages } from './utils';
|
|
|
|
/**
|
|
* Generate rule metadata (for all relevant languages) and write it in the destination directory.
|
|
* @param srcDir directory containing the original rule metadata and description.
|
|
* @param dstDir directory where the generated metadata and description will be written.
|
|
* @param branch the branch containing the given version of the rule. Typically 'master' but can be different for not merged rules.
|
|
* @param prUrl optional link to the PR adding the rule. absent for merged rules.
|
|
*/
|
|
export function generateOneRuleMetadata(srcDir: string, dstDir: string,
|
|
branch: string, prUrl?: string) {
|
|
fs.mkdirSync(dstDir, { recursive: true });
|
|
const allLanguages = listSupportedLanguages(srcDir);
|
|
const allMetadata = allLanguages.map((language) => {
|
|
const metadata = generateRuleMetadata(srcDir, language);
|
|
return {language, metadata};
|
|
});
|
|
|
|
// Update language status for all
|
|
const languageSupports =
|
|
allMetadata.map(m => ({name: m.language, status: m.metadata.status} as LanguageSupport));
|
|
|
|
// Merge all sqKeys in an array so that we can use it later to check rule coverage.
|
|
const allKeys = allMetadata
|
|
.reduce((set, {metadata}) => {
|
|
set.add(metadata.sqKey);
|
|
metadata.extra?.legacyKeys?.forEach((key: string) => set.add(key));
|
|
return set;
|
|
}, new Set<string>());
|
|
const allKeysArray = Array.from(allKeys);
|
|
allMetadata.forEach(({metadata}) => {
|
|
metadata.allKeys = allKeysArray;
|
|
if (prUrl) {
|
|
metadata.prUrl = prUrl;
|
|
}
|
|
metadata.branch = branch;
|
|
metadata.languagesSupport = languageSupports;
|
|
});
|
|
|
|
let default_metadata_wanted = true;
|
|
for (const { language, metadata } of allMetadata) {
|
|
const dstJsonFile = path.join(dstDir, language + '-metadata.json');
|
|
fs.writeFileSync(dstJsonFile, JSON.stringify(metadata, null, 2), { encoding: 'utf8' })
|
|
if (default_metadata_wanted) {
|
|
const dstFile = path.join(dstDir, 'default-metadata.json');
|
|
fs.writeFileSync(dstFile, JSON.stringify(metadata, null, 2), { encoding: 'utf8' });
|
|
default_metadata_wanted = false;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate rules metadata and write them in the destination directory.
|
|
* @param srcPath directory containing the original rules metadata and description.
|
|
* @param dstPath directory where the generated rules metadata and description will be written.
|
|
* @param rules an optional list of rules to list. Other rules won't be generated.
|
|
*/
|
|
export function generateRulesMetadata(srcPath: string, dstPath: string, rules?: string[]) {
|
|
for (const { srcDir, dstDir } of getRulesDirectories(srcPath, dstPath, rules)) {
|
|
generateOneRuleMetadata(srcDir, dstDir, 'master');
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Generate the metadata corresponding to one rule and one language.
|
|
* @param srcDir rule's source directory.
|
|
* @param language language for which the metadata should be generated
|
|
*/
|
|
function generateRuleMetadata(srcDir: string, language: string) {
|
|
const parentFile = path.join(srcDir, language, 'metadata.json');
|
|
const parentJson = fs.existsSync(parentFile) ? JSON.parse(fs.readFileSync(parentFile, 'utf8')) : {};
|
|
const childFile = path.join(srcDir, 'metadata.json');
|
|
const childJson = fs.existsSync(childFile) ? JSON.parse(fs.readFileSync(childFile, 'utf8')) : {};
|
|
return {...childJson, ...parentJson};
|
|
}
|