diff options
Diffstat (limited to 'tempdir.js')
-rw-r--r-- | tempdir.js | 86 |
1 files changed, 86 insertions, 0 deletions
diff --git a/tempdir.js b/tempdir.js new file mode 100644 index 0000000..9264ffd --- /dev/null +++ b/tempdir.js @@ -0,0 +1,86 @@ +import {mkdirSync, readdirSync, statSync} from 'node:fs' +import * as os from 'node:os' +import * as path from 'node:path' + +import {nanoid} from 'nanoid' +import {rimrafSync} from 'rimraf' + +// Invariably obliterate contents of the rootDirectory upon +// mtui startup if their mtime is older than this duration +// before the current date. +const ancient = 7 * 24 * 60 * 60 * 1000 + +const ourTemporaryDirectories = [] + +const rootDirectory = path.join(os.homedir(), '.mtui', 'tmp') + +function obliterateTemporaryDirectory(tempdir) { + const rel = path.relative(rootDirectory, tempdir) + if (rel.startsWith('/') || rel.startsWith('.')) { + console.trace() + console.error(`Ostensible tempdir located here:`) + console.error(tempdir) + console.error(`Doesn't appear to be located in tempdir root:`) + console.error(rootDirectory) + console.error(`This is a programming error, and possibly dangerous.`) + console.error(`So, exiting now. This should be investigated.`) + process.exit(1) + } + + rimrafSync(tempdir) +} + +function cleanupAncient() { + const fsOp = (fn, ...args) => { + try { + return fn(...args) + } catch (error) { + console.error(error) + console.error(`There was an error preparing the temporary file directory.`) + console.error(`You may be able to resolve this by deleting or moving away`) + console.error(`this path:`) + console.error(rootDirectory) + process.exit(1) + } + } + + fsOp(() => + mkdirSync(rootDirectory, {recursive: true})) + + const tempdirs = + (fsOp(readdirSync, rootDirectory) + .map(dir => path.join(rootDirectory, dir))) + + let first = true + for (const tempdir of tempdirs) { + const stats = fsOp(statSync, tempdir) + + if (Date.now() - stats.mtimeMs > ancient) { + if (first) { + console.log(`One or more tempdirs haven't been modified in a while, removing:`) + first = false + } + console.log(tempdir) + fsOp(obliterateTemporaryDirectory, tempdir) + } + } +} + +// This has to be a sync function, since it'll run on +// the process' 'exit' event. +function cleanupOurs() { + for (const tempdir of ourTemporaryDirectories) { + obliterateTemporaryDirectory(tempdir) + } +} + +cleanupAncient() +process.on('exit', cleanupOurs) + +export default function temporaryDirectory() { + const name = nanoid() + const dir = path.join(rootDirectory, name) + ourTemporaryDirectories.push(dir) + mkdirSync(dir) + return dir +} |