git-local-info
Version:
Retrieve current sha, branch name, repository from a git repo.
193 lines (192 loc) • 7.77 kB
JavaScript
'use strict';
Object.defineProperty(exports, "__esModule", { value: true });
var fs = require("fs");
var path = require("path");
var ini = require("ini");
var zlib = require("zlib");
var GitInfo = /** @class */ (function () {
function GitInfo(args) {
if (args === void 0) { args = {}; }
this.GIT_DIR = '.git';
var gitPath = args.gitPath, _a = args.GIT_DIR, GIT_DIR = _a === void 0 ? '.git' : _a;
this.GIT_DIR = GIT_DIR;
this.gitPath = this._findRepo(gitPath);
this.headPath = path.join(this.gitPath, 'HEAD');
}
Object.defineProperty(GitInfo.prototype, "getGitInfo", {
get: function () {
return {
branch: this.getBranch(),
repository: this.getRepository(),
sha: this.getSha(),
commit: this.getCommit(),
rootDir: path.dirname(path.resolve(this.gitPath)),
};
},
enumerable: true,
configurable: true
});
// get branch
GitInfo.prototype.getBranch = function () {
try {
if (fs.existsSync(this.headPath)) {
var headFile = this._readFile(this.headPath);
var match = headFile.match(/refs\/heads\/(\S+$)/);
var branchName = match && match[1];
return branchName;
}
}
catch (_) { }
};
// get repository
GitInfo.prototype.getRepository = function () {
try {
var configFilePath = path.join(this.gitPath, 'config');
if (fs.existsSync(configFilePath)) {
var config = ini.parse(this._readFile(configFilePath));
var repository = config['remote "origin"'].url;
return repository;
}
}
catch (_) { }
};
// get sha/commit hash
GitInfo.prototype.getSha = function () {
try {
if (fs.existsSync(this.headPath)) {
var headFile = fs.readFileSync(this.headPath, 'utf-8');
var refPath = headFile.split(' ')[1];
// Find branch and SHA
if (refPath) {
refPath = refPath.trim();
var branchPath = path.join(this.gitPath, refPath);
var hasBranchPath = fs.existsSync(branchPath);
return hasBranchPath ? this._readFile(branchPath) : this._findPackedCommit(refPath);
}
else {
var sha = headFile.split('/').slice(2).join('/').trim();
if (!sha) {
sha = headFile.split('/').slice(-1)[0].trim();
}
return sha;
}
}
}
catch (_) { }
};
GitInfo.prototype.getCommit = function () {
try {
var sha = this.getSha();
if (!sha) {
return '';
}
var objectPath = path.join(this.gitPath, 'objects', sha.slice(0, 2), sha.slice(2));
if (zlib.inflateSync && fs.existsSync(objectPath)) {
var objectContents = zlib.inflateSync(fs.readFileSync(objectPath)).toString();
var commit = objectContents.split(/\0|\r?\n/)
.filter(function (item) {
return !!item;
})
.reduce(function (data, section) {
var part = section.slice(0, section.indexOf(' ')).trim();
switch (part) {
case 'commit':
case 'tag':
case 'object':
case 'type':
case 'author':
case 'parent':
case 'tree':
// ignore these for now
break;
case 'committer':
var parts = section.match(/^(?:author|committer)\s(.+)\s(\d+\s(?:\+|\-)\d{4})$/);
if (parts) {
data[part] = parts[1];
}
break;
default:
// should just be the commit message left
data.commitMessage = section;
}
return data;
}, {});
return commit;
}
}
catch (_) { }
};
GitInfo.prototype._findPackedCommit = function (refPath) {
return this._getPackedRefsForType(refPath, 'commit')[0];
};
GitInfo.prototype._getPackedRefsFile = function () {
var packedRefsFilePath = path.join(this.gitPath, 'packed-refs');
return fs.existsSync(packedRefsFilePath) ? this._readFile(packedRefsFilePath) : false;
};
GitInfo.prototype._getShaBasedOnType = function (type, shaLine) {
var shaResult = '';
if (type === 'tag') {
shaResult = shaLine.split('tags/')[1];
}
else if (type === 'commit') {
shaResult = shaLine.split(' ')[0];
}
return shaResult;
};
GitInfo.prototype._getLinesForRefPath = function (packedRefsFile, type, refPath) {
var _this = this;
return packedRefsFile.split(/\r?\n/).reduce(function (acc, line, idx, arr) {
var targetLine = line.indexOf('^') > -1 ? arr[idx - 1] : line;
return _this._doesLineMatchRefPath(type, line, refPath) ? acc.concat(targetLine) : acc;
}, []);
};
GitInfo.prototype._doesLineMatchRefPath = function (type, line, refPath) {
var refPrefix = type === 'tag' ? 'refs/tags' : 'refs/heads';
return (line.indexOf(refPrefix) > -1 || line.indexOf('^') > -1) && line.indexOf(refPath) > -1;
};
GitInfo.prototype._getPackedRefsForType = function (refPath, type) {
var _this = this;
var packedRefsFile = this._getPackedRefsFile();
if (packedRefsFile) {
return this._getLinesForRefPath(packedRefsFile, type, refPath).map(function (shaLine) {
return _this._getShaBasedOnType(type, shaLine);
});
}
return [];
};
GitInfo.prototype._readFile = function (filePath) {
return fs.readFileSync(filePath, 'utf-8').trim();
};
GitInfo.prototype._findRepoHandleLinkedWorktree = function (gitPath) {
var stat = fs.statSync(gitPath);
if (stat.isDirectory()) {
return gitPath;
}
else {
// We have a file that tells us where to find the worktree git dir. Once we
// look there we'll know how to find the common git dir, depending on
// whether it's a linked worktree git dir, or a submodule dir
var linkedGitDir = fs.readFileSync(gitPath).toString();
var absolutePath = path.resolve(path.dirname(gitPath));
var worktreeGitDirUnresolved = /gitdir: (.*)/.exec(linkedGitDir)[1];
var worktreeGitDir = path.resolve(absolutePath, worktreeGitDirUnresolved);
return worktreeGitDir;
}
};
GitInfo.prototype._findRepo = function (startingPath) {
var gitPath;
var lastPath;
var currentPath = startingPath || process.cwd();
do {
gitPath = path.join(currentPath, this.GIT_DIR);
if (fs.existsSync(gitPath)) {
return this._findRepoHandleLinkedWorktree(gitPath);
}
lastPath = currentPath;
currentPath = path.resolve(currentPath, '..');
} while (lastPath !== currentPath);
return '';
};
return GitInfo;
}());
exports.default = GitInfo;