Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

♻️ make core independent from the git client. #171

Merged
merged 2 commits into from
Jan 21, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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,
}
}
frinyvonnick marked this conversation as resolved.
Show resolved Hide resolved

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