UNPKG

git-local-info

Version:

Retrieve current sha, branch name, repository from a git repo.

193 lines (192 loc) 7.77 kB
'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;