Comparing version 0.1.1 to 2.0.0
122
index.js
module.exports = gitlog | ||
var exec = require('child_process').exec | ||
, _ = require('underscore') | ||
// The character to split commit fields by in the custom format | ||
, debug = require('debug')('gitlog') | ||
, extend = require('lodash.assign') | ||
, delimiter = '\t' | ||
, fields = { hash: '%H' | ||
, abbrevHash: '%h' | ||
, treeHash: '%T' | ||
, abbrevTreeHash: '%t' | ||
, parentHashes: '%P' | ||
, abbrevParentHashes: '%P' | ||
, authorName: '%an' | ||
, authorEmail: '%ae' | ||
, authorDate: '%ai' | ||
, authorDateRel: '%ar' | ||
, committerName: '%cn' | ||
, committerEmail: '%ce' | ||
, committerDate: '%cd' | ||
, committerDateRel: '%cr' | ||
, subject: '%s' | ||
} | ||
, fields = | ||
{ hash: '%H' | ||
, abbrevHash: '%h' | ||
, treeHash: '%T' | ||
, abbrevTreeHash: '%t' | ||
, parentHashes: '%P' | ||
, abbrevParentHashes: '%P' | ||
, authorName: '%an' | ||
, authorEmail: '%ae' | ||
, authorDate: '%ai' | ||
, authorDateRel: '%ar' | ||
, committerName: '%cn' | ||
, committerEmail: '%ce' | ||
, committerDate: '%cd' | ||
, committerDateRel: '%cr' | ||
, subject: '%s' | ||
} | ||
, notOptFields = [ 'status', 'files' ] | ||
/*** | ||
Add optional parameter to command | ||
*/ | ||
function addOptional(command, options) { | ||
var cmdOptional = [ 'author', 'since', 'after', 'until', 'before', 'committer' ] | ||
for (var i = cmdOptional.length; i--;) { | ||
if (options[cmdOptional[i]]) { | ||
command += ' --' + cmdOptional[i] + '="' + options[cmdOptional[i]] + '"' | ||
} | ||
} | ||
return command | ||
} | ||
function gitlog(options, cb) { | ||
@@ -28,12 +42,10 @@ if (!options.repo) throw new Error('Repo required!') | ||
var defaultOptions= { number: 10 | ||
, fields: [ 'abbrevHash' | ||
, 'hash' | ||
, 'subject' | ||
, 'authorName' | ||
] | ||
} | ||
var defaultOptions = | ||
{ number: 10 | ||
, fields: [ 'abbrevHash', 'hash', 'subject', 'authorName' ] | ||
, nameStatus:true | ||
} | ||
// Set defaults | ||
options = _.extend(defaultOptions, options) | ||
options = extend(defaultOptions, options) | ||
@@ -43,12 +55,10 @@ // Start constructing command | ||
if (options.author) { | ||
command += ' --author="' + options.author + '"' | ||
} | ||
command = addOptional(command, options) | ||
// Start of custom format | ||
command += ' --pretty="' | ||
command += ' --pretty="@begin@' | ||
// Iterating through the fields and adding them to the custom format | ||
options.fields.forEach(function(field) { | ||
if (!fields[field]) throw new Error('Unknown field: ' + field) | ||
if (!fields[field] && field.indexOf(notOptFields) === -1) throw new Error('Unknown field: ' + field) | ||
command += delimiter + fields[field] | ||
@@ -58,5 +68,5 @@ }) | ||
// Close custom format | ||
command += '"' | ||
command += '@end@"' | ||
//Append branch if specified | ||
// Append branch if specified | ||
if (options.branch) { | ||
@@ -67,13 +77,19 @@ command += ' ' + options.branch | ||
if (options.file) { | ||
command += ' -- '+options.file | ||
command += ' -- ' + options.file | ||
} | ||
//File and file status | ||
command += ' --name-status' | ||
debug('command', command) | ||
exec(command, function(err, stdout, stderr) { | ||
var commits = stdout.split('\n') | ||
debug('stdout',stdout) | ||
var commits = stdout.split('\n@begin@') | ||
if (commits.length === 1 && commits[0] === '' ){ | ||
commits.shift() | ||
} | ||
debug('commits',commits) | ||
// Remove the last blank element from the array | ||
commits.pop() | ||
commits = parseCommits(commits, options.fields,options.nameStatus) | ||
commits = parseCommits(commits, options.fields) | ||
cb(stderr || err, commits) | ||
@@ -83,6 +99,13 @@ }) | ||
function parseCommits(commits, fields) { | ||
function parseCommits(commits, fields,nameStatus) { | ||
return commits.map(function(commit) { | ||
commit = commit.split(delimiter) | ||
var parts = commit.split('@end@\n\n') | ||
commit = parts[0].split(delimiter) | ||
if (parts[1]) { | ||
commit = commit.concat(parts[1].replace(/\n/g, '\t').split(delimiter)) | ||
} | ||
debug('commit', commit) | ||
// Remove the first empty char from the array | ||
@@ -94,3 +117,16 @@ commit.shift() | ||
commit.forEach(function(commitField, index) { | ||
parsed[fields[index]] = commitField | ||
if (fields[index]) { | ||
parsed[fields[index]] = commitField | ||
} else { | ||
if (nameStatus){ | ||
var pos = (index - fields.length) % notOptFields.length | ||
if (!parsed[notOptFields[pos]]) { | ||
parsed[notOptFields[pos]] = [] | ||
} | ||
debug('nameStatus', (index - fields.length) ,notOptFields.length,pos,commitField) | ||
parsed[notOptFields[pos]].push(commitField) | ||
} | ||
} | ||
}) | ||
@@ -97,0 +133,0 @@ |
{ | ||
"name": "gitlog", | ||
"version": "0.1.1", | ||
"version": "2.0.0", | ||
"description": "Git log parser for Node.JS", | ||
"main": "index.js", | ||
"scripts": { | ||
"test": "mocha -r should" | ||
"lint": "jshint .", | ||
"checkStyle": "jscs .", | ||
"pretest": "npm run-script lint && npm run-script checkStyle", | ||
"test": "istanbul cover ./node_modules/.bin/_mocha -- -r should", | ||
"posttest": "istanbul check-coverage --statements 95 --branches 92 --functions 100 --lines 95 && rm -rf coverage" | ||
}, | ||
@@ -24,11 +28,12 @@ "publishConfig": { | ||
"devDependencies": { | ||
"debug": "^2.1.3", | ||
"should": "~0.6.3", | ||
"mocha": "~1.4.0" | ||
"istanbul": "^0.3.8", | ||
"jscs": "^1.6.1", | ||
"jshint": "^2.5.6", | ||
"mocha": "^2.2.1" | ||
}, | ||
"dependencies": { | ||
"underscore": "~1.3.3" | ||
}, | ||
"engines": { | ||
"node": ">= 0.4.6 <=0.8.0" | ||
"lodash.assign": "^3.0.0" | ||
} | ||
} |
@@ -1,32 +0,39 @@ | ||
[![build status](https://secure.travis-ci.org/domharrington/node-gitlog.png)](http://travis-ci.org/domharrington/node-gitlog) | ||
node-gitlog | ||
=========== | ||
# node-gitlog | ||
Git log parser for Node.JS | ||
[![build status](https://api.travis-ci.org/domharrington/node-gitlog.svg)](http://travis-ci.org/domharrington/node-gitlog) | ||
[![dependency status](https://david-dm.org/domharrington/node-gitlog.svg)](https://david-dm.org/domharrington/node-gitlog) | ||
## Installation | ||
npm install gitlog | ||
npm install gitlog --save | ||
## Usage | ||
var gitlog = require('../') | ||
, options = { repo: __dirname + '/test-repo-folder' | ||
, number: 20 | ||
, author: 'Dom Harrington' | ||
, fields: [ 'hash' | ||
, 'abbrevHash' | ||
, 'subject' | ||
, 'authorName' | ||
, 'authorDateRel' | ||
] | ||
} | ||
```js | ||
var gitlog = require('../') | ||
, options = | ||
{ repo: __dirname + '/test-repo-folder' | ||
, number: 20 | ||
, author: 'Dom Harrington' | ||
, fields: | ||
[ 'hash' | ||
, 'abbrevHash' | ||
, 'subject' | ||
, 'authorName' | ||
, 'authorDateRel' | ||
] | ||
} | ||
gitlog(options, function(error, commits) { | ||
// Commits is an array of commits in the repo | ||
console.log(commits) | ||
}) | ||
gitlog(options, function(error, commits) { | ||
// Commits is an array of commits in the repo | ||
console.log(commits) | ||
}) | ||
``` | ||
## Options | ||
See [git log](http://git-scm.com/docs/git-log) | ||
### repo | ||
@@ -38,6 +45,20 @@ The location of the repo, required field. | ||
### author | ||
The author who's commits to return. | ||
### since/after | ||
Show commits more recent than a specific date. | ||
### fields | ||
### until/before | ||
Show commits older than a specific date. | ||
### author/committer | ||
Limit the commits output to ones with author/committer header lines that match the specified pattern. | ||
### nameStatus | ||
Below fields was returned from the log: | ||
- files - changed files names (array) | ||
- status - changed files status (array) | ||
This option is enabled by default. | ||
### optional fields | ||
An array of fields to return from the log, here are the possible options: | ||
@@ -61,2 +82,3 @@ | ||
Defaults to 'abbrevHash', 'hash', 'subject' and 'authorName'. | ||
@@ -66,2 +88,23 @@ | ||
This module works by executing a child process (using `child_process.exec()`) to the `git` executable, then parsing the stdout into commits. This is done using the `--pretty` command line option which allows you to provide a custom formatter to `git log`. To enable easy parsing the format is delimited by a tab (`\t`) character. | ||
This module works by executing a child process (using `child_process.exec()`) to the `git` executable, then parsing the stdout into commits. This is done using the `--pretty` command line option which allows you to provide a custom formatter to `git log`. To enable easy parsing the format is delimited by a tab (`\t`) character. | ||
## Example | ||
```javascript | ||
{ hash: '6a7ef5e3b3d9c77743140443c8f9e792b0715721', | ||
abbrevHash: '6a7ef5e', | ||
treeHash: 'f1bf51b15b48a00c33727f364afef695029864c0', | ||
abbrevTreeHash: 'f1bf51b', | ||
parentHashes: 'cfe06dbdb8d0a193640977e016a04678f8f3b04f', | ||
abbrevParentHashes: 'cfe06dbdb8d0a193640977e016a04678f8f3b04f', | ||
authorName: 'Dom Harrington', | ||
authorEmail: 'dom@harringtonxxxxx', | ||
authorDate: '2015-04-09 09:39:23 +0100', | ||
authorDateRel: '6 days ago', | ||
committerName: 'Dom Harrington', | ||
committerEmail: 'dom@harringtonxxxxx', | ||
committerDate: 'Thu Apr 9 09:39:23 2015 +0100', | ||
committerDateRel: '6 days ago', | ||
subject: '1.0.0', | ||
status: [ 'M' ], | ||
files: [ 'package.json' ] } | ||
``` |
@@ -35,3 +35,3 @@ var gitlog = require('../') | ||
; (function() { | ||
gitlog({ repo: 'test-repo', fields: [field] }, function() {}); | ||
gitlog({ repo: 'test-repo', fields: [ field ] }, function() {}); | ||
}).should.throw('Unknown field: ' + field) | ||
@@ -41,5 +41,4 @@ }) | ||
it('returns 20 commits from specified branch', function(done) { | ||
gitlog({ repo: testRepoLocation, branch: 'master', number: 100}, function(err, commits) { | ||
gitlog({ repo: testRepoLocation, branch: 'master', number: 100 }, function(err, commits) { | ||
commits.length.should.equal(20) | ||
done() | ||
@@ -58,10 +57,11 @@ }) | ||
it('returns the fields requested', function(done) { | ||
var fields = [ 'hash' | ||
, 'abbrevHash' | ||
, 'treeHash' | ||
, 'authorName' | ||
, 'authorEmail' | ||
] | ||
var fields = | ||
[ 'hash' | ||
, 'abbrevHash' | ||
, 'treeHash' | ||
, 'authorName' | ||
, 'authorEmail' | ||
] | ||
gitlog({ repo: testRepoLocation, fields: fields }, function(err, commits) { | ||
gitlog({ repo: testRepoLocation, fields: fields, nameStatus: false }, function(err, commits) { | ||
commits[0].should.be.a('object') | ||
@@ -75,4 +75,14 @@ commits[0].should.have.keys(fields) | ||
it('returns a default set of fields', function(done) { | ||
var defaults = ['abbrevHash', 'hash', 'subject', 'authorName'] | ||
var defaults = [ 'abbrevHash', 'hash', 'subject', 'authorName' ] | ||
gitlog({ repo: testRepoLocation, nameStatus: false }, function(err, commits) { | ||
commits[0].should.have.keys(defaults) | ||
done() | ||
}) | ||
}) | ||
it('returns nameStatus fields', function(done) { | ||
var defaults = [ 'abbrevHash', 'hash', 'subject', 'authorName', 'status', 'files' ] | ||
gitlog({ repo: testRepoLocation }, function(err, commits) { | ||
@@ -85,4 +95,41 @@ commits[0].should.have.keys(defaults) | ||
it('returns fields with "since" limit', function(done) { | ||
gitlog({ repo: testRepoLocation, since: '1 minutes ago' }, function(err, commits) { | ||
commits.length.should.equal(10) | ||
done() | ||
}) | ||
}) | ||
it('returns fields with "after" limit', function(done) { | ||
gitlog({ repo: testRepoLocation, after: '1 minutes ago' }, function(err, commits) { | ||
commits.length.should.equal(10) | ||
done() | ||
}) | ||
}) | ||
it('returns fields with "before" limit', function(done) { | ||
gitlog({ repo: testRepoLocation, before: '2001-12-01' }, function(err, commits) { | ||
commits.length.should.equal(0) | ||
done() | ||
}) | ||
}) | ||
it('returns fields with "until" limit', function(done) { | ||
gitlog({ repo: testRepoLocation, until: '2001-12-01' }, function(err, commits) { | ||
commits.length.should.equal(0) | ||
done() | ||
}) | ||
}) | ||
it('returns commits only by author', function(done) { | ||
var command = 'cd ' + testRepoLocation + ' ' + | ||
var defaults = [ 'authorName' ] | ||
, command = 'cd ' + testRepoLocation + ' ' + | ||
'&& touch new-file ' + | ||
@@ -93,8 +140,7 @@ '&& git add new-file ' + | ||
var author = 'Dom Harrington' | ||
, author = 'Dom Harrington' | ||
// Adding a new commit by different author | ||
exec(command, function() { | ||
gitlog({ repo: testRepoLocation, author: author }, | ||
function(err, commits) { | ||
gitlog({ repo: testRepoLocation, author: author, fields: defaults }, function(err, commits) { | ||
@@ -110,2 +156,25 @@ commits.forEach(function(commit) { | ||
it('returns commits only by committer', function(done) { | ||
var defaults = [ 'committerName' ] | ||
, command = 'cd ' + testRepoLocation + ' ' + | ||
'&& touch new-file ' + | ||
'&& git add new-file ' + | ||
'&& git commit -m "New commit" ' + | ||
'--committer="A U Thor <author@example.com>"' | ||
, committer = 'Dom Harrington' | ||
// Adding a new commit by different author | ||
exec(command, function() { | ||
gitlog({ repo: testRepoLocation, committer: committer, fields: defaults }, function(err, commits) { | ||
commits.forEach(function(commit) { | ||
commit.committerName.should.equal(committer) | ||
}) | ||
done() | ||
}) | ||
}) | ||
}) | ||
after(function(done) { | ||
@@ -112,0 +181,0 @@ execInTestDir(__dirname + '/delete-repo.sh', function() { |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
New author
Supply chain riskA new npm collaborator published a version of the package for the first time. New collaborators are usually benign additions to a project, but do indicate a change to the security surface area of a package.
Found 1 instance in 1 package
No v1
QualityPackage is not semver >=1. This means it is not stable and does not support ^ ranges.
Found 1 instance in 1 package
17732
15
260
1
108
2
6
+ Addedlodash.assign@^3.0.0
+ Addedlodash._baseassign@3.2.0(transitive)
+ Addedlodash._basecopy@3.0.1(transitive)
+ Addedlodash._bindcallback@3.0.1(transitive)
+ Addedlodash._createassigner@3.1.1(transitive)
+ Addedlodash._getnative@3.9.1(transitive)
+ Addedlodash._isiterateecall@3.0.9(transitive)
+ Addedlodash.assign@3.2.0(transitive)
+ Addedlodash.isarguments@3.1.0(transitive)
+ Addedlodash.isarray@3.0.4(transitive)
+ Addedlodash.keys@3.1.2(transitive)
+ Addedlodash.restparam@3.6.1(transitive)
- Removedunderscore@~1.3.3
- Removedunderscore@1.3.3(transitive)