UNPKG

@react-gnome/core

Version:

## Getting Started

249 lines (247 loc) 9.28 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/programs/build-program.ts import { existsSync, readdirSync } from "fs"; import fs from "fs/promises"; import path from "path"; import rimraf from "rimraf"; import tar from "tar"; import { html, Output } from "termx-markup"; import { getAppData } from "../packaging/templates/data/appdata.mjs"; import { getDataBusname } from "../packaging/templates/data/busname.mjs"; import { getDataDesktopEntry } from "../packaging/templates/data/desktop-entry.mjs"; import { getDataGSchema } from "../packaging/templates/data/gschema.mjs"; import { getDataResources } from "../packaging/templates/data/resources.mjs"; import { getDataService } from "../packaging/templates/data/service.mjs"; import { getGResourceXml } from "../packaging/templates/gresource.mjs"; import { getInFile } from "../packaging/templates/in-file.mjs"; import { getDataMesonBuild } from "../packaging/templates/meson/data.mjs"; import { getMainMesonBuild } from "../packaging/templates/meson/main.mjs"; import { getPoMesonBuild } from "../packaging/templates/meson/po.mjs"; import { getSrcMesonBuild } from "../packaging/templates/meson/src.mjs"; import { getPackageJson } from "../packaging/templates/package-json.mjs"; import { getPoFiles } from "../packaging/templates/po/get-po-files.mjs"; import { getLinguas } from "../packaging/templates/po/linguas.mjs"; import { getPostInstallScript } from "../packaging/templates/post-install-script.mjs"; import { AppResources } from "../utils/app-resources.mjs"; import { Command } from "../utils/command.mjs"; import { getEntrypoint } from "../utils/get-entrypoint.mjs"; import { getPlugins } from "../utils/get-plugins.mjs"; import { pascalToKebab } from "../utils/pascal-to-kebab.mjs"; import { Program } from "./base.mjs"; import { createBuildOptions } from "./default-build-options.mjs"; var BuildProgram = class extends Program { constructor() { super(...arguments); __publicField(this, "type", "build"); } additionalPlugins() { return {}; } async write(data, ...pathParts) { await fs.writeFile(path.resolve(...pathParts), data, "utf-8"); } async createDataDir(buildDirPath) { const dataDirPath = path.resolve(buildDirPath, "data"); try { await fs.mkdir(dataDirPath, { recursive: true }); } catch (e) { } } async createMesonDir(buildDirPath) { const mesonDirPath = path.resolve(buildDirPath, "meson"); try { await fs.mkdir(mesonDirPath, { recursive: true }); } catch (e) { } } async createPoDir(buildDirPath) { const poDirPath = path.resolve(buildDirPath, "po"); try { await fs.mkdir(poDirPath, { recursive: true }); } catch (e) { } } async preparePoDirFiles(poDirPath, context) { const linguas = getLinguas(); const poFiles = getPoFiles({ appName: context.appName }); const poMesonBuild = getPoMesonBuild(); await this.write(linguas, poDirPath, "LINGUAS"); for (const po of poFiles) { await this.write(po.content, poDirPath, `${po.language}.po`); } await this.write(poMesonBuild, poDirPath, "meson.build"); } async prepareMesonDirFiles(mesonDirPath, context) { const postInstallScript = getPostInstallScript({ packageName: context.packageName }); await this.write(postInstallScript, mesonDirPath, "meson_post_install.py"); } async prepareDataDirFiles(dataDirPath, context) { const appData = getAppData({ appID: context.appID, license: this.config.license ?? "GPL2", friendlyName: this.config.friendlyName ?? this.config.applicationName }); const dataBusname = getDataBusname({ appID: context.appID }); const dataDesktopEntry = getDataDesktopEntry({ appID: context.appID, friendlyName: this.config.friendlyName ?? this.config.applicationName }); const gschema = getDataGSchema({ appID: context.appID }); const resources = getDataResources({ appID: context.appID, files: this.resources?.getAll().map((r) => r.name) }); const dataService = getDataService(); const mesonBuild = getDataMesonBuild(); await this.write(appData, dataDirPath, `${context.appID}.appdata.xml.in`); await this.write(dataBusname, dataDirPath, `${context.appID}.busname`); await this.write( dataDesktopEntry, dataDirPath, `${context.appID}.desktop.in` ); await this.write(gschema, dataDirPath, `${context.appID}.gschema.xml`); await this.write( resources, dataDirPath, `${context.appID}.data.gresource.xml` ); await this.write(dataService, dataDirPath, `${context.appID}.service.in`); await this.write(mesonBuild, dataDirPath, "meson.build"); for (const resource of this.resources?.getAll() || []) { await fs.copyFile( resource.fullPath, path.resolve(dataDirPath, resource.name) ); } } async prepareSrcDirFiles(srcDirPath, context) { const inFile = getInFile({ appID: context.appID }); const gresource = getGResourceXml({ appID: context.appID, files: this.config.sourcemap ? ["main.js.map"] : [] }); const srcMesonBuild = getSrcMesonBuild(); const inFilePath = path.resolve(srcDirPath, `${context.appID}.in`); await this.write(inFile, inFilePath); await this.write( gresource, srcDirPath, `${context.appID}.src.gresource.xml.in` ); await this.write(srcMesonBuild, srcDirPath, "meson.build"); await fs.chmod(inFilePath, "0775"); } async prepareMainBuildDirFiles(buildDirPath, context) { const mainMesonBuild = getMainMesonBuild({ appID: context.appID, packageName: context.packageName, packageVersion: context.appVersion, license: this.config.license ?? "GPL2" }); const packageJson = getPackageJson({ appID: context.appID, packageName: context.packageName }); await this.write(mainMesonBuild, buildDirPath, "meson.build"); await this.write(packageJson, buildDirPath, `${context.appID}.json`); } async prepareBuildFiles(appName, buildDirPath) { const context = { appName, appVersion: this.config.applicationVersion, appID: this.appID, packageName: `${pascalToKebab(appName)}` }; await this.createDataDir(buildDirPath); await this.createMesonDir(buildDirPath); await this.createPoDir(buildDirPath); await this.prepareMainBuildDirFiles(buildDirPath, context); await this.prepareSrcDirFiles(path.resolve(buildDirPath, "src"), context); await this.prepareDataDirFiles(path.resolve(buildDirPath, "data"), context); await this.prepareMesonDirFiles( path.resolve(buildDirPath, "meson"), context ); await this.preparePoDirFiles(path.resolve(buildDirPath, "po"), context); return context; } async afterBuild() { if (this.config.sourcemap && !this.watchMode) { const buildDirPath = path.resolve(this.cwd, this.config.outDir, ".build"); const mapFilePath = path.resolve(buildDirPath, "src", "main.js.map"); const mapContent = await fs.readFile(mapFilePath, "utf-8"); await fs.writeFile(mapFilePath, `export const map = ${mapContent};`); } } /** * @internal */ async main() { Output.print(html` <span color="lightBlue">Building package...</span> `); const appName = this.appName; const buildDirPath = path.resolve(this.cwd, this.config.outDir, ".build"); this.resources = new AppResources(this.appID); if (existsSync(buildDirPath)) await rimraf(buildDirPath, {}); const entrypoint = getEntrypoint(this); await this.esbuildCtx.init( createBuildOptions(this, { stdin: { contents: entrypoint, loader: "js", resolveDir: this.cwd }, outfile: path.resolve(buildDirPath, "src", "main.js"), plugins: getPlugins(this), minify: this.config.minify ?? (this.isDev ? false : true), treeShaking: this.config.treeShake ?? (this.isDev ? false : true) }) ); await this.esbuildCtx.start(); const { packageName, appVersion } = await this.prepareBuildFiles( appName, buildDirPath ); if (this.config.beforeBuild) { await this.config.beforeBuild(buildDirPath); } await new Command("meson", ["setup", "_build"], { cwd: buildDirPath }).run(); await new Command("meson", ["compile", "--clean", "-C", "_build"], { cwd: buildDirPath }).run(); await new Promise((resolve, reject) => { tar.create( { gzip: true, cwd: buildDirPath, file: path.resolve( this.cwd, this.config.outDir, `${packageName}-${appVersion}.tar.gz` ), prefix: packageName }, readdirSync(buildDirPath), (e) => e ? reject(e) : resolve() ); }); Output.print(html`<span color="lightGreen">Package created.</span>`); } }; export { BuildProgram };