UNPKG

@theia/filesystem

Version:
128 lines 5.9 kB
"use strict"; // ***************************************************************************** // Copyright (C) 2018 TypeFox and others. // // This program and the accompanying materials are made available under the // terms of the Eclipse Public License v. 2.0 which is available at // http://www.eclipse.org/legal/epl-2.0. // // This Source Code may also be made available under the following Secondary // Licenses when the conditions for such availability set forth in the Eclipse // Public License v. 2.0 are satisfied: GNU General Public License, version 2 // with the GNU Classpath Exception which is available at // https://www.gnu.org/software/classpath/license.html. // // SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0 // ***************************************************************************** Object.defineProperty(exports, "__esModule", { value: true }); exports.DirectoryArchiver = void 0; const tslib_1 = require("tslib"); const inversify_1 = require("@theia/core/shared/inversify"); const fs = require("@theia/core/shared/fs-extra"); const tar_fs_1 = require("tar-fs"); const uri_1 = require("@theia/core/lib/common/uri"); const file_uri_1 = require("@theia/core/lib/common/file-uri"); let DirectoryArchiver = class DirectoryArchiver { async archive(inputPath, outputPath, entries) { return new Promise(async (resolve, reject) => { (0, tar_fs_1.pack)(inputPath, { entries }).pipe(fs.createWriteStream(outputPath)).on('finish', () => resolve()).on('error', e => reject(e)); }); } async findCommonParents(uris) { const map = new Map(); for (const uri of uris) { // 1. Get the container if not the URI is not a directory. const containerUri = (await this.isDir(uri)) ? uri : uri.parent; let containerUriStr = this.toUriString(containerUri); // 2. If the container already registered, just append the current URI to it. if (map.has(containerUriStr)) { map.set(containerUriStr, [...map.get(containerUriStr), this.toUriString(uri)]); } else { // 3. Try to find the longest container URI that we can use. // When we have `/A/B/` and `/A/C` and a file `A/B/C/D.txt` then we need to find `/A/B`. The longest URIs come first. for (const knownContainerUri of Array.from(map.keys()).sort((left, right) => right.length - left.length)) { if (uri.toString().startsWith(knownContainerUri)) { containerUriStr = knownContainerUri; break; } } const entries = map.get(containerUriStr) || []; entries.push(this.toUriString(uri)); map.set(containerUriStr, entries); } // 4. Collapse the hierarchy by finding the closest common parents for the entries, if any. let collapsed = false; collapseLoop: while (!collapsed) { const knownContainerUris = Array.from(map.keys()).sort((left, right) => right.length - left.length); if (knownContainerUris.length > 1) { for (let i = 0; i < knownContainerUris.length; i++) { for (let j = i + 1; j < knownContainerUris.length; j++) { const left = knownContainerUris[i]; const right = knownContainerUris[j]; const commonParent = this.closestCommonParentUri(new uri_1.default(left), new uri_1.default(right)); if (commonParent && !commonParent.path.isRoot) { const leftEntries = map.get(left) || []; const rightEntries = map.get(right) || []; map.delete(left); map.delete(right); map.set(this.toUriString(commonParent), [...leftEntries, ...rightEntries]); break collapseLoop; } } } } collapsed = true; } } return map; } closestCommonParentUri(left, right) { if (left.scheme !== right.scheme) { return undefined; } const allLeft = left.allLocations; const allRight = right.allLocations; for (const leftUri of allLeft) { for (const rightUri of allRight) { if (this.equal(leftUri, rightUri)) { return leftUri; } } } return undefined; } async isDir(uri) { try { const stat = await fs.stat(file_uri_1.FileUri.fsPath(uri)); return stat.isDirectory(); } catch { return false; } } equal(left, right) { if (Array.isArray(left) && Array.isArray(right)) { if (left === right) { return true; } if (left.length !== right.length) { return false; } return left.map(this.toUriString).sort().toString() === right.map(this.toUriString).sort().toString(); } else if (left instanceof uri_1.default && right instanceof uri_1.default) { return this.toUriString(left) === this.toUriString(right); } return false; } toUriString(uri) { const raw = uri.toString(); return raw.endsWith('/') ? raw.slice(0, -1) : raw; } }; exports.DirectoryArchiver = DirectoryArchiver; exports.DirectoryArchiver = DirectoryArchiver = tslib_1.__decorate([ (0, inversify_1.injectable)() ], DirectoryArchiver); //# sourceMappingURL=directory-archiver.js.map