aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorCyril Sobierajewicz <cyril.sobierajewicz@fretlink.com>2018-12-03 11:37:46 +0100
committerCyril Sobierajewicz <cyril.sobierajewicz@fretlink.com>2018-12-03 11:57:30 +0100
commitf9d5f2faaa11b31661de1a1fcdad4ab51e8ef5fe (patch)
tree7021319353b6c8af625563936deacc21a4311fe5
parent9dcf21578cb7e415e9670cd076182ee3c9b67a6b (diff)
downloadpurs-loader-f9d5f2faaa11b31661de1a1fcdad4ab51e8ef5fe.tar.gz
purs-loader-f9d5f2faaa11b31661de1a1fcdad4ab51e8ef5fe.tar.zst
purs-loader-f9d5f2faaa11b31661de1a1fcdad4ab51e8ef5fe.zip
Watch failed modules and their dependencies on compilation error
-rw-r--r--src/index.js37
-rw-r--r--src/utils.js23
2 files changed, 57 insertions, 3 deletions
diff --git a/src/index.js b/src/index.js
index b151d82..fce6394 100644
--- a/src/index.js
+++ b/src/index.js
@@ -26,6 +26,8 @@ const sourceMaps = require('./source-maps');
26 26
27const dargs = require('./dargs'); 27const dargs = require('./dargs');
28 28
29const utils = require('./utils');
30
29const spawn = require('cross-spawn').sync 31const spawn = require('cross-spawn').sync
30 32
31const eol = require('os').EOL 33const eol = require('os').EOL
@@ -186,9 +188,38 @@ module.exports = function purescriptLoader(source, map) {
186 CACHE_VAR.warnings.push(warning); 188 CACHE_VAR.warnings.push(warning);
187 } 189 }
188 }, 190 },
189 emitError: error => { 191 emitError: pscMessage => {
190 if (error.length) { 192 if (pscMessage.length) {
191 CACHE_VAR.errors.push(error); 193 const matchErrorsSeparator = /\n(?=Error)/;
194 const errors = pscMessage.split(matchErrorsSeparator);
195 for (const error of errors) {
196 const matchErrLocation = /at (.+\.purs) line (\d+), column (\d+) - line (\d+), column (\d+)/;
197 const [, filename] = matchErrLocation.exec(error) || [];
198 if (!filename) continue;
199
200 const baseModulePath = path.join(this.rootContext, filename);
201 this.addDependency(baseModulePath);
202
203 const matchErrModuleName = /in module ((?:\w+\.)*\w+)/;
204 const [, baseModuleName] = matchErrModuleName.exec(error) || [];
205 if (!baseModuleName) continue;
206
207 const matchMissingModuleName = /Module ((?:\w+\.)*\w+) was not found/;
208 const matchMissingImportFromModuleName = /Cannot import value \w+ from module ((?:\w+\.)*\w+)/;
209 for (const re of [matchMissingModuleName, matchMissingImportFromModuleName]) {
210 const [, targetModuleName] = re.exec(error) || [];
211 if (targetModuleName) {
212 const resolved = utils.resolvePursModule({
213 baseModulePath,
214 baseModuleName,
215 targetModuleName
216 });
217 this.addDependency(resolved);
218 }
219 }
220 }
221
222 CACHE_VAR.errors.push(pscMessage);
192 } 223 }
193 } 224 }
194 } 225 }
diff --git a/src/utils.js b/src/utils.js
new file mode 100644
index 0000000..0ab00eb
--- /dev/null
+++ b/src/utils.js
@@ -0,0 +1,23 @@
1const path = require('path');
2
3const repeat = (value, times) =>
4 times <= 0 ? [] : [value, ...repeat(value, times - 1)];
5const diffPursModuleNames = (from, target, parts) => {
6 if (!from.length) return parts.concat(target);
7 if (!target.length) return parts.concat(repeat('..', from.length));
8 const [head_from, ...tail_from] = from;
9 const [head_target, ...tail_target] = target;
10 return head_from === head_target
11 ? diffPursModuleNames(tail_from, tail_target, parts)
12 : parts.concat(repeat('..', from.length), target);
13};
14exports.resolvePursModule = ({ baseModulePath, baseModuleName, targetModuleName }) => {
15 const parts = diffPursModuleNames(
16 baseModuleName.split('.'),
17 targetModuleName.split('.'),
18 []);
19 return parts.length
20 ? path.resolve(baseModulePath,
21 `${path.join(...parts)}.purs`)
22 : baseModulePath;
23};