From 0259c5b010f7e35018c23e65b50edde861bc3b5c Mon Sep 17 00:00:00 2001 From: Benjamin Petetot Date: Tue, 14 Jan 2020 16:34:20 +0100 Subject: [PATCH 1/2] :recycle: Be independent from the git client --- .../gitmoji-changelog-core/src/fromGitFile.js | 32 ++++++++++++++++ packages/gitmoji-changelog-core/src/index.js | 38 ++++++------------- 2 files changed, 43 insertions(+), 27 deletions(-) create mode 100644 packages/gitmoji-changelog-core/src/fromGitFile.js diff --git a/packages/gitmoji-changelog-core/src/fromGitFile.js b/packages/gitmoji-changelog-core/src/fromGitFile.js new file mode 100644 index 0000000..7df2468 --- /dev/null +++ b/packages/gitmoji-changelog-core/src/fromGitFile.js @@ -0,0 +1,32 @@ + +const gitRawCommits = require('git-raw-commits') + +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' + +const { parseCommit } = require('./parser') + +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, +} \ No newline at end of file diff --git a/packages/gitmoji-changelog-core/src/index.js b/packages/gitmoji-changelog-core/src/index.js index 01ed8a0..aef4f17 100644 --- a/packages/gitmoji-changelog-core/src/index.js +++ b/packages/gitmoji-changelog-core/src/index.js @@ -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 { 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 [] @@ -68,8 +48,10 @@ async function generateVersion(options) { to, version, groupSimilarCommits, + client, } = options - let commits = filterCommits(await getCommits(from, to)) + + let commits = filterCommits(await client.getCommits(from, to)) if (groupSimilarCommits) { commits = groupSentencesByDistance(commits.map(commit => commit.message)) @@ -108,6 +90,7 @@ async function generateVersions({ hasNext, release, groupSimilarCommits, + client, }) { let nextTag = HEAD const targetVersion = hasNext ? 'next' : sanitizeVersion(release) @@ -117,7 +100,7 @@ async function generateVersions({ const to = nextTag nextTag = tag return generateVersion({ - from, to, version, groupSimilarCommits, + from, to, version, groupSimilarCommits, client, }) })) .then(versions => versions.sort(sortVersions)) @@ -125,8 +108,8 @@ async function generateVersions({ 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) @@ -146,6 +129,7 @@ async function generateChangelog(from, to, { groupSimilarCommits } = {}) { hasNext, release: to, groupSimilarCommits, + client, }) if (from !== TAIL && changes.length === 1 && isEmpty(changes[0].groups)) { From 386097a6c8bcbf8a96ba6d8d99fc22031c214407 Mon Sep 17 00:00:00 2001 From: Benjamin Petetot Date: Tue, 14 Jan 2020 16:51:31 +0100 Subject: [PATCH 2/2] :recycle: extract parseCommit logic --- .../gitmoji-changelog-core/src/fromGitFile.js | 34 +++++++--- packages/gitmoji-changelog-core/src/index.js | 10 ++- packages/gitmoji-changelog-core/src/parser.js | 9 ++- .../gitmoji-changelog-core/src/parser.spec.js | 65 +++++-------------- 4 files changed, 52 insertions(+), 66 deletions(-) diff --git a/packages/gitmoji-changelog-core/src/fromGitFile.js b/packages/gitmoji-changelog-core/src/fromGitFile.js index 7df2468..fc32e3a 100644 --- a/packages/gitmoji-changelog-core/src/fromGitFile.js +++ b/packages/gitmoji-changelog-core/src/fromGitFile.js @@ -1,6 +1,5 @@ - 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') @@ -8,19 +7,34 @@ const concat = require('concat-stream') const COMMIT_FORMAT = '%n%H%n%an%n%cI%n%s%n%b' -const { parseCommit } = require('./parser') +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) => { + 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) - })) + }) + .pipe( + through.obj((data, enc, next) => { + next(null, parseCommit(data.toString())) + }) + ) + .pipe( + concat(data => { + resolve(data) + }) + ) }) } @@ -29,4 +43,4 @@ const getTags = promisify(gitSemverTags) module.exports = { getTags, getCommits, -} \ No newline at end of file +} diff --git a/packages/gitmoji-changelog-core/src/index.js b/packages/gitmoji-changelog-core/src/index.js index aef4f17..4b68da4 100644 --- a/packages/gitmoji-changelog-core/src/index.js +++ b/packages/gitmoji-changelog-core/src/index.js @@ -3,7 +3,7 @@ const semverCompare = require('semver-compare') const { isEmpty } = require('lodash') -const { getMergedGroupMapping } = require('./parser') +const { parseCommit, getMergedGroupMapping } = require('./parser') const logger = require('./logger') const { groupSentencesByDistance } = require('./utils') const fromGitFileClient = require('./fromGitFile') @@ -51,7 +51,9 @@ async function generateVersion(options) { client, } = options - let commits = filterCommits(await client.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)) @@ -108,7 +110,9 @@ async function generateVersions({ return changes } -async function generateChangelog(from, to, { groupSimilarCommits, client = fromGitFileClient } = {}) { +async function generateChangelog(from, to, { + groupSimilarCommits, client = fromGitFileClient, +} = {}) { const gitTags = await client.getTags() let tagsToProcess = [...gitTags] const hasNext = hasNextVersion(gitTags, to) diff --git a/packages/gitmoji-changelog-core/src/parser.js b/packages/gitmoji-changelog-core/src/parser.js index 1fe3dee..48b3971 100644 --- a/packages/gitmoji-changelog-core/src/parser.js +++ b/packages/gitmoji-changelog-core/src/parser.js @@ -1,4 +1,3 @@ -const splitLines = require('split-lines') const nodeEmoji = require('node-emoji') const groupMapping = require('./groupMapping') const rc = require('rc') @@ -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) @@ -73,7 +72,7 @@ function parseCommit(commit) { message, group, siblings: [], - body: body.join('\n'), + body: Array.isArray(body) ? body.join('\n') : body, } } diff --git a/packages/gitmoji-changelog-core/src/parser.spec.js b/packages/gitmoji-changelog-core/src/parser.spec.js index 4c08d77..ec7d4af 100644 --- a/packages/gitmoji-changelog-core/src/parser.spec.js +++ b/packages/gitmoji-changelog-core/src/parser.spec.js @@ -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: '', })) @@ -69,9 +53,11 @@ 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: '', @@ -79,16 +65,7 @@ describe('commits parser', () => { }) 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', () => { @@ -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' })) }) })