diff --git a/README.md b/README.md index bd72db6f..c9cca8f2 100644 --- a/README.md +++ b/README.md @@ -40,6 +40,7 @@ Options: --ignore-commit-pattern [regex] # pattern to ignore when parsing commits --tag-pattern [regex] # override regex pattern for version tags --tag-prefix [prefix] # prefix used in version tags, default: v + --sort-tags [property] # sort commits by semantic versioning or git fields, default: semver --starting-version [tag] # specify earliest version to include in changelog --starting-date [yyyy-mm-dd] # specify earliest date to include in changelog --sort-commits [property] # sort commits by property [relevance, date, date-desc, subject, subject-desc], default: relevance diff --git a/src/run.js b/src/run.js index 9f988b19..c3487a15 100644 --- a/src/run.js +++ b/src/run.js @@ -13,6 +13,7 @@ const DEFAULT_OPTIONS = { commitLimit: 3, backfillLimit: 3, tagPrefix: '', + sortTags: 'semver', sortCommits: 'relevance', appendGitLog: '', appendGitTag: '', @@ -44,6 +45,7 @@ const getOptions = async argv => { .option('--ignore-commit-pattern ', 'pattern to ignore when parsing commits') .option('--tag-pattern ', 'override regex pattern for version tags') .option('--tag-prefix ', 'prefix used in version tags') + .option('--sort-tags ', `sort commits by semantic versioning or git fields, default: ${DEFAULT_OPTIONS.sortTags}`) .option('--starting-version ', 'specify earliest version to include in changelog') .option('--starting-date ', 'specify earliest date to include in changelog') .option('--sort-commits ', `sort commits by property [relevance, date, date-desc], default: ${DEFAULT_OPTIONS.sortCommits}`) diff --git a/src/tags.js b/src/tags.js index c097330e..96cb2eca 100644 --- a/src/tags.js +++ b/src/tags.js @@ -6,12 +6,21 @@ const MATCH_V = /^v\d/ const fetchTags = async (options, remote) => { const format = `%(refname:short)${DIVIDER}%(creatordate:short)` - const tags = (await cmd(`git tag -l --format=${format} ${options.appendGitTag}`)) - .trim() - .split('\n') - .map(parseTag(options)) - .filter(isValidTag(options)) - .sort(sortTags) + let tags + if (options.sortTags === 'semver') { + tags = (await cmd(`git tag -l --format=${format} ${options.appendGitTag}`)) + .trim() + .split('\n') + .map(parseTag(options)) + .filter(isValidTag(options)) + .sort(sortTags) + } else { + tags = (await cmd(`git tag -l --sort=${options.sortTags} --format=${format} ${options.appendGitTag}`)) + .trim() + .split('\n') + .map(parseTag(options)) + .filter(isValidTag(options)) + } const { latestVersion, unreleased, unreleasedOnly, getCompareLink } = options if (latestVersion || unreleased || unreleasedOnly) { diff --git a/test/tags.js b/test/tags.js index 5218bd52..69f48047 100644 --- a/test/tags.js +++ b/test/tags.js @@ -9,6 +9,7 @@ const { const options = { tagPrefix: '', + sortTags: 'semver', ...remotes.github } @@ -113,6 +114,39 @@ describe('fetchTags', () => { expect(await fetchTags({ ...options, startingDate: '2000-05-01' })).to.have.lengthOf(1) }) + it('supports --sort-tags=semver', async () => { + const tags = await fetchTags({ ...options, sortTags: 'semver' }) + expect(tags.map(t => t.version)).to.deep.equal([ + 'v1.0.0', + 'v0.3.0', + 'v0.2.2', + 'v0.2.1', + 'v0.2.0', + 'v0.1.0' + ]) + }) + + // with --sort-tags, we shouldn't sort by semver, keep git command's order. + it('supports --sort-tags', async () => { + mock('cmd', () => Promise.resolve([ + 'v0.1.0---2000-02-01', + 'v0.2.0---2000-03-01', + 'v0.2.1---2000-03-02', + 'v1.0.0---2000-03-03', + 'v0.2.2---2000-04-01', + 'v0.3.0---2001-01-01' + ].join('\n'))) + const tags = await fetchTags({ ...options, sortTags: 'creatordate' }) + expect(tags.map(t => t.version)).to.deep.equal([ + 'v0.1.0', + 'v0.2.0', + 'v0.2.1', + 'v1.0.0', + 'v0.2.2', + 'v0.3.0' + ]) + }) + it('supports partial semver tags', async () => { mock('cmd', () => Promise.resolve([ 'v0.1---2000-02-01',