From 335918f28d6cbbac2efbc25990e97549dbd96aee Mon Sep 17 00:00:00 2001 From: Christophe Porteneuve Date: Fri, 8 Nov 2013 19:05:52 +0100 Subject: Fix step 1: for dev-local uses, properly detect local Git branch and commit --- lib/detectLocalGit.js | 30 ++++++++++++++++++++++++++++++ lib/getOptions.js | 8 ++++++++ 2 files changed, 38 insertions(+) create mode 100644 lib/detectLocalGit.js (limited to 'lib') diff --git a/lib/detectLocalGit.js b/lib/detectLocalGit.js new file mode 100644 index 0000000..2d0fba0 --- /dev/null +++ b/lib/detectLocalGit.js @@ -0,0 +1,30 @@ +var fs = require('fs'); +var path = require('path'); + +var REGEX_BRANCH = /^ref: refs\/heads\/(\w+)$/; + +module.exports = function detectLocalGit(knownCommit, knownBranch) { + var dir = process.cwd(), gitDir; + while ('/' !== dir) { + gitDir = path.join(dir, '.git'); + if (fs.existsSync(path.join(gitDir, 'HEAD'))) + break; + + dir = path.dirname(dir); + } + + if ('/' === dir) + return; + + var head = strip(fs.readFileSync(path.join(dir, '.git', 'HEAD'), 'utf-8')); + var branch = (head.match(REGEX_BRANCH) || [])[1]; + if (!branch) + return { git_commit: head }; + + var commit = strip(fs.readFileSync(path.join(dir, '.git', 'refs', 'heads', branch), 'utf-8')); + return { git_commit: commit, git_branch: branch }; +}; + +function strip(str) { + return (str || '').replace(/^\s+|\s+$/g, ''); +} diff --git a/lib/getOptions.js b/lib/getOptions.js index 35187b4..abd2f2e 100644 --- a/lib/getOptions.js +++ b/lib/getOptions.js @@ -43,6 +43,14 @@ var getBaseOptions = function(cb){ options.service_job_id = process.env.COVERALLS_SERVICE_JOB_ID; } + if (!git_commit || !git_branch) { + var data = require('./detectLocalGit')(git_commit, git_branch); + if (data) { + git_commit = git_commit || data.git_commit; + git_branch = git_branch || data.git_branch; + } + } + // try to get the repo token as an environment variable if (process.env.COVERALLS_REPO_TOKEN) { options.repo_token = process.env.COVERALLS_REPO_TOKEN; -- cgit v1.2.3 From 36c62aff7424b12ca9e84370afc65ecfbe73e632 Mon Sep 17 00:00:00 2001 From: Christophe Porteneuve Date: Fri, 8 Nov 2013 19:07:36 +0100 Subject: Fix step 2: properly detect local Git branch, and just keep pre-provided one if any. --- lib/fetchGitData.js | 71 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 40 insertions(+), 31 deletions(-) (limited to 'lib') diff --git a/lib/fetchGitData.js b/lib/fetchGitData.js index a77b4a8..f75ca82 100644 --- a/lib/fetchGitData.js +++ b/lib/fetchGitData.js @@ -25,7 +25,6 @@ var fetchGitData = function(git, cb) { "format": "'%s'", } }; - var remotes = {}; //-- Malformed/undefined git object if ('undefined' === typeof git) { @@ -36,22 +35,6 @@ var fetchGitData = function(git, cb) { return cb(new Error('You must provide the head.id')); } - function saveRemote(name, url, push) { - var key = name + "-" + url; - if ("undefined" === typeof push || "boolean" !== typeof push) { - push = true; - } - if (!remotes.hasOwnProperty(key)) { - remotes[key] = true; - if (push) { - git.remotes.push({ - "name": name, - "url": url - }); - } - } - } - //-- Set required properties of git if they weren"t provided if (!git.hasOwnProperty("branch")) { git.branch = ""; @@ -98,24 +81,50 @@ var fetchGitData = function(git, cb) { git.head[field] = response; remaining--; if (remaining === 0){ - //-- Branch - exec("git branch", function(err, branches){ - if (err) return cb(err); - git.branch = branches.split("\n")[0].replace(/^\*\ /, "").trim(); - exec("git remote -v", function(err, remotes){ - if (err) return cb(err); - remotes.split("\n").forEach(function(remote) { - remote = remote.split(/\s/); - saveRemote(remote[0], remote[1]); - }); - return cb(null, git); - }); - }); + if (git.branch) { + fetchRemotes(git, cb); + } else { + fetchBranch(git, cb); + } } }); }); }); -}; +} + +function fetchBranch(git, cb) { + exec("git branch", function(err, branches){ + if (err) + return cb(err); + + git.branch = (branches.match(/^\* (\w+)/) || [])[1]; + fetchRemotes(git, cb); + }); +} + +function fetchRemotes(git, cb) { + exec("git remote -v", function(err, remotes){ + if (err) + return cb(err); + + var processed = {}; + remotes.split("\n").forEach(function(remote) { + if (!/\s\(push\)$/.test(remote)) + return; + remote = remote.split(/\s+/); + saveRemote(processed, git, remote[0], remote[1]); + }); + cb(null, git); + }); +} + +function saveRemote(processed, git, name, url) { + var key = name + "-" + url; + if (processed.hasOwnProperty(key)) + return; + processed[key] = true; + git.remotes.push({ name: name, url: url }); +} module.exports = fetchGitData; -- cgit v1.2.3 From a49eaa7f533bb7c3338d7864e3d118d43ede861e Mon Sep 17 00:00:00 2001 From: Christophe Porteneuve Date: Fri, 8 Nov 2013 19:31:19 +0100 Subject: Fix step 3: code cleanup + faster/nimbler use of Git to obtain data (rev-parse and cat-file instead of multiple log calls) --- lib/fetchGitData.js | 78 +++++++++++++++++++---------------------------------- lib/handleInput.js | 6 ++--- 2 files changed, 31 insertions(+), 53 deletions(-) (limited to 'lib') diff --git a/lib/fetchGitData.js b/lib/fetchGitData.js index f75ca82..1633bd5 100644 --- a/lib/fetchGitData.js +++ b/lib/fetchGitData.js @@ -1,37 +1,19 @@ var exec = require('child_process').exec; var logger = require('./logger')(); -var fetchGitData = function(git, cb) { +function fetchGitData(git, cb) { if (!cb){ throw new Error("fetchGitData requires a callback"); } - var i; - var execGit = true; - var head = { - "author_name": { - "format": "'%aN'", - }, - "author_email": { - "format": "'%ae'", - }, - "committer_name": { - "format": "'%cN'", - }, - "committer_email": { - "format": "'%ce'", - }, - "message": { - "format": "'%s'", - } - }; - //-- Malformed/undefined git object if ('undefined' === typeof git) { return cb(new Error('No options passed')); - } else if (!git.hasOwnProperty('head')) { + } + if (!git.hasOwnProperty('head')) { return cb(new Error('You must provide the head')); - } else if (!git.head.hasOwnProperty('id')) { + } + if (!git.head.hasOwnProperty('id')) { return cb(new Error('You must provide the head.id')); } @@ -52,7 +34,7 @@ var fetchGitData = function(git, cb) { } //-- Use git? - exec("git log -1 " + git.head.id + " --pretty=format:'%H'", function(err, response){ + exec("git rev-parse --verify " + git.head.id, function(err, response){ if (err){ // git is not available... git.head.author_name = git.head.author_name || "Unknown Author"; @@ -63,32 +45,7 @@ var fetchGitData = function(git, cb) { return cb(null, git); } - //-- Head - var commands = []; - var fields = []; - for (var field in head) { - fields.push(field); - var command = "git log -1 " + git.head.id + " --pretty=format:" + head[field].format; - commands.push(command); - } - var i = 0; - var remaining = commands.length; - commands.forEach(function(command){ - var field = fields[i]; - i++; - exec(command, function(err, response){ - if (err) return cb(err); - git.head[field] = response; - remaining--; - if (remaining === 0){ - if (git.branch) { - fetchRemotes(git, cb); - } else { - fetchBranch(git, cb); - } - } - }); - }); + fetchHeadDetails(git, cb); }); } @@ -102,6 +59,27 @@ function fetchBranch(git, cb) { }); } +var REGEX_COMMIT_DETAILS = /\nauthor (.+?) <(.+?)>.+\ncommitter (.+?) <(.+?)>.+\n\n(.*)/m; + +function fetchHeadDetails(git, cb) { + exec('git cat-file -p ' + git.head.id, function(err, response) { + if (err) + return cb(err); + + var items = response.match(REGEX_COMMIT_DETAILS).slice(1); + var fields = ['author_name', 'author_email', 'committer_name', 'committer_email', 'message']; + fields.forEach(function(field, index) { + git.head[field] = items[index]; + }); + + if (git.branch) { + fetchRemotes(git, cb); + } else { + fetchBranch(git, cb); + } + }); +} + function fetchRemotes(git, cb) { exec("git remote -v", function(err, remotes){ if (err) diff --git a/lib/handleInput.js b/lib/handleInput.js index 1435c1c..807e31d 100644 --- a/lib/handleInput.js +++ b/lib/handleInput.js @@ -1,9 +1,10 @@ var index = require('../index'); var logger = require('./logger')(); -var handleInput = function(input){ +function handleInput(input) { logger.debug(input); var options = index.getOptions(function(err, options){ + if (err){ logger.error("error from getOptions"); throw err; @@ -28,7 +29,6 @@ var handleInput = function(input){ }); }); }); - -}; +} module.exports = handleInput; -- cgit v1.2.3 From b12c8cf5f0bc11486e2b064a834ee9ff81adb0a3 Mon Sep 17 00:00:00 2001 From: Christophe Porteneuve Date: Fri, 8 Nov 2013 20:02:29 +0100 Subject: =?UTF-8?q?Ah,=20right,=20ES5=20has=20String#trim(),=20keep=20forg?= =?UTF-8?q?etting=20that=E2=80=A6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- lib/detectLocalGit.js | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'lib') diff --git a/lib/detectLocalGit.js b/lib/detectLocalGit.js index 2d0fba0..4fd8d1b 100644 --- a/lib/detectLocalGit.js +++ b/lib/detectLocalGit.js @@ -16,15 +16,11 @@ module.exports = function detectLocalGit(knownCommit, knownBranch) { if ('/' === dir) return; - var head = strip(fs.readFileSync(path.join(dir, '.git', 'HEAD'), 'utf-8')); + var head = fs.readFileSync(path.join(dir, '.git', 'HEAD'), 'utf-8').trim(); var branch = (head.match(REGEX_BRANCH) || [])[1]; if (!branch) return { git_commit: head }; - var commit = strip(fs.readFileSync(path.join(dir, '.git', 'refs', 'heads', branch), 'utf-8')); + var commit = fs.readFileSync(path.join(dir, '.git', 'refs', 'heads', branch), 'utf-8').trim(); return { git_commit: commit, git_branch: branch }; }; - -function strip(str) { - return (str || '').replace(/^\s+|\s+$/g, ''); -} -- cgit v1.2.3