Skip to content

Commit

Permalink
♻️ Make core independent from the git client. (#171)
Browse files Browse the repository at this point in the history
  • Loading branch information
bpetetot authored and frinyvonnick committed Jan 21, 2020
1 parent 990ee45 commit 4094bb9
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 79 deletions.
46 changes: 46 additions & 0 deletions packages/gitmoji-changelog-core/src/fromGitFile.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
const gitRawCommits = require('git-raw-commits')
const splitLines = require('split-lines')
const { promisify } = require('util')
const gitSemverTags = require('git-semver-tags')
const through = require('through2')
const concat = require('concat-stream')

const COMMIT_FORMAT = '%n%H%n%an%n%cI%n%s%n%b'

function parseCommit(commit) {
const lines = splitLines(commit)
const [hash, author, date, subject, ...body] = lines.splice(
1,
lines.length - 2
)
return {
hash, author, date, subject, body,
}
}

function getCommits(from, to) {
return new Promise(resolve => {
gitRawCommits({
format: COMMIT_FORMAT,
from,
to,
})
.pipe(
through.obj((data, enc, next) => {
next(null, parseCommit(data.toString()))
})
)
.pipe(
concat(data => {
resolve(data)
})
)
})
}

const getTags = promisify(gitSemverTags)

module.exports = {
getTags,
getCommits,
}
40 changes: 14 additions & 26 deletions packages/gitmoji-changelog-core/src/index.js
Original file line number Diff line number Diff line change
@@ -1,36 +1,16 @@
const semver = require('semver')
const gitRawCommits = require('git-raw-commits')
const gitSemverTags = require('git-semver-tags')
const semverCompare = require('semver-compare')
const through = require('through2')
const concat = require('concat-stream')

const { isEmpty } = require('lodash')
const { promisify } = require('util')

const { parseCommit, getMergedGroupMapping } = require('./parser')
const logger = require('./logger')
const { groupSentencesByDistance } = require('./utils')
const fromGitFileClient = require('./fromGitFile')

const gitSemverTagsAsync = promisify(gitSemverTags)

const COMMIT_FORMAT = '%n%H%n%an%n%cI%n%s%n%b'
const HEAD = ''
const TAIL = ''

function getCommits(from, to) {
return new Promise((resolve) => {
gitRawCommits({
format: COMMIT_FORMAT,
from,
to,
}).pipe(through.obj((data, enc, next) => {
next(null, parseCommit(data.toString()))
})).pipe(concat(data => {
resolve(data)
}))
})
}

function makeGroups(commits) {
if (isEmpty(commits)) return []

Expand Down Expand Up @@ -68,8 +48,12 @@ async function generateVersion(options) {
to,
version,
groupSimilarCommits,
client,
} = options
let commits = filterCommits(await getCommits(from, to))

const rawCommits = await client.getCommits(from, to)

let commits = filterCommits(rawCommits.map(parseCommit))

if (groupSimilarCommits) {
commits = groupSentencesByDistance(commits.map(commit => commit.message))
Expand Down Expand Up @@ -108,6 +92,7 @@ async function generateVersions({
hasNext,
release,
groupSimilarCommits,
client,
}) {
let nextTag = HEAD
const targetVersion = hasNext ? 'next' : sanitizeVersion(release)
Expand All @@ -117,16 +102,18 @@ async function generateVersions({
const to = nextTag
nextTag = tag
return generateVersion({
from, to, version, groupSimilarCommits,
from, to, version, groupSimilarCommits, client,
})
}))
.then(versions => versions.sort(sortVersions))

return changes
}

async function generateChangelog(from, to, { groupSimilarCommits } = {}) {
const gitTags = await gitSemverTagsAsync()
async function generateChangelog(from, to, {
groupSimilarCommits, client = fromGitFileClient,
} = {}) {
const gitTags = await client.getTags()
let tagsToProcess = [...gitTags]
const hasNext = hasNextVersion(gitTags, to)

Expand All @@ -146,6 +133,7 @@ async function generateChangelog(from, to, { groupSimilarCommits } = {}) {
hasNext,
release: to,
groupSimilarCommits,
client,
})

if (from !== TAIL && changes.length === 1 && isEmpty(changes[0].groups)) {
Expand Down
9 changes: 4 additions & 5 deletions packages/gitmoji-changelog-core/src/parser.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
const splitLines = require('split-lines')
const nodeEmoji = require('node-emoji')
const groupMapping = require('./groupMapping')
const rc = require('rc')
Expand Down Expand Up @@ -57,9 +56,9 @@ function getCommitGroup(emojiCode) {
return group.group
}

function parseCommit(commit) {
const lines = splitLines(commit)
const [hash, author, date, subject, ...body] = lines.splice(1, lines.length - 2)
function parseCommit({
hash, author, date, subject = '', body = '',
}) {
const { emoji, emojiCode, message } = parseSubject(subject)
const group = getCommitGroup(emojiCode)

Expand All @@ -73,7 +72,7 @@ function parseCommit(commit) {
message,
group,
siblings: [],
body: body.join('\n'),
body: Array.isArray(body) ? body.join('\n') : body,
}
}

Expand Down
65 changes: 17 additions & 48 deletions packages/gitmoji-changelog-core/src/parser.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,42 +22,26 @@ describe('group mapping', () => {

describe('commits parser', () => {
it('should parse a single commit', () => {
const {
hash,
author,
date,
subject,
body,
} = sparklesCommit
const commit = `\n${hash}\n${author}\n${date}\n${subject}\n${body}\n`

expect(parseCommit(commit)).toEqual(expect.objectContaining(sparklesCommit))
expect(parseCommit(sparklesCommit)).toEqual(expect.objectContaining(sparklesCommit))
})

it('should parse a unicode emoji', () => {
const {
hash,
author,
date,
body,
} = sparklesCommit
const commit = `\n${hash}\n${author}\n${date}\n✨ Upgrade brand new feature\n${body}\n`
const parsed = parseCommit(commit)
const parsed = parseCommit({
...sparklesCommit,
subject: '✨ Upgrade brand new feature',
})
expect(parsed.emoji).toEqual('✨')
expect(parsed.emojiCode).toEqual('sparkles')
expect(parsed.message).toEqual('Upgrade brand new feature')
})

it('should parse a single commit without a body', () => {
const {
hash,
author,
date,
subject,
} = sparklesCommit
const commit = `\n${hash}\n${author}\n${date}\n${subject}\n\n`
const parsed = parseCommit({
...sparklesCommit,
body: '',
})

expect(parseCommit(commit)).toEqual(expect.objectContaining({
expect(parseCommit(parsed)).toEqual(expect.objectContaining({
...sparklesCommit,
body: '',
}))
Expand All @@ -69,26 +53,19 @@ describe('commits parser', () => {
author,
date,
} = sparklesCommit
const commit = `\n${hash}\n${author}\n${date}\n\n`

expect(parseCommit(commit)).toEqual(expect.objectContaining({
expect(parseCommit({
hash,
author,
date,
})).toEqual(expect.objectContaining({
...sparklesCommit,
subject: '',
body: '',
}))
})

it('should add the group to a commit', () => {
const {
hash,
author,
date,
subject,
body,
} = sparklesCommit
const commit = `\n${hash}\n${author}\n${date}\n${subject}\n${body}\n`

expect(parseCommit(commit)).toEqual(expect.objectContaining({ group: 'added' }))
expect(parseCommit(sparklesCommit)).toEqual(expect.objectContaining({ group: 'added' }))
})

it('should handle custom commit mapping', () => {
Expand All @@ -99,16 +76,8 @@ describe('commits parser', () => {
],
}
rc.mockImplementation(() => customConfiguration)
const {
hash,
author,
date,
subject,
body,
} = sparklesCommit
const commit = `\n${hash}\n${author}\n${date}\n${subject}\n${body}\n`

expect(parseCommit(commit)).toEqual(expect.objectContaining({ group: 'custom' }))
expect(parseCommit(sparklesCommit)).toEqual(expect.objectContaining({ group: 'custom' }))
})
})

Expand Down

0 comments on commit 4094bb9

Please sign in to comment.