"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const is_1 = __importDefault(require("is")); const path_1 = __importDefault(require("path")); const crc_1 = __importDefault(require("crc")); const urijs_1 = __importDefault(require("urijs")); const path_2 = __importDefault(require("./path")); const promise_1 = __importDefault(require("./promise")); const command_1 = __importDefault(require("./command")); const fs_1 = __importDefault(require("./fs")); const GIT_PREFIX = "git+"; function Git() { this.tmpDir; this.cloned = {}; } // Return an unique ID for a combinaison host/ref Git.prototype.repoID = function (host, ref) { return crc_1.default.crc32(`${host}#${ref || ""}`).toString(16); }; // Allocate a temporary folder for cloning repos in it Git.prototype.allocateDir = function () { const that = this; if (this.tmpDir) return (0, promise_1.default)(); // @ts-expect-error ts-migrate(2554) FIXME: Expected 1 arguments, but got 0. return fs_1.default.tmpDir().then((dir) => { that.tmpDir = dir; }); }; // Clone a git repository if non existant Git.prototype.clone = function (host, ref) { const that = this; return (this.allocateDir() // Return or clone the git repo .then(() => { // Unique ID for repo/ref combinaison const repoId = that.repoID(host, ref); // Absolute path to the folder const repoPath = path_1.default.join(that.tmpDir, repoId); if (that.cloned[repoId]) return repoPath; // Clone repo return (command_1.default // @ts-expect-error ts-migrate(2554) FIXME: Expected 2 arguments, but got 1. .exec(`git clone ${host} ${repoPath}`) // Checkout reference if specified .then(() => { that.cloned[repoId] = true; if (!ref) return; return command_1.default.exec(`git checkout ${ref}`, { cwd: repoPath }); }) .thenResolve(repoPath)); })); }; // Get file from a git repo Git.prototype.resolve = function (giturl) { // Path to a file in a git repo? if (!Git.isUrl(giturl)) { if (this.resolveRoot(giturl)) return (0, promise_1.default)(giturl); return (0, promise_1.default)(null); } if (is_1.default.string(giturl)) giturl = Git.parseUrl(giturl); if (!giturl) return (0, promise_1.default)(null); // Clone or get from cache return this.clone(giturl.host, giturl.ref).then((repo) => { return path_1.default.resolve(repo, giturl.filepath); }); }; // Return root of git repo from a filepath Git.prototype.resolveRoot = function (filepath) { // No git repo cloned, or file is not in a git repository if (!this.tmpDir || !path_2.default.isInRoot(this.tmpDir, filepath)) return null; // Extract first directory (is the repo id) const relativeToGit = path_1.default.relative(this.tmpDir, filepath); const repoId = relativeToGit.split(path_1.default.sep)[0]; if (!repoId) { return; } // Return an absolute file return path_1.default.resolve(this.tmpDir, repoId); }; // Check if an url is a git dependency url Git.isUrl = function (giturl) { return giturl.indexOf(GIT_PREFIX) === 0; }; // Parse and extract infos Git.parseUrl = function (giturl) { if (!Git.isUrl(giturl)) return null; giturl = giturl.slice(GIT_PREFIX.length); const uri = new urijs_1.default(giturl); const ref = uri.fragment() || null; uri.fragment(null); // Extract file inside the repo (after the .git) const fileParts = uri.path().split(".git"); let filepath = fileParts.length > 1 ? fileParts.slice(1).join(".git") : ""; if (filepath[0] == "/") { filepath = filepath.slice(1); } // Recreate pathname without the real filename uri.path(`${fileParts[0]}.git`); return { host: uri.toString(), ref: ref, filepath: filepath }; }; exports.default = Git;