简化模块加载

deprecated hydro-build
This commit is contained in:
undefined committed 2020-07-15 20:46:45 +08:00
1 parent 8aef05a375
commit 8f6968bbbd
41 files changed
+1361 -1957

No files matched your search

+53 -108
View File
@@ -1,123 +1,68 @@
import fs from 'fs';
/* eslint-disable no-continue */
import os from 'os';
import path from 'path';
import zlib from 'zlib';
import yaml from 'js-yaml';
import AdmZip from 'adm-zip';
import fs from 'fs-extra';
function ensureDir(dir) {
if (!fs.existsSync(dir)) {
fs.mkdirSync(dir);
} else if (!fs.statSync(dir).isDirectory()) {
fs.unlinkSync(dir);
fs.mkdirSync(dir);
}
}
const moduleRoots = Array.from(new Set([
path.resolve(process.cwd(), 'node_modules', '@hydrooj'),
path.resolve(process.cwd(), 'modules'),
path.resolve(process.cwd(), 'module'),
path.resolve(process.cwd(), '.build'),
process.cwd(),
path.resolve(__dirname, 'node_modules', '@hydrooj'),
path.resolve(__dirname, 'modules'),
path.resolve(__dirname, 'module'),
path.resolve(__dirname, '.build'),
__dirname,
path.resolve(os.homedir(), '.hydro', 'module'),
]));
function root(name) {
return path.resolve(process.cwd(), name);
}
const moduleRoots = [
root('.build/module'),
root('module'),
root(path.resolve(os.homedir(), '.hydro', 'module')),
root('.'),
];
let moduleRoot;
for (const i of moduleRoots) {
if (fs.existsSync(i) && fs.statSync(i).isDirectory()) {
moduleRoot = i;
break;
}
}
const moduleTemp = path.resolve(os.tmpdir(), 'hydro', 'module');
const publicTemp = path.resolve(os.tmpdir(), 'hydro', 'public');
const tmp = path.resolve(os.tmpdir(), 'hydro', '__');
export async function load() {
process.on('unhandledRejection', (e) => {
console.error(e);
process.exit(1);
});
ensureDir(path.resolve(os.tmpdir(), 'hydro'));
ensureDir(path.resolve(os.tmpdir(), 'hydro', 'tmp'));
ensureDir(path.resolve(os.tmpdir(), 'hydro', 'public'));
const files = fs.readdirSync(moduleRoot);
const t = ['service', 'lib', 'model', 'handler', 'script'];
for (const file of files) {
if (file.endsWith('.hydro')) {
try {
const f = fs.readFileSync(root(`${moduleRoot}/${file}`));
const s = fs.statSync(root(`${moduleRoot}/${file}`));
const m: any = yaml.safeLoad(zlib.gunzipSync(f).toString());
const { id } = m;
if (m.os) {
if (!m.os.includes(os.platform().toLowerCase())) {
console.error(`Module load fail: ${id} ${file.split('.')[0]} Unsupported OS`);
// eslint-disable-next-line no-continue
continue;
}
}
ensureDir(`${os.tmpdir()}/hydro/tmp/${id}`);
if (m.locale) {
fs.writeFileSync(
`${os.tmpdir()}/hydro/tmp/${id}/locale.json`,
JSON.stringify(m.locale),
);
}
if (m.setting) {
fs.writeFileSync(
`${os.tmpdir()}/hydro/tmp/${id}/setting.yaml`,
m.setting,
);
}
if (m.template) {
fs.writeFileSync(
`${os.tmpdir()}/hydro/tmp/${id}/template.json`,
JSON.stringify(m.template),
);
}
for (const i of t) {
if (m[i]) {
fs.writeFileSync(
`${os.tmpdir()}/hydro/tmp/${id}/${i}.js`,
m[i],
);
}
}
if (m.file) {
ensureDir(path.resolve(os.tmpdir(), 'hydro', m.id));
for (const n in m.file) {
if (m.file[n] === null) {
ensureDir(path.resolve(os.tmpdir(), 'hydro', m.id, n));
} else {
const e = path.resolve(os.tmpdir(), 'hydro', m.id, n);
fs.writeFileSync(e, Buffer.from(m.file[n], 'base64'), { mode: 755 });
fs.ensureDirSync(moduleTemp);
fs.ensureDirSync(publicTemp);
for (const moduleRoot of moduleRoots) {
if (fs.existsSync(moduleRoot)) {
const files = fs.readdirSync(moduleRoot);
for (const file of files) {
try {
// This fixs a mistake.
// Markdown-it-katex is not a hydro module but a dependency.
if (file === 'markdown-it-katex') continue;
const modulePath = path.join(moduleRoot, file);
const packagejson = path.join(modulePath, 'package.json');
if (fs.statSync(modulePath).isFile() && file.endsWith('.hydro')) {
// Is *.hydro module
const zip = new AdmZip(modulePath);
const targetPath = path.resolve(moduleTemp, file.split('.')[0]);
zip.extractAllTo(targetPath, true);
const content = fs.readdirSync(targetPath);
const ipath = path.join(targetPath, content[0]);
if (content.length === 1 && fs.statSync(ipath).isDirectory()) {
fs.moveSync(ipath, tmp);
fs.rmdirSync(targetPath);
fs.moveSync(tmp, targetPath);
}
}
const publicPath = path.resolve(moduleTemp, file.split('.')[0], 'public');
if (fs.existsSync(publicPath)) fs.copySync(publicPath, publicTemp);
} else if (fs.existsSync(packagejson)) {
// Is a npm package
const q = fs.readFileSync(packagejson).toString();
if (!JSON.parse(q).name.startsWith('@hydrooj/')) continue;
const publicPath = path.resolve(modulePath, 'public');
if (fs.existsSync(publicPath)) fs.copySync(publicPath, publicTemp);
} else continue;
} catch (e) {
console.error('Module extract fail:', file, e);
}
if (m.public) {
ensureDir(path.resolve(os.tmpdir(), 'hydro', 'public'));
for (const n in m.public) {
if (m.public[n] === null) {
ensureDir(path.resolve(os.tmpdir(), 'hydro', 'public', n));
} else {
const e = path.resolve(os.tmpdir(), 'hydro', 'public', n);
fs.writeFileSync(e, Buffer.from(m.public[n], 'base64'), { mode: 755 });
}
}
}
fs.writeFileSync(
root(`${os.tmpdir()}/hydro/tmp/${id}/hydro.json`),
JSON.stringify({
size: s.size,
version: m.version,
id: m.id,
name: m.name,
description: m.description,
}),
);
} catch (e) {
if (e.code === 'Z_DATA_ERROR') {
console.error(`Module Load Fail: ${file} (File Corrupted)`);
} else console.error(`Module Load Fail: ${file} ${e}`);
}
}
}