436a9631fc
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
127 lines
5.3 KiB
JavaScript
127 lines
5.3 KiB
JavaScript
import debug from 'debug';
|
|
import fs from 'graceful-fs';
|
|
import path from 'node:path';
|
|
import { cacheModuleState } from './cache.js';
|
|
import { NodeGyp } from './module-type/node-gyp/node-gyp.js';
|
|
import { Prebuildify } from './module-type/prebuildify.js';
|
|
import { PrebuildInstall } from './module-type/prebuild-install.js';
|
|
import { NodePreGyp } from './module-type/node-pre-gyp.js';
|
|
import { promisifiedGracefulFs } from './promisifiedGracefulFs.js';
|
|
const d = debug('electron-rebuild');
|
|
export class ModuleRebuilder {
|
|
modulePath;
|
|
nodeGyp;
|
|
rebuilder;
|
|
prebuildify;
|
|
prebuildInstall;
|
|
nodePreGyp;
|
|
constructor(rebuilder, modulePath) {
|
|
this.modulePath = modulePath;
|
|
this.rebuilder = rebuilder;
|
|
this.nodeGyp = new NodeGyp(rebuilder, modulePath);
|
|
this.prebuildify = new Prebuildify(rebuilder, modulePath);
|
|
this.prebuildInstall = new PrebuildInstall(rebuilder, modulePath);
|
|
this.nodePreGyp = new NodePreGyp(rebuilder, modulePath);
|
|
}
|
|
get metaPath() {
|
|
return path.resolve(this.modulePath, 'build', this.rebuilder.buildType, '.forge-meta');
|
|
}
|
|
get metaData() {
|
|
return `${this.rebuilder.arch}--${this.rebuilder.ABI}`;
|
|
}
|
|
async alreadyBuiltByRebuild() {
|
|
if (fs.existsSync(this.metaPath)) {
|
|
const meta = await promisifiedGracefulFs.readFile(this.metaPath, 'utf8');
|
|
return meta === this.metaData;
|
|
}
|
|
return false;
|
|
}
|
|
async cacheModuleState(cacheKey) {
|
|
if (this.rebuilder.useCache) {
|
|
await cacheModuleState(this.modulePath, this.rebuilder.cachePath, cacheKey);
|
|
}
|
|
}
|
|
/**
|
|
* Whether a prebuild-install-generated native module exists.
|
|
*/
|
|
async prebuildInstallNativeModuleExists() {
|
|
return this.prebuildInstall.prebuiltModuleExists();
|
|
}
|
|
/**
|
|
* If the native module uses prebuildify, check to see if it comes with a prebuilt module for
|
|
* the given platform and arch.
|
|
*/
|
|
async findPrebuildifyModule(cacheKey) {
|
|
if (await this.prebuildify.usesTool()) {
|
|
d(`assuming is prebuildify powered: ${this.prebuildify.moduleName}`);
|
|
if (await this.prebuildify.findPrebuiltModule()) {
|
|
await this.writeMetadata();
|
|
await this.cacheModuleState(cacheKey);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
async findPrebuildInstallModule(cacheKey) {
|
|
if (await this.prebuildInstall.usesTool()) {
|
|
d(`assuming is prebuild-install powered: ${this.prebuildInstall.moduleName}`);
|
|
if (await this.prebuildInstall.findPrebuiltModule()) {
|
|
d('installed prebuilt module:', this.prebuildInstall.moduleName);
|
|
await this.writeMetadata();
|
|
await this.cacheModuleState(cacheKey);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
async findNodePreGypInstallModule(cacheKey) {
|
|
if (await this.nodePreGyp.usesTool()) {
|
|
d(`assuming is node-pre-gyp powered: ${this.nodePreGyp.moduleName}`);
|
|
if (await this.nodePreGyp.findPrebuiltModule()) {
|
|
d('installed prebuilt module:', this.nodePreGyp.moduleName);
|
|
await this.writeMetadata();
|
|
await this.cacheModuleState(cacheKey);
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
async rebuildNodeGypModule(cacheKey) {
|
|
await this.nodeGyp.rebuildModule();
|
|
d('built via node-gyp:', this.nodeGyp.moduleName);
|
|
await this.writeMetadata();
|
|
await this.replaceExistingNativeModule();
|
|
await this.cacheModuleState(cacheKey);
|
|
return true;
|
|
}
|
|
async replaceExistingNativeModule() {
|
|
const buildLocation = path.resolve(this.modulePath, 'build', this.rebuilder.buildType);
|
|
d('searching for .node file', buildLocation);
|
|
const buildLocationFiles = await promisifiedGracefulFs.readdir(buildLocation);
|
|
d('testing files', buildLocationFiles);
|
|
const nodeFile = buildLocationFiles.find((file) => file !== '.node' && file.endsWith('.node'));
|
|
const nodePath = nodeFile ? path.resolve(buildLocation, nodeFile) : undefined;
|
|
if (nodePath && fs.existsSync(nodePath)) {
|
|
d('found .node file', nodePath);
|
|
if (!this.rebuilder.disablePreGypCopy) {
|
|
const abiPath = path.resolve(this.modulePath, `bin/${this.rebuilder.platform}-${this.rebuilder.arch}-${this.rebuilder.ABI}`);
|
|
d('copying to prebuilt place:', abiPath);
|
|
await fs.promises.mkdir(abiPath, { recursive: true });
|
|
await promisifiedGracefulFs.copyFile(nodePath, path.join(abiPath, `${this.nodeGyp.moduleName}.node`));
|
|
}
|
|
}
|
|
}
|
|
async writeMetadata() {
|
|
await fs.promises.mkdir(path.dirname(this.metaPath), { recursive: true });
|
|
await promisifiedGracefulFs.writeFile(this.metaPath, this.metaData);
|
|
}
|
|
async rebuild(cacheKey) {
|
|
if (!this.rebuilder.buildFromSource && ((await this.findPrebuildifyModule(cacheKey)) ||
|
|
(await this.findPrebuildInstallModule(cacheKey)) ||
|
|
(await this.findNodePreGypInstallModule(cacheKey)))) {
|
|
return true;
|
|
}
|
|
return await this.rebuildNodeGypModule(cacheKey);
|
|
}
|
|
}
|
|
//# sourceMappingURL=module-rebuilder.js.map
|