-
Notifications
You must be signed in to change notification settings - Fork 494
/
index.ts
112 lines (102 loc) 路 3.34 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
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";
type UnwrapPromise<T extends Promise<any>> = T extends Promise<infer R>
? R
: never;
export default async function add(
cwd: string,
{ empty, open }: { empty?: boolean; open?: boolean },
config: Config
) {
const packages = await getPackages(cwd);
const changesetBase = path.resolve(cwd, ".changeset");
let newChangeset: UnwrapPromise<ReturnType<typeof createChangeset>>;
if (empty) {
newChangeset = {
confirmed: true,
releases: [],
summary: ``
};
} else {
const changedPackages = await git.getChangedPackagesSinceRef({
cwd,
ref: config.baseBranch
});
const changePackagesName = changedPackages
.filter(a => a)
.map(pkg => pkg.packageJson.name);
newChangeset = await createChangeset(
changePackagesName,
packages.packages,
config.enablePrivatePackageTracking
);
printConfirmationMessage(newChangeset, packages.packages.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"
}
);
}
}
}