From b3a3ea2ff1a391872f10883dba27b828497cfd2e Mon Sep 17 00:00:00 2001 From: TheArcaneBrony Date: Sat, 17 Sep 2022 13:17:12 +0200 Subject: Better patch system --- .gitignore | 2 + build.tab-linux-desktop.json | 16 +++++++ scripts/build/clean_cache.js | 14 ++++++ scripts/build_new.js | 16 ++++++- src/api/util/TestClientPatcher.ts | 16 +++---- src/util/util/formatters/CodeFormatter.ts | 80 +++++++++++++++++++++++++++++++ src/util/util/index.ts | 1 + 7 files changed, 133 insertions(+), 12 deletions(-) create mode 100644 build.tab-linux-desktop.json create mode 100644 scripts/build/clean_cache.js create mode 100644 src/util/util/formatters/CodeFormatter.ts diff --git a/.gitignore b/.gitignore index 8631a69d..fcdeeb3f 100644 --- a/.gitignore +++ b/.gitignore @@ -34,3 +34,5 @@ dbconf.json migrations.db assets/cache_src/ + +package-lock.json diff --git a/build.tab-linux-desktop.json b/build.tab-linux-desktop.json new file mode 100644 index 00000000..f3cce980 --- /dev/null +++ b/build.tab-linux-desktop.json @@ -0,0 +1,16 @@ +{ + "compiler": "tsc", + "verbose": true, + "writeBuildLog": true, + "writeAnsiBuildLog": true, + "logErrors": true, + "tsc": { + "prettyErrors": true + }, + "clean": true, + "quiet": false, + "steps": { + "pre": ["clean", "clean_cache"], + "post": ["remap_imports"] + } +} diff --git a/scripts/build/clean_cache.js b/scripts/build/clean_cache.js new file mode 100644 index 00000000..5a18ee9d --- /dev/null +++ b/scripts/build/clean_cache.js @@ -0,0 +1,14 @@ +const { execSync } = require("child_process"); +const path = require("path"); +const fs = require("fs"); +const { argv, stdout, exit } = require("process"); +const { execIn, parts, getDirs, walk, sanitizeVarName } = require("../utils"); + +module.exports = function (config) { + console.log(`==> Cleaning asset cache...`); + const assetDir = path.resolve(path.join(config.rootDir, "assets", "cache")); + if (fs.existsSync(assetDir)) { + fs.rmSync(assetDir, { recursive: true }); + if (config.verbose) console.log(`Deleted ${assetDir}!`); + } +}; diff --git a/scripts/build_new.js b/scripts/build_new.js index 6a56e7f7..70c43e5b 100644 --- a/scripts/build_new.js +++ b/scripts/build_new.js @@ -3,6 +3,7 @@ const path = require("path"); const fs = require("fs"); const { argv, stdout, exit } = require("process"); const { execIn, parts, getDirs, walk, sanitizeVarName } = require("./utils"); +const os = require('os'); //file paths const rootDir = path.join(__dirname, ".."); @@ -17,14 +18,25 @@ const pluginDir = path.join(srcDir, "plugins"); //more, dont export const buildStepDir = path.join(scriptsDir, "build"); -if (!fs.existsSync(configPath)) { +let config; +if (fs.existsSync(path.join(rootDir, `build.${os.hostname()}.json`))) { + console.log(`Using build.${os.hostname()}.json`); + config = { rootDir, srcDir, distDir, configPath, buildLog, buildLogAnsi, pluginDir, ...require(path.join(rootDir, `build.${os.hostname()}.json`)) }; +} +else if (fs.existsSync(configPath)) { + console.log(`Using build.json`); + config = { rootDir, srcDir, distDir, configPath, buildLog, buildLogAnsi, pluginDir, ...require(configPath) }; +} +else if (!fs.existsSync(configPath)) { + console.log(`Using default config`); if (!fs.existsSync(path.join(configPath + ".default"))) { console.log("build.json.default not found! Exiting!"); exit(1); } fs.copyFileSync(configPath + ".default", configPath); + config = { rootDir, srcDir, distDir, configPath, buildLog, buildLogAnsi, pluginDir, ...require(configPath) }; } -let config = { rootDir, srcDir, distDir, configPath, buildLog, buildLogAnsi, pluginDir, ...require(configPath) }; + config.steps.pre.forEach((step) => require(path.join(buildStepDir, step))(config)); require(path.join(buildStepDir, "compile_" + config.compiler))(config); diff --git a/src/api/util/TestClientPatcher.ts b/src/api/util/TestClientPatcher.ts index 09b8e408..eb255794 100644 --- a/src/api/util/TestClientPatcher.ts +++ b/src/api/util/TestClientPatcher.ts @@ -1,5 +1,6 @@ import path from "path"; import fs from "fs"; +import { formatFile } from "@fosscord/util"; console.log('[TestClient] Loading private assets...'); @@ -27,10 +28,11 @@ fs.readdirSync(path.join(iconsRoot, "custom")).forEach(file => { console.log('[TestClient] Patcher ready!'); export function patchFile(filePath: string, content: string): string { - console.log(`[TestClient] Patching ${filePath}`); + //console.log(`[TestClient] Patching ${filePath}`); let startTime = Date.now(); - content = prettier(filePath, content); + content = formatFile(filePath, content); + //content = prettier(filePath, content); content = autoPatch(filePath, content); console.log(`[TestClient] Patched ${filePath} in ${Date.now() - startTime}ms`); @@ -104,18 +106,12 @@ function autoPatch(filePath: string, content: string): string { content = content.replace(/d: "M23\.0212.*/, `d: "${icons.get("homeIcon.path")!.toString()}"`); content = content.replace('width: n, height: o, viewBox: "0 0 28 20"', 'width: 48, height: 48, viewBox: "0 0 48 48"'); - //undo webpacking - // - booleans - content = content.replace(/!0/g, "true"); - content = content.replace(/!1/g, "false"); - // - real esmodule defs - content = content.replace(/Object.defineProperty\((.), "__esModule", { value: (.*) }\);/g, '\$1.__esModule = \$2;'); - + //save some time on load resolving asset urls... content = content.replaceAll('e.exports = n.p + "', 'e.exports = "/assets/'); content = content.replaceAll('e.exports = r.p + "', 'e.exports = "/assets/'); - console.log(`[TestClient] Autopatched ${path.basename(filePath)}!`); + //console.log(`[TestClient] Autopatched ${path.basename(filePath)}!`); return content; } \ No newline at end of file diff --git a/src/util/util/formatters/CodeFormatter.ts b/src/util/util/formatters/CodeFormatter.ts new file mode 100644 index 00000000..ce9fabe2 --- /dev/null +++ b/src/util/util/formatters/CodeFormatter.ts @@ -0,0 +1,80 @@ +export function formatFile(filePath: string, content: string): string { + let startTime = Date.now(); + + if(filePath.endsWith(".css")) { + content = formatCss(content); + } else if(filePath.endsWith(".js")) { + content = formatJs(content); + } + + console.log(`[CodeFormatter] Formatted ${filePath} in ${Date.now() - startTime}ms`); + return content; +} + +function unfoldBlocks(content: string): string{ + content = content.replaceAll("{", "{\n"); + content = content.replaceAll("}", "\n}\n"); + content = content.replaceAll(";", ";\n"); + return content; +} + +function formatCss(content: string): string { + content = unfoldBlocks(content); + + return content; +} +//simple js formatter... this was absolute pain... +function formatJs(content: string): string { + content = content.replaceAll("{", "{\n"); + content = content.replaceAll("}", "\n}\n"); + content = content.replaceAll(";", ";\n"); + content = content.replaceAll(":\"", ": \""); + content = content.replaceAll(/(\w)=\"/g, "\$1 = \""); + + content = content.replaceAll("function(){", "function() {"); + //undo webpacking, improves performance and debugging + // - booleans + content = content.replaceAll("return!", "return !"); + content = content.replace(/!0/g, "true"); + content = content.replace(/!1/g, "false"); + // - real esmodule defs, slightly faster + content = content.replace(/Object.defineProperty\((.), "__esModule", { value: (.*) }\);/g, '\$1.__esModule = \$2;'); + + //fix accidentals + content = content.replaceAll(";\n\"", ";\""); + content = content.replaceAll("{\n\n}", "{}"); + content = content.replaceAll("\\{\n", "\\{"); + content = content.replaceAll("\\\n}", "\\}"); + + content = content.replaceAll("\\}\n", "\\}"); + content = content.replaceAll("}\n\"", "}\""); + content = content.replaceAll("{\n [polyfill code] \n}\"", "{ [polyfill code] }\""); + content = content.replaceAll(";\n ", "; "); + // --regex-- + content = content.replaceAll(/\{\n(\w{1,4})\n\}/g, '{\$1}') + content = content.replaceAll(/\{\n(\w{1,4},\w{0,4})\n\}/g, '{\$1}') + content = content.replaceAll("}\n)", "})") + content = content.replaceAll("}\n|", "}|") + content = content.replaceAll("}\n\\s", "}\\s") + content = content.replaceAll("}\n$", "}$") + content = content.replaceAll("}\n\\", "}\\") + // --!regex-- + + content = content.replaceAll("\n\\n", "\\n") + content = content.replaceAll(" {\n", " {"); + content = content.replaceAll("\n}\\n", "}\\n"); + content = content.replaceAll(";\nbase64,", ";base64,"); + content = content.replaceAll(/!!{\n(\w*)\n}\n!!/g, "!!{\$1}!!"); + content = content.replaceAll("}\n!!", "}!!"); + content = content.replaceAll("}\n**", "}**"); + content = content.replaceAll("}\nx", "}x"); + content = content.replaceAll(/{\n(\w*)\n}/g, "{\$1}"); + content = content.replaceAll("\",\n\"", "\",\""); + while(/(\w) {\n([^\}\.]*)\n?}/g.test(content)) + content = content.replaceAll(/(\w) {\n?([^\}\.]*)\n?}/g, "\$1 {\$2}"); + //no double newlines + while(content.includes("\n\n")) + content = content.replaceAll("\n\n", "\n"); + + return content; +} \ No newline at end of file diff --git a/src/util/util/index.ts b/src/util/util/index.ts index 11f0b72a..58beb7ed 100644 --- a/src/util/util/index.ts +++ b/src/util/util/index.ts @@ -23,3 +23,4 @@ export * from "./Snowflake"; export * from "./String"; export * from "./Token"; export * from "./TraverseDirectory"; +export * from "./formatters/CodeFormatter"; \ No newline at end of file -- cgit 1.4.1