Skip to content

Commit

Permalink
feat: returns commit information
Browse files Browse the repository at this point in the history
  • Loading branch information
bahmutov committed Oct 28, 2017
1 parent 1df7285 commit 424ca92
Show file tree
Hide file tree
Showing 8 changed files with 168 additions and 16 deletions.
12 changes: 8 additions & 4 deletions README.md
Expand Up @@ -24,17 +24,21 @@ const {commitInfo} = require('@cypress/commit-info')
commitInfo(folder)
.then(info => {
// info object will have properties
// sha
// branch
// message
// email
// author
// sha
// remote
// subject
// body
})
```

Resolves with [Bluebird](https://github.com/petkaantonov/bluebird) promise.
Notes:

- Resolves with [Bluebird](https://github.com/petkaantonov/bluebird) promise.
- Tries to read branch from CI variables first, otherwise uses Git command.
- If a command fails, returns empty string for each property
- If you need to debug, run with `DEBUG=commit-info` environment variable.

### Small print

Expand Down
17 changes: 17 additions & 0 deletions __snapshots__/commit-info-spec.js
@@ -0,0 +1,17 @@
exports['commit-info returns information 1'] = {
"branch": "test-branch",
"message": "important commit",
"email": "me@foo.com",
"author": "John Doe",
"sha": "abc123",
"remote": "git@github.com/repo"
}

exports['commit-info returns empty strings for missing info 1'] = {
"branch": "test-branch",
"message": "",
"email": "me@foo.com",
"author": "",
"sha": "abc123",
"remote": ""
}
7 changes: 7 additions & 0 deletions __snapshots__/utils-spec.js
@@ -0,0 +1,7 @@
exports['utils getting commit info works 1'] = {
"message": "important commit",
"email": "me@foo.com",
"author": "John Doe",
"sha": "abc123",
"remote": "git@github.com/repo"
}
4 changes: 3 additions & 1 deletion package.json
Expand Up @@ -61,7 +61,7 @@
"size": "t=\"$(npm pack .)\"; wc -c \"${t}\"; tar tvf \"${t}\"; rm \"${t}\";",
"test": "npm run unit",
"unit": "mocha src/*-spec.js",
"semantic-release": "semantic-release pre && npm publish && semantic-release post"
"semantic-release": "semantic-release pre && npm publish --access public && semantic-release post"
},
"release": {
"analyzeCommits": "simple-commit-message",
Expand All @@ -86,10 +86,12 @@
"ramda": "0.25.0",
"semantic-release": "8.2.0",
"simple-commit-message": "3.3.2",
"snap-shot-it": "4.0.1",
"standard": "10.0.3",
"stub-spawn-once": "2.3.0"
},
"dependencies": {
"bluebird": "3.5.1",
"chdir-promise": "0.6.2",
"check-more-types": "2.24.0",
"debug": "3.1.0",
Expand Down
40 changes: 37 additions & 3 deletions src/commit-info-spec.js
@@ -1,10 +1,44 @@
'use strict'

/* eslint-env mocha */
const commitInfo = require('.')
const { commitInfo } = require('.')
const { stubSpawnShellOnce } = require('stub-spawn-once')
const snapshot = require('snap-shot-it')
const { gitCommands } = require('./utils')

describe('commit-info', () => {
it('write this test', () => {
console.assert(commitInfo, 'should export something')
const env = process.env

beforeEach(() => {
process.env = {}
})

afterEach(() => {
process.env = env
})

it('returns information', () => {
stubSpawnShellOnce(gitCommands.branch, 0, 'test-branch', '')
stubSpawnShellOnce(gitCommands.message, 0, 'important commit', '')
stubSpawnShellOnce(gitCommands.email, 0, 'me@foo.com', '')
stubSpawnShellOnce(gitCommands.author, 0, 'John Doe', '')
stubSpawnShellOnce(gitCommands.sha, 0, 'abc123', '')
stubSpawnShellOnce(
gitCommands.remoteOriginUrl,
0,
'git@github.com/repo',
''
)
return commitInfo().then(snapshot)
})

it('returns empty strings for missing info', () => {
stubSpawnShellOnce(gitCommands.branch, 0, 'test-branch', '')
stubSpawnShellOnce(gitCommands.message, 1, '', 'no message')
stubSpawnShellOnce(gitCommands.email, 0, 'me@foo.com', '')
stubSpawnShellOnce(gitCommands.author, 1, '', 'missing author')
stubSpawnShellOnce(gitCommands.sha, 0, 'abc123', '')
stubSpawnShellOnce(gitCommands.remoteOriginUrl, 1, '', 'no remote origin')
return commitInfo().then(snapshot)
})
})
22 changes: 22 additions & 0 deletions src/index.js
@@ -1,7 +1,29 @@
'use strict'

const debug = require('debug')('commit-info')
const {
getBranch,
getMessage,
getEmail,
getAuthor,
getSha,
getRemoteOrigin
} = require('./utils')

const Promise = require('bluebird')

function commitInfo (folder) {
folder = folder || process.cwd()
debug('commit-info in folder', folder)

return Promise.props({
branch: getBranch(folder),
message: getMessage(folder),
email: getEmail(folder),
author: getAuthor(folder),
sha: getSha(folder),
remote: getRemoteOrigin(folder)
})
}

module.exports = { commitInfo }
44 changes: 38 additions & 6 deletions src/utils-spec.js
Expand Up @@ -3,9 +3,44 @@
const la = require('lazy-ass')
const R = require('ramda')
const { stubSpawnShellOnce } = require('stub-spawn-once')
const Promise = require('bluebird')
const snapshot = require('snap-shot-it')

/* eslint-env mocha */
describe('utils', () => {
const { gitCommands } = require('./utils')

describe('getting commit info', () => {
const {
getMessage,
getEmail,
getAuthor,
getSha,
getRemoteOrigin
} = require('./utils')

it('works', () => {
stubSpawnShellOnce(gitCommands.message, 0, 'important commit', '')
stubSpawnShellOnce(gitCommands.email, 0, 'me@foo.com', '')
stubSpawnShellOnce(gitCommands.author, 0, 'John Doe', '')
stubSpawnShellOnce(gitCommands.sha, 0, 'abc123', '')
stubSpawnShellOnce(
gitCommands.remoteOriginUrl,
0,
'git@github.com/repo',
''
)

return Promise.props({
message: getMessage(),
email: getEmail(),
author: getAuthor(),
sha: getSha(),
remote: getRemoteOrigin()
}).then(snapshot)
})
})

describe('getBranch', () => {
const { getBranch } = require('./utils')

Expand Down Expand Up @@ -43,24 +78,21 @@ describe('utils', () => {
})

it('uses git to determine branch', () => {
const cmd = 'git rev-parse --abbrev-ref HEAD'
stubSpawnShellOnce(cmd, 0, 'mock-test-branch', '')
stubSpawnShellOnce(gitCommands.branch, 0, 'mock-test-branch', '')
return getBranch().then(branch =>
la(branch === 'mock-test-branch', 'wrong branch from git', branch)
)
})

it('returns empty string on failure', () => {
const cmd = 'git rev-parse --abbrev-ref HEAD'
stubSpawnShellOnce(cmd, 1, '', 'nope')
stubSpawnShellOnce(gitCommands.branch, 1, '', 'nope')
return getBranch().then(branch =>
la(branch === '', 'wrong empty branch from git', branch)
)
})

it('returns empty string on HEAD', () => {
const cmd = 'git rev-parse --abbrev-ref HEAD'
stubSpawnShellOnce(cmd, 0, 'HEAD', '')
stubSpawnShellOnce(gitCommands.branch, 0, 'HEAD', '')
return getBranch().then(branch =>
la(branch === '', 'wrong HEAD branch from git', branch)
)
Expand Down
38 changes: 36 additions & 2 deletions src/utils.js
Expand Up @@ -5,10 +5,21 @@ const la = require('lazy-ass')
const is = require('check-more-types')
const Promise = require('bluebird')

// common git commands for getting basic info
const gitCommands = {
branch: 'git rev-parse --abbrev-ref HEAD',
message: 'git show -s --pretty=%B',
email: 'git show -s --pretty=%ae',
author: 'git show -s --pretty=%an',
sha: 'git show -s --pretty=%H',
remoteOriginUrl: 'git config --get remote.origin.url'
}

const prop = name => object => object[name]
const emptyString = () => ''

const runGitCommand = (pathToRepo, gitCommand) => {
pathToRepo = pathToRepo || process.cwd()
la(is.unemptyString(pathToRepo), 'missing repo path', pathToRepo)
la(is.unemptyString(gitCommand), 'missing git command', gitCommand)
la(gitCommand.startsWith('git'), 'invalid git command', gitCommand)
Expand All @@ -35,7 +46,7 @@ const runGitCommand = (pathToRepo, gitCommand) => {
const checkIfDetached = branch => (branch === 'HEAD' ? '' : branch)

function getGitBranch (pathToRepo) {
return runGitCommand(pathToRepo, 'git rev-parse --abbrev-ref HEAD')
return runGitCommand(pathToRepo, gitCommands.branch)
.then(checkIfDetached)
.catch(emptyString)
}
Expand All @@ -47,6 +58,8 @@ function firstFoundValue (keys, object = process.env) {
return found ? object[found] : null
}

// first try finding branch from CI environment variables
// if fails, use "git" command
function getBranch (pathToRepo) {
pathToRepo = pathToRepo || process.cwd()
const ciNames = [
Expand All @@ -62,4 +75,25 @@ function getBranch (pathToRepo) {
return getGitBranch(pathToRepo)
}

module.exports = { runGitCommand, firstFoundValue, getBranch }
const getMessage = pathToRepo => runGitCommand(pathToRepo, gitCommands.message)

const getEmail = pathToRepo => runGitCommand(pathToRepo, gitCommands.email)

const getAuthor = pathToRepo => runGitCommand(pathToRepo, gitCommands.author)

const getSha = pathToRepo => runGitCommand(pathToRepo, gitCommands.sha)

const getRemoteOrigin = pathToRepo =>
runGitCommand(pathToRepo, gitCommands.remoteOriginUrl)

module.exports = {
runGitCommand,
firstFoundValue,
getBranch,
getMessage,
getEmail,
getAuthor,
getSha,
getRemoteOrigin,
gitCommands
}

0 comments on commit 424ca92

Please sign in to comment.