217 lines
4.7 KiB
JavaScript
217 lines
4.7 KiB
JavaScript
'use strict'
|
|
const conventionalCommitsFilter = require('conventional-commits-filter')
|
|
const Handlebars = require('handlebars')
|
|
const semver = require('semver')
|
|
const _ = require('lodash')
|
|
const stringify = require('json-stringify-safe')
|
|
|
|
function compileTemplates (templates) {
|
|
const main = templates.mainTemplate
|
|
const headerPartial = templates.headerPartial
|
|
const commitPartial = templates.commitPartial
|
|
const footerPartial = templates.footerPartial
|
|
const partials = templates.partials
|
|
|
|
if (_.isString(headerPartial)) {
|
|
Handlebars.registerPartial('header', headerPartial)
|
|
}
|
|
|
|
if (_.isString(commitPartial)) {
|
|
Handlebars.registerPartial('commit', commitPartial)
|
|
}
|
|
|
|
if (_.isString(footerPartial)) {
|
|
Handlebars.registerPartial('footer', footerPartial)
|
|
}
|
|
|
|
_.forEach(partials, function (partial, name) {
|
|
if (_.isString(partial)) {
|
|
Handlebars.registerPartial(name, partial)
|
|
}
|
|
})
|
|
|
|
return Handlebars.compile(main, {
|
|
noEscape: true
|
|
})
|
|
}
|
|
|
|
function functionify (strOrArr) {
|
|
if (strOrArr && !_.isFunction(strOrArr)) {
|
|
return (a, b) => {
|
|
let str1 = ''
|
|
let str2 = ''
|
|
if (Array.isArray(strOrArr)) {
|
|
for (const key of strOrArr) {
|
|
str1 += a[key] || ''
|
|
str2 += b[key] || ''
|
|
}
|
|
} else {
|
|
str1 += a[strOrArr]
|
|
str2 += b[strOrArr]
|
|
}
|
|
return str1.localeCompare(str2)
|
|
}
|
|
} else {
|
|
return strOrArr
|
|
}
|
|
}
|
|
|
|
function getCommitGroups (groupBy, commits, groupsSort, commitsSort) {
|
|
const commitGroups = []
|
|
const commitGroupsObj = _.groupBy(commits, function (commit) {
|
|
return commit[groupBy] || ''
|
|
})
|
|
|
|
_.forEach(commitGroupsObj, function (commits, title) {
|
|
if (title === '') {
|
|
title = false
|
|
}
|
|
|
|
if (commitsSort) {
|
|
commits.sort(commitsSort)
|
|
}
|
|
|
|
commitGroups.push({
|
|
title: title,
|
|
commits: commits
|
|
})
|
|
})
|
|
|
|
if (groupsSort) {
|
|
commitGroups.sort(groupsSort)
|
|
}
|
|
|
|
return commitGroups
|
|
}
|
|
|
|
function getNoteGroups (notes, noteGroupsSort, notesSort) {
|
|
const retGroups = []
|
|
|
|
_.forEach(notes, function (note) {
|
|
const title = note.title
|
|
let titleExists = false
|
|
|
|
_.forEach(retGroups, function (group) {
|
|
if (group.title === title) {
|
|
titleExists = true
|
|
group.notes.push(note)
|
|
return false
|
|
}
|
|
})
|
|
|
|
if (!titleExists) {
|
|
retGroups.push({
|
|
title: title,
|
|
notes: [note]
|
|
})
|
|
}
|
|
})
|
|
|
|
if (noteGroupsSort) {
|
|
retGroups.sort(noteGroupsSort)
|
|
}
|
|
|
|
if (notesSort) {
|
|
_.forEach(retGroups, function (group) {
|
|
group.notes.sort(notesSort)
|
|
})
|
|
}
|
|
|
|
return retGroups
|
|
}
|
|
|
|
function processCommit (chunk, transform, context) {
|
|
let commit
|
|
|
|
try {
|
|
chunk = JSON.parse(chunk)
|
|
} catch (e) {}
|
|
|
|
commit = _.cloneDeep(chunk)
|
|
|
|
if (_.isFunction(transform)) {
|
|
commit = transform(commit, context)
|
|
|
|
if (commit) {
|
|
commit.raw = chunk
|
|
}
|
|
|
|
return commit
|
|
}
|
|
|
|
_.forEach(transform, function (el, path) {
|
|
let value = _.get(commit, path)
|
|
|
|
if (_.isFunction(el)) {
|
|
value = el(value, path)
|
|
} else {
|
|
value = el
|
|
}
|
|
|
|
_.set(commit, path, value)
|
|
})
|
|
|
|
commit.raw = chunk
|
|
|
|
return commit
|
|
}
|
|
|
|
function getExtraContext (commits, notes, options) {
|
|
const context = {}
|
|
|
|
// group `commits` by `options.groupBy`
|
|
context.commitGroups = getCommitGroups(options.groupBy, commits, options.commitGroupsSort, options.commitsSort)
|
|
|
|
// group `notes` for footer
|
|
context.noteGroups = getNoteGroups(notes, options.noteGroupsSort, options.notesSort)
|
|
|
|
return context
|
|
}
|
|
|
|
function generate (options, commits, context, keyCommit) {
|
|
let notes = []
|
|
let filteredCommits
|
|
const compiled = compileTemplates(options)
|
|
|
|
if (options.ignoreReverted) {
|
|
filteredCommits = conventionalCommitsFilter(commits)
|
|
} else {
|
|
filteredCommits = _.clone(commits)
|
|
}
|
|
|
|
_.forEach(filteredCommits, function (commit) {
|
|
_.map(commit.notes, function (note) {
|
|
note.commit = commit
|
|
|
|
return note
|
|
})
|
|
|
|
notes = notes.concat(commit.notes)
|
|
})
|
|
|
|
context = _.merge({}, context, keyCommit, getExtraContext(filteredCommits, notes, options))
|
|
|
|
if (keyCommit && keyCommit.committerDate) {
|
|
context.date = keyCommit.committerDate
|
|
}
|
|
|
|
if (context.version && semver.valid(context.version)) {
|
|
context.isPatch = context.isPatch || semver.patch(context.version) !== 0
|
|
}
|
|
|
|
context = options.finalizeContext(context, options, filteredCommits, keyCommit, commits)
|
|
options.debug('Your final context is:\n' + stringify(context, null, 2))
|
|
|
|
return compiled(context)
|
|
}
|
|
|
|
module.exports = {
|
|
compileTemplates: compileTemplates,
|
|
functionify: functionify,
|
|
getCommitGroups: getCommitGroups,
|
|
getNoteGroups: getNoteGroups,
|
|
processCommit: processCommit,
|
|
getExtraContext: getExtraContext,
|
|
generate: generate
|
|
}
|