UNPKG

@melonproject/protocol

Version:

Technology Regulated and Operated Investment Funds

126 lines (100 loc) 3.48 kB
import * as fs from 'fs'; import * as path from 'path'; import * as glob from 'glob'; import * as solc from 'solc'; import * as mkdirp from 'mkdirp'; import * as R from 'ramda'; import * as rimraf from 'rimraf'; const soliditySourceDirectory = path.join(__dirname, '..', 'src', 'contracts'); const solidityCompileTarget = path.join(__dirname, '..', 'out'); const debug = require('debug').default('melon:protocol:bin'); const findImports = (missingPath: string, b, c) => { const query = path.join(soliditySourceDirectory, '**', missingPath); const candidates = glob.sync(query); if (candidates.length > 1) { throw new Error( `Multiple source files named ${missingPath} found. ${candidates}`, ); } if (candidates.length === 0) { throw new Error(`Can not find import named: ${missingPath}`); } debug('Resolved import', missingPath, candidates[0]); const contents = fs.readFileSync(candidates[0], { encoding: 'utf-8' }); return { contents, }; }; const writeFiles = (compileOutput, contract) => { const [sourceName, contractName] = contract.split(':'); const parsedPath = path.parse(sourceName); const targetDir = path.join(solidityCompileTarget, parsedPath.dir); const targetBasePath = path.join(targetDir, contractName); debug('Writing', contract); mkdirp.sync(targetDir); if (fs.existsSync(`${targetBasePath}.abi`)) { console.warn( // tslint:disable-next-line:max-line-length `Contract name duplication detected: ${targetBasePath}.abi. Please make sure that every contract is uniquely named across all dirctories.`, ); } fs.writeFileSync(`${targetBasePath}.bin`, compileOutput.bytecode); fs.writeFileSync( `${targetBasePath}.abi.json`, JSON.stringify(JSON.parse(compileOutput.interface), null, 2), ); fs.writeFileSync(`${targetBasePath}.abi`, compileOutput.interface); fs.writeFileSync( `${targetBasePath}.gasEstimates.json`, JSON.stringify(compileOutput.gasEstimates, null, 2), ); }; export const compileGlob = ( query = path.join(soliditySourceDirectory, '**', '*.sol'), ) => { const candidates = glob.sync(query); debug(`Compiling ${query}, ${candidates.length} files ...`); const unmerged = candidates.map(source => ({ [path.basename(source)]: fs.readFileSync(source, { encoding: 'utf-8', }), })); const sources = R.mergeAll(unmerged); const output = solc.compile({ sources }, 1, findImports); const messages = output.errors; const errors = []; const warnings = []; messages.forEach(msg => { if (msg.match(/^(.*:[0-9]*:[0-9]* )?Warning: /)) { warnings.push(msg); } else { errors.push(msg); } process.stderr.write(msg); }); debug('Writing compilation results'); if (query === path.join(soliditySourceDirectory, '**', '*.sol')) { // Delete and recreate out/ rimraf.sync(solidityCompileTarget); mkdirp.sync(solidityCompileTarget); } fs.writeFileSync( path.join(solidityCompileTarget, 'compilerResult.json'), JSON.stringify(output, null, 2), ); if (messages.length > 0) { fs.writeFileSync( path.join(solidityCompileTarget, 'compilerMessages.txt'), output.errors.join('\n\n'), ); } R.forEachObjIndexed(writeFiles, output.contracts); if (errors.length > 0) { debug('Finished with errors'); process.stderr.write(errors.join('\n\n')); process.exit(1); } else { debug('Finished'); process.exit(0); } };