UNPKG

@pando/git-remote-pando

Version:
111 lines (110 loc) 4.33 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const debug_1 = __importDefault(require("debug")); const fs_extra_1 = __importDefault(require("fs-extra")); const path_1 = __importDefault(require("path")); const shelljs_1 = __importDefault(require("shelljs")); // tslint:disable-next-line:no-submodule-imports const promise_1 = __importDefault(require("simple-git/promise")); const smart_buffer_1 = require("smart-buffer"); const zlib_1 = __importDefault(require("zlib")); const git = promise_1.default(); class GitHelper { // OK constructor(helper) { this.helper = helper; this.debug = debug_1.default('pando'); } /***** core methods *****/ // OK async collect(oid, mapping) { this.debug('collecting', oid); const cid = this.helper.ipld.shaToCid(oid); if (mapping[cid]) return mapping; const node = await this.load(oid); if (node.gitType === 'commit') { // node is a commit const _mapping = await this.collect(this.helper.ipld.cidToSha(node.tree['/']), mapping); return Object.assign({}, mapping, _mapping, { [cid]: node }); } else if (Buffer.isBuffer(node)) { // node is a blob return Object.assign({}, mapping, { [cid]: node }); } else { // node is a tree // tslint:disable-next-line:forin for (const entry in node) { const _mapping = await this.collect(this.helper.ipld.cidToSha(node[entry].hash['/']), mapping); mapping = Object.assign({}, mapping, _mapping); } return Object.assign({}, mapping, { [cid]: node }); } } // OK async download(oid) { this.debug('downloading', oid); if (await this.exists(oid)) return; const cid = this.helper.ipld.shaToCid(oid); const node = await this.helper.ipld.get(cid); if (node.gitType === 'commit') { // node is a commit await this.download(this.helper.ipld.cidToSha(node.tree['/'])); for (const parent of node.parents) { await this.download(this.helper.ipld.cidToSha(parent['/'])); } await this.dump(oid, node); } else if (Buffer.isBuffer(node)) { // node is a blob await this.dump(oid, node); } else { // node is a tree // tslint:disable-next-line:forin for (const entry in node) { await this.download(await this.helper.ipld.cidToSha(node[entry].hash['/'])); } await this.dump(oid, node); } } /***** fs-related methods *****/ // OK async exists(oid) { // modify this function to rely on git cat-file -e $sha^{commit} // see https://stackoverflow.com/questions/18515488/how-to-check-if-the-commit-exists-in-a-git-repository-by-its-sha-1 return fs_extra_1.default.pathExists(await this.path(oid)); } // OK async load(oid) { const type = shelljs_1.default.exec(`git cat-file -t ${oid}`, { silent: true }).stdout.trim(); const size = shelljs_1.default.exec(`git cat-file -s ${oid}`, { silent: true }).stdout.trim(); const data = await git.binaryCatFile([type, oid]); const raw = new smart_buffer_1.SmartBuffer(); raw.writeString(`${type} `); raw.writeString(size); raw.writeUInt8(0); raw.writeBuffer(data); return this.helper.ipld.deserialize(raw.toBuffer()); } // OK async dump(oid, node) { const path = await this.path(oid); const buffer = await this.helper.ipld.serialize(node); await fs_extra_1.default.ensureFile(path); fs_extra_1.default.writeFileSync(path, zlib_1.default.deflateSync(buffer)); } /***** utility methods *****/ // OK async path(oid) { const subdirectory = oid.substring(0, 2); const filename = oid.substring(2); return path_1.default.join(this.helper.path, 'objects', subdirectory, filename); } } exports.default = GitHelper;