You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

120 lines
4.6 KiB

// This is a simple generic build script in TypeScript that should work for most projects without modification
// It assumes that it is running from the repo root, and the directories are organized this way:
// ./build/ - directory for build artifacts exists
// ./contracts/*.fc - root contracts that are deployed separately are here
// ./contracts/imports/*.fc - utility code that should be imported as compilation dependency is here
import fs from "fs";
import path from "path";
import process from "process";
import child_process from "child_process";
import fg from "fast-glob";
console.log(`=================================================================`);
console.log(`Build script running, let's find some FunC contracts to compile..`);
// make sure func compiler is available
let funcVersion = "";
try {
funcVersion = child_process.execSync("func -V").toString();
} catch (e) {}
if (!funcVersion.includes(`Func build information`)) {
console.log(`\nFATAL ERROR: 'func' executable is not found, is it installed and in path?`);
process.exit(1);
}
// make sure fift cli is available
let fiftVersion = "";
try {
fiftVersion = child_process.execSync("fift -V").toString();
} catch (e) {}
if (!fiftVersion.includes(`Fift build information`)) {
console.log(`\nFATAL ERROR: 'fift' executable is not found, is it installed and in path?`);
process.exit(1);
}
const rootContracts = fg.sync(["contracts/*.fc", "contracts/*.func"]);
for (const rootContract of rootContracts) {
// compile a new root contract
console.log(`\n* Found root contract '${rootContract}' - let's compile it:`);
const contractName = path.parse(rootContract).name;
// delete existing build artifacts
const fiftArtifact = `build/${contractName}.fif`;
if (fs.existsSync(fiftArtifact)) {
console.log(` - Deleting old build artifact '${fiftArtifact}'`);
fs.unlinkSync(fiftArtifact);
}
const mergedFuncArtifact = `build/${contractName}.merged.fc`;
if (fs.existsSync(mergedFuncArtifact)) {
console.log(` - Deleting old build artifact '${mergedFuncArtifact}'`);
fs.unlinkSync(mergedFuncArtifact);
}
const fiftCellArtifact = `build/${contractName}.cell.fif`;
if (fs.existsSync(fiftCellArtifact)) {
console.log(` - Deleting old build artifact '${fiftCellArtifact}'`);
fs.unlinkSync(fiftCellArtifact);
}
const cellArtifact = `build/${contractName}.cell`;
if (fs.existsSync(cellArtifact)) {
console.log(` - Deleting old build artifact '${cellArtifact}'`);
fs.unlinkSync(cellArtifact);
}
// create a merged fc file with source code from all dependencies
let sourceToCompile = "";
const importFiles = fg.sync(["contracts/imports/**/*.fc", "contracts/imports/**/*.func"]);
for (const importFile of importFiles) {
console.log(` - Adding import '${importFile}'`);
sourceToCompile += `${fs.readFileSync(importFile).toString()}\n`;
}
console.log(` - Adding the contract itself '${rootContract}'`);
sourceToCompile += `${fs.readFileSync(rootContract).toString()}\n`;
fs.writeFileSync(mergedFuncArtifact, sourceToCompile);
console.log(` - Build artifact created '${mergedFuncArtifact}'`);
// run the func compiler to create a fif file
console.log(` - Trying to compile '${mergedFuncArtifact}' with 'func' compiler..`);
const buildErrors = child_process.execSync(`func -APS -o build/${contractName}.fif ${mergedFuncArtifact} 2>&1 >&-`).toString();
if (buildErrors.length > 0) {
console.log(` - OH NO! Compilation Errors! The compiler output was:`);
console.log(`\n${buildErrors}`);
process.exit(1);
} else {
console.log(` - Compilation successful!`);
}
// make sure fif build artifact was created
if (!fs.existsSync(fiftArtifact)) {
console.log(` - For some reason '${fiftArtifact}' was not created!`);
process.exit(1);
} else {
console.log(` - Build artifact created '${fiftArtifact}'`);
}
// create a temp cell.fif that will generate the cell
let fiftCellSource = `"Asm.fif" include\n`;
fiftCellSource += `${fs.readFileSync(fiftArtifact).toString()}\n`;
fiftCellSource += `boc>B "${cellArtifact}" B>file`;
fs.writeFileSync(fiftCellArtifact, fiftCellSource);
// run fift cli to create the cell
try {
child_process.execSync(`fift ${fiftCellArtifact}`);
} catch (e) {
console.log(`FATAL ERROR: 'fift' executable failed, is FIFTPATH env variable defined?`);
process.exit(1);
}
// make sure cell build artifact was created
if (!fs.existsSync(cellArtifact)) {
console.log(` - For some reason '${cellArtifact}' was not created!`);
process.exit(1);
} else {
console.log(` - Build artifact created '${cellArtifact}'`);
fs.unlinkSync(fiftCellArtifact);
}
}
console.log(``);