From cb99d29b05ae0dcb5be9b5103c8cc4a6c531d5a5 Mon Sep 17 00:00:00 2001 From: q13x <84165981+WorldEditAxe@users.noreply.github.com> Date: Wed, 21 Jun 2023 01:26:19 +0000 Subject: [PATCH] smart replit runtime --- .gitignore | 3 +- replit_runtime/config.js | 5 ++ replit_runtime/index.js | 102 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 replit_runtime/config.js create mode 100644 replit_runtime/index.js diff --git a/.gitignore b/.gitignore index b7dab5e..711a6eb 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules -build \ No newline at end of file +build +.sourcehash \ No newline at end of file diff --git a/replit_runtime/config.js b/replit_runtime/config.js new file mode 100644 index 0000000..b045050 --- /dev/null +++ b/replit_runtime/config.js @@ -0,0 +1,5 @@ +const path = require("path") + +module.exports = { + sourceDir: path.resolve("~", process.env.REPL_SLUG) +} \ No newline at end of file diff --git a/replit_runtime/index.js b/replit_runtime/index.js new file mode 100644 index 0000000..b8ae019 --- /dev/null +++ b/replit_runtime/index.js @@ -0,0 +1,102 @@ +// libraries +const fs = require("fs/promises") +const path = require("path") +const crypto = require("crypto") +const { + sourceDir +} = require("./config.js") + + +class Logger { + constructor({ name, logDebug }) { + this.name = name + this.debug = logDebug + } + + _log(logType, data, method) { + console[method](`[${this.name}] [${logType}] ${typeof data == "string" ? data : data.toString()}`) + } + + info(data) { + this._log("info", data, "log") + } + + warn(data) { + this._log("warn", data, "error") + } + + error(data) { + this._log("error", data, "error") + } + + debug(data) { + if (this.debug) { + this._log("debug", data, "error") + } + } +} + +async function recursiveFileSearch(dir) { + const fileList = [] + for (const file of await fs.readdir(dir, { withFileTypes: true })) { + let pathDir = path.resolve(dir, file) + if (file.isFile()) { + fileList.push(file) + } else if (file.isDirectory()) { + fileList.push(...(await recursiveFileSearch(pathDir))) + } else { + logger.warn(`Found directory entry that is neither a file or directory (${pathDir}), ignoring!`) + } + } + return fileList +} + +const logger = new Logger("Launcher", process.env.DEBUG == "true"), + LINE_SEPERATOR = "-----------------------------------" + +if (!process.env.REPL_SLUG) { + logger.error(LINE_SEPERATOR) + logger.error("Repl not detected!") + logger.error("") + logger.error("This file is meant to be ran in a Repl") + logger.error(LINE_SEPERATOR) +} + +logger.info(LINE_SEPERATOR) +logger.info("Checking if the proxy needs to be recompiled...") +logger.info(LINE_SEPERATOR) + +fs.readFile(path.join(__dirname, ".sourcehash")) + .then(data => { + let oldHash = data.toString() + logger.info("Found old hash, calculating hash of source files...") + recursiveFileSearch(sourceDir) + .then(files => { + Promise.all(files.map(f => fs.readFile(f))) + .then(data => { + const hash = crypto.createHash("sha256") + data.forEach(d => hash.update(d)) + let sourceHash = hash.digest().toString() + + if (sourceHash === oldHash) { + logger.info("Source hasn't been changed, skipping compilation...") + process.exit(0) + } else { + logger.info("Source has been changed, recompiling...") + process.exit(2) + } + }) + }) + .catch(err => { + logger.error(`Could not calculate file hashes for files in directory ${sourceDir}!\n${err.stack}`) + process.exit(1) + }) + }) + .catch(err => { + if (err.code == "ENOENT") { + logger.warn("Previous source hash not found! Assuming a clean install is being used.") + } else { + logger.error(`Could not read .sourcehash file in ${path.join(__dirname, ".sourcehash")} due to an unknown error! Try again with a clean repl?\n${err.stack}`) + process.exit(2) + } + }) \ No newline at end of file