release-notes-cli
Version:
Generate release notes from git for playstore/appstore or github
171 lines (170 loc) • 6.01 kB
JavaScript
;
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.gitRemoteOriginUrl = void 0;
let debug = require("debug")("release-notes:git");
let parser = require("debug")("release-notes:parser");
const gitconfig = require("gitconfiglocal");
const { promisify } = require("util");
const pGitconfig = promisify(gitconfig);
exports.log = function (options) {
return new Promise(function (resolve, reject) {
let spawn = require("child_process").spawn;
let gitArgs = ["log", "--no-color"];
if (options.additionalOptions && options.additionalOptions.length > 0) {
options.additionalOptions.forEach(function (o) {
gitArgs.push("--" + o);
});
}
else {
gitArgs.push(options.mergeCommits ? "--merges" : "--no-merges");
}
gitArgs.push("--branches=" + options.branch, "--format=" + formatOptions, "--decorate=full", options.range);
debug("Spawning git with args %o", gitArgs);
let gitLog = spawn("git", gitArgs, {
cwd: options.cwd,
stdio: ["ignore", "pipe", process.stderr],
});
let allCommits = "";
gitLog.stdout.on("data", function (data) {
allCommits += data;
});
gitLog.on("exit", function (code) {
debug("Git command exited with code '%d'", code);
if (code === 0) {
allCommits = normalizeNewlines(allCommits).trim();
if (allCommits) {
let commits = processCommits(allCommits, options);
resolve(commits);
}
else {
resolve([]);
}
}
else {
reject(new Error("Git log exited with error code " + code));
}
});
});
};
let newCommit = "___";
const formatOptions = [
newCommit,
"sha1:%H",
"authorName:%an",
"authorEmail:%ae",
"authorDate:%aD",
"committerName:%cn",
"committerEmail:%ce",
"committerDate:%cD",
"title:%s",
"%D",
"%w(80,1,1)%b",
].join("%n");
function processCommits(commitMessages, options) {
let stream = commitMessages.split("\n");
let commits = [];
let workingCommit;
parser("Iterating on %d lines", stream.length);
stream.forEach(function (rawLine) {
parser("Raw line\n\t%s", rawLine);
let line = parseLine(rawLine);
parser("Parsed line %o", line);
if (line.type === "new") {
workingCommit = {
messageLines: [],
};
commits.push(workingCommit);
}
else if (line.type === "message") {
workingCommit.messageLines.push(line.message);
}
else if (line.type === "title") {
let title = parseTitle(line.message, options);
parser("Parsed title %o", title);
for (let prop in title) {
workingCommit[prop] = title[prop];
}
if (!workingCommit.title) {
workingCommit.title = line.message;
}
}
else if (line.type === "tag") {
parser("Trying to parse tag %o", line.message);
let tag = parseTag(line.message);
parser("Parse tag %o", tag);
workingCommit[line.type] = tag;
}
else {
workingCommit[line.type] = line.message;
}
});
return commits;
}
function parseLine(line) {
if (line === newCommit) {
return {
type: "new",
};
}
let match = line.match(/^([a-zA-Z]+1?)\s?:\s?(.*)$/i);
if (match) {
return {
type: match[1],
message: match[2].trim(),
};
}
else {
return {
type: "message",
message: line.substring(1),
};
}
}
function parseTitle(title, options) {
let expression = options.title;
let names = options.meaning || [];
parser("Parsing title '%s' with regular expression '%s' and meanings %o", title, expression, names);
let match = title.match(expression);
if (!match) {
return {
title: title,
};
}
else {
let builtObject = {};
for (let i = 0; i < names.length; i += 1) {
let name = names[i];
let index = i + 1;
builtObject[name] = match[index];
}
return builtObject;
}
}
function parseTag(line) {
let refs = line.split(/(refs)\/(tags|remotes|heads)\//);
let tagIndex = refs.findIndex((token, index, all) => all[index - 2] === "refs" && all[index - 1] === "tags");
if (tagIndex === refs.length - 1) {
return refs[tagIndex];
}
return refs[tagIndex].replace(/, $/, "");
}
function normalizeNewlines(message) {
return message.replace(/\r\n?|[\n\u2028\u2029]/g, "\n").replace(/^\uFEFF/, "");
}
function gitRemoteOriginUrl({ cwd = process.cwd(), remoteName = "origin" } = {}) {
return __awaiter(this, void 0, void 0, function* () {
const config = yield pGitconfig(cwd);
const url = (config.remote && config.remote[remoteName] && config.remote[remoteName].url) || "";
return url.replace(/\.git$/, "");
});
}
exports.gitRemoteOriginUrl = gitRemoteOriginUrl;