UNPKG

@needle-tools/engine

Version:

Needle Engine is a web-based runtime for 3D apps. It runs on your machine for development with great integrations into editors like Unity or Blender - and can be deployed onto any device! It is flexible, extensible and networking and XR are built-in.

106 lines (101 loc) 4.42 kB
import fs, { existsSync, statSync } from 'fs'; import crypto from 'crypto'; import { relative } from 'path'; import { needleLog } from '../vite/logging.js'; /** Create a file containing information about the build inside the build directory * @param {String} buildDirectory * @param {{log?:boolean}} [options] */ export function createBuildInfoFile(buildDirectory, options = undefined) { const shouldLog = options?.log !== false; const rel = (pathValue) => { const value = relative(process.cwd(), pathValue).replaceAll("\\", "/"); return value?.length ? value : "."; }; if (!buildDirectory) { if (shouldLog) needleLog("needle-buildinfo", "Can not create build info file because \"buildDirectory\" is not defined", "warn", { dimBody: false }); return { ok: false, error: "buildDirectory is not defined" }; } // start creating the buildinfo const buildInfo = { time: new Date().toISOString(), totalsize: 0, files: [] }; if (shouldLog) needleLog("needle-buildinfo", `Begin collecting files in \"${rel(buildDirectory)}\"`); recursivelyCollectFiles(buildDirectory, "", buildInfo); const buildInfoPath = `${buildDirectory}/needle.buildinfo.json`; const totalSizeInMB = buildInfo.totalsize / 1024 / 1024; if (shouldLog) needleLog("needle-buildinfo", `Collected ${buildInfo.files.length} files (${totalSizeInMB.toFixed(2)} MB). Writing build info to \"${rel(buildInfoPath)}\"`); const str = JSON.stringify(buildInfo); fs.writeFileSync(buildInfoPath, str); if(!existsSync(buildDirectory)) { if (shouldLog) needleLog("needle-buildinfo", `Could not write build info file to \"${rel(buildInfoPath)}\"`, "warn", { dimBody: false }); return { ok: false, error: `Could not write build info file to \"${rel(buildInfoPath)}\"` }; } if (shouldLog) needleLog("needle-buildinfo", `Build info file successfully written to \"${rel(buildInfoPath)}\"`); return { ok: true, buildDirectory: rel(buildDirectory), buildInfoPath: rel(buildInfoPath), fileCount: buildInfo.files.length, totalSizeBytes: buildInfo.totalsize, totalSizeInMB, }; } /** * Collect information about the build output directory, such as total file count and size * @param {String} buildDirectory * @returns {import("./buildinfo").BuildInfo} */ export function collectBuildDirectoryStats(buildDirectory) { if (!buildDirectory || !existsSync(buildDirectory)) { return { fileCount: 0, totalSizeBytes: 0, totalSizeInMB: 0, }; } const info = { totalsize: 0, files: [], }; recursivelyCollectFiles(buildDirectory, "", info); return { fileCount: info.files.length, totalSizeBytes: info.totalsize, totalSizeInMB: info.totalsize / 1024 / 1024, }; } /** Recursively collect all files in a directory * @param {String} directory to search * @param {{ time?: string, files: Array<{path:string, hash:string, size:number}>, totalsize:number }} info */ function recursivelyCollectFiles(directory, path, info) { const entries = fs.readdirSync(directory, { withFileTypes: true }); for (const entry of entries) { if (entry.isDirectory()) { // make sure we never collect files inside node_modules if (entry.name === "node_modules") { needleLog("needle-buildinfo", "Skipping node_modules directory at " + path, "warn", { dimBody: false }); continue; } const newPath = path?.length <= 0 ? entry.name : `${path}/${entry.name}`; const newDirectory = `${directory}/${entry.name}`; recursivelyCollectFiles(newDirectory, newPath, info); } else { const relpath = path?.length <= 0 ? entry.name : `${path}/${entry.name}`; // console.log("[needle-buildinfo] - New File: " + relpath); const filehash = crypto.createHash('sha256'); const fullpath = `${directory}/${entry.name}`; filehash.update(fs.readFileSync(fullpath)); const stats = statSync(fullpath); info.files.push({ path: relpath, hash: filehash.digest('hex'), size: stats.size }); info.totalsize += stats.size; } } }