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.
119 lines
4.6 KiB
119 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(``);
|
|
|