UNPKG

git-local-info-ts

Version:

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

192 lines (191 loc) 7.85 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.GitInfo = void 0; var fs_1 = require("fs"); var path_1 = require("path"); var zlib_1 = require("zlib"); var ini_1 = require("ini"); var GitInfo = /** @class */ (function () { function GitInfo(args) { if (args === void 0) { args = {}; } this.GIT_DIR = '.git'; var gitPath = args.gitPath, GIT_DIR = args.GIT_DIR; if (GIT_DIR) { this.GIT_DIR = GIT_DIR; } this.gitPath = this._findRepo(gitPath); this.headPath = (0, path_1.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: (0, path_1.dirname)((0, path_1.resolve)(this.gitPath)), }; }, enumerable: false, configurable: true }); // Get branch GitInfo.prototype.getBranch = function () { try { if ((0, fs_1.existsSync)(this.headPath)) { var headFile = this._readFile(this.headPath); var match = /refs\/heads\/(\S+$)/.exec(headFile); var branchName = match && match[1]; return branchName; } } catch (_a) { } }; // Get repository GitInfo.prototype.getRepository = function () { try { var configFilePath = (0, path_1.join)(this.gitPath, 'config'); if ((0, fs_1.existsSync)(configFilePath)) { var config = (0, ini_1.parse)(this._readFile(configFilePath)); var repository = config['remote "origin"'].url; return repository; } } catch (_a) { } }; // Get sha/commit hash GitInfo.prototype.getSha = function () { try { if ((0, fs_1.existsSync)(this.headPath)) { var headFile = (0, fs_1.readFileSync)(this.headPath, 'utf-8'); var refPath = headFile.split(' ')[1]; // Find branch and SHA if (refPath) { refPath = refPath.trim(); var branchPath = (0, path_1.join)(this.gitPath, refPath); var hasBranchPath = (0, fs_1.existsSync)(branchPath); return hasBranchPath ? this._readFile(branchPath) : this._findPackedCommit(refPath); } var sha = headFile.split('/').slice(2).join('/').trim(); if (!sha) { sha = headFile.split('/').slice(-1)[0].trim(); } return sha; } } catch (_a) { } }; GitInfo.prototype.getCommit = function () { try { var sha = this.getSha(); if (!sha) { return ''; } var objectPath = (0, path_1.join)(this.gitPath, 'objects', sha.slice(0, 2), sha.slice(2)); if (zlib_1.inflateSync && (0, fs_1.existsSync)(objectPath)) { var objectContents = (0, zlib_1.inflateSync)((0, fs_1.readFileSync)(objectPath)).toString(); var commit = objectContents .split(/\0|\r?\n/) .filter(Boolean) .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 (_a) { } }; GitInfo.prototype._findPackedCommit = function (refPath) { return this._getPackedRefsForType(refPath, 'commit')[0]; }; GitInfo.prototype._getPackedRefsFile = function () { var packedRefsFilePath = (0, path_1.join)(this.gitPath, 'packed-refs'); return (0, fs_1.existsSync)(packedRefsFilePath) ? this._readFile(packedRefsFilePath) : false; }; GitInfo.prototype._getShaBasedOnType = function (type, shaLine) { if (type === 'tag') { return shaLine.split('tags/')[1]; } else if (type === 'commit') { return shaLine.split(' ')[0]; } return ''; }; GitInfo.prototype._getLinesForRefPath = function (packedRefsFile, type, refPath) { var _this = this; return packedRefsFile.split(/\r?\n/).reduce(function (acc, line, idx, array) { var targetLine = line.includes('^') ? array[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.includes(refPrefix) || line.includes('^')) && line.includes(refPath); }; 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 (0, fs_1.readFileSync)(filePath, 'utf-8').trim(); }; GitInfo.prototype._findRepoHandleLinkedWorktree = function (gitPath) { var stat = (0, fs_1.statSync)(gitPath); if (stat.isDirectory()) { return gitPath; } // 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 = (0, fs_1.readFileSync)(gitPath).toString(); var absolutePath = (0, path_1.resolve)((0, path_1.dirname)(gitPath)); var worktreeGitDirUnresolved = /gitdir: (.*)/.exec(linkedGitDir)[1]; var worktreeGitDir = (0, path_1.resolve)(absolutePath, worktreeGitDirUnresolved); return worktreeGitDir; }; GitInfo.prototype._findRepo = function (startingPath) { var lastPath; var currentPath = startingPath || process.cwd(); do { var gitPath = (0, path_1.join)(currentPath, this.GIT_DIR); if ((0, fs_1.existsSync)(gitPath)) { return this._findRepoHandleLinkedWorktree(gitPath); } lastPath = currentPath; currentPath = (0, path_1.resolve)(currentPath, '..'); } while (lastPath !== currentPath); return ''; }; return GitInfo; }()); exports.GitInfo = GitInfo;