Skip to content

Commit

Permalink
Merge pull request #1127 from denieler/patch-1
Browse files Browse the repository at this point in the history
Use full unformatted subject message
  • Loading branch information
orta committed Mar 24, 2021
2 parents bf04df7 + 040d5a3 commit 69cd960
Show file tree
Hide file tree
Showing 7 changed files with 233 additions and 71 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -131,7 +131,7 @@
"tslint": "^5.11.0",
"tslint-config-prettier": "^1.15.0",
"typedoc": "0.9.0",
"typescript": "^3.1.1",
"typescript": "^3.9.7",
"typescript-json-schema": "^0.32.0"
},
"dependencies": {
Expand Down
65 changes: 59 additions & 6 deletions source/platforms/git/_tests/localGetCommits.test.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,63 @@
import { formatJSON } from "../localGetCommits"
import { localGetCommits } from "../localGetCommits"
import { logGitCommits } from "../localLogGitCommits"

const hash = "hash"
const abbrevParentHashes = "abbrevParentHashes"
const treeHash = "treeHash"
const authorName = "authorName"
const authorEmail = "authorEmail"
const authorDate = "authorDate"
const committerName = "committerName"
const committerEmail = "committerEmail"
const committerDate = "committerDate"
const subject = "subject"

const gitLogCommitMock = {
hash,
abbrevParentHashes,
treeHash,
authorName,
authorEmail,
authorDate,
committerName,
committerEmail,
committerDate,
subject,
}

jest.mock("../localLogGitCommits", () => ({
__esModule: true,
logGitCommits: jest.fn(() => [gitLogCommitMock]),
}))

it("generates a JSON-like commit message", () => {
expect(formatJSON).toEqual(
'{ "sha": "%H", "parents": "%p", "author": {"name": "%an", "email": "%ae", "date": "%ai" }, "committer": {"name": "%cn", "email": "%ce", "date": "%ci" }, "message": "%f"},'
)
const base = "base-branch"
const head = "head-branch"

const result = localGetCommits(base, head)

expect(logGitCommits).toHaveBeenCalledWith({
number: expect.any(Number),
branch: `${base}...${head}`,
fields: expect.any(Array),
})

const withoutComma = formatJSON.substring(0, formatJSON.length - 1)
expect(() => JSON.parse(withoutComma)).not.toThrow()
expect(result).toEqual([
{
sha: hash,
author: {
name: authorName,
email: authorEmail,
date: authorDate,
},
committer: {
name: committerName,
email: committerEmail,
date: committerDate,
},
message: subject,
tree: treeHash,
url: expect.stringContaining(hash),
},
])
})
30 changes: 30 additions & 0 deletions source/platforms/git/_tests/localLogGitCommits.test.ts
Original file line number Diff line number Diff line change
@@ -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([])
})
94 changes: 38 additions & 56 deletions source/platforms/git/localGetCommits.ts
Original file line number Diff line number Diff line change
@@ -1,58 +1,40 @@
import { debug } from "../../debug"
import JSON5 from "json5"

import { spawn } from "child_process"
import { logGitCommits } from "./localLogGitCommits"
import { GitCommit } from "../../dsl/Commit"

const d = debug("localGetDiff")

const sha = "%H"
const parents = "%p"
const authorName = "%an"
const authorEmail = "%ae"
const authorDate = "%ai"
const committerName = "%cn"
const committerEmail = "%ce"
const committerDate = "%ci"
const message = "%f" // this is subject, not message, so it'll only be one line

const author = `"author": {"name": "${authorName}", "email": "${authorEmail}", "date": "${authorDate}" }`
const committer = `"committer": {"name": "${committerName}", "email": "${committerEmail}", "date": "${committerDate}" }`
export const formatJSON = `{ "sha": "${sha}", "parents": "${parents}", ${author}, ${committer}, "message": "${message}"},`

export const localGetCommits = (base: string, head: string) =>
new Promise<GitCommit[]>((resolve, reject) => {
const args = ["log", `${base}...${head}`, `--pretty=format:${formatJSON}`]
const child = spawn("git", args, { env: process.env })
d("> git", args.join(" "))
const commits: GitCommit[] = []

child.stdout.on("data", async (chunk: Buffer) => {
const data = chunk.toString()
// remove trailing comma, and wrap into an array
const asJSONString = `[${data.substring(0, data.length - 1)}]`
const parsedCommits = JSON5.parse(asJSONString)
const realCommits = parsedCommits.map((c: any) => ({
...c,
parents: c.parents.split(" "),
url: "fake.danger.systems/" + c.sha,
}))

commits.push(...realCommits)
})

child.stderr.on("end", () => resolve(commits))

const errorParts: string[] = []

child.stderr.on("data", (chunk: Buffer) => errorParts.push(chunk.toString()))

child.on("close", code => {
if (code !== 0) {
console.error(`Could not get commits from git between ${base} and ${head}`)
reject(new Error(errorParts.join("")))
} else {
resolve(commits)
}
})
})
export const localGetCommits = (base: string, head: string) => {
const options = {
number: 100,
branch: `${base}...${head}`,
fields: [
"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[] = logGitCommits(options).map(commit => ({
sha: commit.hash,
author: {
name: commit.authorName,
email: commit.authorEmail,
date: commit.authorDate,
},
committer: {
name: commit.committerName,
email: commit.committerEmail,
date: commit.committerDate,
},
message: commit.subject,
tree: commit.treeHash,
url: "fake.danger.systems/" + commit.hash,
}))

return commits
}
97 changes: 97 additions & 0 deletions source/platforms/git/localLogGitCommits.ts
Original file line number Diff line number Diff line change
@@ -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<Partial<keyof typeof fieldMap>>
}

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)
}
2 changes: 1 addition & 1 deletion source/runner/Executor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ export interface ExecutorOptions {
const isTests = typeof jest === "object"

interface ExitCodeContainer {
exitCode: number
exitCode?: number
}

export class Executor {
Expand Down
14 changes: 7 additions & 7 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -1169,9 +1169,9 @@
integrity sha512-GnZbirvmqZUzMgkFn70c74OQpTTUcCzlhQliTzYjQMqg+hVKcDnxdL19Ne3UdYzdMA/+W3eb646FWn/ZaT1NfQ==

"@types/node@^10.11.3":
version "10.11.3"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.11.3.tgz#c055536ac8a5e871701aa01914be5731539d01ee"
integrity sha512-3AvcEJAh9EMatxs+OxAlvAEs7OTy6AG94mcH1iqyVDwVVndekLxzwkWQ/Z4SDbY6GO2oyUXyWW8tQ4rENSSQVQ==
version "10.17.55"
resolved "https://registry.yarnpkg.com/@types/node/-/node-10.17.55.tgz#a147f282edec679b894d4694edb5abeb595fecbd"
integrity sha512-koZJ89uLZufDvToeWO5BrC4CR4OUfHnUz2qoPs/daQH6qq3IN62QFxCTZ+bKaCE0xaoCAJYE4AXre8AbghCrhg==

"@types/p-limit@^2.0.0":
version "2.0.0"
Expand Down Expand Up @@ -8837,10 +8837,10 @@ typescript@^3.0.1:
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.3.tgz#01b70247a6d3c2467f70c45795ef5ea18ce191d5"
integrity sha512-+81MUSyX+BaSo+u2RbozuQk/UWx6hfG0a5gHu4ANEM4sU96XbuIyAB+rWBW1u70c6a5QuZfuYICn3s2UjuHUpA==

typescript@^3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.1.1.tgz#3362ba9dd1e482ebb2355b02dfe8bcd19a2c7c96"
integrity sha512-Veu0w4dTc/9wlWNf2jeRInNodKlcdLgemvPsrNpfu5Pq39sgfFjvIIgTsvUHCoLBnMhPoUA+tFxsXjU6VexVRQ==
typescript@^3.9.7:
version "3.9.9"
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.9.9.tgz#e69905c54bc0681d0518bd4d587cc6f2d0b1a674"
integrity sha512-kdMjTiekY+z/ubJCATUPlRDl39vXYiMV9iyeMuEuXZh2we6zz80uovNN2WlAxmmdE/Z/YQe+EbOEXB5RHEED3w==

uglify-js@^2.6:
version "2.8.29"
Expand Down

0 comments on commit 69cd960

Please sign in to comment.