githublogen 0.0.2 → 0.0.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cli.cjs +3 -2
- package/dist/cli.mjs +3 -2
- package/dist/index.cjs +38 -20
- package/dist/index.mjs +38 -20
- package/package.json +1 -1
package/dist/cli.cjs
CHANGED
|
@@ -13,7 +13,7 @@ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'defau
|
|
|
13
13
|
const fs__default = /*#__PURE__*/_interopDefaultCompat(fs);
|
|
14
14
|
const cac__default = /*#__PURE__*/_interopDefaultCompat(cac);
|
|
15
15
|
|
|
16
|
-
const version = "0.0.
|
|
16
|
+
const version = "0.0.4";
|
|
17
17
|
|
|
18
18
|
const cli = cac__default("githublogen");
|
|
19
19
|
cli.version(version).option("-t, --token <path>", "GitHub Token").option("--from <ref>", "From tag").option("--to <ref>", "To tag").option("--github <path>", "GitHub Repository, e.g. soybeanjs/githublogen").option("--name <name>", "Name of the release").option("--contributors", "Show contributors section").option("--prerelease", "Mark release as prerelease").option("-d, --draft", "Mark release as draft").option("--output <path>", "Output to file instead of sending to GitHub").option("--capitalize", "Should capitalize for each comment message").option("--emoji", "Use emojis in section titles", { default: true }).option("--group", "Nest commit messages under their scopes").option("--dry", "Dry run").help();
|
|
@@ -60,8 +60,9 @@ cli.command("").action(async (args) => {
|
|
|
60
60
|
await index.sendRelease(config, md);
|
|
61
61
|
} catch (e) {
|
|
62
62
|
console.error(kolorist.red(String(e)));
|
|
63
|
-
if (e?.stack)
|
|
63
|
+
if (e?.stack) {
|
|
64
64
|
console.error(kolorist.dim(e.stack?.split("\n").slice(1).join("\n")));
|
|
65
|
+
}
|
|
65
66
|
process.exit(1);
|
|
66
67
|
}
|
|
67
68
|
});
|
package/dist/cli.mjs
CHANGED
|
@@ -6,7 +6,7 @@ import { generate, hasTagOnGitHub, isRepoShallow, sendRelease } from './index.mj
|
|
|
6
6
|
import 'ohmyfetch';
|
|
7
7
|
import 'convert-gitmoji';
|
|
8
8
|
|
|
9
|
-
const version = "0.0.
|
|
9
|
+
const version = "0.0.4";
|
|
10
10
|
|
|
11
11
|
const cli = cac("githublogen");
|
|
12
12
|
cli.version(version).option("-t, --token <path>", "GitHub Token").option("--from <ref>", "From tag").option("--to <ref>", "To tag").option("--github <path>", "GitHub Repository, e.g. soybeanjs/githublogen").option("--name <name>", "Name of the release").option("--contributors", "Show contributors section").option("--prerelease", "Mark release as prerelease").option("-d, --draft", "Mark release as draft").option("--output <path>", "Output to file instead of sending to GitHub").option("--capitalize", "Should capitalize for each comment message").option("--emoji", "Use emojis in section titles", { default: true }).option("--group", "Nest commit messages under their scopes").option("--dry", "Dry run").help();
|
|
@@ -53,8 +53,9 @@ cli.command("").action(async (args) => {
|
|
|
53
53
|
await sendRelease(config, md);
|
|
54
54
|
} catch (e) {
|
|
55
55
|
console.error(red(String(e)));
|
|
56
|
-
if (e?.stack)
|
|
56
|
+
if (e?.stack) {
|
|
57
57
|
console.error(dim(e.stack?.split("\n").slice(1).join("\n")));
|
|
58
|
+
}
|
|
58
59
|
process.exit(1);
|
|
59
60
|
}
|
|
60
61
|
});
|
package/dist/index.cjs
CHANGED
|
@@ -102,15 +102,16 @@ async function resolveAuthorInfo(options, info) {
|
|
|
102
102
|
authorInfo.login = data.items[0].login;
|
|
103
103
|
} catch {
|
|
104
104
|
}
|
|
105
|
-
if (
|
|
106
|
-
return
|
|
105
|
+
if (authorInfo.login) {
|
|
106
|
+
return authorInfo;
|
|
107
|
+
}
|
|
107
108
|
if (info.commits.length) {
|
|
108
109
|
try {
|
|
109
110
|
const data = await ohmyfetch.$fetch(`https://api.github.com/repos/${options.github}/commits/${info.commits[0]}`, {
|
|
110
111
|
headers: getHeaders(options)
|
|
111
112
|
});
|
|
112
113
|
authorInfo.login = data.author.login;
|
|
113
|
-
} catch
|
|
114
|
+
} catch {
|
|
114
115
|
}
|
|
115
116
|
}
|
|
116
117
|
return authorInfo;
|
|
@@ -119,8 +120,9 @@ async function resolveAuthors(commits, options) {
|
|
|
119
120
|
const map = /* @__PURE__ */ new Map();
|
|
120
121
|
commits.forEach((commit) => {
|
|
121
122
|
commit.resolvedAuthors = commit.authors.map((a, idx) => {
|
|
122
|
-
if (!a.email || !a.name)
|
|
123
|
+
if (!a.email || !a.name) {
|
|
123
124
|
return null;
|
|
125
|
+
}
|
|
124
126
|
if (!map.has(a.email)) {
|
|
125
127
|
map.set(a.email, {
|
|
126
128
|
commits: [],
|
|
@@ -129,8 +131,9 @@ async function resolveAuthors(commits, options) {
|
|
|
129
131
|
});
|
|
130
132
|
}
|
|
131
133
|
const info = map.get(a.email);
|
|
132
|
-
if (idx === 0)
|
|
134
|
+
if (idx === 0) {
|
|
133
135
|
info.commits.push(commit.shortHash);
|
|
136
|
+
}
|
|
134
137
|
return info;
|
|
135
138
|
}).filter(notNullish);
|
|
136
139
|
});
|
|
@@ -139,13 +142,15 @@ async function resolveAuthors(commits, options) {
|
|
|
139
142
|
const loginSet = /* @__PURE__ */ new Set();
|
|
140
143
|
const nameSet = /* @__PURE__ */ new Set();
|
|
141
144
|
return resolved.sort((a, b) => (a.login || a.name).localeCompare(b.login || b.name)).filter((i) => {
|
|
142
|
-
if (i.login && loginSet.has(i.login))
|
|
145
|
+
if (i.login && loginSet.has(i.login)) {
|
|
143
146
|
return false;
|
|
147
|
+
}
|
|
144
148
|
if (i.login) {
|
|
145
149
|
loginSet.add(i.login);
|
|
146
150
|
} else {
|
|
147
|
-
if (nameSet.has(i.name))
|
|
151
|
+
if (nameSet.has(i.name)) {
|
|
148
152
|
return false;
|
|
153
|
+
}
|
|
149
154
|
nameSet.add(i.name);
|
|
150
155
|
}
|
|
151
156
|
return true;
|
|
@@ -165,8 +170,9 @@ async function hasTagOnGitHub(tag, options) {
|
|
|
165
170
|
async function getGitHubRepo() {
|
|
166
171
|
const url = await execCommand("git", ["config", "--get", "remote.origin.url"]);
|
|
167
172
|
const match = url.match(/github\.com[\/:]([\w\d._-]+?)\/([\w\d._-]+?)(\.git)?$/i);
|
|
168
|
-
if (!match)
|
|
173
|
+
if (!match) {
|
|
169
174
|
throw new Error(`Can not parse GitHub repo from url ${url}`);
|
|
175
|
+
}
|
|
170
176
|
return `${match[1]}/${match[2]}`;
|
|
171
177
|
}
|
|
172
178
|
async function getCurrentGitBranch() {
|
|
@@ -225,19 +231,23 @@ async function getGitDiff(from, to = "HEAD") {
|
|
|
225
231
|
const emojisRE = /([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g;
|
|
226
232
|
function formatReferences(references, github, type) {
|
|
227
233
|
const refs = references.filter((i) => {
|
|
228
|
-
if (type === "issues")
|
|
234
|
+
if (type === "issues") {
|
|
229
235
|
return i.type === "issue" || i.type === "pull-request";
|
|
236
|
+
}
|
|
230
237
|
return i.type === "hash";
|
|
231
238
|
}).map((ref) => {
|
|
232
|
-
if (!github)
|
|
239
|
+
if (!github) {
|
|
233
240
|
return ref.value;
|
|
234
|
-
|
|
241
|
+
}
|
|
242
|
+
if (ref.type === "pull-request" || ref.type === "issue") {
|
|
235
243
|
return `https://github.com/${github}/issues/${ref.value.slice(1)}`;
|
|
244
|
+
}
|
|
236
245
|
return `[<samp>(${ref.value.slice(0, 5)})</samp>](https://github.com/${github}/commit/${ref.value})`;
|
|
237
246
|
});
|
|
238
247
|
const referencesString = join(refs).trim();
|
|
239
|
-
if (type === "issues")
|
|
248
|
+
if (type === "issues") {
|
|
240
249
|
return referencesString && `in ${referencesString}`;
|
|
250
|
+
}
|
|
241
251
|
return referencesString;
|
|
242
252
|
}
|
|
243
253
|
function formatLine(commit, options) {
|
|
@@ -246,11 +256,13 @@ function formatLine(commit, options) {
|
|
|
246
256
|
let authors = join([
|
|
247
257
|
...new Set(commit.resolvedAuthors?.map((i) => i.login ? `@${i.login}` : `**${i.name}**`))
|
|
248
258
|
])?.trim();
|
|
249
|
-
if (authors)
|
|
259
|
+
if (authors) {
|
|
250
260
|
authors = `by ${authors}`;
|
|
261
|
+
}
|
|
251
262
|
let refs = [authors, prRefs, hashRefs].filter((i) => i?.trim()).join(" ");
|
|
252
|
-
if (refs)
|
|
263
|
+
if (refs) {
|
|
253
264
|
refs = ` - ${refs}`;
|
|
265
|
+
}
|
|
254
266
|
const description = options.capitalize ? capitalize(commit.description) : commit.description;
|
|
255
267
|
return [description, refs].filter((i) => i?.trim()).join(" ");
|
|
256
268
|
}
|
|
@@ -262,13 +274,15 @@ function formatTitle(name, options) {
|
|
|
262
274
|
return `### ${formatName}`;
|
|
263
275
|
}
|
|
264
276
|
function formatSection(commits, sectionName, options) {
|
|
265
|
-
if (!commits.length)
|
|
277
|
+
if (!commits.length) {
|
|
266
278
|
return [];
|
|
279
|
+
}
|
|
267
280
|
const lines = ["", formatTitle(sectionName, options), ""];
|
|
268
281
|
const scopes = groupBy(commits, "scope");
|
|
269
282
|
let useScopeGroup = options.group;
|
|
270
|
-
if (!Object.entries(scopes).some(([k, v]) => k && v.length > 1))
|
|
283
|
+
if (!Object.entries(scopes).some(([k, v]) => k && v.length > 1)) {
|
|
271
284
|
useScopeGroup = false;
|
|
285
|
+
}
|
|
272
286
|
Object.keys(scopes).sort().forEach((scope) => {
|
|
273
287
|
let padding = "";
|
|
274
288
|
let prefix = "";
|
|
@@ -292,8 +306,9 @@ function generateMarkdown(commits, options) {
|
|
|
292
306
|
const items = group[type] || [];
|
|
293
307
|
lines.push(...formatSection(items, options.types[type].title, options));
|
|
294
308
|
}
|
|
295
|
-
if (!lines.length)
|
|
309
|
+
if (!lines.length) {
|
|
296
310
|
lines.push("*No significant changes*");
|
|
311
|
+
}
|
|
297
312
|
const url = `https://github.com/${options.github}/compare/${options.from}...${options.to}`;
|
|
298
313
|
lines.push("", `##### [View changes on GitHub](${url})`);
|
|
299
314
|
return convertGitmoji.convert(lines.join("\n").trim(), true);
|
|
@@ -336,8 +351,9 @@ async function resolveConfig(options) {
|
|
|
336
351
|
config.to = config.to || await getCurrentGitBranch();
|
|
337
352
|
config.github = config.github || await getGitHubRepo();
|
|
338
353
|
config.prerelease = config.prerelease ?? isPrerelease(config.to);
|
|
339
|
-
if (config.to === config.from)
|
|
354
|
+
if (config.to === config.from) {
|
|
340
355
|
config.from = await getLastGitTag(-1) || await getFirstGitCommit();
|
|
356
|
+
}
|
|
341
357
|
return config;
|
|
342
358
|
}
|
|
343
359
|
|
|
@@ -394,8 +410,10 @@ async function generate(options) {
|
|
|
394
410
|
const resolved = await resolveConfig(options);
|
|
395
411
|
const rawCommits = await getGitDiff(resolved.from, resolved.to);
|
|
396
412
|
const commits = parseCommits(rawCommits, resolved);
|
|
397
|
-
if (resolved.contributors)
|
|
398
|
-
await resolveAuthors(commits, resolved);
|
|
413
|
+
if (resolved.contributors) {
|
|
414
|
+
const authorInfo = await resolveAuthors(commits, resolved);
|
|
415
|
+
Object.assign(resolved, authorInfo);
|
|
416
|
+
}
|
|
399
417
|
const md = generateMarkdown(commits, resolved);
|
|
400
418
|
return { config: resolved, md, commits };
|
|
401
419
|
}
|
package/dist/index.mjs
CHANGED
|
@@ -100,15 +100,16 @@ async function resolveAuthorInfo(options, info) {
|
|
|
100
100
|
authorInfo.login = data.items[0].login;
|
|
101
101
|
} catch {
|
|
102
102
|
}
|
|
103
|
-
if (
|
|
104
|
-
return
|
|
103
|
+
if (authorInfo.login) {
|
|
104
|
+
return authorInfo;
|
|
105
|
+
}
|
|
105
106
|
if (info.commits.length) {
|
|
106
107
|
try {
|
|
107
108
|
const data = await $fetch(`https://api.github.com/repos/${options.github}/commits/${info.commits[0]}`, {
|
|
108
109
|
headers: getHeaders(options)
|
|
109
110
|
});
|
|
110
111
|
authorInfo.login = data.author.login;
|
|
111
|
-
} catch
|
|
112
|
+
} catch {
|
|
112
113
|
}
|
|
113
114
|
}
|
|
114
115
|
return authorInfo;
|
|
@@ -117,8 +118,9 @@ async function resolveAuthors(commits, options) {
|
|
|
117
118
|
const map = /* @__PURE__ */ new Map();
|
|
118
119
|
commits.forEach((commit) => {
|
|
119
120
|
commit.resolvedAuthors = commit.authors.map((a, idx) => {
|
|
120
|
-
if (!a.email || !a.name)
|
|
121
|
+
if (!a.email || !a.name) {
|
|
121
122
|
return null;
|
|
123
|
+
}
|
|
122
124
|
if (!map.has(a.email)) {
|
|
123
125
|
map.set(a.email, {
|
|
124
126
|
commits: [],
|
|
@@ -127,8 +129,9 @@ async function resolveAuthors(commits, options) {
|
|
|
127
129
|
});
|
|
128
130
|
}
|
|
129
131
|
const info = map.get(a.email);
|
|
130
|
-
if (idx === 0)
|
|
132
|
+
if (idx === 0) {
|
|
131
133
|
info.commits.push(commit.shortHash);
|
|
134
|
+
}
|
|
132
135
|
return info;
|
|
133
136
|
}).filter(notNullish);
|
|
134
137
|
});
|
|
@@ -137,13 +140,15 @@ async function resolveAuthors(commits, options) {
|
|
|
137
140
|
const loginSet = /* @__PURE__ */ new Set();
|
|
138
141
|
const nameSet = /* @__PURE__ */ new Set();
|
|
139
142
|
return resolved.sort((a, b) => (a.login || a.name).localeCompare(b.login || b.name)).filter((i) => {
|
|
140
|
-
if (i.login && loginSet.has(i.login))
|
|
143
|
+
if (i.login && loginSet.has(i.login)) {
|
|
141
144
|
return false;
|
|
145
|
+
}
|
|
142
146
|
if (i.login) {
|
|
143
147
|
loginSet.add(i.login);
|
|
144
148
|
} else {
|
|
145
|
-
if (nameSet.has(i.name))
|
|
149
|
+
if (nameSet.has(i.name)) {
|
|
146
150
|
return false;
|
|
151
|
+
}
|
|
147
152
|
nameSet.add(i.name);
|
|
148
153
|
}
|
|
149
154
|
return true;
|
|
@@ -163,8 +168,9 @@ async function hasTagOnGitHub(tag, options) {
|
|
|
163
168
|
async function getGitHubRepo() {
|
|
164
169
|
const url = await execCommand("git", ["config", "--get", "remote.origin.url"]);
|
|
165
170
|
const match = url.match(/github\.com[\/:]([\w\d._-]+?)\/([\w\d._-]+?)(\.git)?$/i);
|
|
166
|
-
if (!match)
|
|
171
|
+
if (!match) {
|
|
167
172
|
throw new Error(`Can not parse GitHub repo from url ${url}`);
|
|
173
|
+
}
|
|
168
174
|
return `${match[1]}/${match[2]}`;
|
|
169
175
|
}
|
|
170
176
|
async function getCurrentGitBranch() {
|
|
@@ -223,19 +229,23 @@ async function getGitDiff(from, to = "HEAD") {
|
|
|
223
229
|
const emojisRE = /([\u2700-\u27BF]|[\uE000-\uF8FF]|\uD83C[\uDC00-\uDFFF]|\uD83D[\uDC00-\uDFFF]|[\u2011-\u26FF]|\uD83E[\uDD10-\uDDFF])/g;
|
|
224
230
|
function formatReferences(references, github, type) {
|
|
225
231
|
const refs = references.filter((i) => {
|
|
226
|
-
if (type === "issues")
|
|
232
|
+
if (type === "issues") {
|
|
227
233
|
return i.type === "issue" || i.type === "pull-request";
|
|
234
|
+
}
|
|
228
235
|
return i.type === "hash";
|
|
229
236
|
}).map((ref) => {
|
|
230
|
-
if (!github)
|
|
237
|
+
if (!github) {
|
|
231
238
|
return ref.value;
|
|
232
|
-
|
|
239
|
+
}
|
|
240
|
+
if (ref.type === "pull-request" || ref.type === "issue") {
|
|
233
241
|
return `https://github.com/${github}/issues/${ref.value.slice(1)}`;
|
|
242
|
+
}
|
|
234
243
|
return `[<samp>(${ref.value.slice(0, 5)})</samp>](https://github.com/${github}/commit/${ref.value})`;
|
|
235
244
|
});
|
|
236
245
|
const referencesString = join(refs).trim();
|
|
237
|
-
if (type === "issues")
|
|
246
|
+
if (type === "issues") {
|
|
238
247
|
return referencesString && `in ${referencesString}`;
|
|
248
|
+
}
|
|
239
249
|
return referencesString;
|
|
240
250
|
}
|
|
241
251
|
function formatLine(commit, options) {
|
|
@@ -244,11 +254,13 @@ function formatLine(commit, options) {
|
|
|
244
254
|
let authors = join([
|
|
245
255
|
...new Set(commit.resolvedAuthors?.map((i) => i.login ? `@${i.login}` : `**${i.name}**`))
|
|
246
256
|
])?.trim();
|
|
247
|
-
if (authors)
|
|
257
|
+
if (authors) {
|
|
248
258
|
authors = `by ${authors}`;
|
|
259
|
+
}
|
|
249
260
|
let refs = [authors, prRefs, hashRefs].filter((i) => i?.trim()).join(" ");
|
|
250
|
-
if (refs)
|
|
261
|
+
if (refs) {
|
|
251
262
|
refs = ` - ${refs}`;
|
|
263
|
+
}
|
|
252
264
|
const description = options.capitalize ? capitalize(commit.description) : commit.description;
|
|
253
265
|
return [description, refs].filter((i) => i?.trim()).join(" ");
|
|
254
266
|
}
|
|
@@ -260,13 +272,15 @@ function formatTitle(name, options) {
|
|
|
260
272
|
return `### ${formatName}`;
|
|
261
273
|
}
|
|
262
274
|
function formatSection(commits, sectionName, options) {
|
|
263
|
-
if (!commits.length)
|
|
275
|
+
if (!commits.length) {
|
|
264
276
|
return [];
|
|
277
|
+
}
|
|
265
278
|
const lines = ["", formatTitle(sectionName, options), ""];
|
|
266
279
|
const scopes = groupBy(commits, "scope");
|
|
267
280
|
let useScopeGroup = options.group;
|
|
268
|
-
if (!Object.entries(scopes).some(([k, v]) => k && v.length > 1))
|
|
281
|
+
if (!Object.entries(scopes).some(([k, v]) => k && v.length > 1)) {
|
|
269
282
|
useScopeGroup = false;
|
|
283
|
+
}
|
|
270
284
|
Object.keys(scopes).sort().forEach((scope) => {
|
|
271
285
|
let padding = "";
|
|
272
286
|
let prefix = "";
|
|
@@ -290,8 +304,9 @@ function generateMarkdown(commits, options) {
|
|
|
290
304
|
const items = group[type] || [];
|
|
291
305
|
lines.push(...formatSection(items, options.types[type].title, options));
|
|
292
306
|
}
|
|
293
|
-
if (!lines.length)
|
|
307
|
+
if (!lines.length) {
|
|
294
308
|
lines.push("*No significant changes*");
|
|
309
|
+
}
|
|
295
310
|
const url = `https://github.com/${options.github}/compare/${options.from}...${options.to}`;
|
|
296
311
|
lines.push("", `##### [View changes on GitHub](${url})`);
|
|
297
312
|
return convert(lines.join("\n").trim(), true);
|
|
@@ -334,8 +349,9 @@ async function resolveConfig(options) {
|
|
|
334
349
|
config.to = config.to || await getCurrentGitBranch();
|
|
335
350
|
config.github = config.github || await getGitHubRepo();
|
|
336
351
|
config.prerelease = config.prerelease ?? isPrerelease(config.to);
|
|
337
|
-
if (config.to === config.from)
|
|
352
|
+
if (config.to === config.from) {
|
|
338
353
|
config.from = await getLastGitTag(-1) || await getFirstGitCommit();
|
|
354
|
+
}
|
|
339
355
|
return config;
|
|
340
356
|
}
|
|
341
357
|
|
|
@@ -392,8 +408,10 @@ async function generate(options) {
|
|
|
392
408
|
const resolved = await resolveConfig(options);
|
|
393
409
|
const rawCommits = await getGitDiff(resolved.from, resolved.to);
|
|
394
410
|
const commits = parseCommits(rawCommits, resolved);
|
|
395
|
-
if (resolved.contributors)
|
|
396
|
-
await resolveAuthors(commits, resolved);
|
|
411
|
+
if (resolved.contributors) {
|
|
412
|
+
const authorInfo = await resolveAuthors(commits, resolved);
|
|
413
|
+
Object.assign(resolved, authorInfo);
|
|
414
|
+
}
|
|
397
415
|
const md = generateMarkdown(commits, resolved);
|
|
398
416
|
return { config: resolved, md, commits };
|
|
399
417
|
}
|