Files
Bubberstation/tools/build/cbt/dm.js
SkyratBot 0178550af2 [MIRROR] Stop compiling DM if compiler outputs are locked. (#6770)
* Stop compiling DM if compiler outputs are locked.

* Update CODEOWNERS

Co-authored-by: Aleksej Komarov <stylemistake@gmail.com>
Co-authored-by: Useroth <37159550+Useroth@users.noreply.github.com>
2021-07-08 00:05:51 +02:00

109 lines
3.0 KiB
JavaScript

const Juke = require('../juke');
const { stat } = require('./fs');
const { regQuery } = require('./winreg');
const fs = require('fs');
/**
* Cached path to DM compiler
*/
let dmPath;
/**
* DM compiler
*
* @param {string} dmeFile
* @param {{ defines?: string[] }} options
*/
const dm = async (dmeFile, options = {}) => {
// Get path to DM compiler
if (!dmPath) {
dmPath = await (async () => {
// Search in array of paths
const paths = [
...((process.env.DM_EXE && process.env.DM_EXE.split(',')) || []),
'C:\\Program Files\\BYOND\\bin\\dm.exe',
'C:\\Program Files (x86)\\BYOND\\bin\\dm.exe',
['reg', 'HKLM\\Software\\Dantom\\BYOND', 'installpath'],
['reg', 'HKLM\\SOFTWARE\\WOW6432Node\\Dantom\\BYOND', 'installpath'],
];
const isFile = path => {
try {
const fstat = stat(path);
return fstat && fstat.isFile();
}
catch (err) {}
return false;
};
for (let path of paths) {
// Resolve a registry key
if (Array.isArray(path)) {
const [type, ...args] = path;
path = await regQuery(...args);
}
if (!path) {
continue;
}
// Check if path exists
if (isFile(path)) {
return path;
}
if (isFile(path + '/dm.exe')) {
return path + '/dm.exe';
}
if (isFile(path + '/bin/dm.exe')) {
return path + '/bin/dm.exe';
}
}
// Default paths
return (
process.platform === 'win32' && 'dm.exe'
|| 'DreamMaker'
);
})();
}
// Get project basename
const dmeBaseName = dmeFile.replace(/\.dme$/, '');
// Make sure output files are writable
const testOutputFile = (name) => {
try {
fs.closeSync(fs.openSync(name, 'r+'));
}
catch (err) {
if (err && err.code === 'ENOENT') {
return;
}
if (err && err.code === 'EBUSY') {
Juke.logger.error(`File '${name}' is locked by the DreamDaemon process.`);
Juke.logger.error(`Stop the currently running server and try again.`);
throw new Juke.ExitCode(1);
}
throw err;
}
};
testOutputFile(`${dmeBaseName}.dmb`);
testOutputFile(`${dmeBaseName}.rsc`);
// Compile
const { defines } = options;
if (defines && defines.length > 0) {
const injectedContent = defines
.map(x => `#define ${x}\n`)
.join('');
fs.writeFileSync(`${dmeBaseName}.mdme`, injectedContent);
const dmeContent = fs.readFileSync(`${dmeBaseName}.dme`);
fs.appendFileSync(`${dmeBaseName}.mdme`, dmeContent);
await Juke.exec(dmPath, [`${dmeBaseName}.mdme`]);
fs.writeFileSync(`${dmeBaseName}.dmb`, fs.readFileSync(`${dmeBaseName}.mdme.dmb`));
fs.writeFileSync(`${dmeBaseName}.rsc`, fs.readFileSync(`${dmeBaseName}.mdme.rsc`));
fs.unlinkSync(`${dmeBaseName}.mdme.dmb`);
fs.unlinkSync(`${dmeBaseName}.mdme.rsc`);
fs.unlinkSync(`${dmeBaseName}.mdme`);
}
else {
await Juke.exec(dmPath, [dmeFile]);
}
};
module.exports = {
dm,
};