Skip to content

Commit 35aa892

Browse files
authored
Create separate contract & artifact temp folders at root (#386)
1 parent 9ea1085 commit 35aa892

File tree

3 files changed

+56
-60
lines changed

3 files changed

+56
-60
lines changed

dist/truffle.plugin.js

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ async function plugin(truffleConfig){
5050
coverageConfig = req.silent(coverageConfigPath) || {};
5151

5252
coverageConfig.cwd = truffleConfig.working_directory;
53-
coverageConfig.contractsDir = truffleConfig.contracts_directory;
53+
coverageConfig.originalContractsDir = truffleConfig.contracts_directory;
5454

5555
app = new App(coverageConfig);
5656

@@ -66,8 +66,8 @@ async function plugin(truffleConfig){
6666
app.instrument();
6767

6868
// Ask truffle to use temp folders
69-
truffleConfig.contracts_directory = paths.contracts(app);
70-
truffleConfig.build_directory = paths.build(app);
69+
truffleConfig.contracts_directory = app.contractsDir;
70+
truffleConfig.build_directory = app.artifactsDir;
7171
truffleConfig.contracts_build_directory = paths.artifacts(truffleConfig, app);
7272

7373
// Additional config
@@ -142,27 +142,11 @@ function loadTruffleLibrary(){
142142
* @type {Object}
143143
*/
144144
const paths = {
145-
// "contracts_directory":
146-
contracts: (app) => {
147-
return path.join(
148-
app.coverageDir,
149-
app.contractsDirName
150-
)
151-
},
152-
153-
// "build_directory":
154-
build: (app) => {
155-
return path.join(
156-
app.coverageDir,
157-
app.artifactsDirName
158-
)
159-
},
160145

161146
// "contracts_build_directory":
162147
artifacts: (truffle, app) => {
163148
return path.join(
164-
app.coverageDir,
165-
app.artifactsDirName,
149+
app.artifactsDir,
166150
path.basename(truffle.contracts_build_directory)
167151
)
168152
}

lib/app.js

Lines changed: 28 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,12 @@ class App {
2323
this.testsErrored = false;
2424

2525
this.cwd = config.cwd;
26-
this.tempFolderName = '.coverageEnv';
27-
this.contractsDir = config.contractsDir
28-
this.coverageDir = path.join(this.cwd, this.tempFolderName);
29-
this.contractsDirName = 'contracts';
30-
this.artifactsDirName = 'artifacts';
26+
this.contractsDirName = '.coverage_contracts';
27+
this.artifactsDirName = '.coverage_artifacts';
28+
this.contractsDir = path.join(this.cwd, this.contractsDirName);
29+
this.artifactsDir = path.join(this.cwd, this.artifactsDirName);
30+
31+
this.originalContractsDir = config.originalContractsDir
3132

3233
this.client = config.provider;
3334
this.providerOptions = config.providerOptions || {};
@@ -55,7 +56,7 @@ class App {
5556
this.registerSkippedItems();
5657
this.generateEnvelope();
5758

58-
const target = `${this.coverageDir}/**/*.sol`;
59+
const target = `${this.contractsDir}/**/*.sol`;
5960

6061
shell.ls(target).forEach(file => {
6162
currentFile = file;
@@ -66,10 +67,11 @@ class App {
6667
// Remember the real path
6768
const contractPath = this.platformNeutralPath(file);
6869
const canonicalPath = path.join(
69-
this.cwd,
70-
contractPath.split(`/${this.tempFolderName}`)[1]
70+
this.originalContractsDir,
71+
contractPath.split(`/${this.contractsDirName}`)[1]
7172
);
7273

74+
7375
// Instrument contract, save, add to coverage map
7476
const contract = this.loadContract(contractPath);
7577
const instrumented = this.instrumenter.instrument(contract, canonicalPath);
@@ -115,7 +117,7 @@ class App {
115117

116118
return new Promise((resolve, reject) => {
117119
try {
118-
this.coverage.generate(this.instrumenter.instrumentationData, this.contractsDir);
120+
this.coverage.generate(this.instrumenter.instrumentationData, this.originalContractsDir);
119121
const relativeMapping = this.makeKeysRelative(this.coverage.data, this.cwd);
120122
this.saveCoverage(relativeMapping);
121123

@@ -147,7 +149,8 @@ class App {
147149
const self = this;
148150
this.log('Cleaning up...');
149151
shell.config.silent = true;
150-
shell.rm('-Rf', this.coverageDir);
152+
shell.rm('-Rf', this.contractsDir);
153+
shell.rm('-Rf', this.artifactsDir);
151154

152155
if (this.provider && this.provider.close){
153156
this.log('Shutting down ganache-core')
@@ -168,26 +171,31 @@ class App {
168171
}
169172

170173
saveCoverage(data){
171-
fs.writeFileSync('./coverage.json', JSON.stringify(data));
174+
const covPath = path.join(this.cwd, "coverage.json");
175+
fs.writeFileSync(covPath, JSON.stringify(data));
172176
}
173177

174178
// ======
175179
// Launch
176180
// ======
177-
sanityCheckContext(contractsDir){
178-
if (!shell.test('-e', this.contractsDir)){
181+
sanityCheckContext(){
182+
if (!shell.test('-e', this.originalContractsDir)){
179183
this.cleanUp("Couldn't find a 'contracts' folder to instrument.");
180184
}
181185

182-
if (shell.test('-e', path.join(this.cwd, this.coverageDir))){
183-
shell.rm('-Rf', this.coverageDir);
186+
if (shell.test('-e', path.join(this.cwd, this.contractsDir))){
187+
shell.rm('-Rf', this.contractsDir);
188+
}
189+
190+
if (shell.test('-e', path.join(this.cwd, this.artifactsDir))){
191+
shell.rm('-Rf', this.artifactsDir);
184192
}
185193
}
186194

187195
generateEnvelope(){
188-
shell.mkdir(this.coverageDir);
189-
shell.mkdir(path.join(this.coverageDir, this.artifactsDirName))
190-
shell.cp('-Rf', this.contractsDir, this.coverageDir)
196+
shell.mkdir(this.contractsDir);
197+
shell.mkdir(this.artifactsDir);
198+
shell.cp('-Rf', `${this.originalContractsDir}/*`, this.contractsDir);
191199
}
192200

193201
// =====
@@ -226,7 +234,7 @@ class App {
226234
*/
227235
inSkippedFolder(file){
228236
let shouldSkip;
229-
const root = `${this.coverageDir}/${this.contractsDirName}`;
237+
const root = `${this.contractsDir}`;
230238
this.skippedFolders.forEach(folderToSkip => {
231239
folderToSkip = `${root}/${folderToSkip}`;
232240
if (file.indexOf(folderToSkip) === 0)
@@ -239,7 +247,7 @@ class App {
239247
* Parses the skipFiles option (which also accepts folders)
240248
*/
241249
registerSkippedItems(){
242-
const root = `${this.coverageDir}/${this.contractsDirName}`;
250+
const root = `${this.contractsDir}`;
243251
this.skippedFolders = this.skipFiles.filter(item => path.extname(item) !== '.sol')
244252
this.skipFiles = this.skipFiles.map(contract => `${root}/${contract}`);
245253
this.skipFiles.push(`${root}/Migrations.sol`);

test/units/app.js

Lines changed: 24 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ const fs = require('fs');
33
const shell = require('shelljs');
44
const mock = require('../util/integration.truffle');
55
const plugin = require('../../dist/truffle.plugin');
6+
const path = require('path')
67
const util = require('util')
78
const opts = { compact: false, depth: 5, breakLength: 80 };
89

@@ -16,18 +17,21 @@ function assertCleanInitialState(){
1617
assert(pathExists('./coverage.json') === false, 'should start without: coverage.json');
1718
}
1819

19-
function assertCoverageGenerated(){
20+
function assertCoverageGenerate(truffleConfig){
21+
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json");
2022
assert(pathExists('./coverage') === true, 'should gen coverage folder');
21-
assert(pathExists('./coverage.json') === true, 'should gen coverage.json');
23+
assert(pathExists(jsonPath) === true, 'should gen coverage.json');
2224
}
2325

24-
function assertCoverageNotGenerated(){
26+
function assertCoverageNotGenerated(truffleConfig){
27+
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json");
2528
assert(pathExists('./coverage') !== true, 'should NOT gen coverage folder');
26-
assert(pathExists('./coverage.json') !== true, 'should NOT gen coverage.json');
29+
assert(pathExists(jsonPath) !== true, 'should NOT gen coverage.json');
2730
}
2831

29-
function getOutput(){
30-
return JSON.parse(fs.readFileSync('./coverage.json', 'utf8'));
32+
function getOutput(truffleConfig){
33+
const jsonPath = path.join(truffleConfig.working_directory, "coverage.json");
34+
return JSON.parse(fs.readFileSync(jsonPath, 'utf8'));
3135
}
3236

3337
// ========
@@ -54,9 +58,9 @@ describe('app', function() {
5458
mock.install('Simple', 'simple.js', solcoverConfig);
5559
await plugin(truffleConfig);
5660

57-
assertCoverageGenerated();
61+
assertCoverageGenerate(truffleConfig);
5862

59-
const output = getOutput();
63+
const output = getOutput(truffleConfig);
6064
const path = Object.keys(output)[0];
6165

6266
assert(output[path].fnMap['1'].name === 'test', 'coverage.json missing "test"');
@@ -92,7 +96,7 @@ describe('app', function() {
9296
await plugin(truffleConfig);
9397
});
9498

95-
it.skip('project with node_modules packages and relative path solidity imports', async function() {
99+
it('project with node_modules packages and relative path solidity imports', async function() {
96100
assertCleanInitialState();
97101
mock.installFullProject('import-paths');
98102
await plugin(truffleConfig);
@@ -105,9 +109,9 @@ describe('app', function() {
105109
mock.install('OnlyCall', 'only-call.js', solcoverConfig);
106110
await plugin(truffleConfig);
107111

108-
assertCoverageGenerated();
112+
assertCoverageGenerate(truffleConfig);
109113

110-
const output = getOutput();
114+
const output = getOutput(truffleConfig);
111115
const path = Object.keys(output)[0];
112116
assert(output[path].fnMap['1'].name === 'addTwo', 'cov should map "addTwo"');
113117
});
@@ -118,9 +122,9 @@ describe('app', function() {
118122
mock.install('Wallet', 'wallet.js', solcoverConfig);
119123
await plugin(truffleConfig);
120124

121-
assertCoverageGenerated();
125+
assertCoverageGenerate(truffleConfig);
122126

123-
const output = getOutput();
127+
const output = getOutput(truffleConfig);
124128
const path = Object.keys(output)[0];
125129
assert(output[path].fnMap['1'].name === 'transferPayment', 'cov should map "transferPayment"');
126130
});
@@ -133,9 +137,9 @@ describe('app', function() {
133137
mock.installDouble(['Proxy', 'Owned'], 'inheritance.js', solcoverConfig);
134138
await plugin(truffleConfig);
135139

136-
assertCoverageGenerated();
140+
assertCoverageGenerate(truffleConfig);
137141

138-
const output = getOutput();
142+
const output = getOutput(truffleConfig);
139143
const firstKey = Object.keys(output)[0];
140144
assert(Object.keys(output).length === 1, 'Wrong # of contracts covered');
141145
assert(firstKey.substr(firstKey.length - 9) === 'Proxy.sol', 'Wrong contract covered');
@@ -147,9 +151,9 @@ describe('app', function() {
147151
mock.installDouble(['Proxy', 'Owned'], 'inheritance.js', solcoverConfig);
148152
await plugin(truffleConfig);
149153

150-
assertCoverageGenerated();
154+
assertCoverageGenerate(truffleConfig);
151155

152-
const output = getOutput();
156+
const output = getOutput(truffleConfig);
153157
const ownedPath = Object.keys(output)[0];
154158
const proxyPath = Object.keys(output)[1];
155159
assert(output[ownedPath].fnMap['1'].name === 'constructor', '"constructor" not covered');
@@ -169,9 +173,9 @@ describe('app', function() {
169173
assert(err.message.includes('failed under coverage'));
170174
}
171175

172-
assertCoverageGenerated();
176+
assertCoverageGenerate(truffleConfig);
173177

174-
const output = getOutput();
178+
const output = getOutput(truffleConfig);
175179
const path = Object.keys(output)[0];
176180

177181
assert(output[path].fnMap['1'].name === 'test', 'cov missing "test"');
@@ -210,7 +214,7 @@ describe('app', function() {
210214
assert(err.message.includes('Compilation failed'));
211215
}
212216

213-
assertCoverageNotGenerated();
217+
assertCoverageNotGenerated(truffleConfig);
214218
});
215219

216220
});

0 commit comments

Comments
 (0)