Skip to content

Commit

Permalink
✨ Add configuration so users can customize commit mapping (#155)
Browse files Browse the repository at this point in the history
  • Loading branch information
frinyvonnick committed Jan 5, 2020
1 parent a51fee2 commit be1fca2
Show file tree
Hide file tree
Showing 8 changed files with 193 additions and 16 deletions.
1 change: 1 addition & 0 deletions packages/gitmoji-changelog-cli/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"inquirer": "^6.3.1",
"libnpm": "^1.0.0",
"lodash": "^4.17.11",
"rc": "^1.2.8",
"semver": "^5.6.0",
"semver-compare": "^1.0.0",
"simple-git": "^1.113.0",
Expand Down
46 changes: 46 additions & 0 deletions packages/gitmoji-changelog-cli/src/cli.e2e.js
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,25 @@ describe('generate changelog', () => {
expect(getChangelog()).includes(['1.0.0'])
})

it('should use a custom commit mapping to create commit categories', async () => {
makeCustomConfig({
commitMapping: [
{ group: 'style', label: 'Style', emojis: ['lipstick'] },
{ group: 'changed', label: 'Changed', emojis: [] },
],
})
await makeChanges('file1')
await commit(':sparkles: Add some file')
await makeChanges('file2')
await commit(':lipstick: Add some style file')
await bumpVersion('1.0.0')
gitmojiChangelog()
await commit(':bookmark: Version 1.0.0')

expect(getChangelog()).includes(['### Style'])
expect(getChangelog()).not.includes(['### Changed'])
})

it("should get a 1.0.0 version while initializing changelog by calling cli with 1.0.0 and having package.json's version set to 0.0.1", async () => {
await makeChanges('file1')
await commit(':sparkles: Add some file')
Expand Down Expand Up @@ -139,6 +158,29 @@ describe('generate changelog', () => {
expect(getChangelog()).includes(['second file'])
})

it('should use a custom commit mapping to create commit categories', async () => {
makeCustomConfig({
commitMapping: [
{ group: 'style', label: 'Style', emojis: ['lipstick'] },
{ group: 'changed', label: 'Changed', emojis: [] },
],
})
await bumpVersion('1.0.0')
await makeChanges('file1')
await commit(':sparkles: Add some file')
await makeChanges('file3')
await commit(':lipstick: Add some file')
gitmojiChangelog()
await makeChanges('file2')
await commit(':sparkles: Add a second file')
await makeChanges('file4')
await commit(':lipstick: Add some file')
gitmojiChangelog()

expect(getChangelog()).includes(['### Style'])
expect(getChangelog()).not.includes(['### Changed'])
})

it("should get two versions 1.0.0 and next while updating changelog by calling cli without arguments and having package.json's version set to 1.0.0", async () => {
await makeChanges('file1')
await commit(':sparkles: Add some file')
Expand Down Expand Up @@ -386,6 +428,10 @@ describe('generate changelog', () => {
fs.writeFileSync(path.join(testDir, fileName))
}

async function makeCustomConfig(config) {
fs.writeFileSync(path.join(testDir, '.gitmoji-changelogrc'), JSON.stringify(config, undefined, 2))
}

async function commit(message) {
await repo.add('.')
await repo.commit(message)
Expand Down
12 changes: 10 additions & 2 deletions packages/gitmoji-changelog-cli/src/cli.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,13 @@ const { set } = require('immutadot')
const libnpm = require('libnpm')
const semver = require('semver')
const semverCompare = require('semver-compare')
const rc = require('rc')

const { generateChangelog, logger } = require('@gitmoji-changelog/core')
const { buildMarkdownFile, getLatestVersion } = require('@gitmoji-changelog/markdown')
const { executeInteractiveMode } = require('./interactiveMode')

const { executeInteractiveMode } = require('./interactiveMode')
const getRepositoryInfo = require('./repository')

const pkg = require('../package.json')

async function getGitmojiChangelogLatestVersion() {
Expand All @@ -26,6 +27,13 @@ async function main(options = {}) {
logger.start(`gitmoji-changelog v${pkg.version}`)
logger.info(`${options.mode} ${options.output}`)

const customConfiguration = rc('gitmoji-changelog')
if (customConfiguration.configs) {
logger.info('Custom configuration found')
} else {
logger.info('No custom configuration found')
}

try {
const latestVersion = await getGitmojiChangelogLatestVersion()
if (semverCompare(latestVersion, pkg.version) > 0) {
Expand Down
26 changes: 15 additions & 11 deletions packages/gitmoji-changelog-core/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@ const concat = require('concat-stream')
const { isEmpty } = require('lodash')
const { promisify } = require('util')

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

Expand All @@ -35,15 +34,20 @@ function getCommits(from, to) {
function makeGroups(commits) {
if (isEmpty(commits)) return []

return groupMapping
.map(({ group, label }) => ({
group,
label,
commits: commits
.filter(commit => commit.group === group)
.sort((first, second) => second.date.localeCompare(first.date)),
}))
.filter(group => group.commits.length)
const mapCommits = groups => {
return groups
.map(({ group, label }) => ({
group,
label,
commits: commits
.filter(commit => commit.group === group)
.sort((first, second) => second.date.localeCompare(first.date)),
}))
.filter(group => group.commits.length)
}

const mergedCommitMapping = getMergedGroupMapping()
return mapCommits(mergedCommitMapping)
}

function sanitizeVersion(version) {
Expand Down
59 changes: 59 additions & 0 deletions packages/gitmoji-changelog-core/src/index.spec.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
/* eslint-disable global-require */
const gitRawCommits = require('git-raw-commits')
const gitSemverTags = require('git-semver-tags')
const rc = require('rc')

const { generateChangelog } = require('./index')

Expand All @@ -18,6 +19,19 @@ const uselessCommit = {
message: 'Bump version to 1.9.2',
}

const lockCommit = {
hash: '460b79497ae7e791bc8ba8475bda8f0b93630dd9',
author: 'John Doe',
date: '2018-09-14T22:00:18+02:00',
subject: ':lock: Improve security',
body: 'Yes!',
emoji: '🔒',
emojiCode: 'lock',
group: 'security',
message: 'Improve security',
siblings: [],
}

const sparklesCommit = {
hash: 'c40ee8669ba7ea5151adc2942fa8a7fc98d9e23a',
author: 'John Doe',
Expand Down Expand Up @@ -84,6 +98,10 @@ const secondLipstickCommit = {
}

describe('changelog', () => {
beforeEach(() => {
rc.mockImplementation(() => ({}))
})

it('should generate changelog for next release on init', async () => {
mockGroup([sparklesCommit])

Expand All @@ -105,6 +123,46 @@ describe('changelog', () => {
])
})

it('should generate changelog using custom commit mapping', async () => {
const customConfiguration = {
commitMapping: [
{ group: 'added', label: 'Added', emojis: ['sparkles'] },
{ group: 'style', label: 'Style', emojis: ['lipstick'] },
{ group: 'changed', label: 'Changed', emojis: [] },
],
}

rc.mockImplementation(() => customConfiguration)
mockGroup([sparklesCommit, lipstickCommit, lockCommit])

gitSemverTags.mockImplementation(cb => cb(null, []))

const { changes } = await generateChangelog(TAIL, 'next')

expect(changes).toEqual([
{
version: 'next',
groups: [
{
group: 'added',
label: 'Added',
commits: expect.arrayContaining([expect.objectContaining(sparklesCommit)]),
},
{
group: 'security',
label: 'Security',
commits: expect.arrayContaining([expect.objectContaining(lockCommit)]),
},
{
group: 'style',
label: 'Style',
commits: expect.arrayContaining([expect.objectContaining({ ...lipstickCommit, group: 'style' })]),
},
],
},
])
})

it('should generate changelog for next release', async () => {
mockGroup([sparklesCommit])

Expand Down Expand Up @@ -308,6 +366,7 @@ describe('changelog', () => {

jest.mock('git-raw-commits')
jest.mock('git-semver-tags')
jest.mock('rc')

function mockGroup(commits) {
gitRawCommits.mockImplementationOnce(() => {
Expand Down
28 changes: 27 additions & 1 deletion packages/gitmoji-changelog-core/src/parser.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
const splitLines = require('split-lines')
const nodeEmoji = require('node-emoji')
const groupMapping = require('./groupMapping')
const rc = require('rc')

function parseSubject(subject) {
if (!subject) return {}
Expand All @@ -26,8 +27,32 @@ function parseSubject(subject) {
}
}

function getMergedGroupMapping() {
const customConfiguration = rc('gitmoji-changelog')
const customGroupMapping = customConfiguration ? customConfiguration.commitMapping : undefined
if (!customGroupMapping) return groupMapping
const newCategories = customGroupMapping.filter(cg => {
return !groupMapping.some(g => g.group === cg.group)
})

const overridedCategories = groupMapping.map(group => {
const customGroup = customGroupMapping.find(cg => cg.group === group.group)
return customGroup || group
})

const miscellaneousIndex = overridedCategories.findIndex(g => g.group === 'misc')
const miscellaneousCategory = overridedCategories.splice(miscellaneousIndex, 1)[0]

return [
...overridedCategories,
...newCategories,
miscellaneousCategory,
]
}

function getCommitGroup(emojiCode) {
const group = groupMapping.find(({ emojis }) => emojis.includes(emojiCode))
const group = getMergedGroupMapping()
.find(({ emojis }) => emojis.includes(emojiCode))
if (!group) return 'misc'
return group.group
}
Expand Down Expand Up @@ -55,4 +80,5 @@ function parseCommit(commit) {
module.exports = {
parseCommit,
getCommitGroup,
getMergedGroupMapping,
}
35 changes: 34 additions & 1 deletion packages/gitmoji-changelog-core/src/parser.spec.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
const { parseCommit } = require('./parser.js')
const { getMergedGroupMapping, parseCommit } = require('./parser.js')
const rc = require('rc')

const sparklesCommit = {
hash: 'c40ee8669ba7ea5151adc2942fa8a7fc98d9e23f',
Expand All @@ -8,6 +9,16 @@ const sparklesCommit = {
body: 'Waouh this is awesome 2',
}

describe('group mapping', () => {
it('should place miscellaneous category at the end', () => {
const mergeGroupMapping = getMergedGroupMapping([
{ group: 'added', emojis: [] },
{ group: 'custom', emojis: ['sparkles'] },
])

expect(mergeGroupMapping.pop()).toEqual(expect.objectContaining({ group: 'misc' }))
})
})

describe('commits parser', () => {
it('should parse a single commit', () => {
Expand Down Expand Up @@ -79,4 +90,26 @@ describe('commits parser', () => {

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

it('should handle custom commit mapping', () => {
const customConfiguration = {
commitMapping: [
{ group: 'added', emojis: [] },
{ group: 'custom', emojis: ['sparkles'] },
],
}
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' }))
})
})

jest.mock('rc')
2 changes: 1 addition & 1 deletion yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -4844,7 +4844,7 @@ randomatic@^3.0.0:
kind-of "^6.0.0"
math-random "^1.0.1"

rc@^1.0.1, rc@^1.1.6, rc@^1.2.7:
rc@^1.0.1, rc@^1.1.6, rc@^1.2.7, rc@^1.2.8:
version "1.2.8"
resolved "https://registry.yarnpkg.com/rc/-/rc-1.2.8.tgz#cd924bf5200a075b83c188cd6b9e211b7fc0d3ed"
integrity sha512-y3bGgqKj3QBdxLbLkomlohkvsA8gdAiUQlSBJnBhfn+BPxg4bc62d8TcBW15wavDfgexCgccckhcZvywyQYPOw==
Expand Down

0 comments on commit be1fca2

Please sign in to comment.