UNPKG

hardhat-scilla-plugin

Version:
124 lines (104 loc) 3.42 kB
import clc from "cli-color"; import { createHash } from "crypto"; import fs from "fs"; import { glob } from "glob"; import path, { dirname } from "path"; import { ContractName, ParsedContract, parseScilla, parseScillaLibrary, } from "./ScillaParser"; // For some reason, hardhat deletes json files in artifacts, so it couldn't be scilla.json const CONTRACTS_INFO_CACHE_FILE = "artifacts/scilla.cache"; export interface ContractInfo { hash: string; path: string; parsedContract: ParsedContract; } type ContractPath = string; type ContractMapByName = Record<ContractName, ContractInfo>; export type ScillaContracts = ContractMapByName; type ContractMapByPath = Record<ContractPath, ContractInfo>; export const updateContractsInfo = async () => { let contractsInfo: ContractMapByName = {}; const files = glob.sync("contracts/**/*(*.scilla|*.scillib)"); if (files.length === 0) { console.log( clc.yellowBright("No scilla contracts were found in contracts directory.") ); return; } contractsInfo = loadContractsInfo(); let somethingChanged = false; for (const file of files) { if ( file in contractsInfo && contractsInfo[file].hash === getFileHash(file) ) { continue; } // Either the file is new or has been changed const contract = await parseScillaFile(file); console.log(`Parsing ${file}...`); if (contract) { somethingChanged = true; contractsInfo[file] = contract; } else { console.log(clc.redBright(" Failed!")); } } if (somethingChanged) { console.log("Cache updated."); saveContractsInfo(contractsInfo); } else { console.log("Nothing changed since last compile."); } }; export const loadScillaContractsInfo = (): ContractMapByName => { const contractsInfo = loadContractsInfo(); return convertToMapByName(contractsInfo); }; const convertToMapByName = ( contracts: ContractMapByPath ): ContractMapByName => { const contractsByName: ContractMapByName = {}; for (const key in contracts) { const elem = contracts[key]; const contractName: ContractName = elem.parsedContract.name; contractsByName[contractName] = elem; } return contractsByName; }; const loadContractsInfo = (): ContractMapByPath => { if (!fs.existsSync(CONTRACTS_INFO_CACHE_FILE)) { console.log("Cache file doesn't exist, creating a new one"); return {}; } const contents = fs.readFileSync(CONTRACTS_INFO_CACHE_FILE, "utf8"); return JSON.parse(contents); }; const saveContractsInfo = (contracts: ContractMapByPath) => { fs.mkdirSync(dirname(CONTRACTS_INFO_CACHE_FILE), { recursive: true }); fs.writeFileSync(CONTRACTS_INFO_CACHE_FILE, JSON.stringify(contracts)); }; export const getFileHash = (fileName: string): string => { const contents = fs.readFileSync(fileName, "utf8"); const hashSum = createHash("md5"); hashSum.update(contents); return hashSum.digest("hex"); }; const parseScillaFile = async ( fileName: string ): Promise<ContractInfo | null> => { const contents = fs.readFileSync(fileName, "utf8"); const hashSum = createHash("md5"); hashSum.update(contents); let parsedContract; if (path.extname(fileName) === ".scillib") { parsedContract = await parseScillaLibrary(fileName); } else { parsedContract = parseScilla(fileName); } return { hash: hashSum.digest("hex"), path: fileName, parsedContract }; };