summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKimmo Brunfeldt <kimmobrunfeldt@gmail.com>2015-07-24 12:28:41 +0300
committerKimmo Brunfeldt <kimmobrunfeldt@gmail.com>2015-07-24 12:28:41 +0300
commitd4a95d8430b9da20b900162d657775855b24fec0 (patch)
treed1582b8b36349f406fb546182cea76ff93ddea19
parentb0e802a31675eca57823408e59d278894915cfb5 (diff)
downloadgit-hours-d4a95d8430b9da20b900162d657775855b24fec0.zip
git-hours-d4a95d8430b9da20b900162d657775855b24fec0.tar.gz
git-hours-d4a95d8430b9da20b900162d657775855b24fec0.tar.bz2
Update nodegit version. Improve algorithm to calculate hours per author. Fix linter errors. Fixes #7.
-rw-r--r--Gruntfile.js3
-rw-r--r--README.md5
-rwxr-xr-xindex.js113
-rw-r--r--package.json6
-rw-r--r--test/test-functional.js2
5 files changed, 62 insertions, 67 deletions
diff --git a/Gruntfile.js b/Gruntfile.js
index 16b9d7d..ce4e96b 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -8,7 +8,8 @@ module.exports = function(grunt) {
globals: {
jQuery: true,
console: true,
- module: true
+ module: true,
+ Promise: true
}
}
},
diff --git a/README.md b/README.md
index 54d3588..46e0db1 100644
--- a/README.md
+++ b/README.md
@@ -20,7 +20,7 @@ From a person working 8 hours per day, it would take more than 3 years to build
## How it works
-The algorithm for estimating hours is quite simple.
+The algorithm for estimating hours is quite simple. For each author in the commit history, do the following:
<br><br>
@@ -52,7 +52,8 @@ to a same coding session.*
![](docs/step4.png)
-*Continue until we have determined all coding sessions.*
+*Continue until we have determined all coding sessions and sum the hours
+made by individual authors.*
<br>
diff --git a/index.js b/index.js
index e4a3f70..d38f616 100755
--- a/index.js
+++ b/index.js
@@ -23,11 +23,25 @@ function main() {
config = mergeDefaultsWithArgs(config);
commits('.').then(function(commits) {
- var work = {
- total: {
- hours: estimateHours(_.pluck(commits, 'date')),
- commits: commits.length
- }
+ var work = {};
+
+ var commitsByEmail = _.groupBy(commits, function(commit) {
+ return commit.author.email || 'unknown';
+ });
+ _.each(commitsByEmail, function(authorCommits, authorEmail) {
+ work[authorEmail] = {
+ name: authorCommits[0].author.name,
+ hours: estimateHours(_.pluck(authorCommits, 'date')),
+ commits: authorCommits.length
+ };
+ });
+
+ var totalHours = _.reduce(work, function(sum, authorWork) {
+ return sum + authorWork.hours;
+ }, 0);
+ work.total = {
+ hours: totalHours,
+ commits: commits.length
};
console.log(JSON.stringify(work, undefined, 2));
@@ -49,11 +63,6 @@ function parseArgs() {
.version(require('./package.json').version)
.usage('[options]')
.option(
- '-b, --branches [branches]',
- 'list of branches to calculate commits from e.g. master,dev. Default: all local branches',
- list
- )
- .option(
'-d, --max-commit-diff [max-commit-diff]',
'maximum difference in minutes between commits counted to one session. Default: ' + config.maxCommitDiffInMinutes,
int
@@ -71,10 +80,6 @@ function parseArgs() {
console.log('');
console.log(' $ git hours');
console.log('');
- console.log(' - Estimate hours of development branch');
- console.log('');
- console.log(' $ git hours --branches development');
- console.log('');
console.log(' - Estimate hours in repository where developers commit more seldom: they might have 4h(240min) pause between commits');
console.log('');
console.log(' $ git hours --max-commit-diff 240');
@@ -92,7 +97,7 @@ function parseArgs() {
function mergeDefaultsWithArgs(config) {
return {
- branches: program.branches || [],
+ range: program.range,
maxCommitDiffInMinutes: program.maxCommitDiff || config.maxCommitDiffInMinutes,
firstCommitAdditionInMinutes: program.firstCommitAdd || config.firstCommitAdditionInMinutes
};
@@ -131,37 +136,30 @@ function estimateHours(dates) {
// Promisify nodegit's API of getting all commits in repository
function commits(gitPath) {
- // Promisifing nodegit did not work.
- return new Promise(function(resolve, reject) {
- git.Repo.open(gitPath, function(err, repo) {
- if (err) {
- reject(err);
- return;
- }
-
- var branchNames = config.branches;
- if (_.isEmpty(branchNames)) {
- // If no command line parameters set, get all branches
- branchNames = getBranchNames(gitPath);
- }
-
- Promise.map(branchNames, function(branchName) {
- return getBranch(repo, branchName);
- }).map(function(branch) {
- return getBranchCommits(branch);
- }).reduce(function(allCommits, branchCommits) {
- _.each(branchCommits, function(commit) {
- allCommits.push(commit);
- });
-
- return allCommits;
- }, []).then(function(commits) {
- var uniqueCommits = _.uniq(commits, function(item, key, a) {
- return item.sha;
- });
-
- resolve(uniqueCommits);
- }).catch(reject);
+ return git.Repository.open(gitPath)
+ .then(function(repo) {
+ var branchNames = getBranchNames(gitPath);
+
+ return Promise.map(branchNames, function(branchName) {
+ return getBranchLatestCommit(repo, branchName);
+ })
+ .map(function(branchLatestCommit) {
+ return getBranchCommits(branchLatestCommit);
+ })
+ .reduce(function(allCommits, branchCommits) {
+ _.each(branchCommits, function(commit) {
+ allCommits.push(commit);
+ });
+
+ return allCommits;
+ }, [])
+ .then(function(commits) {
+ // Multiple branches might share commits, so take unique
+ var uniqueCommits = _.uniq(commits, function(item, key, a) {
+ return item.sha;
+ });
+
+ return uniqueCommits;
});
});
}
@@ -192,25 +190,20 @@ function getBranches(repo, names) {
return Promise.all(branches);
}
-function getBranch(repo, name) {
- return new Promise(function(resolve, reject) {
- repo.getBranch(name, function(err, branch) {
- if (err) {
- reject(err);
- return;
- }
+function getBranchLatestCommit(repo, branchName) {
+ var type = git.Reference.TYPE.SYMBOLIC;
- resolve(branch);
- });
+ return repo.getBranch(branchName).then(function(reference) {
+ return repo.getBranchCommit(reference.name());
});
}
-function getBranchCommits(branch) {
+function getBranchCommits(branchLatestCommit) {
return new Promise(function(resolve, reject) {
- var history = branch.history();
+ var history = branchLatestCommit.history();
var commits = [];
- history.on("commit", function(commit) {
+ history.on('commit', function(commit) {
var author = null;
if (!_.isNull(commit.author())) {
author = {
@@ -229,11 +222,11 @@ function getBranchCommits(branch) {
commits.push(commitData);
});
- history.on("end", function() {
+ history.on('end', function() {
resolve(commits);
});
- history.on("error", function(err) {
+ history.on('error', function(err) {
reject(err);
});
diff --git a/package.json b/package.json
index 03d2818..3350f7d 100644
--- a/package.json
+++ b/package.json
@@ -31,13 +31,13 @@
"bluebird": "^2.1.3",
"commander": "^2.2.0",
"lodash": "^2.4.1",
- "mocha": "^1.20.1",
- "nodegit": "^0.1.4"
+ "nodegit": "^0.4.1"
},
"devDependencies": {
"grunt": "^0.4.5",
"grunt-contrib-jshint": "^0.10.0",
"grunt-release": "^0.7.0",
- "grunt-shell": "^0.7.0"
+ "grunt-shell": "^0.7.0",
+ "mocha": "^2.2.5"
}
}
diff --git a/test/test-functional.js b/test/test-functional.js
index 1c7c170..e91f281 100644
--- a/test/test-functional.js
+++ b/test/test-functional.js
@@ -12,7 +12,7 @@ describe('git-hours', function() {
throw new Error(stderr);
}
- console.log('output json', stdout);
+ console.log('stdout:', stdout);
var work = JSON.parse(stdout);
assert.notEqual(work.total.hours.length, 0);
assert.notEqual(work.total.commits.length, 0);