main.js 5.45 KB
Newer Older
huahua committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.TmpDir = exports.getTempName = void 0;
const fs_extra_1 = require("fs-extra");
const os_1 = require("os");
const path = require("path");
let tmpFileCounter = 0;
const tmpDirManagers = new Set();
// add date to avoid use stale temp dir
const tempDirPrefix = `${process.pid.toString(36)}-${Date.now().toString(36)}`;
function getTempName(prefix) {
    return `${prefix == null ? "" : `${prefix}-`}${tempDirPrefix}-${(tmpFileCounter++).toString(36)}`;
}
exports.getTempName = getTempName;
let tempDirPromise;
let tempBaseDir;
function getBaseTempDir() {
    if (tempDirPromise != null) {
        return tempDirPromise;
    }
    if (tempBaseDir != null) {
        return Promise.resolve(tempBaseDir);
    }
    const systemTmpDir = process.env.APP_BUILDER_TMP_DIR || os_1.tmpdir();
    const isEnsureRemovedOnExit = process.env.TMP_DIR_MANAGER_ENSURE_REMOVED_ON_EXIT !== "false";
    tempDirPromise = fs_extra_1.mkdtemp(path.join(systemTmpDir, "t-"))
        .then(it => fs_extra_1.realpath(it))
        .then(dir => {
        if (isEnsureRemovedOnExit) {
            addExitHook(dir);
        }
        tempBaseDir = dir;
        return dir;
    });
    return tempDirPromise;
}
function addExitHook(dir) {
    require("async-exit-hook")((callback) => {
        const managers = Array.from(tmpDirManagers);
        tmpDirManagers.clear();
        if (callback == null) {
            for (const manager of managers) {
                manager.cleanupSync();
            }
            try {
                fs_extra_1.removeSync(dir);
            }
            catch (e) {
                handleError(e, dir);
            }
            return;
        }
        Promise.all(managers.map(it => it.cleanup()))
            .then(() => fs_extra_1.remove(dir))
            .then(() => callback())
            .catch(e => {
            try {
                handleError(e, dir);
            }
            finally {
                callback();
            }
        });
    });
}
function handleError(e, file) {
    if (e.code !== "EPERM" && e.code !== "ENOENT") {
        // use only console.* instead of our warn on exit (otherwise nodeEmoji can be required on request)
        console.warn(`Cannot delete temporary "${file}": ${(e.stack || e).toString()}`);
    }
}
class TmpDir {
    constructor(debugName = "") {
        this.debugName = debugName;
        this.tempFiles = [];
        this.registered = false;
    }
    // noinspection JSMethodCanBeStatic,JSUnusedGlobalSymbols
    get rootTempDir() {
        return getBaseTempDir();
    }
    getTempDir(options) {
        return this.getTempFile(options, true);
    }
    createTempDir(options) {
        return this.getTempFile(options, true)
            .then(it => fs_extra_1.ensureDir(it).then(() => it));
    }
    getTempFile(options, isDir = false) {
        return getBaseTempDir()
            .then(baseTempDir => {
            if (!this.registered) {
                this.registered = true;
                tmpDirManagers.add(this);
            }
            const prefix = nullize(options == null ? null : options.prefix);
            const suffix = nullize(options == null ? null : options.suffix);
            const namePrefix = prefix == null ? "" : `${prefix}-`;
            const nameSuffix = suffix == null ? "" : (suffix.startsWith(".") ? suffix : `-${suffix}`);
            const result = `${baseTempDir}${path.sep}${namePrefix}${(tmpFileCounter++).toString(36)}${nameSuffix}`;
            this.tempFiles.push({
                path: result,
                isDir,
                disposer: options == null ? null : options.disposer,
            });
            return result;
        });
    }
    cleanupSync() {
        const tempFiles = this.tempFiles;
        tmpDirManagers.delete(this);
        this.registered = false;
        if (tempFiles.length === 0) {
            return;
        }
        this.tempFiles = [];
        for (const file of tempFiles) {
            if (file.disposer != null) {
                // noinspection JSIgnoredPromiseFromCall
                file.disposer(file.path);
                continue;
            }
            try {
                if (file.isDir) {
                    fs_extra_1.removeSync(file.path);
                }
                else {
                    fs_extra_1.unlinkSync(file.path);
                }
            }
            catch (e) {
                handleError(e, file.path);
            }
        }
    }
    cleanup() {
        const tempFiles = this.tempFiles;
        tmpDirManagers.delete(this);
        this.registered = false;
        if (tempFiles.length === 0) {
            return Promise.resolve();
        }
        this.tempFiles = [];
        if (tmpDirManagers.size === 0) {
            const dir = tempBaseDir;
            if (dir == null) {
                return Promise.resolve();
            }
            tempBaseDir = null;
            tempDirPromise = null;
            return fs_extra_1.remove(dir);
        }
        return Promise.all(tempFiles.map(it => {
            if (it.disposer != null) {
                return it.disposer(it.path);
            }
            return (it.isDir ? fs_extra_1.remove(it.path) : fs_extra_1.unlink(it.path))
                .catch(e => {
                handleError(e, it.path);
            });
        }));
    }
    toString() {
        return this.debugName;
    }
}
exports.TmpDir = TmpDir;
function nullize(s) {
    return s == null || s.length === 0 ? null : s;
}
//# sourceMappingURL=main.js.map