|
|
|
@ -142,20 +142,24 @@ class App { |
|
|
|
|
this.skipFiles = this.skipFiles.map(contract => `${this.coverageDir}/contracts/${contract}`); |
|
|
|
|
this.skipFiles.push(`${this.coverageDir}/contracts/Migrations.sol`); |
|
|
|
|
|
|
|
|
|
const instrumentedFiles = []; |
|
|
|
|
let currentFile; |
|
|
|
|
try { |
|
|
|
|
shell.ls(`${this.coverageDir}/contracts/**/*.sol`).forEach(file => { |
|
|
|
|
const contractPath = this.platformNeutralPath(file); |
|
|
|
|
const working = this.workingDir.substring(1); |
|
|
|
|
const canonicalPath = contractPath.split('/coverageEnv').join(working); |
|
|
|
|
const contract = fs.readFileSync(contractPath).toString(); |
|
|
|
|
currentFile = file; |
|
|
|
|
|
|
|
|
|
if (!this.skipFiles.includes(file) && !this.inSkippedFolder(file)) { |
|
|
|
|
this.log('Instrumenting ', file); |
|
|
|
|
currentFile = file; |
|
|
|
|
|
|
|
|
|
const contractPath = this.platformNeutralPath(file); |
|
|
|
|
const working = this.workingDir.substring(1); |
|
|
|
|
const canonicalPath = contractPath.split('/coverageEnv').join(working); |
|
|
|
|
const contract = fs.readFileSync(contractPath).toString(); |
|
|
|
|
const instrumentedContractInfo = getInstrumentedVersion(contract, canonicalPath); |
|
|
|
|
fs.writeFileSync(contractPath, instrumentedContractInfo.contract); |
|
|
|
|
|
|
|
|
|
this.coverage.addContract(instrumentedContractInfo, canonicalPath); |
|
|
|
|
instrumentedFiles.push(file); |
|
|
|
|
} else { |
|
|
|
|
this.log('Skipping instrumentation of ', file); |
|
|
|
|
} |
|
|
|
@ -164,7 +168,30 @@ class App { |
|
|
|
|
const msg = `There was a problem instrumenting ${currentFile}: `; |
|
|
|
|
this.cleanUp(msg + err); |
|
|
|
|
} |
|
|
|
|
this.postProcessPure(this.coverageDir); |
|
|
|
|
|
|
|
|
|
// Strip any view / pure modifiers in other files in case they depend on any instrumented files
|
|
|
|
|
shell |
|
|
|
|
.ls(`${this.coverageDir}/**/*.sol`) |
|
|
|
|
.filter(file => !instrumentedFiles.includes(file)) |
|
|
|
|
.forEach(file => { |
|
|
|
|
const contractPath = this.platformNeutralPath(file); |
|
|
|
|
const contract = fs.readFileSync(contractPath).toString(); |
|
|
|
|
const contractProcessed = preprocessor.run(contract); |
|
|
|
|
if (contractProcessed.name && contractProcessed.name === 'SyntaxError' && file.slice(-15) !== 'SimpleError.sol') { |
|
|
|
|
console.log(`Warning: The file at ${file} was identified as a Solidity Contract, ` + |
|
|
|
|
'but did not parse correctly. You may ignore this warning if it is not a Solidity file, ' + |
|
|
|
|
'or your project does not use it'); |
|
|
|
|
} else { |
|
|
|
|
fs.writeFileSync(contractPath, contractProcessed); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// Now that they've been modified, compile all the contracts again
|
|
|
|
|
this.runCompileCommand(); |
|
|
|
|
|
|
|
|
|
// And swap the original abis into the instrumented artifacts so that truffle etc uses 'call'
|
|
|
|
|
// on them.
|
|
|
|
|
this.modifyArtifacts(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
@ -382,33 +409,6 @@ class App { |
|
|
|
|
return shouldSkip; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Replaces all occurences of `pure` and `view` modifiers in all .sols |
|
|
|
|
* in the coverageEnv before the `contracts` folder is instrumented. |
|
|
|
|
* @param {String} env 'coverageEnv' presumably |
|
|
|
|
*/ |
|
|
|
|
postProcessPure(env) { |
|
|
|
|
shell.ls(`${env}/**/*.sol`).forEach(file => { |
|
|
|
|
const contractPath = this.platformNeutralPath(file); |
|
|
|
|
const contract = fs.readFileSync(contractPath).toString(); |
|
|
|
|
const contractProcessed = preprocessor.run(contract); |
|
|
|
|
if (contractProcessed.name && contractProcessed.name === 'SyntaxError' && file.slice(-15) !== 'SimpleError.sol') { |
|
|
|
|
console.log(`Warning: The file at ${file} was identified as a Solidity Contract, ` + |
|
|
|
|
'but did not parse correctly. You may ignore this warning if it is not a Solidity file, ' + |
|
|
|
|
'or your project does not use it'); |
|
|
|
|
} else { |
|
|
|
|
fs.writeFileSync(contractPath, contractProcessed); |
|
|
|
|
} |
|
|
|
|
}); |
|
|
|
|
|
|
|
|
|
// First, compile the instrumented contracts
|
|
|
|
|
this.runCompileCommand(); |
|
|
|
|
|
|
|
|
|
// Now swap the original abis into the instrumented artifacts so that truffle etc uses 'call'
|
|
|
|
|
// on them.
|
|
|
|
|
this.modifyArtifacts(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
/** |
|
|
|
|
* Allows config to turn logging off (for CI) |
|
|
|
|
* @param {Boolean} isSilent |
|
|
|
|