Create separate contract & artifact temp folders at root (#386)

truffle-plugin
cgewecke 5 years ago
parent 4d5a4e21ef
commit 8c7b2f7c65
  1. 24
      dist/truffle.plugin.js
  2. 48
      lib/app.js
  3. 44
      test/units/app.js

@ -50,7 +50,7 @@ async function plugin(truffleConfig){
coverageConfig = req.silent(coverageConfigPath) || {};
coverageConfig.cwd = truffleConfig.working_directory;
coverageConfig.contractsDir = truffleConfig.contracts_directory;
coverageConfig.originalContractsDir = truffleConfig.contracts_directory;
app = new App(coverageConfig);
@ -66,8 +66,8 @@ async function plugin(truffleConfig){
app.instrument();
// Ask truffle to use temp folders
truffleConfig.contracts_directory = paths.contracts(app);
truffleConfig.build_directory = paths.build(app);
truffleConfig.contracts_directory = app.contractsDir;
truffleConfig.build_directory = app.artifactsDir;
truffleConfig.contracts_build_directory = paths.artifacts(truffleConfig, app);
// Additional config
@ -142,27 +142,11 @@ function loadTruffleLibrary(){
* @type {Object}
*/
const paths = {
// "contracts_directory":
contracts: (app) => {
return path.join(
app.coverageDir,
app.contractsDirName
)
},
// "build_directory":
build: (app) => {
return path.join(
app.coverageDir,
app.artifactsDirName
)
},
// "contracts_build_directory":
artifacts: (truffle, app) => {
return path.join(
app.coverageDir,
app.artifactsDirName,
app.artifactsDir,
path.basename(truffle.contracts_build_directory)
)
}

@ -23,11 +23,12 @@ class App {
this.testsErrored = false;
this.cwd = config.cwd;
this.tempFolderName = '.coverageEnv';
this.contractsDir = config.contractsDir
this.coverageDir = path.join(this.cwd, this.tempFolderName);
this.contractsDirName = 'contracts';
this.artifactsDirName = 'artifacts';
this.contractsDirName = '.coverage_contracts';
this.artifactsDirName = '.coverage_artifacts';
this.contractsDir = path.join(this.cwd, this.contractsDirName);
this.artifactsDir = path.join(this.cwd, this.artifactsDirName);
this.originalContractsDir = config.originalContractsDir
this.client = config.provider;
this.providerOptions = config.providerOptions || {};
@ -55,7 +56,7 @@ class App {
this.registerSkippedItems();
this.generateEnvelope();
const target = `${this.coverageDir}/**/*.sol`;
const target = `${this.contractsDir}/**/*.sol`;
shell.ls(target).forEach(file => {
currentFile = file;
@ -66,10 +67,11 @@ class App {
// Remember the real path
const contractPath = this.platformNeutralPath(file);
const canonicalPath = path.join(
this.cwd,
contractPath.split(`/${this.tempFolderName}`)[1]
this.originalContractsDir,
contractPath.split(`/${this.contractsDirName}`)[1]
);
// Instrument contract, save, add to coverage map
const contract = this.loadContract(contractPath);
const instrumented = this.instrumenter.instrument(contract, canonicalPath);
@ -115,7 +117,7 @@ class App {
return new Promise((resolve, reject) => {
try {
this.coverage.generate(this.instrumenter.instrumentationData, this.contractsDir);
this.coverage.generate(this.instrumenter.instrumentationData, this.originalContractsDir);
const relativeMapping = this.makeKeysRelative(this.coverage.data, this.cwd);
this.saveCoverage(relativeMapping);
@ -147,7 +149,8 @@ class App {
const self = this;
this.log('Cleaning up...');
shell.config.silent = true;
shell.rm('-Rf', this.coverageDir);
shell.rm('-Rf', this.contractsDir);
shell.rm('-Rf', this.artifactsDir);
if (this.provider && this.provider.close){
this.log('Shutting down ganache-core')
@ -168,26 +171,31 @@ class App {
}
saveCoverage(data){
fs.writeFileSync('./coverage.json', JSON.stringify(data));
const covPath = path.join(this.cwd, "coverage.json");
fs.writeFileSync(covPath, JSON.stringify(data));
}
// ======
// Launch
// ======
sanityCheckContext(contractsDir){
if (!shell.test('-e', this.contractsDir)){
sanityCheckContext(){
if (!shell.test('-e', this.originalContractsDir)){
this.cleanUp("Couldn't find a 'contracts' folder to instrument.");
}
if (shell.test('-e', path.join(this.cwd, this.coverageDir))){
shell.rm('-Rf', this.coverageDir);
if (shell.test('-e', path.join(this.cwd, this.contractsDir))){
shell.rm('-Rf', this.contractsDir);
}
if (shell.test('-e', path.join(this.cwd, this.artifactsDir))){
shell.rm('-Rf', this.artifactsDir);
}
}
generateEnvelope(){
shell.mkdir(this.coverageDir);
shell.mkdir(path.join(this.coverageDir, this.artifactsDirName))
shell.cp('-Rf', this.contractsDir, this.coverageDir)
shell.mkdir(this.contractsDir);
shell.mkdir(this.artifactsDir);
shell.cp('-Rf', `${this.originalContractsDir}/*`, this.contractsDir);
}
// =====
@ -226,7 +234,7 @@ class App {
*/
inSkippedFolder(file){
let shouldSkip;
const root = `${this.coverageDir}/${this.contractsDirName}`;
const root = `${this.contractsDir}`;
this.skippedFolders.forEach(folderToSkip => {
folderToSkip = `${root}/${folderToSkip}`;
if (file.indexOf(folderToSkip) === 0)
@ -239,7 +247,7 @@ class App {
* Parses the skipFiles option (which also accepts folders)
*/
registerSkippedItems(){
const root = `${this.coverageDir}/${this.contractsDirName}`;
const root = `${this.contractsDir}`;
this.skippedFolders = this.skipFiles.filter(item => path.extname(item) !== '.sol')
this.skipFiles = this.skipFiles.map(contract => `${root}/${contract}`);
this.skipFiles.push(`${root}/Migrations.sol`);

@ -3,6 +3,7 @@ const fs = require('fs');
const shell = require('shelljs');
const mock = require('../util/integration.truffle');
const plugin = require('../../dist/truffle.plugin');
const path = require('path')
const util = require('util')
const opts = { compact: false, depth: 5, breakLength: 80 };
@ -16,18 +17,21 @@ function assertCleanInitialState(){
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json');
}
function assertCoverageGenerated(){
function assertCoverageGenerate(truffleConfig){
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json");
assert(pathExists('./coverage') === true, 'should gen coverage folder');
assert(pathExists('./coverage.json') === true, 'should gen coverage.json');
assert(pathExists(jsonPath) === true, 'should gen coverage.json');
}
function assertCoverageNotGenerated(){
function assertCoverageNotGenerated(truffleConfig){
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json");
assert(pathExists('./coverage') !== true, 'should NOT gen coverage folder');
assert(pathExists('./coverage.json') !== true, 'should NOT gen coverage.json');
assert(pathExists(jsonPath) !== true, 'should NOT gen coverage.json');
}
function getOutput(){
return JSON.parse(fs.readFileSync('./coverage.json', 'utf8'));
function getOutput(truffleConfig){
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json");
return JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
}
// ========
@ -54,9 +58,9 @@ describe('app', function() {
mock.install('Simple', 'simple.js', solcoverConfig);
await plugin(truffleConfig);
assertCoverageGenerated();
assertCoverageGenerate(truffleConfig);
const output = getOutput();
const output = getOutput(truffleConfig);
const path = Object.keys(output)[0];
assert(output[path].fnMap['1'].name === 'test', 'coverage.json missing "test"');
@ -92,7 +96,7 @@ describe('app', function() {
await plugin(truffleConfig);
});
it.skip('project with node_modules packages and relative path solidity imports', async function() {
it('project with node_modules packages and relative path solidity imports', async function() {
assertCleanInitialState();
mock.installFullProject('import-paths');
await plugin(truffleConfig);
@ -105,9 +109,9 @@ describe('app', function() {
mock.install('OnlyCall', 'only-call.js', solcoverConfig);
await plugin(truffleConfig);
assertCoverageGenerated();
assertCoverageGenerate(truffleConfig);
const output = getOutput();
const output = getOutput(truffleConfig);
const path = Object.keys(output)[0];
assert(output[path].fnMap['1'].name === 'addTwo', 'cov should map "addTwo"');
});
@ -118,9 +122,9 @@ describe('app', function() {
mock.install('Wallet', 'wallet.js', solcoverConfig);
await plugin(truffleConfig);
assertCoverageGenerated();
assertCoverageGenerate(truffleConfig);
const output = getOutput();
const output = getOutput(truffleConfig);
const path = Object.keys(output)[0];
assert(output[path].fnMap['1'].name === 'transferPayment', 'cov should map "transferPayment"');
});
@ -133,9 +137,9 @@ describe('app', function() {
mock.installDouble(['Proxy', 'Owned'], 'inheritance.js', solcoverConfig);
await plugin(truffleConfig);
assertCoverageGenerated();
assertCoverageGenerate(truffleConfig);
const output = getOutput();
const output = getOutput(truffleConfig);
const firstKey = Object.keys(output)[0];
assert(Object.keys(output).length === 1, 'Wrong # of contracts covered');
assert(firstKey.substr(firstKey.length - 9) === 'Proxy.sol', 'Wrong contract covered');
@ -147,9 +151,9 @@ describe('app', function() {
mock.installDouble(['Proxy', 'Owned'], 'inheritance.js', solcoverConfig);
await plugin(truffleConfig);
assertCoverageGenerated();
assertCoverageGenerate(truffleConfig);
const output = getOutput();
const output = getOutput(truffleConfig);
const ownedPath = Object.keys(output)[0];
const proxyPath = Object.keys(output)[1];
assert(output[ownedPath].fnMap['1'].name === 'constructor', '"constructor" not covered');
@ -169,9 +173,9 @@ describe('app', function() {
assert(err.message.includes('failed under coverage'));
}
assertCoverageGenerated();
assertCoverageGenerate(truffleConfig);
const output = getOutput();
const output = getOutput(truffleConfig);
const path = Object.keys(output)[0];
assert(output[path].fnMap['1'].name === 'test', 'cov missing "test"');
@ -210,7 +214,7 @@ describe('app', function() {
assert(err.message.includes('Compilation failed'));
}
assertCoverageNotGenerated();
assertCoverageNotGenerated(truffleConfig);
});
});

Loading…
Cancel
Save