/
index.ts
114 lines (104 loc) 路 3.58 KB
/
index.ts
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
import chalk from "chalk";
import path from "path";
import { spawn } from "child_process";
import * as cli from "../../utils/cli-utilities";
import * as git from "@changesets/git";
import { info, log, warn } from "@changesets/logger";
import { Config } from "@changesets/types";
import { getPackages } from "@manypkg/get-packages";
import writeChangeset from "@changesets/write";
import { getCommitFunctions } from "../../commit/getCommitFunctions";
import createChangeset from "./createChangeset";
import printConfirmationMessage from "./messages";
import { ExternalEditor } from "external-editor";
import { isListablePackage } from "./isListablePackage";
export default async function add(
cwd: string,
{ empty, open }: { empty?: boolean; open?: boolean },
config: Config
) {
const packages = await getPackages(cwd);
if (packages.packages.length === 0) {
throw new Error(
`No packages found. You might have ${packages.tool} workspaces configured but no packages yet?`
);
}
const listablePackages = packages.packages.filter((pkg) =>
isListablePackage(config, pkg.packageJson)
);
const changesetBase = path.resolve(cwd, ".changeset");
let newChangeset: Awaited<ReturnType<typeof createChangeset>>;
if (empty) {
newChangeset = {
confirmed: true,
releases: [],
summary: ``,
};
} else {
const changedPackages = await git.getChangedPackagesSinceRef({
cwd,
ref: config.baseBranch,
});
const changedPackagesName = changedPackages
.filter((pkg) => isListablePackage(config, pkg.packageJson))
.map((pkg) => pkg.packageJson.name);
newChangeset = await createChangeset(changedPackagesName, listablePackages);
printConfirmationMessage(newChangeset, listablePackages.length > 1);
if (!newChangeset.confirmed) {
newChangeset = {
...newChangeset,
confirmed: await cli.askConfirm("Is this your desired changeset?"),
};
}
}
if (newChangeset.confirmed) {
const changesetID = await writeChangeset(newChangeset, cwd);
const [{ getAddMessage }, commitOpts] = getCommitFunctions(
config.commit,
cwd
);
if (getAddMessage) {
await git.add(path.resolve(changesetBase, `${changesetID}.md`), cwd);
await git.commit(await getAddMessage(newChangeset, commitOpts), cwd);
log(chalk.green(`${empty ? "Empty " : ""}Changeset added and committed`));
} else {
log(
chalk.green(
`${empty ? "Empty " : ""}Changeset added! - you can now commit it\n`
)
);
}
let hasMajorChange = [...newChangeset.releases].find(
(c) => c.type === "major"
);
if (hasMajorChange) {
warn(
"This Changeset includes a major change and we STRONGLY recommend adding more information to the changeset:"
);
warn("WHAT the breaking change is");
warn("WHY the change was made");
warn("HOW a consumer should update their code");
} else {
log(
chalk.green(
"If you want to modify or expand on the changeset summary, you can find it here"
)
);
}
const changesetPath = path.resolve(changesetBase, `${changesetID}.md`);
info(chalk.blue(changesetPath));
if (open) {
// this is really a hack to reuse the logic embedded in `external-editor` related to determining the editor
const externalEditor = new ExternalEditor();
externalEditor.cleanup();
spawn(
externalEditor.editor.bin,
externalEditor.editor.args.concat([changesetPath]),
{
detached: true,
stdio: "inherit",
}
);
}
}
}