UNPKG

16.9 kBJavaScriptView Raw
1"use strict";
2var __assign = (this && this.__assign) || function () {
3 __assign = Object.assign || function(t) {
4 for (var s, i = 1, n = arguments.length; i < n; i++) {
5 s = arguments[i];
6 for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7 t[p] = s[p];
8 }
9 return t;
10 };
11 return __assign.apply(this, arguments);
12};
13var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14 return new (P || (P = Promise))(function (resolve, reject) {
15 function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
16 function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
17 function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); }
18 step((generator = generator.apply(thisArg, _arguments || [])).next());
19 });
20};
21var __generator = (this && this.__generator) || function (thisArg, body) {
22 var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
23 return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
24 function verb(n) { return function (v) { return step([n, v]); }; }
25 function step(op) {
26 if (f) throw new TypeError("Generator is already executing.");
27 while (_) try {
28 if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
29 if (y = 0, t) op = [op[0] & 2, t.value];
30 switch (op[0]) {
31 case 0: case 1: t = op; break;
32 case 4: _.label++; return { value: op[1], done: false };
33 case 5: _.label++; y = op[1]; op = [0]; continue;
34 case 7: op = _.ops.pop(); _.trys.pop(); continue;
35 default:
36 if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
37 if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
38 if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
39 if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
40 if (t[2]) _.ops.pop();
41 _.trys.pop(); continue;
42 }
43 op = body.call(thisArg, _);
44 } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
45 if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
46 }
47};
48var __read = (this && this.__read) || function (o, n) {
49 var m = typeof Symbol === "function" && o[Symbol.iterator];
50 if (!m) return o;
51 var i = m.call(o), r, ar = [], e;
52 try {
53 while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
54 }
55 catch (error) { e = { error: error }; }
56 finally {
57 try {
58 if (r && !r.done && (m = i["return"])) m.call(i);
59 }
60 finally { if (e) throw e.error; }
61 }
62 return ar;
63};
64var __spread = (this && this.__spread) || function () {
65 for (var ar = [], i = 0; i < arguments.length; i++) ar = ar.concat(__read(arguments[i]));
66 return ar;
67};
68var __importDefault = (this && this.__importDefault) || function (mod) {
69 return (mod && mod.__esModule) ? mod : { "default": mod };
70};
71Object.defineProperty(exports, "__esModule", { value: true });
72var arr_flatten_1 = __importDefault(require("arr-flatten"));
73var url_1 = require("url");
74var url_join_1 = __importDefault(require("url-join"));
75var make_hooks_1 = require("./utils/make-hooks");
76var filterLabel = function (commits, label) {
77 return commits.filter(function (commit) { return commit.labels.includes(label); });
78};
79var Changelog = /** @class */ (function () {
80 function Changelog(logger, options) {
81 this.logger = logger;
82 this.options = options;
83 this.hooks = make_hooks_1.makeChangelogHooks();
84 this.options.labels.pushToMaster = __assign({ name: 'pushToMaster', title: '⚠️ Pushed to master', description: 'N/A' }, (this.options.labels.pushToMaster || {}));
85 }
86 Changelog.prototype.loadDefaultHooks = function () {
87 var _this = this;
88 this.hooks.renderChangelogAuthor.tap('Default', function (author, commit) {
89 return _this.createUserLink(author, commit);
90 });
91 this.hooks.renderChangelogAuthorLine.tap('Default', function (author, user) {
92 var authorString = author.name && user ? author.name + " (" + user + ")" : user;
93 return authorString ? "- " + authorString : undefined;
94 });
95 this.hooks.renderChangelogLine.tapPromise('Default', function (currCommits, renderLine) { return __awaiter(_this, void 0, void 0, function () {
96 var _this = this;
97 return __generator(this, function (_a) {
98 return [2 /*return*/, Promise.all(currCommits.map(function (commit) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
99 return [2 /*return*/, renderLine(commit)];
100 }); }); }))];
101 });
102 }); });
103 this.hooks.renderChangelogTitle.tap('Default', function (label, changelogTitles) { return "#### " + changelogTitles[label] + "\n"; });
104 };
105 // Every Commit will either be a PR, jira story, or push to master (patch)
106 Changelog.prototype.generateReleaseNotes = function (commits) {
107 return __awaiter(this, void 0, void 0, function () {
108 var split, sections, result;
109 return __generator(this, function (_a) {
110 switch (_a.label) {
111 case 0:
112 if (commits.length === 0) {
113 return [2 /*return*/, ''];
114 }
115 this.logger.verbose.info('Generating release notes for:\n', commits);
116 split = this.splitCommits(commits);
117 this.logger.verbose.info('Split commits into groups');
118 this.logger.veryVerbose.info('\n', split);
119 sections = [];
120 return [4 /*yield*/, this.createLabelSection(split, sections)];
121 case 1:
122 _a.sent();
123 this.logger.verbose.info('Added groups to changelog');
124 return [4 /*yield*/, this.createAuthorSection(split, sections)];
125 case 2:
126 _a.sent();
127 this.logger.verbose.info('Added authors to changelog');
128 result = sections.join('\n\n');
129 this.logger.verbose.info('Successfully generated release notes.');
130 return [2 /*return*/, result];
131 }
132 });
133 });
134 };
135 Changelog.prototype.createUserLink = function (author, commit) {
136 var githubUrl = new url_1.URL(this.options.baseUrl).origin;
137 if (author.username === 'invalid-email-address') {
138 return;
139 }
140 return author.username
141 ? "[@" + author.username + "](" + url_join_1.default(githubUrl, author.username) + ")"
142 : author.email || commit.authorEmail;
143 };
144 /**
145 * Split commits into changelogTitle sections.
146 */
147 Changelog.prototype.splitCommits = function (commits) {
148 var currentCommits = __spread(commits);
149 commits
150 .filter(function (commit) { return commit.labels.length === 0; })
151 .map(function (commit) { return commit.labels.push('patch'); });
152 var sections = Object.values(this.options.labels).filter(function (label) { return label.title; });
153 return Object.assign.apply(Object, __spread([{}], sections.map(function (label) {
154 var _a;
155 var matchedCommits = filterLabel(currentCommits, label.name);
156 if (matchedCommits.length === 0) {
157 return {};
158 }
159 currentCommits = currentCommits.filter(function (commit) { return !matchedCommits.includes(commit); });
160 return _a = {},
161 _a[label.name] = matchedCommits,
162 _a;
163 })));
164 };
165 Changelog.prototype.createUserLinkList = function (commit) {
166 return __awaiter(this, void 0, void 0, function () {
167 var result;
168 var _this = this;
169 return __generator(this, function (_a) {
170 switch (_a.label) {
171 case 0:
172 result = new Set();
173 return [4 /*yield*/, Promise.all(commit.authors.map(function (author) { return __awaiter(_this, void 0, void 0, function () {
174 var link;
175 return __generator(this, function (_a) {
176 switch (_a.label) {
177 case 0: return [4 /*yield*/, this.hooks.renderChangelogAuthor.promise(author, commit, this.options)];
178 case 1:
179 link = _a.sent();
180 if (link) {
181 result.add(link);
182 }
183 return [2 /*return*/];
184 }
185 });
186 }); }))];
187 case 1:
188 _a.sent();
189 return [2 /*return*/, __spread(result).join(' ')];
190 }
191 });
192 });
193 };
194 Changelog.prototype.generateCommitNote = function (commit) {
195 return __awaiter(this, void 0, void 0, function () {
196 var jira, pr, link, prLink, user;
197 return __generator(this, function (_a) {
198 switch (_a.label) {
199 case 0:
200 jira = '';
201 pr = '';
202 if (commit.jira && this.options.jira) {
203 link = url_join_1.default.apply(void 0, __spread([this.options.jira], commit.jira.number));
204 jira = "[" + commit.jira.number + "](" + link + "): ";
205 }
206 if (commit.pullRequest) {
207 prLink = url_join_1.default(this.options.baseUrl, 'pull', commit.pullRequest.number.toString());
208 pr = "[#" + commit.pullRequest.number + "](" + prLink + ")";
209 }
210 return [4 /*yield*/, this.createUserLinkList(commit)];
211 case 1:
212 user = _a.sent();
213 return [2 /*return*/, "- " + jira + commit.subject.trim() + " " + pr + (user ? " (" + user + ")" : '')];
214 }
215 });
216 });
217 };
218 Changelog.prototype.createAuthorSection = function (split, sections) {
219 return __awaiter(this, void 0, void 0, function () {
220 var seenUsers, authors, commits, authorSection;
221 var _this = this;
222 return __generator(this, function (_a) {
223 switch (_a.label) {
224 case 0:
225 seenUsers = new Set();
226 authors = new Set();
227 commits = Object.values(split).reduce(function (labeledCommits, sectionCommits) { return __spread(labeledCommits, sectionCommits); }, []);
228 return [4 /*yield*/, Promise.all(arr_flatten_1.default(commits.map(function (commit) {
229 return commit.authors.map(function (author) { return __awaiter(_this, void 0, void 0, function () {
230 var user, authorEntry;
231 return __generator(this, function (_a) {
232 switch (_a.label) {
233 case 0:
234 if (author.username === 'invalid-email-address') {
235 return [2 /*return*/];
236 }
237 return [4 /*yield*/, this.hooks.renderChangelogAuthor.promise(author, commit, this.options)];
238 case 1:
239 user = _a.sent();
240 if (user && seenUsers.has(user)) {
241 return [2 /*return*/];
242 }
243 seenUsers.add(user);
244 return [4 /*yield*/, this.hooks.renderChangelogAuthorLine.promise(author, user)];
245 case 2:
246 authorEntry = _a.sent();
247 if (authorEntry && !authors.has(authorEntry)) {
248 authors.add(authorEntry);
249 }
250 return [2 /*return*/];
251 }
252 });
253 }); });
254 })))];
255 case 1:
256 _a.sent();
257 if (authors.size === 0) {
258 return [2 /*return*/];
259 }
260 authorSection = "#### Authors: " + authors.size + "\n\n";
261 authorSection += __spread(authors).join('\n');
262 sections.push(authorSection);
263 return [2 /*return*/];
264 }
265 });
266 });
267 };
268 Changelog.prototype.createLabelSection = function (split, sections) {
269 return __awaiter(this, void 0, void 0, function () {
270 var changelogTitles;
271 var _this = this;
272 return __generator(this, function (_a) {
273 switch (_a.label) {
274 case 0:
275 changelogTitles = Object.entries(this.options.labels).reduce(function (titles, _a) {
276 var _b = __read(_a, 2), labelDef = _b[1];
277 if (labelDef.title) {
278 titles[labelDef.name] = labelDef.title;
279 }
280 return titles;
281 }, {});
282 return [4 /*yield*/, Promise.all(Object.entries(split).map(function (_a) {
283 var _b = __read(_a, 2), label = _b[0], labelCommits = _b[1];
284 return __awaiter(_this, void 0, void 0, function () {
285 var title, lines;
286 var _this = this;
287 return __generator(this, function (_c) {
288 switch (_c.label) {
289 case 0: return [4 /*yield*/, this.hooks.renderChangelogTitle.promise(label, changelogTitles)];
290 case 1:
291 title = _c.sent();
292 return [4 /*yield*/, this.hooks.renderChangelogLine.promise(labelCommits, function (commit) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) {
293 return [2 /*return*/, this.generateCommitNote(commit)];
294 }); }); })];
295 case 2:
296 lines = _c.sent();
297 sections.push(__spread([title], lines).join('\n'));
298 return [2 /*return*/];
299 }
300 });
301 });
302 }))];
303 case 1:
304 _a.sent();
305 return [2 /*return*/];
306 }
307 });
308 });
309 };
310 return Changelog;
311}());
312exports.default = Changelog;
313//# sourceMappingURL=changelog.js.map
\No newline at end of file