diff --git a/.gitignore b/.gitignore index 176bd3ef..c30200ae 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,6 @@ coverage/ lib-cov/ coverage.json npm-debug.log + +# Webstorm IDE +.idea \ No newline at end of file diff --git a/lib/detectLocalGit.js b/lib/detectLocalGit.js index ac8ed294..46a9e675 100644 --- a/lib/detectLocalGit.js +++ b/lib/detectLocalGit.js @@ -23,6 +23,25 @@ module.exports = function detectLocalGit() { if (!branch) return { git_commit: head }; - var commit = fs.readFileSync(path.join(dir, '.git', 'refs', 'heads', branch), 'utf-8').trim(); + var commit = _parseCommitHashFromRef(dir, branch); + return { git_commit: commit, git_branch: branch }; }; + +function _parseCommitHashFromRef(dir, branch) { + var ref = path.join(dir, '.git', 'refs', 'heads', branch); + if (fs.existsSync(ref)) { + return fs.readFileSync(ref, 'utf-8').trim(); + } else { + // ref does not exist; get it from packed-refs + var commit = ''; + var packedRefs = path.join(dir, '.git', 'packed-refs'); + var packedRefsText = fs.readFileSync(packedRefs, 'utf-8'); + packedRefsText.split('\n').forEach(function (line) { + if (line.match('refs/heads/'+branch)) { + commit = line.split(' ')[0]; + } + }); + return commit; + } +} diff --git a/test/detectLocalGit.js b/test/detectLocalGit.js new file mode 100644 index 00000000..64da493e --- /dev/null +++ b/test/detectLocalGit.js @@ -0,0 +1,77 @@ +var should = require('should'); +var fs = require('fs'); +var path = require('path'); + +var detectLocalGit = require('../lib/detectLocalGit'); + +var ORIGINAL_CWD = process.cwd(); +var TEST_DIR = path.resolve(__dirname); +var TEMP_GIT_DIR = path.join(TEST_DIR, '.git'); + +describe("detectLocalGit", function() { + + before(function() { + _makeTempGitDir(); + process.chdir(TEST_DIR); + }); + + after(function() { + _cleanTempGitDir(); + process.chdir(ORIGINAL_CWD); + }); + + it('should get commit hash from packed-refs when refs/heads/master does not exist', function() { + var results = detectLocalGit(); + should.exist(results); + (results).should.deepEqual({ + git_commit: '0000000000000000ffffffffffffffffffffffff', + git_branch: 'master' + }); + }); + +}); + +function _makeTempGitDir() { + + _cleanTempGitDir(); + + var dir = TEMP_GIT_DIR; + + fs.mkdirSync(dir); + + var HEAD = path.join(dir, 'HEAD'); + var packedRefs = path.join(dir, 'packed-refs'); + + fs.writeFileSync(HEAD, 'ref: refs/heads/master'); + fs.writeFileSync(packedRefs, "" + +"# pack-refs with: peeled fully-peeled\n" + +"0000000000000000000000000000000000000000 refs/heads/other/ref\n" + +"0000000000000000ffffffffffffffffffffffff refs/heads/master\n" + +"ffffffffffffffffffffffffffffffffffffffff refs/remotes/origin/other\n"); + +} + +function _cleanTempGitDir() { + _deleteFolderRecursive(TEMP_GIT_DIR); +} + +function _deleteFolderRecursive(dir) { + + if (!dir.match('node-coveralls/test')) { + throw new Error('Tried to clean a temp git directory that did not match path: node-coveralls/test'); + } + + if(fs.existsSync(dir)) { + + fs.readdirSync(dir).forEach(function(file,index){ + var curPath = path.join(dir, file); + if(fs.lstatSync(curPath).isDirectory()) { // recurse + _deleteFolderRecursive(curPath); + } else { // delete file + fs.unlinkSync(curPath); + } + }); + + fs.rmdirSync(dir); + } +}