File size: 4,355 Bytes
0ad74ed
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
const { join } = require("path");
const { readFileSync, existsSync, writeFileSync, unlinkSync } = require("fs");
const { getPackagesSync } = require("@manypkg/get-packages");

const RE_PKG_NAME = /^[\w-]+\b/;
const pkg_meta = getPackagesSync(process.cwd());

/**
 * @typedef {{dirs: string[], highlight: {summary: string}[], feat: {summary: string}[], fix: {summary: string}[], current_changelog: string}} ChangesetMeta
 */

/**
 * @typedef {{[key: string]: ChangesetMeta}} ChangesetMetaCollection
 */

function run() {
	if (!existsSync(join(pkg_meta.rootDir, ".changeset", "_changelog.json"))) {
		console.warn("No changesets to process");
		return;
	}

	/**
	 * @type { ChangesetMetaCollection & { _handled: string[] } }}
	 */
	const { _handled, ...packages } = JSON.parse(
		readFileSync(
			join(pkg_meta.rootDir, ".changeset", "_changelog.json"),
			"utf-8"
		)
	);

	/**
	 * @typedef { {packageJson: {name: string, version: string, python: boolean}, dir: string} } PackageMeta
	 */

	/**
	 * @type { {[key:string]: PackageMeta} }
	 */
	const all_packages = pkg_meta.packages.reduce((acc, pkg) => {
		acc[pkg.packageJson.name] = /**@type {PackageMeta} */ (
			/** @type {unknown} */ (pkg)
		);
		return acc;
	}, /** @type {{[key:string] : PackageMeta}} */ ({}));

	for (const pkg_name in packages) {
		const { dirs, highlight, feat, fix, current_changelog, dependencies } =
			/**@type {ChangesetMeta} */ (packages[pkg_name]);

		if (pkg_name === "@gradio/lite") {
			const target = all_packages.gradio.packageJson.version.split(".");

			const current_version = packages[pkg_name].previous_version.split(".");

			if (!packages.gradio) {
				const patch = parseInt(current_version[2]) + 1;
				const new_version = [target[0], target[1], patch];
				all_packages[pkg_name].packageJson.version = new_version.join(".");
			} else {
				if (parseInt(target[1]) > parseInt(current_version[1])) {
					all_packages[pkg_name].packageJson.version = target.join(".");
				} else if (parseInt(target[1]) === parseInt(current_version[1])) {
					const patch = parseInt(current_version[2]) + 1;
					const new_version = [target[0], target[1], patch];
					all_packages[pkg_name].packageJson.version = new_version.join(".");
				}
			}

			writeFileSync(
				join(all_packages[pkg_name].dir, "package.json"),
				JSON.stringify(all_packages[pkg_name].packageJson, null, "\t") + "\n"
			);
		}

		const { version, python } = all_packages[pkg_name].packageJson;

		const highlights = highlight?.map((h) => `${h.summary}`) || [];
		const features = feat?.map((f) => `- ${f.summary}`) || [];
		const fixes = fix?.map((f) => `- ${f.summary}`) || [];
		const deps = Array.from(new Set(dependencies?.map((d) => d.trim()))) || [];

		const release_notes = /** @type {[string[], string][]} */ ([
			[highlights, "### Highlights"],
			[features, "### Features"],
			[fixes, "### Fixes"],
			[deps, "### Dependency updates"]
		])
			.filter(([s], i) => s.length > 0)
			.map(([lines, title]) => {
				if (title === "### Highlights") {
					return `${title}\n\n${lines.join("\n\n")}`;
				}

				return `${title}\n\n${lines.join("\n")}`;
			})
			.join("\n\n");

		const new_changelog = `# ${pkg_name}

## ${version}

${release_notes}

${current_changelog.replace(`# ${pkg_name}`, "").trim()}
`.trim();

		dirs.forEach((dir) => {
			writeFileSync(join(dir, "CHANGELOG.md"), new_changelog);
		});

		if (python) {
			bump_local_dependents(pkg_name, version);
		}
	}

	unlinkSync(join(pkg_meta.rootDir, ".changeset", "_changelog.json"));

	/**
	 * @param {string} pkg_to_bump The name of the package to bump
	 * @param {string} version The version to bump to
	 * @returns {void}
	 * */
	function bump_local_dependents(pkg_to_bump, version) {
		for (const pkg_name in all_packages) {
			const {
				dir,
				packageJson: { python }
			} = all_packages[pkg_name];

			if (!python) continue;

			const requirements_path = join(dir, "..", "requirements.txt");
			const requirements = readFileSync(requirements_path, "utf-8").split("\n");

			const pkg_index = requirements.findIndex((line) => {
				const m = line.trim().match(RE_PKG_NAME);
				if (!m) return false;
				return m[0] === pkg_to_bump;
			});

			if (pkg_index !== -1) {
				requirements[pkg_index] = `${pkg_to_bump}==${version}`;
				writeFileSync(requirements_path, requirements.join("\n"));
			}
		}
	}
}

run();