* 从 README.md 提取所有 GitHub 仓库链接(去重) * @param {string} filePath README.md 路径 * @returns {string[]} 去重后的仓库链接列表
(filePath)
| 109 | * @returns {string[]} 去重后的仓库链接列表 |
| 110 | */ |
| 111 | function extractGithubRepos(filePath) { |
| 112 | try { |
| 113 | if (!fs.existsSync(filePath)) { |
| 114 | console.error(`❌ 错误:未找到文件 ${filePath}`); |
| 115 | return []; |
| 116 | } |
| 117 | |
| 118 | const content = fs.readFileSync(filePath, 'utf8'); |
| 119 | const markdownLinks = []; |
| 120 | const rawLinks = []; |
| 121 | |
| 122 | // 匹配 Markdown 链接格式 [xxx](https://github.com/xxx/xxx) |
| 123 | let match; |
| 124 | while ((match = GITHUB_LINK_REGEX.exec(content)) !== null) { |
| 125 | markdownLinks.push(match[1].trim()); |
| 126 | } |
| 127 | |
| 128 | // 匹配纯 GitHub 链接(兜底) |
| 129 | while ((match = RAW_GITHUB_REGEX.exec(content)) !== null) { |
| 130 | rawLinks.push(match[0].trim()); |
| 131 | } |
| 132 | |
| 133 | // 合并并去重 |
| 134 | const allLinks = [...new Set([...markdownLinks, ...rawLinks])]; |
| 135 | // 过滤空链接 |
| 136 | return allLinks.filter((link) => link); |
| 137 | } catch (err) { |
| 138 | console.error(`❌ 读取文件异常:${err.message}`); |
| 139 | return []; |
| 140 | } |
| 141 | } |
| 142 | const cleanError = (str) => { |
| 143 | return str |
| 144 | .split('\n') |