You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
120 lines
3.6 KiB
120 lines
3.6 KiB
"use strict";
|
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
exports.archiveDirectory = void 0;
|
|
const archiver = require("archiver");
|
|
const filesize = require("filesize");
|
|
const fs = require("fs");
|
|
const path = require("path");
|
|
const tar = require("tar");
|
|
const tmp = require("tmp");
|
|
const error_1 = require("./error");
|
|
const listFiles_1 = require("./listFiles");
|
|
const logger_1 = require("./logger");
|
|
const fsAsync = require("./fsAsync");
|
|
async function archiveDirectory(sourceDirectory, options = {}) {
|
|
let postfix = ".tar.gz";
|
|
if (options.type === "zip") {
|
|
postfix = ".zip";
|
|
}
|
|
const tempFile = tmp.fileSync({
|
|
prefix: "firebase-archive-",
|
|
postfix,
|
|
});
|
|
if (!options.ignore) {
|
|
options.ignore = [];
|
|
}
|
|
let makeArchive;
|
|
if (options.type === "zip") {
|
|
makeArchive = zipDirectory(sourceDirectory, tempFile, options);
|
|
}
|
|
else {
|
|
makeArchive = tarDirectory(sourceDirectory, tempFile, options);
|
|
}
|
|
try {
|
|
const archive = await makeArchive;
|
|
logger_1.logger.debug(`Archived ${filesize(archive.size)} in ${sourceDirectory}.`);
|
|
return archive;
|
|
}
|
|
catch (err) {
|
|
if (err instanceof error_1.FirebaseError) {
|
|
throw err;
|
|
}
|
|
throw new error_1.FirebaseError("Failed to create archive.", { original: err });
|
|
}
|
|
}
|
|
exports.archiveDirectory = archiveDirectory;
|
|
async function tarDirectory(sourceDirectory, tempFile, options) {
|
|
const allFiles = (0, listFiles_1.listFiles)(sourceDirectory, options.ignore);
|
|
try {
|
|
fs.statSync(sourceDirectory);
|
|
}
|
|
catch (err) {
|
|
if (err.code === "ENOENT") {
|
|
throw new error_1.FirebaseError(`Could not read directory "${sourceDirectory}"`);
|
|
}
|
|
throw err;
|
|
}
|
|
if (!allFiles.length) {
|
|
throw new error_1.FirebaseError(`Cannot create a tar archive with 0 files from directory "${sourceDirectory}"`);
|
|
}
|
|
await tar.create({
|
|
gzip: true,
|
|
file: tempFile.name,
|
|
cwd: sourceDirectory,
|
|
follow: true,
|
|
noDirRecurse: true,
|
|
portable: true,
|
|
}, allFiles);
|
|
const stats = fs.statSync(tempFile.name);
|
|
return {
|
|
file: tempFile.name,
|
|
stream: fs.createReadStream(tempFile.name),
|
|
manifest: allFiles,
|
|
size: stats.size,
|
|
source: sourceDirectory,
|
|
};
|
|
}
|
|
async function zipDirectory(sourceDirectory, tempFile, options) {
|
|
const archiveFileStream = fs.createWriteStream(tempFile.name, {
|
|
flags: "w",
|
|
encoding: "binary",
|
|
});
|
|
const archive = archiver("zip");
|
|
const archiveDone = pipeAsync(archive, archiveFileStream);
|
|
const allFiles = [];
|
|
let files;
|
|
try {
|
|
files = await fsAsync.readdirRecursive({ path: sourceDirectory, ignore: options.ignore });
|
|
}
|
|
catch (err) {
|
|
if (err.code === "ENOENT") {
|
|
throw new error_1.FirebaseError(`Could not read directory "${sourceDirectory}"`, { original: err });
|
|
}
|
|
throw err;
|
|
}
|
|
for (const file of files) {
|
|
const name = path.relative(sourceDirectory, file.name);
|
|
allFiles.push(name);
|
|
archive.file(file.name, {
|
|
name,
|
|
mode: file.mode,
|
|
});
|
|
}
|
|
void archive.finalize();
|
|
await archiveDone;
|
|
const stats = fs.statSync(tempFile.name);
|
|
return {
|
|
file: tempFile.name,
|
|
stream: fs.createReadStream(tempFile.name),
|
|
manifest: allFiles,
|
|
size: stats.size,
|
|
source: sourceDirectory,
|
|
};
|
|
}
|
|
async function pipeAsync(from, to) {
|
|
return new Promise((resolve, reject) => {
|
|
to.on("finish", resolve);
|
|
to.on("error", reject);
|
|
from.pipe(to);
|
|
});
|
|
}
|