gradio

Форк
0
/
changeset.cjs 
332 строки · 8.5 Кб
1
const { getPackagesSync } = require("@manypkg/get-packages");
2
const dependents_graph = require("@changesets/get-dependents-graph");
3

4
const gh = require("@changesets/get-github-info");
5
const { existsSync, readFileSync, writeFileSync } = require("fs");
6
const { join } = require("path");
7

8
const { getInfo, getInfoFromPullRequest } = gh;
9
const pkg_data = getPackagesSync(process.cwd());
10
const { packages, rootDir } = pkg_data;
11
const dependents = dependents_graph.getDependentsGraph({
12
	packages,
13
	root: pkg_data.rootPackage
14
});
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
 */
29
function find_packages_dirs(package_name) {
30
	/** @type {string[]} */
31
	let package_dirs = [];
32

33
	/** @type {Package | undefined} */
34
	const _package = packages.find((p) => p.packageJson.name === package_name);
35
	if (!_package) throw new Error(`Package ${package_name} not found`);
36

37
	package_dirs.push(_package.dir);
38
	if (_package.packageJson.python) {
39
		package_dirs.push(join(_package.dir, ".."));
40
	}
41
	return package_dirs;
42
}
43

44
let lines = {
45
	_handled: []
46
};
47

48
const 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
	 */
56
	getDependencyReleaseLine: async (
57
		changesets,
58
		dependenciesUpdated,
59
		options
60
	) => {
61
		if (!options.repo) {
62
			throw new Error(
63
				'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]'
64
			);
65
		}
66
		if (dependenciesUpdated.length === 0) return "";
67

68
		const changesetLink = `- Updated dependencies [${(
69
			await Promise.all(
70
				changesets.map(async (cs) => {
71
					if (cs.commit) {
72
						let { links } = await getInfo({
73
							repo: options.repo,
74
							commit: cs.commit
75
						});
76
						return links.commit;
77
					}
78
				})
79
			)
80
		)
81
			.filter((_) => _)
82
			.join(", ")}]:`;
83

84
		const updatedDepenenciesList = dependenciesUpdated.map(
85
			/**
86
			 *
87
			 * @param {any} dependency The dependency that has been updated
88
			 * @returns {string} The formatted dependency
89
			 */
90
			(dependency) => {
91
				const updates = dependents.get(dependency.name);
92

93
				if (updates && updates.length > 0) {
94
					updates.forEach((update) => {
95
						if (!lines[update]) {
96
							lines[update] = {
97
								dirs: find_packages_dirs(update),
98
								current_changelog: "",
99
								feat: [],
100
								fix: [],
101
								highlight: [],
102
								previous_version: packages.find(
103
									(p) => p.packageJson.name === update
104
								).packageJson.version,
105
								dependencies: []
106
							};
107

108
							const changelog_path = join(
109
								//@ts-ignore
110
								lines[update].dirs[1] || lines[update].dirs[0],
111
								"CHANGELOG.md"
112
							);
113

114
							if (existsSync(changelog_path)) {
115
								//@ts-ignore
116
								lines[update].current_changelog = readFileSync(
117
									changelog_path,
118
									"utf-8"
119
								)
120
									.replace(`# ${update}`, "")
121
									.trim();
122
							}
123
						}
124
						lines[update].dependencies.push(
125
							`  - ${dependency.name}@${dependency.newVersion}`
126
						);
127
					});
128
				}
129

130
				return `  - ${dependency.name}@${dependency.newVersion}`;
131
			}
132
		);
133

134
		writeFileSync(
135
			join(rootDir, ".changeset", "_changelog.json"),
136
			JSON.stringify(lines, null, 2)
137
		);
138

139
		return [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
	 */
148
	getReleaseLine: async (changeset, type, options) => {
149
		if (!options || !options.repo) {
150
			throw new Error(
151
				'Please provide a repo to this changelog generator like this:\n"changelog": ["@changesets/changelog-github", { "repo": "org/repo" }]'
152
			);
153
		}
154

155
		let prFromSummary;
156
		let commitFromSummary;
157
		/**
158
		 * @type {string[]}
159
		 */
160
		let usersFromSummary = [];
161

162
		const replacedChangelog = changeset.summary
163
			.replace(/^\s*(?:pr|pull|pull\s+request):\s*#?(\d+)/im, (_, pr) => {
164
				let num = Number(pr);
165
				if (!isNaN(num)) prFromSummary = num;
166
				return "";
167
			})
168
			.replace(/^\s*commit:\s*([^\s]+)/im, (_, commit) => {
169
				commitFromSummary = commit;
170
				return "";
171
			})
172
			.replace(/^\s*(?:author|user):\s*@?([^\s]+)/gim, (_, user) => {
173
				usersFromSummary.push(user);
174
				return "";
175
			})
176
			.trim();
177

178
		const [firstLine, ...futureLines] = replacedChangelog
179
			.split("\n")
180
			.map((l) => l.trimRight());
181

182
		const links = await (async () => {
183
			if (prFromSummary !== undefined) {
184
				let { links } = await getInfoFromPullRequest({
185
					repo: options.repo,
186
					pull: prFromSummary
187
				});
188
				if (commitFromSummary) {
189
					links = {
190
						...links,
191
						commit: `[\`${commitFromSummary}\`](https://github.com/${options.repo}/commit/${commitFromSummary})`
192
					};
193
				}
194
				return links;
195
			}
196
			const commitToFetchFrom = commitFromSummary || changeset.commit;
197
			if (commitToFetchFrom) {
198
				let { links } = await getInfo({
199
					repo: options.repo,
200
					commit: commitToFetchFrom
201
				});
202
				return links;
203
			}
204
			return {
205
				commit: null,
206
				pull: null,
207
				user: null
208
			};
209
		})();
210

211
		const user_link = /\[(@[^]+)\]/.exec(links.user);
212
		const users =
213
			usersFromSummary && usersFromSummary.length
214
				? usersFromSummary
215
						.map((userFromSummary) => `@${userFromSummary}`)
216
						.join(", ")
217
				: user_link
218
				? user_link[1]
219
				: links.user;
220

221
		const prefix = [
222
			links.pull === null ? "" : `${links.pull}`,
223
			links.commit === null ? "" : `${links.commit}`
224
		]
225
			.join(" ")
226
			.trim();
227

228
		const 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

238
		if (lines._handled.includes(changeset.id)) {
239
			return "done";
240
		}
241
		lines._handled.push(changeset.id);
242

243
		changeset.releases.forEach((release) => {
244
			if (!lines[release.name]) {
245
				lines[release.name] = {
246
					dirs: find_packages_dirs(release.name),
247
					current_changelog: "",
248
					feat: [],
249
					fix: [],
250
					highlight: [],
251
					previous_version: packages.find(
252
						(p) => p.packageJson.name === release.name
253
					).packageJson.version,
254
					dependencies: []
255
				};
256
			}
257

258
			const changelog_path = join(
259
				//@ts-ignore
260
				lines[release.name].dirs[1] || lines[release.name].dirs[0],
261
				"CHANGELOG.md"
262
			);
263

264
			if (existsSync(changelog_path)) {
265
				//@ts-ignore
266
				lines[release.name].current_changelog = readFileSync(
267
					changelog_path,
268
					"utf-8"
269
				)
270
					.replace(`# ${release.name}`, "")
271
					.trim();
272
			}
273

274
			const [, _type, summary] = changeset.summary
275
				.trim()
276
				.match(/^(feat|fix|highlight)\s*:\s*([^]*)/im) || [
277
				,
278
				"feat",
279
				changeset.summary
280
			];
281

282
			let formatted_summary = "";
283

284
			if (_type === "highlight") {
285
				const [heading, ...rest] = summary.trim().split("\n");
286
				const _heading = `${heading} ${prefix ? `(${prefix})` : ""}`;
287
				const _rest = rest.concat(["", suffix]);
288

289
				formatted_summary = `${_heading}\n${_rest.join("\n")}`;
290
			} else {
291
				formatted_summary = handle_line(summary, prefix, suffix);
292
			}
293

294
			//@ts-ignore
295
			lines[release.name][_type].push({
296
				summary: formatted_summary
297
			});
298
		});
299

300
		writeFileSync(
301
			join(rootDir, ".changeset", "_changelog.json"),
302
			JSON.stringify(lines, null, 2)
303
		);
304

305
		return `\n\n-${prefix ? `${prefix} -` : ""} ${firstLine}\n${futureLines
306
			.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
 */
317
function handle_line(str, prefix, suffix) {
318
	const [_s, ...lines] = str.split("\n").filter(Boolean);
319

320
	const desc = `${prefix ? `${prefix} -` : ""} ${_s.replace(
321
		/[\s\.]$/,
322
		""
323
	)}. ${suffix}`;
324

325
	if (_s.length === 1) {
326
		return desc;
327
	}
328

329
	return [desc, ...lines.map((l) => `  ${l}`)].join("/n");
330
}
331

332
module.exports = changelogFunctions;
333

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.