UNPKG

@quenty/nevermore-template-helpers

Version:

Helpers to generate Nevermore package and game templates

116 lines 4.17 kB
import { execa } from 'execa'; import * as fs from 'fs/promises'; import * as os from 'os'; import * as path from 'path'; import { OutputHelper } from '@quenty/cli-output-helpers'; /** * Manages a build directory lifecycle for rojo builds. * Handles temp directory creation/cleanup and persistent build directories. */ export class BuildContext { _targetdir; _cleaned = false; _trackedFiles = []; constructor(dir) { this._targetdir = dir; } /** * Create and initialize a BuildContext. The directory is ready to use * when this resolves. */ static async createAsync(options = {}) { const prefix = options.prefix ?? 'build-'; const dir = await fs.mkdtemp(path.join(os.tmpdir(), prefix)); return new BuildContext(dir); } /** Absolute path to the managed build directory. */ get buildDir() { return this._targetdir; } /** Resolve a relative path within the build directory. */ resolvePath(relativePath) { return path.join(this._targetdir, relativePath); } /** * Run rojo build using this context's directory. * Returns the full plugin output path when in plugin mode, undefined otherwise. */ async rojoBuildAsync(options) { const { projectPath, output, plugin, pluginsFolder } = options; if (output && plugin) { throw new Error('rojoBuildAsync: specify either output or plugin, not both'); } if (!output && !plugin) { throw new Error('rojoBuildAsync: must specify either output or plugin'); } if (plugin && !pluginsFolder) { throw new Error('rojoBuildAsync: plugin requires pluginsFolder for cleanup tracking'); } const args = ['build', projectPath]; // On Linux, rojo's --plugin flag is not supported. Build to a temp // file with -o and copy to the plugins folder ourselves. const usePluginFallback = plugin && process.platform === 'linux'; if (output) { args.push('-o', output); } else if (usePluginFallback) { const tempOutput = path.join(this._targetdir, plugin); args.push('-o', tempOutput); } else if (plugin) { args.push('--plugin', plugin); } await execa('rojo', args); if (plugin && pluginsFolder) { const pluginPath = path.join(pluginsFolder, plugin); if (usePluginFallback) { const tempOutput = path.join(this._targetdir, plugin); await fs.mkdir(pluginsFolder, { recursive: true }); await fs.copyFile(tempOutput, pluginPath); } this._trackedFiles.push(pluginPath); return pluginPath; } return undefined; } /** * Execute a Lune transform script with the given arguments. */ async executeLuneTransformScriptAsync(scriptPath, ...args) { await execa('lune', ['run', scriptPath, ...args]); } /** * Write a file into the build directory. * @returns Absolute path to the written file. */ async writeFileAsync(relativePath, content) { const fullPath = path.join(this._targetdir, relativePath); await fs.mkdir(path.dirname(fullPath), { recursive: true }); await fs.writeFile(fullPath, content, 'utf-8'); return fullPath; } /** * Clean up the build directory and tracked files. Idempotent — safe to call multiple times. */ async cleanupAsync() { if (this._cleaned) return; this._cleaned = true; for (const filePath of this._trackedFiles) { try { await fs.unlink(filePath); } catch { // best effort — file may already be gone } } try { OutputHelper.verbose(`[Build] Cleaning up build directory: ${this._targetdir}`); await fs.rm(this._targetdir, { recursive: true, force: true }); } catch { // best effort } } } //# sourceMappingURL=build-context.js.map