/* eslint-disable no-loop-func */ // Collect from `changelog.md` to get all components changelog import path from 'path'; import fs from 'fs-extra'; import { globSync } from 'glob'; const output = '.dumi/preset'; // Collect components const componentNames = globSync( path.join(process.cwd(), 'components/!(version|icon|col|row)/index.zh-CN.md'), ) .map((filePath) => filePath.match(/components\/([^/]*)\//)![1]) .filter((name) => name !== 'overview'); const camelComponentNames = componentNames.map((componentName) => componentName .split('-') .map((cell) => (cell.length <= 2 ? cell.toUpperCase() : cell[0].toUpperCase() + cell.slice(1))) .join(''), ); // Convert a mapping logic const componentNameMap: Record = {}; camelComponentNames.forEach((name) => { componentNameMap[name] = [` ${name}`, `\`${name}`, 'Global:']; }); componentNameMap.ConfigProvider.push('Wave'); componentNameMap.Grid.push('Row', 'Col'); componentNameMap.Message.push('message'); componentNameMap.Notification.push('notification'); // Collect misc. When ComponentName not match will fallback to misc const miscKeys = [ 'ComponentToken', 'Component Token', 'Design Token', 'MISC:', 'ๆ‚้กน๏ผš', '@ant-design/cssinjs', '@ant-design/icons', 'rc-motion', ' IE ', 'reset.css', '๐Ÿ“–', '๐Ÿ› ', '๐ŸŒ', ' locale ', ' RTL ', '๐Ÿ‡ง๐Ÿ‡ช', '๐Ÿ‡จ๐Ÿ‡ฆ', '๐Ÿ‡ช๐Ÿ‡ธ', '๐Ÿ‡ท๐Ÿ‡บ', '๐Ÿ‡บ๐Ÿ‡ฆ', '๐Ÿ‡ฒ๐Ÿ‡ฒ', '๐Ÿ‡ธ๐Ÿ‡ช', '๐Ÿ‡ป๐Ÿ‡ณ', '๐Ÿ‡ฎ๐Ÿ‡ณ', '๐Ÿ‡ฎ๐Ÿ‡ท', '๐Ÿ‡ฐ๐Ÿ‡ท', '๐Ÿ‡ฉ๐Ÿ‡ช', '๐Ÿ‡ฑ๐Ÿ‡น', ]; (() => { const missingChangelog = []; const miscChangelog: string[] = []; // Read & write components changelog function syncChangelog(sourceFile: string, targetFile: string) { const content = fs.readFileSync(sourceFile).toString(); // let lastGroup = ''; let lastVersion = ''; // Split with lines const lines = content.split(/[\n\r]+/).filter((line) => line.trim()); // Changelog map const componentChangelog: Record< string, { version: string; changelog: string; refs: string[] }[] > = {}; Object.keys(componentNameMap).forEach((name) => { componentChangelog[name] = []; }); for (let i = 0; i < lines.length; i += 1) { const line = lines[i]; // Skip for v5 release if (line === '## 5.0.0') { break; } // Get version if (line.startsWith('## ')) { lastVersion = line.replace('## ', ''); continue; } // Start when get version if (!lastVersion) { continue; } // Group end if (line.startsWith('- ')) { // lastGroup = ''; } // Group check if (line.startsWith('- ') && lines[i + 1].startsWith(' - ')) { // lastGroup = line.replace('- ', ''); continue; } // Filter not is changelog if (!line.trim().startsWith('-') && !line.includes('github.')) { continue; } // Collect Components let matched = false; const refs: string[] = []; let changelogLine = line.trim().replace('- ', ''); changelogLine = changelogLine .replace(/\[([^\]]+)]\(([^)]+)\)/g, (...match) => { const [, , ref] = match; if (ref.includes('/pull/')) { refs.push(ref); } return ''; }) .trim(); Object.keys(componentNameMap).forEach((name) => { const matchKeys = componentNameMap[name]; if (matchKeys.some((key) => line.includes(key))) { componentChangelog[name].push({ version: lastVersion, changelog: changelogLine, refs, }); matched = true; } }); if (matched) { continue; } // Misc if (miscKeys.some((key) => line.includes(key))) { miscChangelog.push(line); continue; } if (!matched) { console.log('๐Ÿšจ Miss Component:', line); missingChangelog.push(line); } } fs.writeFileSync(path.join(output, targetFile), JSON.stringify(componentChangelog), 'utf-8'); } syncChangelog('CHANGELOG.zh-CN.md', 'components-changelog-cn.json'); syncChangelog('CHANGELOG.en-US.md', 'components-changelog-en.json'); fs.writeFileSync( path.join(output, 'misc-changelog.json'), JSON.stringify(miscChangelog), 'utf-8', ); if (missingChangelog.length) { console.log('\nMISC key word should be:'); console.log(miscKeys.join(' , '), '\n'); throw new Error(`Component changelog miss match!`); } })();