Comparing version 4.0.1 to 4.0.2
@@ -0,1 +1,17 @@ | ||
# v4.0.2 (Fri Oct 02 2020) | ||
:tada: This release contains work from a new contributor! :tada: | ||
Thank you, Chris NeJame ([@SalmonMode](https://github.com/SalmonMode)), for all your work! | ||
#### 🐛 Bug Fix | ||
- Add support for getting commits of line range [#61](https://github.com/domharrington/node-gitlog/pull/61) ([@SalmonMode](https://github.com/SalmonMode)) | ||
#### Authors: 1 | ||
- Chris NeJame ([@SalmonMode](https://github.com/SalmonMode)) | ||
--- | ||
# v4.0.1 (Thu Oct 01 2020) | ||
@@ -2,0 +18,0 @@ |
@@ -181,6 +181,10 @@ 'use strict'; | ||
if (options.nameStatus) { | ||
if (options.nameStatus && !options.fileLineRange) { | ||
command += " --name-status"; | ||
} | ||
if (options.fileLineRange) { | ||
command += " -L " + options.fileLineRange.startLine + "," + options.fileLineRange.endLine + ":" + options.fileLineRange.file; | ||
} | ||
if (options.file) { | ||
@@ -187,0 +191,0 @@ command += " -- " + options.file; |
@@ -1,2 +0,2 @@ | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=require("child_process"),r=require("fs");function n(){return(n=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}var i=((e=require("debug"))&&"object"==typeof e&&"default"in e?e.default:e)("gitlog"),a={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",body:"%b",rawBody:"%B"},o=["status","files"],s={number:10,fields:["abbrevHash","hash","subject","authorName","authorDate"],nameStatus:!0,includeMergeCommitFiles:!1,findCopiesHarder:!1,all:!1},u=function(e,t,r){return e.map((function(e){var n=e.split("@end@"),a=n[0].split("\t");if(n[1]){var s=n[1].trimLeft().split("\n");""===s[s.length-1]&&s.pop(),s.map((function(e){return e.split("\t")})).forEach((function(e){for(var t=e[0],r=[t,e[e.length-1]],n=1,i=e.length-1;n<i;n++)"R"===t.slice(0,1)&&r.push("D",e[n]);a.push.apply(a,r)}))}i("commit",a),a.shift();var u={};return r&&o.forEach((function(e){u[e]=[]})),a.forEach((function(e,n){if(t[n])u[t[n]]=e;else if(r){var a=(n-t.length)%o.length;i("nameStatus",n-t.length,o.length,a,e);var s=u[o[a]];Array.isArray(s)&&s.push(e)}})),u}))};function c(e,c){if(!e.repo)throw new Error("Repo required!");if(!r.existsSync(e.repo))throw new Error("Repo location does not exist");var l=n({},s,{},e),f=n({cwd:e.repo},e.execOptions),h=function(e){var t="git log ";return e.findCopiesHarder&&(t+="--find-copies-harder "),e.all&&(t+="--all "),e.includeMergeCommitFiles&&(t+="-m "),t=function(e,t){for(var r=e,n=["author","since","after","until","before","committer"],i=n.length;i--;)t[n[i]]&&(r+=" --"+n[i]+'="'+t[n[i]]+'"');return r}(t+="-n "+e.number,e),t+=' --pretty="@begin@',e.fields&&e.fields.forEach((function(e){if(!a[e]&&!o.includes(e))throw new Error("Unknown field: "+e);t+="\t"+a[e]})),t+='@end@"',e.branch&&(t+=" "+e.branch),e.nameStatus&&(t+=" --name-status"),e.file&&(t+=" -- "+e.file),i("command",e.execOptions,t),t}(l);if(!c){var m=t.execSync(h,f).toString().split("@begin@");return""===m[0]&&m.shift(),i("commits",m),u(m,l.fields,l.nameStatus)}t.exec(h,f,(function(e,t,r){i("stdout",t);var n=t.split("@begin@");""===n[0]&&n.shift(),i("commits",n),c(r||e,u(n,l.fields,l.nameStatus))}))}exports.default=c,exports.gitlogPromise=function(e){return new Promise((function(t,r){c(e,(function(e,n){e?r(e):t(n)}))}))}; | ||
"use strict";Object.defineProperty(exports,"__esModule",{value:!0});var e,t=require("child_process"),r=require("fs");function n(){return(n=Object.assign||function(e){for(var t=1;t<arguments.length;t++){var r=arguments[t];for(var n in r)Object.prototype.hasOwnProperty.call(r,n)&&(e[n]=r[n])}return e}).apply(this,arguments)}var i=((e=require("debug"))&&"object"==typeof e&&"default"in e?e.default:e)("gitlog"),a={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",body:"%b",rawBody:"%B"},o=["status","files"],s={number:10,fields:["abbrevHash","hash","subject","authorName","authorDate"],nameStatus:!0,includeMergeCommitFiles:!1,findCopiesHarder:!1,all:!1},l=function(e,t,r){return e.map((function(e){var n=e.split("@end@"),a=n[0].split("\t");if(n[1]){var s=n[1].trimLeft().split("\n");""===s[s.length-1]&&s.pop(),s.map((function(e){return e.split("\t")})).forEach((function(e){for(var t=e[0],r=[t,e[e.length-1]],n=1,i=e.length-1;n<i;n++)"R"===t.slice(0,1)&&r.push("D",e[n]);a.push.apply(a,r)}))}i("commit",a),a.shift();var l={};return r&&o.forEach((function(e){l[e]=[]})),a.forEach((function(e,n){if(t[n])l[t[n]]=e;else if(r){var a=(n-t.length)%o.length;i("nameStatus",n-t.length,o.length,a,e);var s=l[o[a]];Array.isArray(s)&&s.push(e)}})),l}))};function u(e,u){if(!e.repo)throw new Error("Repo required!");if(!r.existsSync(e.repo))throw new Error("Repo location does not exist");var f=n({},s,{},e),c=n({cwd:e.repo},e.execOptions),h=function(e){var t="git log ";return e.findCopiesHarder&&(t+="--find-copies-harder "),e.all&&(t+="--all "),e.includeMergeCommitFiles&&(t+="-m "),t=function(e,t){for(var r=e,n=["author","since","after","until","before","committer"],i=n.length;i--;)t[n[i]]&&(r+=" --"+n[i]+'="'+t[n[i]]+'"');return r}(t+="-n "+e.number,e),t+=' --pretty="@begin@',e.fields&&e.fields.forEach((function(e){if(!a[e]&&!o.includes(e))throw new Error("Unknown field: "+e);t+="\t"+a[e]})),t+='@end@"',e.branch&&(t+=" "+e.branch),e.nameStatus&&!e.fileLineRange&&(t+=" --name-status"),e.fileLineRange&&(t+=" -L "+e.fileLineRange.startLine+","+e.fileLineRange.endLine+":"+e.fileLineRange.file),e.file&&(t+=" -- "+e.file),i("command",e.execOptions,t),t}(f);if(!u){var m=t.execSync(h,c).toString().split("@begin@");return""===m[0]&&m.shift(),i("commits",m),l(m,f.fields,f.nameStatus)}t.exec(h,c,(function(e,t,r){i("stdout",t);var n=t.split("@begin@");""===n[0]&&n.shift(),i("commits",n),u(r||e,l(n,f.fields,f.nameStatus))}))}exports.default=u,exports.gitlogPromise=function(e){return new Promise((function(t,r){u(e,(function(e,n){e?r(e):t(n)}))}))}; | ||
//# sourceMappingURL=gitlog.cjs.production.min.js.map |
@@ -175,6 +175,10 @@ import { execSync, exec } from 'child_process'; | ||
if (options.nameStatus) { | ||
if (options.nameStatus && !options.fileLineRange) { | ||
command += " --name-status"; | ||
} | ||
if (options.fileLineRange) { | ||
command += " -L " + options.fileLineRange.startLine + "," + options.fileLineRange.endLine + ":" + options.fileLineRange.file; | ||
} | ||
if (options.file) { | ||
@@ -181,0 +185,0 @@ command += " -- " + options.file; |
@@ -23,2 +23,14 @@ /// <reference types="node" /> | ||
export declare type CommitField = keyof typeof fieldMap; | ||
export interface FileLineRange { | ||
/** Will be pass as -L <startLine>,<endLine>:<file> */ | ||
/** The file to get the commits for */ | ||
file: string; | ||
/** The number of the first line in the desired range */ | ||
startLine: number; | ||
/** | ||
* Either the absolute line number for the end of the desired range, | ||
* or the offset from the startLine | ||
*/ | ||
endLine: number | string; | ||
} | ||
declare const defaultFields: readonly ["abbrevHash", "hash", "subject", "authorName", "authorDate"]; | ||
@@ -70,2 +82,4 @@ declare type DefaultField = typeof defaultFields[number]; | ||
branch?: string; | ||
/** Range of lines for a given file to find the commits for */ | ||
fileLineRange?: FileLineRange; | ||
/** File filter for the git log command */ | ||
@@ -72,0 +86,0 @@ file?: string; |
{ | ||
"name": "gitlog", | ||
"version": "4.0.1", | ||
"version": "4.0.2", | ||
"description": "Git log parser for Node.JS", | ||
@@ -5,0 +5,0 @@ "module": "dist/gitlog.esm.js", |
@@ -138,2 +138,6 @@ # node-gitlog | ||
### fileLineRange | ||
Optional field for getting only the commits that affected a specific line range of a given file. | ||
### file | ||
@@ -243,2 +247,3 @@ | ||
<td align="center"><a href="https://huntr.dev/"><img src="https://avatars0.githubusercontent.com/u/61279246?v=4?s=100" width="100px;" alt=""/><br /><sub><b>huntr-helper</b></sub></a><br /><a href="https://github.com/domharrington/node-gitlog/commits?author=huntr-helper" title="Code">💻</a></td> | ||
<td align="center"><a href="https://salmonmode.github.io/"><img src="https://avatars3.githubusercontent.com/u/13908130?v=4?s=100" width="100px;" alt=""/><br /><sub><b>Chris NeJame</b></sub></a><br /><a href="https://github.com/domharrington/node-gitlog/commits?author=SalmonMode" title="Documentation">📖</a> <a href="https://github.com/domharrington/node-gitlog/commits?author=SalmonMode" title="Tests">⚠️</a> <a href="https://github.com/domharrington/node-gitlog/commits?author=SalmonMode" title="Code">💻</a></td> | ||
</tr> | ||
@@ -245,0 +250,0 @@ </table> |
@@ -32,2 +32,16 @@ import { exec, execSync, ExecSyncOptions, ExecException } from "child_process"; | ||
export interface FileLineRange { | ||
/** Will be pass as -L <startLine>,<endLine>:<file> */ | ||
/** The file to get the commits for */ | ||
file: string; | ||
/** The number of the first line in the desired range */ | ||
startLine: number; | ||
/** | ||
* Either the absolute line number for the end of the desired range, | ||
* or the offset from the startLine | ||
*/ | ||
endLine: number | string; | ||
} | ||
const defaultFields = [ | ||
@@ -86,2 +100,4 @@ "abbrevHash", | ||
branch?: string; | ||
/** Range of lines for a given file to find the commits for */ | ||
fileLineRange?: FileLineRange; | ||
/** File filter for the git log command */ | ||
@@ -268,6 +284,10 @@ file?: string; | ||
// File and file status | ||
if (options.nameStatus) { | ||
if (options.nameStatus && !options.fileLineRange) { | ||
command += " --name-status"; | ||
} | ||
if (options.fileLineRange) { | ||
command += ` -L ${options.fileLineRange.startLine},${options.fileLineRange.endLine}:${options.fileLineRange.file}`; | ||
} | ||
if (options.file) { | ||
@@ -274,0 +294,0 @@ command += ` -- ${options.file}`; |
@@ -61,3 +61,3 @@ /* eslint-disable handle-callback-err, no-unused-expressions */ | ||
it("returns 22 commits from repository with all=false", (done) => { | ||
it("returns 25 commits from repository with all=false", (done) => { | ||
gitlog( | ||
@@ -67,3 +67,3 @@ { repo: testRepoLocation, all: false, number: 100 }, | ||
expect(err).toBeNull(); | ||
expect(commits.length).toBe(22); | ||
expect(commits.length).toBe(25); | ||
done(); | ||
@@ -74,3 +74,3 @@ } | ||
it("returns 23 commits from repository with all=true", (done) => { | ||
it("returns 26 commits from repository with all=true", (done) => { | ||
gitlog( | ||
@@ -80,3 +80,3 @@ { repo: testRepoLocation, all: true, number: 100 }, | ||
expect(err).toBeNull(); | ||
expect(commits.length).toBe(23); | ||
expect(commits.length).toBe(26); | ||
done(); | ||
@@ -160,13 +160,2 @@ } | ||
it("returns nameStatus fields", () => { | ||
const commits = gitlog({ repo: testRepoLocation }); | ||
expect(commits[0].abbrevHash).toBeDefined(); | ||
expect(commits[0].subject).toBeDefined(); | ||
expect(commits[0].authorName).toBeDefined(); | ||
expect(commits[0].hash).toBeDefined(); | ||
expect(commits[0].status).toBeDefined(); | ||
expect(commits[0].files).toBeDefined(); | ||
}); | ||
it('returns fields with "since" limit', () => { | ||
@@ -245,10 +234,5 @@ const commits = gitlog({ repo: testRepoLocation, since: "1 minutes ago" }); | ||
it("returns A status for files that are added", () => { | ||
const commits = gitlog({ repo: testRepoLocation }); | ||
expect(commits[1].status[0]).toBe("A"); | ||
}); | ||
it("returns C100 status for files that are copied", () => { | ||
const commits = gitlog({ repo: testRepoLocation, findCopiesHarder: true }); | ||
expect(commits[1].status[0]).toBe("C100"); | ||
expect(commits[4].status[0]).toBe("C100"); | ||
}); | ||
@@ -261,22 +245,38 @@ | ||
}); | ||
expect(commits[0].files[0]).toBe("foo"); | ||
expect(commits[3].files[0]).toBe("foo"); | ||
}); | ||
it("returns M status for files that are modified", () => { | ||
const commits = gitlog({ repo: testRepoLocation }); | ||
expect(commits[3].status[0]).toBe("M"); | ||
}); | ||
describe("Only repo option", () => { | ||
let commits: any[]; | ||
beforeAll(() => { | ||
commits = gitlog({ repo: testRepoLocation }); | ||
}); | ||
it("returns D status for files that are deleted", () => { | ||
const commits = gitlog({ repo: testRepoLocation }); | ||
expect(commits[4].status[0]).toBe("D"); | ||
}); | ||
it("returns nameStatus fields", () => { | ||
expect(commits[0].abbrevHash).toBeDefined(); | ||
expect(commits[0].subject).toBeDefined(); | ||
expect(commits[0].authorName).toBeDefined(); | ||
expect(commits[0].hash).toBeDefined(); | ||
expect(commits[0].status).toBeDefined(); | ||
expect(commits[0].files).toBeDefined(); | ||
}); | ||
it("returns author name correctly", () => { | ||
const commits = gitlog({ repo: testRepoLocation }); | ||
it("returns A status for files that are added", () => { | ||
expect(commits[4].status[0]).toBe("A"); | ||
}); | ||
expect.assertions(10); | ||
commits.forEach((commit) => { | ||
expect(commit.authorName).toBe("Your Name"); | ||
it("returns M status for files that are modified", () => { | ||
expect(commits[6].status[0]).toBe("M"); | ||
}); | ||
it("returns D status for files that are deleted", () => { | ||
expect(commits[7].status[0]).toBe("D"); | ||
}); | ||
it("returns author name correctly", () => { | ||
expect.assertions(10); | ||
commits.forEach((commit) => { | ||
expect(commit.authorName).toBe("Your Name"); | ||
}); | ||
}); | ||
}); | ||
@@ -309,2 +309,23 @@ | ||
it("should be able to get commit counts for a specific line only", () => { | ||
const commitsForFirstLine = gitlog({ | ||
repo: testRepoLocation, | ||
fileLineRange: { | ||
file: "fileToModify", | ||
startLine: 1, | ||
endLine: 1, | ||
}, | ||
}); | ||
expect(commitsForFirstLine.length).toBe(1); | ||
const commitsForLastLine = gitlog({ | ||
repo: testRepoLocation, | ||
fileLineRange: { | ||
file: "fileToModify", | ||
startLine: 20, | ||
endLine: 20, | ||
}, | ||
}); | ||
expect(commitsForLastLine.length).toBe(3); | ||
}); | ||
afterAll(() => { | ||
@@ -311,0 +332,0 @@ execInTestDir(`${__dirname}/delete-repo.sh`); |
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
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
120910
1181
256