QR-master/scripts/build.js

138 lines
3.2 KiB
JavaScript

const { spawnSync } = require('child_process');
const fs = require('fs');
const path = require('path');
const repoRoot = path.resolve(__dirname, '..');
const prismaSchemaPath = path.join(repoRoot, 'prisma', 'schema.prisma');
const generatedSchemaPath = path.join(
repoRoot,
'node_modules',
'.prisma',
'client',
'schema.prisma'
);
function readFileIfExists(filePath) {
try {
return fs.readFileSync(filePath, 'utf8');
} catch (error) {
if (error && error.code === 'ENOENT') {
return null;
}
throw error;
}
}
function normalizeSchema(schema) {
return schema.replace(/\s+/g, '');
}
function schemasMatch() {
const sourceSchema = readFileIfExists(prismaSchemaPath);
const generatedSchema = readFileIfExists(generatedSchemaPath);
return Boolean(
sourceSchema &&
generatedSchema &&
normalizeSchema(sourceSchema) === normalizeSchema(generatedSchema)
);
}
function run(command, args, options = {}) {
const shouldUseShell =
process.platform === 'win32' && command.toLowerCase().endsWith('.cmd');
const result = spawnSync(command, args, {
cwd: repoRoot,
encoding: 'utf8',
stdio: 'pipe',
shell: shouldUseShell,
env: {
...process.env,
...options.env,
},
});
if (result.stdout) {
process.stdout.write(result.stdout);
}
if (result.stderr) {
process.stderr.write(result.stderr);
}
return result;
}
function isWindowsPrismaRenameLock(output) {
const text = [output.stdout, output.stderr]
.filter(Boolean)
.join('\n');
return (
process.platform === 'win32' &&
text.includes('EPERM: operation not permitted, rename') &&
text.includes('query_engine-windows.dll.node')
);
}
function runPrismaGenerate() {
const prismaBin =
process.platform === 'win32'
? path.join(repoRoot, 'node_modules', '.bin', 'prisma.cmd')
: path.join(repoRoot, 'node_modules', '.bin', 'prisma');
const result = run(prismaBin, ['generate']);
if (result.error) {
throw result.error;
}
if ((result.status ?? 1) === 0) {
return 0;
}
if (!isWindowsPrismaRenameLock(result) || !schemasMatch()) {
return result.status ?? 1;
}
console.warn(
'\nPrisma generate hit a Windows file lock, but the generated client already matches prisma/schema.prisma. Continuing with the existing client.\n'
);
return 0;
}
function runNextBuild() {
const nextBin =
process.platform === 'win32'
? path.join(repoRoot, 'node_modules', '.bin', 'next.cmd')
: path.join(repoRoot, 'node_modules', '.bin', 'next');
// WSL needs more aggressive memory settings
const isWSL = process.platform === 'linux' && require('fs').existsSync('/proc/version') &&
require('fs').readFileSync('/proc/version', 'utf8').toLowerCase().includes('microsoft');
const memoryLimit = isWSL ? '8192' : '4096';
return run(nextBin, ['build'], {
env: {
NODE_OPTIONS: `--max-old-space-size=${memoryLimit}`,
SKIP_ENV_VALIDATION: 'true',
},
});
}
const prismaExitCode = runPrismaGenerate();
if (prismaExitCode !== 0) {
process.exit(prismaExitCode);
}
const nextResult = runNextBuild();
if (nextResult.error) {
throw nextResult.error;
}
process.exit(nextResult.status ?? 1);