'use strict'
// Compile with solcjs
const fs = require('fs')
const path = require('path')
const assert = require('chai').assert
const { List, Map, Set }
= require('immutable')
const { ContractsManager } = require('./contractsManager')
const { BuildsManager } = require('./buildsManager')
const { Logger, LINKS_DIR, DEPLOYS_DIR, getNetwork, awaitInputter, awaitOutputter }
= require('demo-utils')
const LOGGER = new Logger('BuildsManager')
const bm = {}
/**
* A BuildsManager is a ContractsManager which in addition to managing contracts and compiles,
* also handles network-specific builds like links and deploys.
* @class BuildsManager
* @memberof module:contract
* @param _outputter {Function} a (possibly asynchronous) function that
* takes (key: string, val: {Map} | {List} | null ) and returns a Promise or
* other value that you want returned from `compile` or `clean*` methods.
* If missing, _outputter defaults to `setImmutableKey`
* to a local file-based DB store.
*/
bm.BuildsManager = class extends ContractsManager {
constructor({sourcePathList, inputter, outputter, chainId, allowForking}) {
super(...arguments)
if (!chainId) { throw new Error("no chain ID passed in") }
this.chainId = chainId
}
getChainID() {
return this.chainId
}
async getDeploys() {
if (!this.deploysMap) {
this.deploysMap = await this.inputter(`${DEPLOYS_DIR}/${this.chainId}`, new Map({}))
}
return this.deploysMap
}
/**
* Asynchronous method to get parent-level deploy information (not specific to a fork)
* @method getDeploy
* @memberof class:BuildsManager
* @param deployName {String} the full deploy name including contract and deploy ID
* Example: `ContractName-deploy`
*/
async getDeploy(deployName, forkTime) {
const deploysMap = await this.getDeploys()
return this.deploysMap.get(deployName)
}
/**
* Write parent deploy-data (ABI, constructor args) to the (possibly remote) keystore.
* Should be accompanied with a `setForkedData` call for fork-level data.
* @method setDeploy
* @memberof module:deployer
*
* @param deployName {String} name of the deploy in the form of ContractName-deployID.
* @param deployOutput {Object} Immutable Map of key-value deploy data.
* @param overwrite {Boolean} whether to overwrite any existing deploys with this name.
*/
async setDeploy(deployName, deployOutput, overwrite) {
const deployKeyPath = `${DEPLOYS_DIR}/${this.chainId}/${deployName}`
LOGGER.debug(`Writing deploy to ${deployKeyPath}`)
this.deploysMap = this.deploysMap.set(deployName, deployOutput)
return awaitOutputter(this.outputter(deployKeyPath, deployOutput, overwrite),
() => { return deployOutput })
}
async getLinks() {
if (!(this.linksMap)) {
this.linksMap = await this.inputter(`${LINKS_DIR}`, new Map({}))
}
return this.linksMap
}
async getLink(linkName) {
const linksMap = await this.getLinks()
return linksMap.get(linkName)
}
async setLink(linkName, linkOutput, overwrite) {
const linkFilePath = `${LINKS_DIR}/${linkName}`
LOGGER.debug(`Writing link to ${linkFilePath}`)
this.linksMap = this.linksMap.set(linkName, linkOutput)
return awaitOutputter(this.outputter(linkFilePath, linkOutput, overwrite),
() => { return linkOutput })
}
async cleanLink(linkName) {
const fn = `${LINKS_DIR}/${linkName}`
return this.outputter(`${fn}`, null)
}
async cleanDeploy(deployName) {
const fn = `${DEPLOYS_DIR}/${this.chainId}/${deployName}`
return this.outputter(`${fn}`, null)
}
}
bm.createBM = async ({ sourcePathList, chainId, hostname, port, autoConfig }) => {
const { createInOut } = require('demo-client')
const { inputter, outputter } = createInOut({hostname, port, autoConfig})
const _chainId = (autoConfig) ? (await getNetwork().net_version()) : chainId
return new bm.BuildsManager({
sourcePathList : sourcePathList,
chainId : _chainId,
inputter : inputter,
outputter : outputter,
})
}
module.exports = bm