gradio
332 строки · 8.5 Кб
1const { getPackagesSync } = require("@manypkg/get-packages");2const dependents_graph = require("@changesets/get-dependents-graph");3
4const gh = require("@changesets/get-github-info");5const { existsSync, readFileSync, writeFileSync } = require("fs");6const { join } = require("path");7
8const { getInfo, getInfoFromPullRequest } = gh;9const pkg_data = getPackagesSync(process.cwd());10const { packages, rootDir } = pkg_data;11const dependents = dependents_graph.getDependentsGraph({12packages,13root: pkg_data.rootPackage14});15
16/**
17* @typedef {{packageJson: {name: string, python?: boolean}, dir: string}} Package
18*/
19
20/**
21* @typedef {{summary: string, id: string, commit: string, releases: {name: string}}} Changeset
22*/
23
24/**
25*
26* @param {string} package_name The name of the package to find the directories for
27* @returns {string[]} The directories for the package
28*/
29function find_packages_dirs(package_name) {30/** @type {string[]} */31let package_dirs = [];32
33/** @type {Package | undefined} */34const _package = packages.find((p) => p.packageJson.name === package_name);35if (!_package) throw new Error(`Package ${package_name} not found`);36
37package_dirs.push(_package.dir);38if (_package.packageJson.python) {39package_dirs.push(join(_package.dir, ".."));40}41return package_dirs;42}
43
44let lines = {45_handled: []46};47
48const changelogFunctions = {49/**50*
51* @param {Changeset[]} changesets The changesets that have been created
52* @param {any} dependenciesUpdated The dependencies that have been updated
53* @param {any} options The options passed to the changelog generator
54* @returns {Promise<string>} The release line for the dependencies
55*/
56getDependencyReleaseLine: async (57changesets,58dependenciesUpdated,59options
60) => {61if (!options.repo) {62throw new Error(63'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]'64);65}66if (dependenciesUpdated.length === 0) return "";67
68const changesetLink = `- Updated dependencies [${(69await Promise.all(70changesets.map(async (cs) => {71if (cs.commit) {72let { links } = await getInfo({73repo: options.repo,74commit: cs.commit75});76return links.commit;77}78})79)
80)
81.filter((_) => _)
82.join(", ")}]:`;83
84const updatedDepenenciesList = dependenciesUpdated.map(85/**86*
87* @param {any} dependency The dependency that has been updated
88* @returns {string} The formatted dependency
89*/
90(dependency) => {91const updates = dependents.get(dependency.name);92
93if (updates && updates.length > 0) {94updates.forEach((update) => {95if (!lines[update]) {96lines[update] = {97dirs: find_packages_dirs(update),98current_changelog: "",99feat: [],100fix: [],101highlight: [],102previous_version: packages.find(103(p) => p.packageJson.name === update104).packageJson.version,105dependencies: []106};107
108const changelog_path = join(109//@ts-ignore110lines[update].dirs[1] || lines[update].dirs[0],111"CHANGELOG.md"112);113
114if (existsSync(changelog_path)) {115//@ts-ignore116lines[update].current_changelog = readFileSync(117changelog_path,118"utf-8"119)120.replace(`# ${update}`, "")121.trim();122}123}124lines[update].dependencies.push(125` - ${dependency.name}@${dependency.newVersion}`126);127});128}129
130return ` - ${dependency.name}@${dependency.newVersion}`;131}132);133
134writeFileSync(135join(rootDir, ".changeset", "_changelog.json"),136JSON.stringify(lines, null, 2)137);138
139return [changesetLink, ...updatedDepenenciesList].join("\n");140},141/**142*
143* @param {{summary: string, id: string, commit: string, releases: {name: string}[]}} changeset The changeset that has been created
144* @param {any} type The type of changeset
145* @param {any} options The options passed to the changelog generator
146* @returns {Promise<string>} The release line for the changeset
147*/
148getReleaseLine: async (changeset, type, options) => {149if (!options || !options.repo) {150throw new Error(151'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]'152);153}154
155let prFromSummary;156let commitFromSummary;157/**158* @type {string[]}
159*/
160let usersFromSummary = [];161
162const replacedChangelog = changeset.summary163.replace(/^\s*(?:pr|pull|pull\s+request):\s*#?(\d+)/im, (_, pr) => {164let num = Number(pr);165if (!isNaN(num)) prFromSummary = num;166return "";167})168.replace(/^\s*commit:\s*([^\s]+)/im, (_, commit) => {169commitFromSummary = commit;170return "";171})172.replace(/^\s*(?:author|user):\s*@?([^\s]+)/gim, (_, user) => {173usersFromSummary.push(user);174return "";175})176.trim();177
178const [firstLine, ...futureLines] = replacedChangelog179.split("\n")180.map((l) => l.trimRight());181
182const links = await (async () => {183if (prFromSummary !== undefined) {184let { links } = await getInfoFromPullRequest({185repo: options.repo,186pull: prFromSummary187});188if (commitFromSummary) {189links = {190...links,191commit: `[\`${commitFromSummary}\`](https://github.com/${options.repo}/commit/${commitFromSummary})`192};193}194return links;195}196const commitToFetchFrom = commitFromSummary || changeset.commit;197if (commitToFetchFrom) {198let { links } = await getInfo({199repo: options.repo,200commit: commitToFetchFrom201});202return links;203}204return {205commit: null,206pull: null,207user: null208};209})();210
211const user_link = /\[(@[^]+)\]/.exec(links.user);212const users =213usersFromSummary && usersFromSummary.length214? usersFromSummary215.map((userFromSummary) => `@${userFromSummary}`)216.join(", ")217: user_link218? user_link[1]219: links.user;220
221const prefix = [222links.pull === null ? "" : `${links.pull}`,223links.commit === null ? "" : `${links.commit}`224]225.join(" ")226.trim();227
228const suffix = users === null ? "" : ` Thanks ${users}!`;229
230/**231* @typedef {{[key: string]: string[] | {dirs: string[], current_changelog: string, feat: {summary: string}[], fix: {summary: string}[], highlight: {summary: string}[]}}} ChangesetMeta
232*/
233
234/**235* @type { ChangesetMeta & { _handled: string[] } }}
236*/
237
238if (lines._handled.includes(changeset.id)) {239return "done";240}241lines._handled.push(changeset.id);242
243changeset.releases.forEach((release) => {244if (!lines[release.name]) {245lines[release.name] = {246dirs: find_packages_dirs(release.name),247current_changelog: "",248feat: [],249fix: [],250highlight: [],251previous_version: packages.find(252(p) => p.packageJson.name === release.name253).packageJson.version,254dependencies: []255};256}257
258const changelog_path = join(259//@ts-ignore260lines[release.name].dirs[1] || lines[release.name].dirs[0],261"CHANGELOG.md"262);263
264if (existsSync(changelog_path)) {265//@ts-ignore266lines[release.name].current_changelog = readFileSync(267changelog_path,268"utf-8"269)270.replace(`# ${release.name}`, "")271.trim();272}273
274const [, _type, summary] = changeset.summary275.trim()276.match(/^(feat|fix|highlight)\s*:\s*([^]*)/im) || [277,278"feat",279changeset.summary280];281
282let formatted_summary = "";283
284if (_type === "highlight") {285const [heading, ...rest] = summary.trim().split("\n");286const _heading = `${heading} ${prefix ? `(${prefix})` : ""}`;287const _rest = rest.concat(["", suffix]);288
289formatted_summary = `${_heading}\n${_rest.join("\n")}`;290} else {291formatted_summary = handle_line(summary, prefix, suffix);292}293
294//@ts-ignore295lines[release.name][_type].push({296summary: formatted_summary297});298});299
300writeFileSync(301join(rootDir, ".changeset", "_changelog.json"),302JSON.stringify(lines, null, 2)303);304
305return `\n\n-${prefix ? `${prefix} -` : ""} ${firstLine}\n${futureLines306.map((l) => ` ${l}`)307.join("\n")}`;308}309};310
311/**
312* @param {string} str The changelog entry
313* @param {string} prefix The prefix to add to the first line
314* @param {string} suffix The suffix to add to the last line
315* @returns {string} The formatted changelog entry
316*/
317function handle_line(str, prefix, suffix) {318const [_s, ...lines] = str.split("\n").filter(Boolean);319
320const desc = `${prefix ? `${prefix} -` : ""} ${_s.replace(321/[\s\.]$/,322""323)}. ${suffix}`;324
325if (_s.length === 1) {326return desc;327}328
329return [desc, ...lines.map((l) => ` ${l}`)].join("/n");330}
331
332module.exports = changelogFunctions;333