UNPKG

release-notes-cli

Version:

Generate release notes from git for playstore/appstore or github

171 lines (170 loc) 6.01 kB
"use strict"; 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;