-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.js
executable file
·145 lines (115 loc) · 3.62 KB
/
index.js
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
#!/usr/bin/env node
"use strict";
const args = require("minimist")(process.argv.slice(2));
const shell = require("shelljs");
const chalk = require("chalk");
const fs = require("fs");
const path = require("path");
const version = require("./package.json").version;
if (!shell.which("git")) {
shell.echo(chalk.red("Sorry, this script requires git"));
shell.exit(1);
}
if (args.version || args.v) {
shell.echo(version);
shell.exit(0);
}
if (args.help || args.h) {
shell.echo(
fs.readFileSync(path.resolve(__dirname, "./ressource/usage.txt"), "utf8")
);
shell.exit(0);
}
const isInRepoGit =
shell.exec("git rev-parse --show-toplevel", { silent: true }).code === 0;
if (!isInRepoGit) {
shell.echo(chalk.red("Sorry, this script must be run in a git repository"));
shell.exit(1);
}
const baseBranch = args.base ?? "develop";
const maxLines = args.max ?? 500;
if (!(typeof maxLines === "number")) {
shell.echo(chalk.red("Sorry, max must be a number"));
shell.exit(1);
}
const isBaseBranchExists =
shell.exec(`git rev-parse --verify ${baseBranch}`, { silent: true }).code ===
0;
if (!isBaseBranchExists) {
shell.echo(chalk.red(`Sorry, the base branch ${baseBranch} does not exist`));
shell.exit(1);
}
const isSomethingToCommit =
shell.exec("git status --porcelain", { silent: true }).stdout.length > 0;
if (isSomethingToCommit) {
shell.echo(chalk.red("Sorry, there are changes in stage"));
shell.exit(1);
}
const prBranch = shell
.exec("git rev-parse --abbrev-ref HEAD", { silent: true })
.stdout.trim();
const onFinish = () => {
shell.exec(`git merge --abort`, { silent: true });
shell.exec(`git checkout ${prBranch}`, { silent: true });
};
shell.exec(`git checkout ${baseBranch}`, { silent: true });
const mergeStatusCode = shell.exec(
`git merge --no-ff --no-commit ${prBranch}`,
{ silent: true }
).code;
if (mergeStatusCode !== 0) {
shell.echo(chalk.red("Sorry, merge failed"));
onFinish();
shell.exit(1);
}
const excludeFiles = (args.exclude?.split(";") ?? []).flatMap((glob) =>
shell.ls(glob)
);
const includeFiles = (args.include?.split(";") ?? []).flatMap((glob) =>
shell.ls(glob)
);
const excludeOptions = excludeFiles.map((f) => `':!${f}'`).join(" ");
const includeOptions = includeFiles.map((f) => `'${f}'`).join(" ");
const changes = shell.exec(
`git diff --staged --stat ${excludeOptions} ${includeOptions}`,
{ silent: true }
).stdout;
if (!changes || changes.length === 0) {
shell.echo(chalk.red("Sorry, there are no changes"));
onFinish();
shell.exit(1);
}
onFinish();
const changesLines = changes.split("\n").filter((l) => l.trim());
const lastLine = changesLines[changesLines.length - 1];
const changesSummaryRegex =
/(\d+ files? changed, )(\d+)( insertions?\(\+\))(, )(\d+)( deletions?\(\-\))/;
const [
filesInfo,
insertionCount,
insertionInfo,
comma,
deletionCount,
deletionInfo,
] = changesSummaryRegex.exec(lastLine).slice(1);
const isMaxLinesInsertionReached = Number(insertionCount) > maxLines;
const isMaxLinesDeletionReached = Number(deletionCount) > maxLines;
shell.echo("PR number of changes:");
shell.echo(changesLines.slice(0, -1).join("\n"));
shell.echo(
`${filesInfo}${
isMaxLinesInsertionReached
? chalk.red(`${insertionCount}${insertionInfo}`)
: chalk.green(`${insertionCount}${insertionInfo}`)
}${comma}${
isMaxLinesDeletionReached
? chalk.red(`${deletionCount}${deletionInfo}`)
: chalk.green(`${deletionCount}${deletionInfo}`)
}`
);
if (isMaxLinesInsertionReached || isMaxLinesDeletionReached) {
shell.echo(chalk.red(`Sorry, the PR is too big`));
shell.exit(1);
} else {
shell.echo(chalk.green(`The PR is fine`));
}