I hate writing Webpack configs. I hate it so much.

This commit is contained in:
Radon Rosborough 2020-12-27 12:42:06 -08:00
parent 8b8266c752
commit 2dd3e31f1a
9 changed files with 2067 additions and 379 deletions

View File

@ -76,7 +76,7 @@ endif
.PHONY: install .PHONY: install
install: install:
@: $${L} $${T} @: $${L} $${T}
[[ -z "$$(ls -A /var/lib/apt/lists)" ]] && sudo apt update if [[ -z "$$(ls -A /var/lib/apt/lists)" ]]; then sudo apt update; fi
sudo apt reinstall -y ./$(BUILD)/$(DEB) sudo apt reinstall -y ./$(BUILD)/$(DEB)
### Build and run application code ### Build and run application code
@ -87,7 +87,7 @@ frontend:
.PHONY: frontend-dev .PHONY: frontend-dev
frontend-dev: frontend-dev:
npx webpack --mode=development --watch watchexec -w webpack.config.cjs -w node_modules -r --no-environment -- "echo 'Running webpack...' >&2; npx webpack --mode=development --watch"
.PHONY: system .PHONY: system
system: system:
@ -95,7 +95,7 @@ system:
.PHONY: system-dev .PHONY: system-dev
system-dev: system-dev:
watchexec -w system/src -n ./system/compile.bash watchexec -w system/src -n -- ./system/compile.bash
.PHONY: server .PHONY: server
server: server:
@ -103,7 +103,7 @@ server:
.PHONY: server-dev .PHONY: server-dev
server-dev: server-dev:
watchexec -w backend -r -n node backend/server.js watchexec -w backend -r -n -- node backend/server.js
.PHONY: build .PHONY: build
build: frontend system build: frontend system
@ -112,6 +112,10 @@ build: frontend system
dev: dev:
make -j3 frontend-dev system-dev server-dev make -j3 frontend-dev system-dev server-dev
.PHONY: test
test:
node backend/test-runner.js $(F)
### Fetch artifacts from registries ### Fetch artifacts from registries
.PHONY: pull .PHONY: pull

View File

@ -43,5 +43,6 @@ async function readLangsFromDisk() {
} }
} }
readLangsFromDisk(); export const langsPromise = readLangsFromDisk().then(() => langs);
fsOrig.watch("/opt/riju/langs", debounce(readLangsFromDisk, 200)); fsOrig.watch("/opt/riju/langs", debounce(readLangsFromDisk, 200));

View File

@ -22,10 +22,17 @@ app.set("query parser", (qs) => new URLSearchParams(qs));
app.set("view engine", "ejs"); app.set("view engine", "ejs");
app.get("/", (_, res) => { app.get("/", (_, res) => {
res.render(path.resolve("frontend/pages/index"), { if (Object.keys(langs).length > 0) {
langs, res.render(path.resolve("frontend/pages/index"), {
analyticsEnabled, langs,
}); analyticsEnabled,
});
} else {
res.send(
503,
"Still loading languages, or encountered error while doing so\n"
);
}
}); });
for (const [lang, { aliases }] of Object.entries(langs)) { for (const [lang, { aliases }] of Object.entries(langs)) {
if (aliases) { if (aliases) {

View File

@ -1,27 +1,25 @@
import fs from "fs"; import { promises as fs } from "fs";
import process from "process"; import process from "process";
import { promisify } from "util";
import _ from "lodash"; import _ from "lodash";
import { Moment } from "moment";
import moment from "moment";
import pQueue from "p-queue"; import pQueue from "p-queue";
const PQueue = pQueue.default; const PQueue = pQueue.default;
import rimraf from "rimraf";
import stripAnsi from "strip-ansi"; import stripAnsi from "strip-ansi";
import { v4 as getUUID } from "uuid"; import { v4 as getUUID } from "uuid";
import api from "./api"; import * as api from "./api.js";
import { langs } from "./langs"; import { langsPromise } from "./langs.js";
let langs = {};
function parseIntOr(thing, def) { function parseIntOr(thing, def) {
const num = parseInt(thing); const num = parseInt(thing);
return Number.isNaN(num) ? def : num; return Number.isNaN(num) ? def : num;
} }
const TIMEOUT_FACTOR = parseIntOr(process.env.TIMEOUT_FACTOR, 1); const TIMEOUT = parseIntOr(process.env.TEST_TIMEOUT_SECS, 15);
const CONCURRENCY = parseIntOr(process.env.CONCURRENCY, 2); const PATIENCE = parseIntOr(process.env.TEST_PATIENCE, 1);
const BASE_TIMEOUT_SECS = 5; const CONCURRENCY = parseIntOr(process.env.TEST_CONCURRENCY, 2);
function findPosition(str, idx) { function findPosition(str, idx) {
const lines = str.substring(0, idx).split("\n"); const lines = str.substring(0, idx).split("\n");
@ -38,7 +36,7 @@ async function sendInput(send, input) {
const delay = parseFloat(line.replace(/DELAY: */, "")); const delay = parseFloat(line.replace(/DELAY: */, ""));
if (Number.isNaN(delay)) continue; if (Number.isNaN(delay)) continue;
await new Promise((resolve) => await new Promise((resolve) =>
setTimeout(resolve, delay * 1000 * TIMEOUT_FACTOR) setTimeout(resolve, delay * 1000 * PATIENCE)
); );
} else { } else {
send({ event: "terminalInput", input: line + "\r" }); send({ event: "terminalInput", input: line + "\r" });
@ -52,8 +50,8 @@ class Test {
} }
record = (msg) => { record = (msg) => {
const dur = moment.duration(moment().diff(this.startTime)); const dur = (new Date().getTime() - this.startTime) / 1000;
this.messages.push({ time: dur.asSeconds(), ...msg }); this.messages.push({ time: dur, ...msg });
}; };
send = (msg) => { send = (msg) => {
@ -84,7 +82,7 @@ class Test {
if ((this.config.skip || []).includes(this.type)) { if ((this.config.skip || []).includes(this.type)) {
return "skipped"; return "skipped";
} }
this.startTime = moment(); this.startTime = new Date().getTime();
let session = null; let session = null;
let timeout = null; let timeout = null;
try { try {
@ -123,7 +121,7 @@ class Test {
timeout = setTimeout(() => { timeout = setTimeout(() => {
this.timedOut = true; this.timedOut = true;
this.handleUpdate(); this.handleUpdate();
}, (this.config.timeout || BASE_TIMEOUT_SECS) * 1000 * TIMEOUT_FACTOR); }, TIMEOUT * 1000 * PATIENCE);
await session.setup(); await session.setup();
switch (this.type) { switch (this.type) {
case "ensure": case "ensure":
@ -547,7 +545,9 @@ class Test {
}, },
}); });
} else if (msg.output.id === "ecdb8a55-f755-4553-ae8e-91d6ebbc2045") { } else if (msg.output.id === "ecdb8a55-f755-4553-ae8e-91d6ebbc2045") {
return msg.output.result.items || msg.output.result; if (msg.output && msg.output.result) {
return msg.output.result.items || msg.output.result;
}
} }
} }
} }
@ -615,21 +615,22 @@ function getTestList() {
async function writeLog(lang, type, result, log) { async function writeLog(lang, type, result, log) {
log = `${result.toUpperCase()}: ${lang}/${type}\n` + log; log = `${result.toUpperCase()}: ${lang}/${type}\n` + log;
await promisify(fs.mkdir)(`tests/${lang}`, { recursive: true }); await fs.mkdir(`tests/${lang}`, { recursive: true });
await promisify(fs.writeFile)(`tests/${lang}/${type}.log`, log); await fs.writeFile(`tests/${lang}/${type}.log`, log);
await promisify(fs.mkdir)(`tests-run/${lang}`, { recursive: true }); await fs.mkdir(`tests-run/${lang}`, { recursive: true });
await promisify(fs.symlink)( await fs.symlink(
`../../tests/${lang}/${type}.log`, `../../tests/${lang}/${type}.log`,
`tests-run/${lang}/${type}.log` `tests-run/${lang}/${type}.log`
); );
await promisify(fs.mkdir)(`tests-${result}/${lang}`, { recursive: true }); await fs.mkdir(`tests-${result}/${lang}`, { recursive: true });
await promisify(fs.symlink)( await fs.symlink(
`../../tests/${lang}/${type}.log`, `../../tests/${lang}/${type}.log`,
`tests-${result}/${lang}/${type}.log` `tests-${result}/${lang}/${type}.log`
); );
} }
async function main() { async function main() {
langs = await langsPromise;
let tests = getTestList(); let tests = getTestList();
const args = process.argv.slice(2); const args = process.argv.slice(2);
for (const arg of args) { for (const arg of args) {
@ -672,10 +673,10 @@ async function main() {
); );
process.exit(1); process.exit(1);
} }
await promisify(rimraf)("tests-run"); await fs.rm("tests-run", { recursive: true, force: true });
await promisify(rimraf)("tests-passed"); await fs.rm("tests-passed", { recursive: true, force: true });
await promisify(rimraf)("tests-skipped"); await fs.rm("tests-skipped", { recursive: true, force: true });
await promisify(rimraf)("tests-failed"); await fs.rm("tests-failed", { recursive: true, force: true });
const queue = new PQueue({ concurrency: CONCURRENCY }); const queue = new PQueue({ concurrency: CONCURRENCY });
let passed = new Set(); let passed = new Set();
let skipped = new Set(); let skipped = new Set();

View File

@ -1,4 +1,4 @@
import monaco from "monaco-editor"; import * as monaco from "monaco-editor";
import { import {
createConnection, createConnection,
MonacoLanguageClient, MonacoLanguageClient,
@ -22,7 +22,7 @@ const DEBUG = window.location.hash === "#debug";
const config = window.rijuConfig; const config = window.rijuConfig;
class RijuMessageReader extends AbstractMessageReader { class RijuMessageReader extends AbstractMessageReader {
constructor(socketSocket) { constructor(socket) {
super(); super();
this.state = "initial"; this.state = "initial";
this.callback = null; this.callback = null;

View File

@ -48,6 +48,6 @@ lsp:
interpreter: interpreter:
properties: properties:
InterpreterPath: "/usr/bin/python3" InterpreterPath: "/usr/bin/python3"
code: | code: |
import func import func
item: "functools" item: "functools"

View File

@ -18,19 +18,20 @@
"express-ws": "^4.0.0", "express-ws": "^4.0.0",
"file-loader": "^6.2.0", "file-loader": "^6.2.0",
"lodash": "^4.17.20", "lodash": "^4.17.20",
"monaco-editor": "^0.21.2", "monaco-editor": "0.20.0",
"monaco-editor-webpack-plugin": "^2.1.0", "monaco-editor-webpack-plugin": "1.9.0",
"monaco-languageclient": "^0.13.0", "monaco-languageclient": "0.13.0",
"node-pty": "^0.9.0", "node-pty": "^0.9.0",
"p-queue": "^6.6.2", "p-queue": "^6.6.2",
"parse-passwd": "^1.0.0", "parse-passwd": "^1.0.0",
"regenerator-runtime": "^0.13.7", "regenerator-runtime": "^0.13.7",
"shell-quote": "^1.7.2", "shell-quote": "^1.7.2",
"strip-ansi": "^6.0.0",
"style-loader": "^2.0.0", "style-loader": "^2.0.0",
"uuid": "^8.3.2", "uuid": "^8.3.2",
"vscode-languageserver-protocol": "3.15.3", "vscode-languageserver-protocol": "3.15.3",
"webpack": "^5.11.0", "webpack": "^4.44.2",
"webpack-cli": "^4.2.0", "webpack-cli": "^4.3.0",
"xterm": "^4.9.0", "xterm": "^4.9.0",
"xterm-addon-fit": "^0.4.0", "xterm-addon-fit": "^0.4.0",
"yaml": "^1.10.0" "yaml": "^1.10.0"

View File

@ -33,6 +33,9 @@ module.exports = (_, argv) => ({
}, },
], ],
}, },
node: {
net: "mock",
},
output: { output: {
path: path.resolve(__dirname, "frontend/out"), path: path.resolve(__dirname, "frontend/out"),
publicPath: "/js/", publicPath: "/js/",
@ -43,7 +46,6 @@ module.exports = (_, argv) => ({
}, },
plugins: [ plugins: [
new webpack.ProvidePlugin({ new webpack.ProvidePlugin({
Buffer: ["buffer", "Buffer"],
regeneratorRuntime: "regenerator-runtime/runtime", regeneratorRuntime: "regenerator-runtime/runtime",
}), }),
new MonacoWebpackPlugin(), new MonacoWebpackPlugin(),
@ -52,11 +54,5 @@ module.exports = (_, argv) => ({
alias: { alias: {
vscode: require.resolve("monaco-languageclient/lib/vscode-compatibility"), vscode: require.resolve("monaco-languageclient/lib/vscode-compatibility"),
}, },
fallback: {
crypto: false,
net: false,
os: false,
path: false,
},
}, },
}); });

2332
yarn.lock

File diff suppressed because it is too large Load Diff