diff --git a/README.md b/README.md index 2b4a3d9d..597231f7 100644 --- a/README.md +++ b/README.md @@ -30,6 +30,12 @@ Specify an output file with `-o` or `--output`. auto-changelog --output HISTORY.md # Writes log to HISTORY.md ``` +Specify a theme with `-t` or `--template`. + +```bash +auto-changelog --template compact # Writes log using compact template +``` + #### What you might do if you’re clever - `npm install auto-changelog --save-dev` diff --git a/src/index.js b/src/index.js index f90fa1eb..42022975 100755 --- a/src/index.js +++ b/src/index.js @@ -7,17 +7,25 @@ import { version } from '../package.json' import { cmd } from './utils' import { parseCommits, LOG_FORMAT } from './commits' import { parseReleases } from './releases' -import Template from './templates/Base' +import templates from './templates' const DEFAULT_OUTPUT = 'CHANGELOG.md' +const DEFAULT_TEMPLATE = 'default' const NPM_VERSION_TAG_PREFIX = 'v' commander - .option('-o, --output [file]', `output file (default: ${DEFAULT_OUTPUT})`, DEFAULT_OUTPUT) + .option('-o, --output [file]', `output file, default: ${DEFAULT_OUTPUT}`, DEFAULT_OUTPUT) .option('-p, --package', 'use version from package.json as latest release') + .option('-t, --template [template]', `specify template to use for output, templates: ${Object.keys(templates).join(', ')}`, DEFAULT_TEMPLATE) .version(version) .parse(process.argv) +const Template = templates[commander.template] + +if (!Template) { + throw new Error(`Template '${commander.template}' was not found`) +} + function getCommits () { return cmd('git', ['log', '--shortstat', '--pretty=format:' + LOG_FORMAT]).then(parseCommits) } diff --git a/src/templates.js b/src/templates.js new file mode 100644 index 00000000..77bf3aab --- /dev/null +++ b/src/templates.js @@ -0,0 +1,7 @@ +import Default from './templates/Default' +import Compact from './templates/Compact' + +export default { + default: Default, + compact: Compact +} diff --git a/src/templates/Compact.js b/src/templates/Compact.js new file mode 100644 index 00000000..4ecac638 --- /dev/null +++ b/src/templates/Compact.js @@ -0,0 +1,28 @@ +// Simple, slimline template based on https://github.com/rackt/react-router/blob/master/CHANGES.md + +import Default from './Default' + +export default class Compact extends Default { + mergesTitle = null + fixesTitle = null + commitsTitle = null + + fixPrefix = 'Fixed ' + mergePrefix = 'Merged ' + + listSpacing = '\n' + + renderReleaseHeading = (release, previousRelease) => { + const title = this.renderReleaseTitle(release, previousRelease) + const date = release.tag ? `\n> ${formatDate(release.date)}` : '' + return `### ${title}${date}\n` + } +} + +function formatDate (string) { + const date = new Date(string) + const day = date.getDate() + const month = date.toLocaleString('en', { month: 'long' }) + const year = date.getFullYear() + return `${day} ${month} ${year}` +} diff --git a/src/templates/Base.js b/src/templates/Default.js similarity index 85% rename from src/templates/Base.js rename to src/templates/Default.js index a7f4df38..e00a7f2e 100644 --- a/src/templates/Base.js +++ b/src/templates/Default.js @@ -1,4 +1,7 @@ -export default class Base { +// The default template attempts to follow the schema from +// https://github.com/olivierlacan/keep-a-changelog + +export default class Default { logHeader = '# Change Log\nAll notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/).\n\nGenerated by [auto-changelog](https://github.com/CookPete/auto-changelog)' unreleasedTitle = 'Unreleased' @@ -6,9 +9,15 @@ export default class Base { fixesTitle = 'Fixed' commitsTitle = 'Commits' + fixPrefix = '' + mergePrefix = '' + commitListLimit = 3 commitHashLength = 7 + sectionSpacing = '\n\n\n' + listSpacing = '\n\n' + constructor (origin) { this.origin = origin } @@ -20,8 +29,8 @@ export default class Base { render = (releases) => { return [ this.logHeader, - releases.map(this.renderRelease).join('\n\n\n') - ].join('\n\n\n') + '\n' + releases.map(this.renderRelease).join(this.sectionSpacing) + ].join(this.sectionSpacing) + '\n' } renderRelease = (release, index, releases) => { @@ -33,7 +42,7 @@ export default class Base { if (merges.length + fixes.length === 0) { log = log.concat(this.renderCommits(release.commits)) } - return log.join('\n\n') + return log.join(this.listSpacing) } renderReleaseHeading = (release, previousRelease) => { @@ -63,7 +72,7 @@ export default class Base { renderMerge = ({ pr, message }) => { const href = pr.replace('#', this.origin + '/pull/') - return `* [${pr}](${href}): ${message}` + return `* ${this.mergePrefix}[${pr}](${href}): ${message}` } renderFixes = (fixes) => { @@ -74,7 +83,7 @@ export default class Base { renderFix = ({ fixes, commit }) => { const numbers = fixes.map(this.renderFixNumber).join(', ') - return `* ${numbers}: ${commit.subject}` + return `* ${this.fixPrefix}${numbers}: ${commit.subject}` } renderFixNumber = (string) => { diff --git a/test/data/changelog-compact.js b/test/data/changelog-compact.js new file mode 100644 index 00000000..bbc89d31 --- /dev/null +++ b/test/data/changelog-compact.js @@ -0,0 +1,24 @@ +export default `# Change Log +All notable changes to this project will be documented in this file. This project adheres to [Semantic Versioning](http://semver.org/). + +Generated by [auto-changelog](https://github.com/CookPete/auto-changelog) + + +### [Unreleased](https://github.com/user/repo/compare/v0.0.2...HEAD) + +* Fixed [#6](https://github.com/user/repo/issues/6): Unreleased commit + + +### [v0.0.2](https://github.com/user/repo/compare/v0.0.1...v0.0.2) +> 28 December 2015 + +* Merged [#5](https://github.com/user/repo/pull/5): Should not parse #4 in PR title +* Fixed [#4](https://github.com/user/repo/issues/4): Commit 4 fixes #4 in the subject + + +### v0.0.1 +> 15 December 2015 + +* Merged [#3](https://github.com/user/repo/pull/3): Pull request title +* Fixed [#1](https://github.com/user/repo/issues/1), [#2](https://github.com/user/repo/issues/2): Second commit +` diff --git a/test/data/changelog.js b/test/data/changelog-default.js similarity index 100% rename from test/data/changelog.js rename to test/data/changelog-default.js diff --git a/test/render.js b/test/render.js index 92e5f4dc..d272732a 100644 --- a/test/render.js +++ b/test/render.js @@ -2,12 +2,22 @@ import { describe, it } from 'mocha' import { expect } from 'chai' import releases from './data/releases' -import changelog from './data/changelog' -import Template from '../src/templates/Base' +import changelogDefault from './data/changelog-default' +import changelogCompact from './data/changelog-compact' +import templates from '../src/templates' + +const origin = 'https://github.com/user/repo' describe('Template', () => { - it('renders a log', () => { - const result = new Template('https://github.com/user/repo').render(releases) - expect(result).to.equal(changelog) + it('renders using default template', () => { + const Template = templates.default + const result = new Template(origin).render(releases) + expect(result).to.equal(changelogDefault) + }) + + it('renders using compact template', () => { + const Template = templates.compact + const result = new Template(origin).render(releases) + expect(result).to.equal(changelogCompact) }) })