diff --git a/index.js b/index.js index 3a91d65..949fe1f 100644 --- a/index.js +++ b/index.js @@ -53,37 +53,48 @@ class KeepAChangelog extends Plugin { } getChangelog(latestVersion) { - const { isIncrement } = this.config; - // Return the unchanged changelog content when no increment is made - if (!isIncrement) { - return this.changelogContent; - } - const { changelog } = this.getContext(); if (changelog) return changelog; const { filename, strictLatest } = this; - const previousReleaseTitle = strictLatest ? `## [${latestVersion}]` : `## [`; const hasPreviousReleaseSection = this.changelogContent.includes(previousReleaseTitle); - if (strictLatest && !hasPreviousReleaseSection) { throw Error(`Missing section for previous release ("${latestVersion}") in ${filename}.`); } - const startIndex = this.changelogContent.indexOf(this.unreleasedTitle) + this.unreleasedTitle.length; - let endIndex = this.changelogContent.indexOf(previousReleaseTitle, startIndex); - if (!strictLatest && endIndex === -1) { - endIndex = this.changelogContent.length; + const { isIncrement } = this.config; + const titleToFind = isIncrement ? this.unreleasedTitleRaw : latestVersion; + const changelogContent = this.getChangelogEntryContent(titleToFind); + + this.setContext({ changelog: changelogContent }); + return changelogContent; + } + + getChangelogEntryContent(releaseTitleRaw) { + const { filename, changelogContent, EOL } = this; + + const releaseTitleMarkdown = `## [${releaseTitleRaw}]`; + const previousReleaseTitle = `## [`; + + const indexOfReleaseTitle = changelogContent.indexOf(releaseTitleMarkdown); + + if (indexOfReleaseTitle === -1) { + throw Error(`Missing section for previous release ("${releaseTitleRaw}") in ${filename}.`); + } + + const entryContentStartIndex = changelogContent.indexOf(EOL, indexOfReleaseTitle); + let entryContentEndIndex = changelogContent.indexOf(previousReleaseTitle, entryContentStartIndex); + if (entryContentEndIndex === -1) { + entryContentEndIndex = changelogContent.length; } - const changelogContent = this.changelogContent.substring(startIndex, endIndex).trim(); - if (!changelogContent) { - throw Error(`There are no entries under "${this.unreleasedTitleRaw}" section in ${filename}.`); + const changelogEntryContent = changelogContent.substring(entryContentStartIndex, entryContentEndIndex).trim(); + if (!changelogEntryContent) { + throw Error(`There are no entries under "${releaseTitleRaw}" section in ${filename}.`); } - this.setContext({ changelog: changelogContent }); - return changelogContent; + return changelogEntryContent; } bump(version) { diff --git a/test.js b/test.js index f32a4ae..2832830 100644 --- a/test.js +++ b/test.js @@ -1,9 +1,9 @@ -import fs from 'fs'; -import test from 'bron'; import { strict as assert } from 'assert'; +import test from 'bron'; +import fs from 'fs'; import mock from 'mock-fs'; +import { factory, runTasks } from 'release-it/test/util/index.js'; import sinon from 'sinon'; -import { factory, runTasks } from 'release-it/test/util'; import Plugin from './index.js'; const initialDryRunFileContents = @@ -56,11 +56,30 @@ test('should throw for empty "unreleased" section', async t => { await assert.rejects(runTasks(plugin), /There are no entries under "Unreleased" section in CHANGELOG-EMPTY\.md/); }); -test('should not throw for empty "unreleased" section when no-increment flag is set', async t => { +test('should throw for missing "unreleased" section when no-increment flag is set if changelog is misformatted', async t => { + const options = { increment: false, [namespace]: { filename: 'CHANGELOG-FOO.md' } }; + const plugin = factory(Plugin, { namespace, options }); + await assert.rejects(runTasks(plugin), /Missing "Unreleased" section in CHANGELOG-FOO.md/); +}); + +test('should throw for missing "1.0.0" section when no-increment flag is set', async t => { + const options = { increment: false, [namespace]: { filename: 'CHANGELOG-MISSING.md' } }; + const plugin = factory(Plugin, { namespace, options }); + await assert.rejects(runTasks(plugin), /Missing section for previous release \("1\.0\.0"\) in CHANGELOG-MISSING\.md/); +}); + +test('should find "1.0.0" section when no-increment flag is set when items under version', async t => { const options = { increment: false, [namespace]: { filename: 'CHANGELOG-EMPTY.md' } }; const plugin = factory(Plugin, { namespace, options }); await runTasks(plugin); - assert.equal(plugin.getChangelog(), readFile('./CHANGELOG-EMPTY.md')); + assert.equal(plugin.getChangelog('1.0.0'), '* Item A\n* Item B'); +}); + +test('should find "1.0.0" section when no-increment flag is set when items under unreleased and version', async t => { + const options = { increment: false, [namespace]: { filename: 'CHANGELOG-FULL.md' } }; + const plugin = factory(Plugin, { namespace, options }); + await runTasks(plugin); + assert.equal(plugin.getChangelog('1.0.0'), '* Item C\n* Item D'); }); test('should throw for missing section for previous release', async t => {