diff options
author | Cyril Sobierajewicz <38043722+cyrilfretlink@users.noreply.github.com> | 2018-12-03 15:16:50 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-12-03 15:16:50 +0100 |
commit | d8239dd526facd516600acfdbc808f415919117d (patch) | |
tree | e91543c1738871b9ed9acc19314cf7baec8fd8a6 | |
parent | 59223097e35133918db227b3f75e009c1c46dc68 (diff) | |
parent | a30f8b466b7746ec4f29ce68452af4c238f2d8b2 (diff) | |
download | purs-loader-d8239dd526facd516600acfdbc808f415919117d.tar.gz purs-loader-d8239dd526facd516600acfdbc808f415919117d.tar.zst purs-loader-d8239dd526facd516600acfdbc808f415919117d.zip |
Merge pull request #1 from cyrilfretlink/3.3.0
Version 3.3.0
-rw-r--r-- | package.json | 2 | ||||
-rw-r--r-- | src/index.js | 72 | ||||
-rw-r--r-- | src/utils.js | 34 | ||||
-rw-r--r-- | utils.js | 1 |
4 files changed, 101 insertions, 8 deletions
diff --git a/package.json b/package.json index 2b5b1ba..7383175 100644 --- a/package.json +++ b/package.json | |||
@@ -1,6 +1,6 @@ | |||
1 | { | 1 | { |
2 | "name": "purs-loader", | 2 | "name": "purs-loader", |
3 | "version": "3.2.0", | 3 | "version": "3.3.0", |
4 | "description": "A webpack loader for PureScript.", | 4 | "description": "A webpack loader for PureScript.", |
5 | "main": "lib/index.js", | 5 | "main": "lib/index.js", |
6 | "files": [ | 6 | "files": [ |
diff --git a/src/index.js b/src/index.js index cc779f7..8a2e468 100644 --- a/src/index.js +++ b/src/index.js | |||
@@ -26,6 +26,8 @@ const sourceMaps = require('./source-maps'); | |||
26 | 26 | ||
27 | const dargs = require('./dargs'); | 27 | const dargs = require('./dargs'); |
28 | 28 | ||
29 | const utils = require('./utils'); | ||
30 | |||
29 | const spawn = require('cross-spawn').sync | 31 | const spawn = require('cross-spawn').sync |
30 | 32 | ||
31 | const eol = require('os').EOL | 33 | const eol = require('os').EOL |
@@ -40,6 +42,7 @@ var CACHE_VAR = { | |||
40 | errors: [], | 42 | errors: [], |
41 | compilationStarted: false, | 43 | compilationStarted: false, |
42 | compilationFinished: false, | 44 | compilationFinished: false, |
45 | compilationFailed: false, | ||
43 | installed: false, | 46 | installed: false, |
44 | srcOption: [] | 47 | srcOption: [] |
45 | }; | 48 | }; |
@@ -147,6 +150,7 @@ module.exports = function purescriptLoader(source, map) { | |||
147 | errors: [], | 150 | errors: [], |
148 | compilationStarted: false, | 151 | compilationStarted: false, |
149 | compilationFinished: false, | 152 | compilationFinished: false, |
153 | compilationFailed: false, | ||
150 | installed: CACHE_VAR.installed, | 154 | installed: CACHE_VAR.installed, |
151 | srcOption: [] | 155 | srcOption: [] |
152 | }; | 156 | }; |
@@ -184,9 +188,57 @@ module.exports = function purescriptLoader(source, map) { | |||
184 | CACHE_VAR.warnings.push(warning); | 188 | CACHE_VAR.warnings.push(warning); |
185 | } | 189 | } |
186 | }, | 190 | }, |
187 | emitError: error => { | 191 | emitError: pscMessage => { |
188 | if (error.length) { | 192 | if (pscMessage.length) { |
189 | CACHE_VAR.errors.push(error); | 193 | const modules = []; |
194 | |||
195 | const matchErrorsSeparator = /\n(?=Error)/; | ||
196 | const errors = pscMessage.split(matchErrorsSeparator); | ||
197 | for (const error of errors) { | ||
198 | const matchErrLocation = /at (.+\.purs) line (\d+), column (\d+) - line (\d+), column (\d+)/; | ||
199 | const [, filename] = matchErrLocation.exec(error) || []; | ||
200 | if (!filename) continue; | ||
201 | |||
202 | const baseModulePath = path.join(this.rootContext, filename); | ||
203 | this.addDependency(baseModulePath); | ||
204 | |||
205 | const matchErrModuleName = /in module ((?:\w+\.)*\w+)/; | ||
206 | const [, baseModuleName] = matchErrModuleName.exec(error) || []; | ||
207 | if (!baseModuleName) continue; | ||
208 | |||
209 | const matchMissingModuleName = /Module ((?:\w+\.)*\w+) was not found/; | ||
210 | const matchMissingImportFromModuleName = /Cannot import value \w+ from module ((?:\w+\.)*\w+)/; | ||
211 | for (const re of [matchMissingModuleName, matchMissingImportFromModuleName]) { | ||
212 | const [, targetModuleName] = re.exec(error) || []; | ||
213 | if (targetModuleName) { | ||
214 | const resolved = utils.resolvePursModule({ | ||
215 | baseModulePath, | ||
216 | baseModuleName, | ||
217 | targetModuleName | ||
218 | }); | ||
219 | this.addDependency(resolved); | ||
220 | } | ||
221 | } | ||
222 | |||
223 | const desc = { | ||
224 | name: baseModuleName, | ||
225 | filename: baseModulePath | ||
226 | }; | ||
227 | |||
228 | if (typeof this.describePscError === 'function') { | ||
229 | const { dependencies = [], details } = this.describePscError(error, desc); | ||
230 | |||
231 | for (const dep of dependencies) { | ||
232 | this.addDependency(dep); | ||
233 | } | ||
234 | |||
235 | Object.assign(desc, details); | ||
236 | } | ||
237 | |||
238 | modules.push(desc); | ||
239 | } | ||
240 | |||
241 | CACHE_VAR.errors.push(new utils.PscError(pscMessage, modules)); | ||
190 | } | 242 | } |
191 | } | 243 | } |
192 | } | 244 | } |
@@ -258,6 +310,8 @@ module.exports = function purescriptLoader(source, map) { | |||
258 | ) | 310 | ) |
259 | ) | 311 | ) |
260 | .catch(error => { | 312 | .catch(error => { |
313 | CACHE_VAR.compilationFailed = true; | ||
314 | |||
261 | CACHE_VAR.deferred[0].reject(error); | 315 | CACHE_VAR.deferred[0].reject(error); |
262 | 316 | ||
263 | CACHE_VAR.deferred.slice(1).forEach(psModule => { | 317 | CACHE_VAR.deferred.slice(1).forEach(psModule => { |
@@ -265,8 +319,9 @@ module.exports = function purescriptLoader(source, map) { | |||
265 | }) | 319 | }) |
266 | }) | 320 | }) |
267 | ; | 321 | ; |
268 | } | 322 | } else if (CACHE_VAR.compilationFailed) { |
269 | else { | 323 | CACHE_VAR.deferred.pop().reject(new Error('purs-loader failed')); |
324 | } else { | ||
270 | // The compilation has started. We must wait until it is | 325 | // The compilation has started. We must wait until it is |
271 | // done in order to ensure the module map contains all of | 326 | // done in order to ensure the module map contains all of |
272 | // the unknown modules. | 327 | // the unknown modules. |
@@ -318,6 +373,8 @@ module.exports = function purescriptLoader(source, map) { | |||
318 | ) | 373 | ) |
319 | ) | 374 | ) |
320 | .catch(error => { | 375 | .catch(error => { |
376 | CACHE_VAR.compilationFailed = true; | ||
377 | |||
321 | CACHE_VAR.deferred[0].reject(error); | 378 | CACHE_VAR.deferred[0].reject(error); |
322 | 379 | ||
323 | CACHE_VAR.deferred.slice(1).forEach(psModule => { | 380 | CACHE_VAR.deferred.slice(1).forEach(psModule => { |
@@ -325,8 +382,9 @@ module.exports = function purescriptLoader(source, map) { | |||
325 | }) | 382 | }) |
326 | }) | 383 | }) |
327 | ; | 384 | ; |
328 | } | 385 | } else if (CACHE_VAR.compilationFailed) { |
329 | else { | 386 | CACHE_VAR.deferred.pop().reject(new Error('purs-loader failed')); |
387 | } else { | ||
330 | // The complation has started. Nothing to do but wait until it is | 388 | // The complation has started. Nothing to do but wait until it is |
331 | // done before loading all of the modules. | 389 | // done before loading all of the modules. |
332 | } | 390 | } |
diff --git a/src/utils.js b/src/utils.js new file mode 100644 index 0000000..671b580 --- /dev/null +++ b/src/utils.js | |||
@@ -0,0 +1,34 @@ | |||
1 | const path = require('path'); | ||
2 | |||
3 | exports.PscError = class PscError extends Error { | ||
4 | constructor(message, modules) { | ||
5 | super(message); | ||
6 | this.modules = modules; | ||
7 | } | ||
8 | |||
9 | static get name() { | ||
10 | return 'PscError'; | ||
11 | } | ||
12 | }; | ||
13 | |||
14 | const repeat = (value, times) => | ||
15 | times <= 0 ? [] : [value, ...repeat(value, times - 1)]; | ||
16 | const diffPursModuleNames = (from, target, parts) => { | ||
17 | if (!from.length) return parts.concat(target); | ||
18 | if (!target.length) return parts.concat(repeat('..', from.length)); | ||
19 | const [head_from, ...tail_from] = from; | ||
20 | const [head_target, ...tail_target] = target; | ||
21 | return head_from === head_target | ||
22 | ? diffPursModuleNames(tail_from, tail_target, parts) | ||
23 | : parts.concat(repeat('..', from.length), target); | ||
24 | }; | ||
25 | exports.resolvePursModule = ({ baseModulePath, baseModuleName, targetModuleName }) => { | ||
26 | const parts = diffPursModuleNames( | ||
27 | baseModuleName.split('.'), | ||
28 | targetModuleName.split('.'), | ||
29 | []); | ||
30 | return parts.length | ||
31 | ? path.resolve(baseModulePath, | ||
32 | `${path.join(...parts)}.purs`) | ||
33 | : baseModulePath; | ||
34 | }; | ||
diff --git a/utils.js b/utils.js new file mode 100644 index 0000000..cec6101 --- /dev/null +++ b/utils.js | |||
@@ -0,0 +1 @@ | |||
module.exports = require('./lib/utils'); | |||