Skip to content

Commit 6a11f60

Browse files
author
Illia Obukhau
committed
chore: finish version and changelog scripts
1 parent 49e9c4d commit 6a11f60

File tree

8 files changed

+165
-92
lines changed

8 files changed

+165
-92
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#!/usr/bin/env ts-node-script
2+
3+
import { prompt } from "enquirer";
4+
import { selectPackage } from "../src";
5+
import { getNextVersion, writeVersion } from "../src/bump-version";
6+
7+
import { oraPromise } from "../src/cli-utils";
8+
9+
async function main(): Promise<void> {
10+
const pkg = await selectPackage();
11+
const nextVersion = await getNextVersion(pkg.version);
12+
13+
const { save } = await prompt<{ save: boolean }>({
14+
type: "confirm",
15+
name: "save",
16+
message: "Save changes?"
17+
});
18+
19+
if (save) {
20+
await oraPromise(writeVersion(pkg, nextVersion), "Writing changes...");
21+
console.log("Done.");
22+
} else {
23+
console.log("Exit without changes.");
24+
}
25+
}
26+
27+
main().catch(e => {
28+
console.error(e);
29+
process.exit(1);
30+
});

packages/tools/release-utils-internal/bin/rui-changelog-helper.ts

Lines changed: 21 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,16 @@
11
#!/usr/bin/env ts-node-script
22

33
import { prompt } from "enquirer";
4-
import ora from "ora";
5-
import { bumpPackageJson, bumpXml, getNextVersion } from "../src/bump-version";
6-
import { getWidgetChangelog } from "../src/changelog-parser";
4+
import { getModuleInfo, PackageListing, selectPackage } from "../src";
5+
import { getNextVersion, writeVersion } from "../src/bump-version";
6+
import {
7+
getModuleChangelog,
8+
getWidgetChangelog,
9+
ModuleChangelogFileWrapper,
10+
WidgetChangelogFileWrapper
11+
} from "../src/changelog-parser";
712
import { LogSection } from "../src/changelog-parser/types";
8-
import { listPackages, PackageListing } from "../src/monorepo";
9-
10-
async function oraPromise<T>(task: Promise<T>, msg: string): Promise<T> {
11-
const spinner = ora(msg);
12-
spinner.start();
13-
const r = await task;
14-
spinner.stop();
15-
return r;
16-
}
17-
18-
async function selectPackage(): Promise<PackageListing> {
19-
const pkgs = await oraPromise(listPackages(["'*'", "!web-widgets"]), "Loading packages...");
20-
21-
const { packageName } = await prompt<{ packageName: string }>({
22-
type: "autocomplete",
23-
name: "packageName",
24-
message: "Please select package",
25-
choices: pkgs.map(pkg => pkg.name)
26-
});
27-
28-
const pkg = pkgs.find(p => p.name === packageName);
29-
30-
if (!pkg) {
31-
throw new Error(`Unable to find package meta for ${packageName}`);
32-
}
33-
34-
return pkg;
35-
}
13+
import { oraPromise } from "../src/cli-utils";
3614

3715
async function getChangelogSections(): Promise<LogSection[]> {
3816
const sections: LogSection[] = [];
@@ -78,36 +56,40 @@ async function getChangelogSections(): Promise<LogSection[]> {
7856
return sections;
7957
}
8058

81-
async function updateVersion(currentVersion: string): Promise<string | undefined> {
59+
async function selectNextVersion(currentVersion: string): Promise<string | undefined> {
8260
const { bump } = await prompt<{ bump: boolean }>({
8361
type: "confirm",
8462
name: "bump",
8563
message: "Would you like to bump the package version?"
8664
});
8765

8866
if (bump) {
89-
const nextVersion = await getNextVersion(currentVersion);
90-
console.log(`Version change: ${currentVersion} => ${nextVersion}`);
91-
return nextVersion;
67+
return getNextVersion(currentVersion);
9268
}
9369

9470
return undefined;
9571
}
9672

9773
async function writeChanges(pkg: PackageListing, sections: LogSection[], nextVersion?: string): Promise<void> {
98-
const changelog = await getWidgetChangelog(pkg.path);
74+
let changelog: WidgetChangelogFileWrapper | ModuleChangelogFileWrapper;
75+
try {
76+
changelog = await getWidgetChangelog(pkg.path);
77+
} catch {
78+
const module = await getModuleInfo(pkg.path);
79+
changelog = await getModuleChangelog(pkg.path, module.mxpackage.name);
80+
}
81+
9982
changelog.addUnreleasedSections(sections).save();
10083

10184
if (nextVersion) {
102-
bumpPackageJson(pkg.path, nextVersion);
103-
await bumpXml(pkg.path, nextVersion);
85+
await writeVersion(pkg, nextVersion);
10486
}
10587
}
10688

10789
async function main(): Promise<void> {
10890
const pkg = await selectPackage();
10991
const sections = await getChangelogSections();
110-
const nextVersion = await updateVersion(pkg.version);
92+
const nextVersion = await selectNextVersion(pkg.version);
11193

11294
const { save } = await prompt<{ save: boolean }>({
11395
type: "confirm",

packages/tools/release-utils-internal/package.json

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,13 @@
1818
"compile:parser:widget": "peggy -o ./src/changelog-parser/parser/module/module.js ./src/changelog-parser/parser/module/module.pegjs",
1919
"compile:parser:module": "peggy -o ./src/changelog-parser/parser/widget/widget.js ./src/changelog-parser/parser/widget/widget.pegjs",
2020
"prepare": "pnpm run compile:parser:widget && pnpm run compile:parser:module && tsc",
21-
"changelog": "ts-node bin/rui-changelog-helper.ts"
21+
"changelog": "ts-node bin/rui-changelog-helper.ts",
22+
"version": "ts-node bin/rui-bump-version.ts"
2223
},
2324
"devDependencies": {
2425
"@types/cross-zip": "^4.0.0",
2526
"@types/node-fetch": "2.6.1",
27+
"chalk": "^4.1.2",
2628
"cross-zip": "^4.0.0",
2729
"enquirer": "^2.3.6",
2830
"eslint": "^7.20.0",
Lines changed: 43 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,33 +1,10 @@
1-
import { promises as fs } from "fs";
2-
import { join } from "path";
1+
import chalk from "chalk";
32
import { spawnSync } from "child_process";
43
import { prompt } from "enquirer";
5-
6-
export async function selectBumpVersionType(): Promise<BumpVersionType> {
7-
const { bumpType } = await prompt<{ bumpType: string }>({
8-
type: "autocomplete",
9-
name: "bumpType",
10-
message: "Want to bump?",
11-
choices: ["major", "minor", "patch", "set manually"]
12-
});
13-
14-
if (bumpType === "set manually") {
15-
const { nextVersion } = await prompt<{ nextVersion: string }>({
16-
type: "input",
17-
name: "nextVersion",
18-
message: "Set package version to"
19-
});
20-
21-
return nextVersion;
22-
} else {
23-
return bumpType;
24-
}
25-
}
26-
27-
export async function getNextVersion(currentVersion: string): Promise<string> {
28-
const bumpVersionType = await selectBumpVersionType();
29-
return getNewVersion(bumpVersionType, currentVersion);
30-
}
4+
import { promises as fs } from "fs";
5+
import { join } from "path";
6+
import { nextTick } from "process";
7+
import { PackageListing } from "./monorepo";
318

329
export type BumpVersionType = "patch" | "minor" | "major" | string;
3310

@@ -64,7 +41,42 @@ export async function bumpXml(path: string, version: string): Promise<boolean> {
6441
}
6542
}
6643

67-
export async function updateVersion(path: string, version: string): Promise<void> {
68-
bumpPackageJson(path, version);
69-
await bumpXml(path, version);
44+
export async function writeVersion(pkg: PackageListing, version: string): Promise<void> {
45+
bumpPackageJson(pkg.path, version);
46+
try {
47+
await bumpXml(pkg.path, version);
48+
} catch {
49+
nextTick(() => {
50+
const msg = `[WARN] Update version: package ${pkg.name} is missing package.xml, skip`;
51+
console.warn(chalk.yellow(msg));
52+
});
53+
}
54+
}
55+
56+
export async function selectBumpVersionType(): Promise<BumpVersionType> {
57+
const { bumpType } = await prompt<{ bumpType: string }>({
58+
type: "autocomplete",
59+
name: "bumpType",
60+
message: "Want to bump?",
61+
choices: ["major", "minor", "patch", "set manually"]
62+
});
63+
64+
if (bumpType === "set manually") {
65+
const { nextVersion } = await prompt<{ nextVersion: string }>({
66+
type: "input",
67+
name: "nextVersion",
68+
message: "Set package version to"
69+
});
70+
71+
return nextVersion;
72+
} else {
73+
return bumpType;
74+
}
75+
}
76+
77+
export async function getNextVersion(currentVersion: string): Promise<string> {
78+
const bumpVersionType = await selectBumpVersionType();
79+
const nextVersion = getNewVersion(bumpVersionType, currentVersion);
80+
console.log(chalk.green(`Version change: ${currentVersion} => ${nextVersion}`));
81+
return nextVersion;
7082
}

packages/tools/release-utils-internal/src/changelog-parser/index.ts

Lines changed: 36 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,28 @@ function formatDate(date: Date): string {
8080
.padStart(2, "0")}`;
8181
}
8282

83+
function mergeUnreleased<T extends UnreleasedVersionEntry>(unreleased: T, sections: LogSection[]): T {
84+
const currentTypes = unreleased.sections.map(s => s.type);
85+
const incomingTypes = sections.map(s => s.type);
86+
const uniqueTypes = new Set([...currentTypes, ...incomingTypes]);
87+
88+
const nextSections = Array.from(uniqueTypes).map(type => {
89+
const section = unreleased.sections.find(s => s.type === type) ?? {
90+
type,
91+
logs: []
92+
};
93+
94+
const incomingLogs = sections.flatMap(s => (s.type === type ? s.logs : []));
95+
96+
return { type: section.type, logs: [...section.logs, ...incomingLogs] };
97+
});
98+
99+
return {
100+
...unreleased,
101+
sections: nextSections
102+
};
103+
}
104+
83105
export class WidgetChangelogFileWrapper {
84106
changelog: WidgetChangelogFile;
85107

@@ -141,31 +163,11 @@ export class WidgetChangelogFileWrapper {
141163

142164
addUnreleasedSections(sections: LogSection[]): WidgetChangelogFileWrapper {
143165
const [unreleased, ...rest] = this.changelog.content;
144-
const currentTypes = unreleased.sections.map(s => s.type);
145-
const incomingTypes = sections.map(s => s.type);
146-
const uniqueTypes = new Set([...currentTypes, ...incomingTypes]);
147-
148-
const nextSections = Array.from(uniqueTypes).map(type => {
149-
const section = unreleased.sections.find(s => s.type === type) ?? {
150-
type,
151-
logs: []
152-
};
153-
154-
const incomingLogs = sections.flatMap(s => (s.type === type ? s.logs : []));
155-
156-
return { type: section.type, logs: [...section.logs, ...incomingLogs] };
157-
});
158166

159167
return new WidgetChangelogFileWrapper(
160168
{
161169
header: this.changelog.header,
162-
content: [
163-
{
164-
type: "unreleased",
165-
sections: nextSections
166-
},
167-
...rest
168-
]
170+
content: [mergeUnreleased(unreleased, sections), ...rest]
169171
},
170172
this.changelogPath
171173
);
@@ -247,6 +249,19 @@ export class ModuleChangelogFileWrapper {
247249
);
248250
}
249251

252+
addUnreleasedSections(sections: LogSection[]): ModuleChangelogFileWrapper {
253+
const [unreleased, ...rest] = this.changelog.content;
254+
255+
return new ModuleChangelogFileWrapper(
256+
{
257+
header: this.changelog.header,
258+
content: [mergeUnreleased(unreleased, sections), ...rest],
259+
moduleName: this.moduleName
260+
},
261+
this.changelogPath
262+
);
263+
}
264+
250265
addUnreleasedSubcomponents(subcomponents: SubComponentEntry[]): ModuleChangelogFileWrapper {
251266
const [unreleased, ...releasedContent] = this.changelog.content;
252267

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import ora from "ora";
2+
3+
export async function oraPromise<T>(task: Promise<T>, msg: string): Promise<T> {
4+
const spinner = ora(msg);
5+
spinner.start();
6+
const r = await task;
7+
spinner.stop();
8+
return r;
9+
}

packages/tools/release-utils-internal/src/monorepo.ts

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { prompt } from "enquirer";
2+
import { oraPromise } from "./cli-utils";
13
import { exec, find, mkdir, cp } from "./shell";
24

35
type DependencyName = string;
@@ -37,3 +39,22 @@ export async function copyMpkFiles(packageNames: string[], dest: string): Promis
3739
mkdir("-p", dest);
3840
cp(paths, dest);
3941
}
42+
43+
export async function selectPackage(): Promise<PackageListing> {
44+
const pkgs = await oraPromise(listPackages(["'*'", "!web-widgets"]), "Loading packages...");
45+
46+
const { packageName } = await prompt<{ packageName: string }>({
47+
type: "autocomplete",
48+
name: "packageName",
49+
message: "Please select package",
50+
choices: pkgs.map(pkg => pkg.name)
51+
});
52+
53+
const pkg = pkgs.find(p => p.name === packageName);
54+
55+
if (!pkg) {
56+
throw new Error(`Unable to find package meta for ${packageName}`);
57+
}
58+
59+
return pkg;
60+
}

pnpm-lock.yaml

Lines changed: 2 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)