Skip to content

Commit

Permalink
Use tag date rather than first commit date
Browse files Browse the repository at this point in the history
Fixes #162
  • Loading branch information
cookpete committed Jun 14, 2020
1 parent bc441f1 commit dcc35c4
Show file tree
Hide file tree
Showing 6 changed files with 70 additions and 47 deletions.
15 changes: 8 additions & 7 deletions src/releases.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,12 +5,12 @@ const { niceDate } = require('./utils')
const MERGE_COMMIT_PATTERN = /^Merge (remote-tracking )?branch '.+'/
const COMMIT_MESSAGE_PATTERN = /\n+([\S\s]+)/

async function createRelease (tag, previousTag, diff, remote, options, onParsed) {
async function createRelease (tag, previousTag, date, diff, remote, options, onParsed) {
const commits = await fetchCommits(diff, remote, options)
const merges = commits.filter(commit => commit.merge).map(commit => commit.merge)
const fixes = commits.filter(commit => commit.fixes).map(commit => ({ fixes: commit.fixes, commit }))
const emptyRelease = merges.length === 0 && fixes.length === 0
const { date, message } = commits[0] || { date: new Date().toISOString() }
const { message } = commits[0] || { message: null }
const breakingCount = commits.filter(c => c.breaking).length
const filteredCommits = commits
.filter(commit => filterCommit(commit, options, merges))
Expand All @@ -36,16 +36,17 @@ async function createRelease (tag, previousTag, diff, remote, options, onParsed)
}

function parseReleases (tags, remote, latestVersion, options, onParsed) {
const releases = tags.map((tag, index, tags) => {
const previousTag = tags[index + 1]
const releases = tags.map(({ tag, date }, index, tags) => {
const previousTag = tags[index + 1] ? tags[index + 1].tag : null
const diff = previousTag ? `${previousTag}..${tag}` : tag
return createRelease(tag, previousTag, diff, remote, options, onParsed)
return createRelease(tag, previousTag, date, diff, remote, options, onParsed)
})
if (latestVersion || options.unreleased) {
const tag = latestVersion || null
const previousTag = tags[0]
const previousTag = tags[0].tag
const date = new Date().toISOString()
const diff = `${previousTag}..`
releases.unshift(createRelease(tag, previousTag, diff, remote, options, onParsed))
releases.unshift(createRelease(tag, previousTag, date, diff, remote, options, onParsed))
}
return Promise.all(releases)
}
Expand Down
2 changes: 1 addition & 1 deletion src/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ async function getLatestVersion (options, tags) {
throw new Error(`File ${file} does not exist`)
}
const { version } = await readJson(file)
const prefix = tags.some(tag => /^v/.test(tag)) ? 'v' : ''
const prefix = tags.some(({ tag }) => /^v/.test(tag)) ? 'v' : ''
return `${prefix}${version}`
}
return null
Expand Down
21 changes: 15 additions & 6 deletions src/tags.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,37 @@
const semver = require('semver')
const { cmd } = require('./utils')

const DIVIDER = '---'

async function fetchTags (options) {
const tags = (await cmd('git tag --sort=committerdate'))
const tags = (await cmd(`git tag -l --sort=-creatordate --format=%(refname:short)${DIVIDER}%(creatordate:short)`))
.trim()
.split('\n')
.reverse()
.map(parseTag)
.filter(isValidTag(options))
.sort(sortTags(options))
if (options.startingVersion) {
const limit = tags.indexOf(options.startingVersion) + 1
return tags.slice(0, limit)
const index = tags.findIndex(({ tag }) => tag === options.startingVersion)
if (index !== -1) {
return tags.slice(0, index + 1)
}
}
return tags
}

const isValidTag = ({ tagPattern, tagPrefix }) => tag => {
const parseTag = string => {
const [tag, date] = string.split(DIVIDER)
return { tag, date }
}

const isValidTag = ({ tagPattern, tagPrefix }) => ({ tag }) => {
if (tagPattern) {
return new RegExp(tagPattern).test(tag)
}
return semver.valid(tag.replace(tagPrefix, ''))
}

const sortTags = ({ tagPrefix }) => (a, b) => {
const sortTags = ({ tagPrefix }) => ({ tag: a }, { tag: b }) => {
const versions = {
a: inferSemver(a.replace(tagPrefix, '')),
b: inferSemver(b.replace(tagPrefix, ''))
Expand Down
7 changes: 6 additions & 1 deletion test/data/commits-map.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
const { generateCommits } = require('../utils/commits')

const tags = ['v1.0.0', 'v0.1.0', 'v0.0.2', 'v0.0.1']
const tags = [
{ tag: 'v1.0.0', date: '2015-12-15T12:03:09.000Z' },
{ tag: 'v0.1.0', date: '2015-12-29T21:19:17.000Z' },
{ tag: 'v0.0.2', date: '2015-12-28T21:17:17.000Z' },
{ tag: 'v0.0.1', date: '2015-12-15T12:03:09.000Z' }
]

const commitsMap = {
'v1.0.0..': generateCommits([
Expand Down
18 changes: 13 additions & 5 deletions test/releases.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,11 @@ describe('parseReleases', () => {
backfillLimit: 3,
tagPrefix: ''
}
const releases = await parseReleases(['v2.0.0', 'v1.0.0'], remotes.github, null, options)
const tags = [
{ tag: 'v2.0.0', date: '2000-01-01' },
{ tag: 'v1.0.0', date: '2000-01-01' }
]
const releases = await parseReleases(tags, remotes.github, null, options)
expect(releases).to.be.an('array')
expect(releases[0]).to.include({
tag: 'v2.0.0',
Expand All @@ -59,7 +63,8 @@ describe('parseReleases', () => {
}
mock('fetchCommits', diff => Promise.resolve(map[diff]))
const options = { commitLimit: 1 }
const releases = await parseReleases(['v1.0.0'], remotes.github, null, options)
const tags = [{ tag: 'v1.0.0', date: '2000-01-01' }]
const releases = await parseReleases(tags, remotes.github, null, options)
expect(releases[0].commits).to.have.lengthOf(1)
expect(releases[0].commits[0]).to.include({ subject: 'Second commit' })
})
Expand All @@ -70,7 +75,8 @@ describe('parseReleases', () => {
}
mock('fetchCommits', diff => Promise.resolve(map[diff]))
const options = { commitLimit: false }
const releases = await parseReleases(['v1.0.0'], remotes.github, null, options)
const tags = [{ tag: 'v1.0.0', date: '2000-01-01' }]
const releases = await parseReleases(tags, remotes.github, null, options)
expect(releases[0].commits).to.have.lengthOf(4)
})

Expand All @@ -80,7 +86,8 @@ describe('parseReleases', () => {
}
mock('fetchCommits', diff => Promise.resolve(map[diff]))
const options = { backfillLimit: 1 }
const releases = await parseReleases(['v1.0.0'], remotes.github, null, options)
const tags = [{ tag: 'v1.0.0', date: '2000-01-01' }]
const releases = await parseReleases(tags, remotes.github, null, options)
expect(releases[0].commits).to.have.lengthOf(1)
expect(releases[0].commits[0]).to.include({ subject: 'Second commit' })
})
Expand All @@ -94,7 +101,8 @@ describe('parseReleases', () => {
}
mock('fetchCommits', diff => Promise.resolve(map[diff]))
const options = { commitLimit: 0, backfillLimit: 0 }
const releases = await parseReleases(['v1.0.0'], remotes.github, null, options)
const tags = [{ tag: 'v1.0.0', date: '2000-01-01' }]
const releases = await parseReleases(tags, remotes.github, null, options)
expect(releases[0].commits).to.have.lengthOf(1)
expect(releases[0].commits[0]).to.include({ subject: 'First commit' })
})
Expand Down
54 changes: 27 additions & 27 deletions test/tags.js
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ const sortTags = __get__('sortTags')(options)

describe('fetchTags', () => {
beforeEach(() => {
mock('cmd', () => Promise.resolve('v0.1.0\nv0.2.0\nv0.2.1\nv0.2.2\nv0.3.0\nv1.0.0'))
mock('cmd', () => Promise.resolve('v0.1.0---2000-02-01\nv0.2.0---2000-03-01\nv0.2.1---2000-03-02\nv0.2.2---2000-03-03\nv0.3.0---2000-04-01\nv1.0.0---2001-01-01'))
})

afterEach(() => {
Expand All @@ -24,51 +24,51 @@ describe('fetchTags', () => {

it('fetches tags', async () => {
expect(await fetchTags(options)).to.deep.equal([
'v1.0.0',
'v0.3.0',
'v0.2.2',
'v0.2.1',
'v0.2.0',
'v0.1.0'
{ tag: 'v1.0.0', date: '2001-01-01' },
{ tag: 'v0.3.0', date: '2000-04-01' },
{ tag: 'v0.2.2', date: '2000-03-03' },
{ tag: 'v0.2.1', date: '2000-03-02' },
{ tag: 'v0.2.0', date: '2000-03-01' },
{ tag: 'v0.1.0', date: '2000-02-01' }
])
})

it('supports --starting-version', async () => {
expect(await fetchTags({ ...options, startingVersion: 'v0.3.0' })).to.deep.equal([
'v1.0.0',
'v0.3.0'
{ tag: 'v1.0.0', date: '2001-01-01' },
{ tag: 'v0.3.0', date: '2000-04-01' }
])
})
})

describe('sortTags', () => {
it('compares semver tags', () => {
expect(sortTags('1.0.0', '0.1.0')).to.equal(-1)
expect(sortTags('0.1.0', '1.0.0')).to.equal(1)
expect(sortTags('0.1.0', '0.1.0')).to.equal(0)
expect(sortTags({ tag: '1.0.0' }, { tag: '0.1.0' })).to.equal(-1)
expect(sortTags({ tag: '0.1.0' }, { tag: '1.0.0' })).to.equal(1)
expect(sortTags({ tag: '0.1.0' }, { tag: '0.1.0' })).to.equal(0)
})

it('supports non-semver tags', () => {
expect(sortTags('abc', 'def')).to.equal(1)
expect(sortTags('def', 'abc')).to.equal(-1)
expect(sortTags('abc', 'abc')).to.equal(0)
expect(sortTags({ tag: 'abc' }, { tag: 'def' })).to.equal(1)
expect(sortTags({ tag: 'def' }, { tag: 'abc' })).to.equal(-1)
expect(sortTags({ tag: 'abc' }, { tag: 'abc' })).to.equal(0)
})

it('supports non-semver numeric tags', () => {
expect(sortTags('22.1', '22.0')).to.equal(-1)
expect(sortTags('22.0', '22.1')).to.equal(1)
expect(sortTags('123.0', '22.1')).to.equal(-1)
expect(sortTags('0.1', '0.01')).to.equal(-1)
expect(sortTags('0.14', '0.2')).to.equal(-1)
expect(sortTags('0.2', '0.14')).to.equal(1)
expect(sortTags({ tag: '22.1' }, { tag: '22.0' })).to.equal(-1)
expect(sortTags({ tag: '22.0' }, { tag: '22.1' })).to.equal(1)
expect(sortTags({ tag: '123.0' }, { tag: '22.1' })).to.equal(-1)
expect(sortTags({ tag: '0.1' }, { tag: '0.01' })).to.equal(-1)
expect(sortTags({ tag: '0.14' }, { tag: '0.2' })).to.equal(-1)
expect(sortTags({ tag: '0.2' }, { tag: '0.14' })).to.equal(1)
})

it('supports partial semver tags', () => {
expect(sortTags('v0.50.7', 'v0.51')).to.equal(1)
expect(sortTags('v0.51', 'v0.50.7')).to.equal(-1)
expect(sortTags('v0.6', 'v0.50.7')).to.equal(1)
expect(sortTags('v0.50.7', 'v0.6')).to.equal(-1)
expect(sortTags('v2', 'v11')).to.equal(1)
expect(sortTags('v11', 'v2')).to.equal(-1)
expect(sortTags({ tag: 'v0.50.7' }, { tag: 'v0.51' })).to.equal(1)
expect(sortTags({ tag: 'v0.51' }, { tag: 'v0.50.7' })).to.equal(-1)
expect(sortTags({ tag: 'v0.6' }, { tag: 'v0.50.7' })).to.equal(1)
expect(sortTags({ tag: 'v0.50.7' }, { tag: 'v0.6' })).to.equal(-1)
expect(sortTags({ tag: 'v2' }, { tag: 'v11' })).to.equal(1)
expect(sortTags({ tag: 'v11' }, { tag: 'v2' })).to.equal(-1)
})
})

0 comments on commit dcc35c4

Please sign in to comment.