diff --git a/package.json b/package.json index 273a00c6da..dc0c1273be 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,10 @@ "commitmsg": "node distribution/cli.js --edit", "changelog": "conventional-changelog --preset angular --infile changelog.md --same-file --output-unreleased", "push": "git push && git push --tags && hub release create \"v$npm_package_version\" --message=\"v$npm_package_version\n$(conventional-changelog -p angular)\" && npm publish", - "test": "xo *.js && node distribution/cli.js --from=HEAD~1 && ava", + "pretest": "npm run lint", + "test": "ava", + "lint": "xo *.js", + "commitlint": "node distribution/cli.js --from=HEAD~1", "preversion": "npm run build && npm test", "release": "npm version --no-git-tag-version $(conventional-recommended-bump -p angular)", "version": "npm run changelog && git add .", @@ -76,6 +79,12 @@ "conventional-changelog-cli": "1.2.0", "conventional-recommended-bump": "0.3.0", "cz-conventional-changelog-lint": "0.1.3", + "execa": "0.6.0", + "git-toplevel": "1.1.1", + "mz": "2.6.0", + "path-exists": "3.0.0", + "rimraf": "2.6.1", + "unexpected": "10.20.0", "xo": "0.17.1" }, "dependencies": { diff --git a/source/library/get-messages.js b/source/library/get-messages.js index 78116fb4dc..e73e4ff7c6 100644 --- a/source/library/get-messages.js +++ b/source/library/get-messages.js @@ -1,15 +1,25 @@ -// core modules -import { - readFile as readFileNodeback -} from 'fs'; - -import denodeify from 'denodeify'; +import {join} from 'path'; import gitRawCommits from 'git-raw-commits'; +import gitToplevel from 'git-toplevel'; +import {readFile} from 'mz/fs'; -const readFile = denodeify(readFileNodeback); +export default getCommitMessages; // Get commit messages -function getCommits(options) { +// Object => Promise> +async function getCommitMessages(settings) { + const {from, to, edit} = settings; + + if (edit) { + return getEditCommit(); + } + + return await getHistoryCommits({from, to}); +} + +// Get commit messages from history +// Object => Promise> +function getHistoryCommits(options) { return new Promise((resolve, reject) => { const data = []; gitRawCommits(options) @@ -21,17 +31,11 @@ function getCommits(options) { }); } -// Get commit messages -export default async settings => { - const {from, to, edit} = settings; - - if (edit) { - const editFile = await readFile(`.git/COMMIT_EDITMSG`); - return [editFile.toString('utf-8')]; - } else { - return await getCommits({ - from, - to - }); - } +// Get recently edited commit message +// () => Promise> +async function getEditCommit() { + const top = await gitToplevel(); + const editFilePath = join(top, '.git/COMMIT_EDITMSG'); + const editFile = await readFile(editFilePath); + return [`${editFile.toString('utf-8')}\n`]; } diff --git a/test/integration/get-messages.js b/test/integration/get-messages.js new file mode 100644 index 0000000000..790bcd6a9e --- /dev/null +++ b/test/integration/get-messages.js @@ -0,0 +1,87 @@ +import {tmpdir} from 'os'; +import crypto from 'crypto'; +import {join} from 'path'; + +import test from 'ava'; +import denodeify from 'denodeify'; +import execa from 'execa'; +import {mkdir, writeFile} from 'mz/fs'; +import exists from 'path-exists'; +import rimraf from 'rimraf'; +import expect from 'unexpected'; + +import getMessages from '../../source/library/get-messages'; + +const rm = denodeify(rimraf); + +test.serial('get edit commit message from git root', async () => { + const repo = await initRepository(); + + await writeFile('alpha.txt', 'alpha'); + await execa('git', ['add', '.']); + await execa('git', ['commit', '-m', 'alpha']); + + const expected = ['alpha\n\n']; + const actual = await getMessages({edit: true}); + expect(actual, 'to equal', expected); + + await cleanRepository(repo); +}); + +test.serial('get history commit messages', async () => { + const repo = await initRepository(); + + await writeFile('alpha.txt', 'alpha'); + await execa('git', ['add', 'alpha.txt']); + await execa('git', ['commit', '-m', 'alpha']); + await execa('git', ['rm', 'alpha.txt']); + await execa('git', ['commit', '-m', 'remove alpha']); + + const expected = ['remove alpha\n\n', 'alpha\n\n']; + const actual = await getMessages({}); + expect(actual, 'to equal', expected); + + await cleanRepository(repo); +}); + +test.serial('get edit commit message from git subdirectory', async () => { + const repo = await initRepository(); + + await mkdir('beta'); + await writeFile('beta/beta.txt', 'beta'); + process.chdir('beta'); + await execa('git', ['add', '.']); + await execa('git', ['commit', '-m', 'beta']); + + const expected = ['beta\n\n']; + const actual = await getMessages({edit: true}); + expect(actual, 'to equal', expected); + + await cleanRepository(repo); +}); + +async function initRepository() { + const previous = process.cwd(); + const directory = join(tmpdir(), rand()); + + await execa('git', ['init', directory]); + + process.chdir(directory); + + await execa('git', ['config', 'user.email', 'test@example.com']); + await execa('git', ['config', 'user.name', 'ava']); + + return {directory, previous}; +} + +async function cleanRepository(repo) { + process.chdir(repo.previous); + + if (await exists(repo.directory)) { + await rm(repo.directory); + } +} + +function rand() { + return crypto.randomBytes(Math.ceil(6)).toString('hex').slice(0, 12); +}