From 040d5a374f74e5cf185d182397570e539adbbc18 Mon Sep 17 00:00:00 2001 From: Daniel Ostapenko Date: Wed, 24 Mar 2021 12:54:51 +0200 Subject: [PATCH] Remove gitlog dependency --- package.json | 1 - .../git/_tests/localGetCommits.test.ts | 11 +-- .../git/_tests/localLogGitCommits.test.ts | 30 ++++++ source/platforms/git/localGetCommits.ts | 40 +++----- source/platforms/git/localLogGitCommits.ts | 97 +++++++++++++++++++ yarn.lock | 13 --- 6 files changed, 146 insertions(+), 46 deletions(-) create mode 100644 source/platforms/git/_tests/localLogGitCommits.test.ts create mode 100644 source/platforms/git/localLogGitCommits.ts diff --git a/package.json b/package.json index 84f3bc06a..8d5aefc42 100644 --- a/package.json +++ b/package.json @@ -144,7 +144,6 @@ "fast-json-patch": "^3.0.0-1", "get-stdin": "^6.0.0", "gitlab": "^10.0.1", - "gitlog": "^4.0.4", "http-proxy-agent": "^2.1.0", "https-proxy-agent": "^2.2.1", "hyperlinker": "^1.0.0", diff --git a/source/platforms/git/_tests/localGetCommits.test.ts b/source/platforms/git/_tests/localGetCommits.test.ts index 98d0dc65a..a03caa341 100644 --- a/source/platforms/git/_tests/localGetCommits.test.ts +++ b/source/platforms/git/_tests/localGetCommits.test.ts @@ -1,6 +1,5 @@ -import gitlog from "gitlog" - import { localGetCommits } from "../localGetCommits" +import { logGitCommits } from "../localLogGitCommits" const hash = "hash" const abbrevParentHashes = "abbrevParentHashes" @@ -26,9 +25,9 @@ const gitLogCommitMock = { subject, } -jest.mock("gitlog", () => ({ +jest.mock("../localLogGitCommits", () => ({ __esModule: true, - default: jest.fn(() => [gitLogCommitMock]), + logGitCommits: jest.fn(() => [gitLogCommitMock]), })) it("generates a JSON-like commit message", () => { @@ -37,8 +36,8 @@ it("generates a JSON-like commit message", () => { const result = localGetCommits(base, head) - expect(gitlog).toHaveBeenCalledWith({ - repo: expect.any(String), + expect(logGitCommits).toHaveBeenCalledWith({ + number: expect.any(Number), branch: `${base}...${head}`, fields: expect.any(Array), }) diff --git a/source/platforms/git/_tests/localLogGitCommits.test.ts b/source/platforms/git/_tests/localLogGitCommits.test.ts new file mode 100644 index 000000000..213dd1cf5 --- /dev/null +++ b/source/platforms/git/_tests/localLogGitCommits.test.ts @@ -0,0 +1,30 @@ +import { execFileSync } from "child_process" + +import { logGitCommits } from "../localLogGitCommits" + +const COMMAND_OUTPUT = "" + +jest.mock("child_process", () => ({ + __esModule: true, + execFileSync: jest.fn(() => COMMAND_OUTPUT), +})) + +it("get git commits from the 'git log' command", () => { + const options = { + number: 10, + branch: "test_branch", + fields: ["hash" as "hash", "subject" as "subject"], + } + + const result = logGitCommits(options) + + expect(execFileSync).toHaveBeenCalledWith("git", [ + "log", + "-l0", + `-n ${options.number}`, + "--pretty=@begin@" + "\t%H\t%s" + "@end@", + options.branch, + ]) + + expect(result).toEqual([]) +}) diff --git a/source/platforms/git/localGetCommits.ts b/source/platforms/git/localGetCommits.ts index 57ece7c91..dc96e0eac 100644 --- a/source/platforms/git/localGetCommits.ts +++ b/source/platforms/git/localGetCommits.ts @@ -1,37 +1,25 @@ -import gitlog, { GitlogOptions } from "gitlog" - +import { logGitCommits } from "./localLogGitCommits" import { GitCommit } from "../../dsl/Commit" export const localGetCommits = (base: string, head: string) => { - const options: GitlogOptions< - | "hash" - | "abbrevParentHashes" - | "treeHash" - | "authorName" - | "authorEmail" - | "authorDate" - | "committerName" - | "committerEmail" - | "committerDate" - | "subject" - > = { - repo: process.cwd(), + const options = { + number: 100, branch: `${base}...${head}`, fields: [ - "hash", - "abbrevParentHashes", - "treeHash", - "authorName", - "authorEmail", - "authorDate", - "committerName", - "committerEmail", - "committerDate", - "subject", + "hash" as "hash", + "abbrevParentHashes" as "abbrevParentHashes", + "treeHash" as "treeHash", + "authorName" as "authorName", + "authorEmail" as "authorEmail", + "authorDate" as "authorDate", + "committerName" as "committerName", + "committerEmail" as "committerEmail", + "committerDate" as "committerDate", + "subject" as "subject", ], } - const commits: GitCommit[] = gitlog(options).map(commit => ({ + const commits: GitCommit[] = logGitCommits(options).map(commit => ({ sha: commit.hash, author: { name: commit.authorName, diff --git a/source/platforms/git/localLogGitCommits.ts b/source/platforms/git/localLogGitCommits.ts new file mode 100644 index 000000000..94a7d8702 --- /dev/null +++ b/source/platforms/git/localLogGitCommits.ts @@ -0,0 +1,97 @@ +import { execFileSync } from "child_process" + +const delimiter = "\t" +const fieldMap = { + hash: "%H", + treeHash: "%T", + abbrevParentHashes: "%P", + authorName: "%an", + authorEmail: "%ae", + authorDate: "%ai", + committerName: "%cn", + committerEmail: "%ce", + committerDate: "%cd", + subject: "%s", +} + +export type GitLogOptions = { + number: number + branch: string + fields: Array> +} + +export type GitLogCommit = { + hash: string + treeHash: string + abbrevParentHashes: string + authorName: string + authorEmail: string + authorDate: string + committerName: string + committerEmail: string + committerDate: string + subject: string +} + +const createCommandArguments = (options: GitLogOptions) => { + // Start constructing command + let command: string[] = ["log", "-l0"] + + command.push(`-n ${options.number}`) + + // Start of custom format + let prettyArgument = "--pretty=@begin@" + + // Iterating through the fields and adding them to the custom format + if (options.fields) { + options.fields.forEach(field => { + prettyArgument += delimiter + fieldMap[field] + }) + } + + // Close custom format + prettyArgument += "@end@" + command.push(prettyArgument) + + // Append branch (revision range) if specified + if (options.branch) { + command.push(options.branch) + } + + return command +} + +const parseCommits = (commits: string[], fields: string[]) => + commits.map(rawCommit => { + const parts = rawCommit.split("@end@") + const commit = parts[0].split(delimiter) + + // Remove the first empty char from the array + commit.shift() + + const parsed = {} + + commit.forEach((commitField, index) => { + if (!fields[index]) { + return + } + + parsed[fields[index]] = commitField + }) + + return parsed as GitLogCommit + }) + +export const logGitCommits = (options: GitLogOptions) => { + const commandArguments = createCommandArguments(options) + + const stdout = execFileSync("git", commandArguments).toString() + + const commits = stdout.split("@begin@") + + if (commits[0] === "") { + commits.shift() + } + + return parseCommits(commits, options.fields) +} diff --git a/yarn.lock b/yarn.lock index 4aff9ebc7..af819f096 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3756,14 +3756,6 @@ gitlab@^10.0.1: randomstring "^1.1.5" universal-url "^2.0.0" -gitlog@^4.0.4: - version "4.0.4" - resolved "https://registry.yarnpkg.com/gitlog/-/gitlog-4.0.4.tgz#8da6c08748dc290eb6c2fc11e3c505fb73715564" - integrity sha512-jeY2kO7CVyTa6cUM7ZD2ZxIyBkna1xvW2esV/3o8tbhiUneX1UBQCH4D9aMrHgGiohBjyXbuZogyjKXslnY5Yg== - dependencies: - debug "^4.1.1" - tslib "^1.14.1" - glob-parent@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-3.1.0.tgz#9e6af6299d8d3bd2bd40430832bd113df906c5ae" @@ -8693,11 +8685,6 @@ ts-node@^8.0.2: source-map-support "^0.5.6" yn "^3.0.0" -tslib@^1.14.1: - version "1.14.1" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" - integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== - tslib@^1.8.0: version "1.8.1" resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.8.1.tgz#6946af2d1d651a7b1863b531d6e5afa41aa44eac"