@@ -9,27 +9,21 @@ const path = require('path');
9
9
const Web3 = require ( 'web3' ) ;
10
10
11
11
const { task, types } = require ( "@nomiclabs/buidler/config" ) ;
12
- const { ensurePluginLoadedWithUsePlugin } = require ( "@nomiclabs/buidler/plugins" ) ;
13
12
14
13
const {
15
14
TASK_TEST ,
16
15
TASK_COMPILE ,
17
- TASK_COMPILE_GET_COMPILER_INPUT
16
+ TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT ,
17
+ TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE ,
18
18
} = require ( "@nomiclabs/buidler/builtin-tasks/task-names" ) ;
19
19
20
- ensurePluginLoadedWithUsePlugin ( ) ;
21
-
22
20
function plugin ( ) {
23
21
24
22
// UI for the task flags...
25
23
const ui = new PluginUI ( ) ;
26
24
27
- // Unset useLiteralContent due to solc metadata size restriction
28
- task ( TASK_COMPILE_GET_COMPILER_INPUT ) . setAction ( async ( _ , __ , runSuper ) => {
29
- const input = await runSuper ( ) ;
30
- input . settings . metadata . useLiteralContent = false ;
31
- return input ;
32
- } )
25
+ let measureCoverage = false ;
26
+ let instrumentedSources ;
33
27
34
28
task ( "coverage" , "Generates a code coverage report for tests" )
35
29
@@ -42,6 +36,7 @@ function plugin() {
42
36
let ui ;
43
37
let api ;
44
38
let config ;
39
+ instrumentedSources = { } ;
45
40
46
41
try {
47
42
death ( buidlerUtils . finish . bind ( null , config , api ) ) ; // Catch interrupt signals
@@ -91,6 +86,9 @@ function plugin() {
91
86
} = utils . assembleFiles ( config , skipFiles ) ;
92
87
93
88
targets = api . instrument ( targets ) ;
89
+ for ( const target of targets ) {
90
+ instrumentedSources [ target . canonicalPath ] = target . source ;
91
+ }
94
92
utils . reportSkipped ( config , skipped ) ;
95
93
96
94
// ==============
@@ -104,14 +102,11 @@ function plugin() {
104
102
} = utils . getTempLocations ( config ) ;
105
103
106
104
utils . setupTempFolders ( config , tempContractsDir , tempArtifactsDir )
107
- utils . save ( targets , config . paths . sources , tempContractsDir ) ;
108
- utils . save ( skipped , config . paths . sources , tempContractsDir ) ;
109
105
110
- config . paths . sources = tempContractsDir ;
111
106
config . paths . artifacts = tempArtifactsDir ;
112
107
config . paths . cache = buidlerUtils . tempCacheDir ( config ) ;
113
- config . solc . optimizer . enabled = false ;
114
108
109
+ measureCoverage = true ;
115
110
await env . run ( TASK_COMPILE ) ;
116
111
117
112
await api . onCompileComplete ( config ) ;
@@ -137,14 +132,55 @@ function plugin() {
137
132
await api . onIstanbulComplete ( config ) ;
138
133
139
134
} catch ( e ) {
140
- error = e ;
135
+ error = e ;
136
+ } finally {
137
+ measureCoverage = false ;
141
138
}
142
139
143
140
await buidlerUtils . finish ( config , api ) ;
144
141
145
142
if ( error !== undefined ) throw error ;
146
143
if ( process . exitCode > 0 ) throw new Error ( ui . generate ( 'tests-fail' , [ process . exitCode ] ) ) ;
147
- } )
144
+ } ) ;
145
+
146
+ task ( TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT ) . setAction ( async ( _ , { config } , runSuper ) => {
147
+ const solcInput = await runSuper ( ) ;
148
+ if ( measureCoverage ) {
149
+ // The source name here is actually the global name in the solc input,
150
+ // but buidler uses the fully qualified contract names.
151
+ for ( const [ sourceName , source ] of Object . entries ( solcInput . sources ) ) {
152
+ const absolutePath = path . join ( config . paths . root , sourceName ) ;
153
+ // Patch in the instrumented source code.
154
+ if ( absolutePath in instrumentedSources ) {
155
+ source . content = instrumentedSources [ absolutePath ] ;
156
+ }
157
+ }
158
+ }
159
+ return solcInput ;
160
+ } ) ;
161
+
162
+ // Solidity settings are best set here instead of the TASK_COMPILE_SOLIDITY_GET_COMPILER_INPUT task.
163
+ task ( TASK_COMPILE_SOLIDITY_GET_COMPILATION_JOB_FOR_FILE ) . setAction ( async ( _ , __ , runSuper ) => {
164
+ const compilationJob = await runSuper ( ) ;
165
+ if ( measureCoverage && typeof compilationJob === "object" ) {
166
+ if ( compilationJob . solidityConfig . settings === undefined ) {
167
+ compilationJob . solidityConfig . settings = { } ;
168
+ }
169
+
170
+ const { settings } = compilationJob . solidityConfig ;
171
+ if ( settings . metadata === undefined ) {
172
+ settings . metadata = { } ;
173
+ }
174
+ if ( settings . optimizer === undefined ) {
175
+ settings . optimizer = { } ;
176
+ }
177
+ // Unset useLiteralContent due to solc metadata size restriction
178
+ settings . metadata . useLiteralContent = false ;
179
+ // Override optimizer settings for all compilers
180
+ settings . optimizer . enabled = false ;
181
+ }
182
+ return compilationJob ;
183
+ } ) ;
148
184
}
149
185
150
186
module . exports = plugin ;
0 commit comments