146 lines
4.4 KiB
TypeScript
146 lines
4.4 KiB
TypeScript
import AdmZip from "adm-zip";
|
|
import prettyBytes from "pretty-bytes";
|
|
import { parseArgs } from "node:util";
|
|
import {
|
|
access,
|
|
copyFile,
|
|
cp,
|
|
lstat,
|
|
mkdir,
|
|
mkdtemp,
|
|
rm,
|
|
stat,
|
|
writeFile
|
|
} from "node:fs/promises";
|
|
import type { PathLike } from "node:fs";
|
|
import { tmpdir } from "node:os";
|
|
import { cwd } from "node:process";
|
|
import { resolve } from "node:path";
|
|
|
|
interface Info {
|
|
description: string;
|
|
exports: Array<["all"] | Array<string>>;
|
|
name: string;
|
|
url: string;
|
|
versions: Array<[mcVersion: string, packFormat: number]>;
|
|
}
|
|
|
|
|
|
const { values: { indir: inDir, common: commonDir, revision: rev, outdir: outDir } } = parseArgs({
|
|
args: Bun.argv,
|
|
options: {
|
|
indir: {
|
|
type: "string",
|
|
short: "i",
|
|
default: cwd()
|
|
},
|
|
common: {
|
|
type: "string",
|
|
short: "c",
|
|
default: "common"
|
|
},
|
|
revision: {
|
|
type: "string",
|
|
short: "r"
|
|
},
|
|
outdir: {
|
|
type: "string",
|
|
short: "o",
|
|
default: "dist"
|
|
}
|
|
},
|
|
strict: true,
|
|
allowPositionals: true
|
|
});
|
|
|
|
const directoryExists = (path: PathLike) => access(path).then(() => lstat(path).then(d => d.isDirectory())).catch(() => false);
|
|
const dir = resolve(inDir!);
|
|
console.log("Building packs for:", dir);
|
|
|
|
if (!dir) {
|
|
console.log("No directory specified");
|
|
process.exit(1);
|
|
}
|
|
if (!await directoryExists(dir)) {
|
|
console.log(`Specified input directory "${inDir}" (${dir}) does not exist.`);
|
|
process.exit(1);
|
|
}
|
|
|
|
const info = await Bun.file(`${dir}/info.json`).json() as Info;
|
|
const common = resolve(dir, commonDir!);
|
|
const dist = resolve(dir, outDir!);
|
|
if (!await directoryExists(common)) {
|
|
console.log(`Specified common directory "${commonDir}" (${common}) does not exist.`);
|
|
process.exit(1);
|
|
}
|
|
|
|
let revision = rev;
|
|
if (!revision) {
|
|
if (await directoryExists(`${dir}/.git`)) {
|
|
revision = (await Bun.$`git rev-parse --short HEAD`.cwd(dir).text().catch(() => "")).slice(0, -1);
|
|
if (!revision) {
|
|
console.log("Failed to get git revision.");
|
|
process.exit(1);
|
|
}
|
|
} else {
|
|
console.log("No revision specified and no git directory found.");
|
|
process.exit(1);
|
|
}
|
|
}
|
|
|
|
const tempDir = await mkdtemp(`${tmpdir()}/${info.name.toLowerCase().replaceAll(" ", "-")}`);
|
|
console.log("Temporary Directory:", tempDir);
|
|
let totalSize = 0;
|
|
async function createVersion(mcVersion: string, packFormat: number) {
|
|
console.log("Building %s (pf: %d)", mcVersion, packFormat);
|
|
const mcmeta = {
|
|
pack: {
|
|
pack_format: packFormat,
|
|
description: info.description,
|
|
version: {
|
|
git: revision,
|
|
mc: mcVersion,
|
|
url: info.url
|
|
}
|
|
}
|
|
};
|
|
|
|
await mkdir(`${tempDir}/${mcVersion}`);
|
|
await writeFile(`${tempDir}/${mcVersion}/pack.mcmeta`, JSON.stringify(mcmeta, null, 4));
|
|
await copyFile(`${common}/pack.png`, `${tempDir}/${mcVersion}/pack.png`);
|
|
await cp(`${common}/assets`, `${tempDir}/${mcVersion}/assets`, { recursive: true });
|
|
const zip = new AdmZip();
|
|
await zip.addLocalFolderPromise(`${tempDir}/${mcVersion}`, {});
|
|
await zip.writeZipPromise(`${dist}/${info.name.replaceAll(" ", "")}-${mcVersion}.zip`);
|
|
const { size } = await stat(`${dist}/${info.name.replaceAll(" ", "")}-${mcVersion}.zip`);
|
|
totalSize += size;
|
|
console.log("%s built, size: %s", mcVersion, prettyBytes(size));
|
|
}
|
|
|
|
if (await directoryExists(dist)) {
|
|
await rm(dist, { recursive: true, force: true });
|
|
}
|
|
await mkdir(dist);
|
|
|
|
for (const [mcVersion, packFormat] of info.versions) {
|
|
await createVersion(mcVersion, packFormat);
|
|
}
|
|
await rm(tempDir, { recursive: true, force: true });
|
|
|
|
console.log("Total size: %s", prettyBytes(totalSize));
|
|
|
|
for (const ex of info.exports) {
|
|
const name = (ex[0] === "all" ? info.name : `${info.name}-${ex.join("-")}`).replaceAll(" ", "");
|
|
console.log("Exporting %s", name);
|
|
const zip = new AdmZip();
|
|
const versions = ex[0] === "all" ? info.versions.map(([mcVersion]) => mcVersion) : ex;
|
|
for (const version of versions) {
|
|
zip.addLocalFile(`${dist}/${info.name.replaceAll(" ", "")}-${version}.zip`);
|
|
}
|
|
await zip.writeZipPromise(`${dist}/${name}.zip`);
|
|
const { size } = await stat(`${dist}/${name}.zip`);
|
|
console.log("%s exported, size: %s", name, prettyBytes(size));
|
|
}
|
|
|
|
console.log("Done");
|