« get me outta code hell

Merge branch 'main' into merge-socket-mtui - mtui - Music Text User Interface - user-friendly command line music player
about summary refs log tree commit diff
path: root/tempdir.js
diff options
context:
space:
mode:
author(quasar) nebula <qznebula@protonmail.com>2024-05-16 22:41:33 -0300
committer(quasar) nebula <qznebula@protonmail.com>2024-05-16 22:41:33 -0300
commitcd91ccbea9e76ee1de1e3cbcfe17d8a2cb6ef9b4 (patch)
treed98e0b2a100170c7f913da57fb8e010c4b581603 /tempdir.js
parent2a270f20cc8e2f2a0754d28d6892bb1bd27e45ce (diff)
parenteb6a997df675fc8176fb15f34450a0c1b8416edc (diff)
Merge branch 'main' into merge-socket-mtui merge-socket-mtui
So we made this merge commit *after* going through a whole
fidanglin' bunch of steps to flat-out rebase socket-mtui...
but of course, that was pretty hopeless from the start to
get just quite right. After all, we didn't know the exact
point of each commit and how to test out the changes, so
we couldn't make sure all our rebased commits were working
the same way. (This is maybe the single coolest reason to
make sure that automated tests *pass with 100% coverage
at every commit*, but obviously this project doesn't have
that. Alas!)

This merge commit follows up a different merge commit we
actually made almost exactly one year ago to this day
(also: our birthday LOL). We figure the testing done at
that point was quite a bit more thorough than we'd do
today, and anyway there's little reason to repeat the
work we did in that commit. Comparatively, this merge
commit is way smaller!

It was still fun to go through the whole rebasing
process, even if it didn't practically bring us
anywhere. You know, assuming the merge commit from
last year didn't accidentally destroy any code or
todos lol........ *prays* ^____^
Diffstat (limited to 'tempdir.js')
-rw-r--r--tempdir.js86
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
+}