]> git.immae.eu Git - github/fretlink/purs-loader.git/commitdiff
Support for PureScript 0.11
authoreric thul <thul.eric@gmail.com>
Sat, 22 Apr 2017 14:52:54 +0000 (10:52 -0400)
committereric <thul.eric@gmail.com>
Sun, 23 Apr 2017 22:20:22 +0000 (18:20 -0400)
Resolves #89

README.md
src/Psc.js [deleted file]
src/bundle.js [new file with mode: 0644]
src/compile.js [new file with mode: 0644]
src/ide.js [moved from src/PscIde.js with 85% similarity]
src/index.js
src/purs-module-map.js [moved from src/PsModuleMap.js with 76% similarity]

index c15f03ccf2de64628212f017fb7d7acfc6fddf4b..d82893d591bb2233f1bfe0da6f084b9f8ec55f30 100644 (file)
--- a/README.md
+++ b/README.md
 Install with [npm](https://npmjs.org/package/purs-loader).
 
 ```
-// For PureScript 0.9 and newer
+// For PureScript 0.11 and newer
 npm install purs-loader --save-dev
 
+// For PureScript 0.9 and 0.10
+npm install purs-loader@purescript-0.9 --save-dev
+
 // For PureScript 0.8
 npm install purs-loader@purescript-0.8 --save-dev
 ```
diff --git a/src/Psc.js b/src/Psc.js
deleted file mode 100644 (file)
index ffa32b7..0000000
+++ /dev/null
@@ -1,108 +0,0 @@
-'use strict';
-
-const path = require('path');
-
-const Promise = require('bluebird')
-
-const fs = Promise.promisifyAll(require('fs'))
-
-const spawn = require('cross-spawn')
-
-const debug = require('debug')('purs-loader');
-
-const dargs = require('./dargs');
-
-function compile(psModule) {
-  const options = psModule.options
-  const cache = psModule.cache
-  const stderr = []
-
-  if (cache.compilationStarted) return Promise.resolve(psModule)
-
-  cache.compilationStarted = true
-
-  const args = dargs(Object.assign({
-    _: options.src,
-    output: options.output,
-  }, options.pscArgs))
-
-  debug('spawning compiler %s %o', options.psc, args)
-
-  return (new Promise((resolve, reject) => {
-    debug('compiling PureScript...')
-
-    const compilation = spawn(options.psc, args)
-
-    compilation.stderr.on('data', data => {
-      stderr.push(data.toString());
-    });
-
-    compilation.on('close', code => {
-      debug('finished compiling PureScript.')
-      cache.compilationFinished = true
-      if (code !== 0) {
-        const errorMessage = stderr.join('');
-        if (errorMessage.length) {
-          psModule.emitError(errorMessage);
-        }
-        if (options.watch) {
-          resolve(psModule);
-        }
-        else {
-          reject(new Error('compilation failed'))
-        }
-      } else {
-        const warningMessage = stderr.join('');
-        if (options.warnings && warningMessage.length) {
-          psModule.emitWarning(warningMessage);
-        }
-        resolve(psModule)
-      }
-    })
-  }))
-  .then(compilerOutput => {
-    if (options.bundle) {
-      return bundle(options, cache).then(() => psModule)
-    }
-    return psModule
-  })
-}
-module.exports.compile = compile;
-
-function bundle(options, cache) {
-  if (cache.bundle) return Promise.resolve(cache.bundle)
-
-  const stdout = []
-  const stderr = cache.bundle = []
-
-  const args = dargs(Object.assign({
-    _: [path.join(options.output, '*', '*.js')],
-    output: options.bundleOutput,
-    namespace: options.bundleNamespace,
-  }, options.pscBundleArgs))
-
-  cache.bundleModules.forEach(name => args.push('--module', name))
-
-  debug('spawning bundler %s %o', options.pscBundle, args.join(' '))
-
-  return (new Promise((resolve, reject) => {
-    debug('bundling PureScript...')
-
-    const compilation = spawn(options.pscBundle, args)
-
-    compilation.stdout.on('data', data => stdout.push(data.toString()))
-    compilation.stderr.on('data', data => stderr.push(data.toString()))
-    compilation.on('close', code => {
-      debug('finished bundling PureScript.')
-      if (code !== 0) {
-        const errorMessage = stderr.join('');
-        if (errorMessage.length) {
-          psModule.emitError(errorMessage);
-        }
-        return reject(new Error('bundling failed'))
-      }
-      cache.bundle = stderr
-      resolve(fs.appendFileAsync(options.bundleOutput, `module.exports = ${options.bundleNamespace}`))
-    })
-  }))
-}
diff --git a/src/bundle.js b/src/bundle.js
new file mode 100644 (file)
index 0000000..6627ffe
--- /dev/null
@@ -0,0 +1,59 @@
+'use strict';
+
+const path = require('path');
+
+const Promise = require('bluebird')
+
+const fs = Promise.promisifyAll(require('fs'))
+
+const spawn = require('cross-spawn')
+
+const debug = require('debug')('purs-loader');
+
+const dargs = require('./dargs');
+
+module.exports = function bundle(options, cache) {
+  if (cache.bundle) return Promise.resolve(cache.bundle)
+
+  const stdout = []
+
+  const stderr = cache.bundle = []
+
+  const bundleCommand = options.pscBundle || 'purs';
+
+  const bundleArgs = (options.pscBundle ? [] : [ 'bundle' ]).concat(dargs(Object.assign({
+    _: [path.join(options.output, '*', '*.js')],
+    output: options.bundleOutput,
+    namespace: options.bundleNamespace,
+  }, options.pscBundleArgs)));
+
+  cache.bundleModules.forEach(name => bundleArgs.push('--module', name))
+
+  debug('spawning bundler %s %o', bundleCommand, bundleArgs);
+
+  return (new Promise((resolve, reject) => {
+    debug('bundling PureScript...')
+
+    const compilation = spawn(bundleCommand, bundleArgs)
+
+    compilation.stdout.on('data', data => stdout.push(data.toString()))
+
+    compilation.stderr.on('data', data => stderr.push(data.toString()))
+
+    compilation.on('close', code => {
+      debug('finished bundling PureScript.')
+
+      if (code !== 0) {
+        const errorMessage = stderr.join('');
+        if (errorMessage.length) {
+          psModule.emitError(errorMessage);
+        }
+        return reject(new Error('bundling failed'))
+      }
+
+      cache.bundle = stderr
+
+      resolve(fs.appendFileAsync(options.bundleOutput, `module.exports = ${options.bundleNamespace}`))
+    })
+  }))
+};
diff --git a/src/compile.js b/src/compile.js
new file mode 100644 (file)
index 0000000..8b5d87f
--- /dev/null
@@ -0,0 +1,58 @@
+'use strict';
+
+const Promise = require('bluebird');
+
+const spawn = require('cross-spawn');
+
+const debug = require('debug')('purs-loader');
+
+const dargs = require('./dargs');
+
+module.exports = function compile(psModule) {
+  const options = psModule.options
+
+  const cache = psModule.cache
+
+  const stderr = []
+
+  const compileCommand = options.psc || 'purs';
+
+  const compileArgs = (options.psc ? [] : [ 'compile' ]).concat(dargs(Object.assign({
+    _: options.src,
+    output: options.output,
+  }, options.pscArgs)))
+
+  debug('spawning compiler %s %o', compileCommand, compileArgs)
+
+  return new Promise((resolve, reject) => {
+    debug('compiling PureScript...')
+
+    const compilation = spawn(compileCommand, compileArgs)
+
+    compilation.stderr.on('data', data => {
+      stderr.push(data.toString());
+    });
+
+    compilation.on('close', code => {
+      debug('finished compiling PureScript.')
+      if (code !== 0) {
+        const errorMessage = stderr.join('');
+        if (errorMessage.length) {
+          psModule.emitError(errorMessage);
+        }
+        if (options.watch) {
+          resolve(psModule);
+        }
+        else {
+          reject(new Error('compilation failed'))
+        }
+      } else {
+        const warningMessage = stderr.join('');
+        if (options.warnings && warningMessage.length) {
+          psModule.emitWarning(warningMessage);
+        }
+        resolve(psModule)
+      }
+    })
+  });
+};
similarity index 85%
rename from src/PscIde.js
rename to src/ide.js
index bf92b3860ee502532ee315de68e9f38323cfea0f..f839fd5cc932197ee6c8fbe9de9257f8056343ae 100644 (file)
@@ -20,7 +20,7 @@ const Psc = require('./Psc');
 
 const PsModuleMap = require('./PsModuleMap');
 
-function connect(psModule) {
+module.exports.connect = function connect(psModule) {
   const options = psModule.options
   const cache = psModule.cache
 
@@ -31,14 +31,14 @@ function connect(psModule) {
   const connect_ = () => new Promise((resolve, reject) => {
     const args = dargs(options.pscIdeArgs)
 
-    debug('attempting to connect to psc-ide-server', args)
+    debug('attempting to run purs ide client: %o', args)
 
-    const ideClient = spawn('psc-ide-client', args)
+    const ideClient = spawn('purs', ['ide', 'client'].concat(args))
 
     ideClient.stderr.on('data', data => {
       debug(data.toString())
       cache.ideServer = false
-      reject(new Error('psc-ide-client failed'))
+      reject(new Error('purs ide client failed'))
     })
     ideClient.stdout.once('data', data => {
       debug(data.toString())
@@ -49,11 +49,11 @@ function connect(psModule) {
           resolve(psModule)
         } else {
           cache.ideServer = ideServer
-          reject(new Error('psc-ide-client failed'))
+          reject(new Error('purs ide client failed'))
         }
       } else {
         cache.ideServer = false
-        reject(new Error('psc-ide-client failed'))
+        reject(new Error('purs ide client failed'))
       }
     })
     ideClient.stdin.resume()
@@ -66,24 +66,24 @@ function connect(psModule) {
     '_': options.src
   }, options.pscIdeServerArgs))
 
-  debug('attempting to start psc-ide-server', serverArgs)
+  debug('attempting to start purs ide server: %o', serverArgs)
 
-  const ideServer = cache.ideServer = spawn('psc-ide-server', serverArgs)
+  const ideServer = cache.ideServer = spawn('purs', ['ide', 'server'].concat(serverArgs))
 
   ideServer.stdout.on('data', data => {
-    debug('psc-ide-server stdout: %s', data.toString());
+    debug('purs ide server stdout: %s', data.toString());
   });
 
   ideServer.stderr.on('data', data => {
-    debug('psc-ide-server stderr: %s', data.toString());
+    debug('purs ide server stderr: %s', data.toString());
   });
 
   ideServer.on('error', error => {
-    debug('psc-ide-server error: %o', error);
+    debug('purs ide server error: %o', error);
   });
 
   ideServer.on('close', (code, signal) => {
-    debug('psc-ide-server close: %s %s', code, signal);
+    debug('purs ide server close: %s %s', code, signal);
   });
 
   return retryPromise((retry, number) => {
@@ -91,7 +91,7 @@ function connect(psModule) {
       if (!cache.ideServer && number === 9) {
         debug(error)
 
-        console.warn('Failed to connect to or start psc-ide-server. A full compilation will occur on rebuild');
+        console.warn('Failed to connect to or start purs ide server. A full compilation will occur on rebuild');
 
         return Promise.resolve(psModule)
       }
@@ -104,18 +104,17 @@ function connect(psModule) {
     minTimeout: 333,
     maxTimeout: 333,
   })
-}
-module.exports.connect = connect;
+};
 
-function rebuild(psModule) {
+module.exports.rebuild = function rebuild(psModule) {
   const options = psModule.options
   const cache = psModule.cache
 
-  debug('attempting rebuild with psc-ide-client %s', psModule.srcPath)
+  debug('attempting rebuild with purs ide client %s', psModule.srcPath)
 
   const request = (body) => new Promise((resolve, reject) => {
     const args = dargs(options.pscIdeArgs)
-    const ideClient = spawn('psc-ide-client', args)
+    const ideClient = spawn('purs', ['ide', 'client'].concat(args))
 
     var stdout = ''
     var stderr = ''
@@ -130,7 +129,7 @@ function rebuild(psModule) {
 
     ideClient.on('close', code => {
       if (code !== 0) {
-        const error = stderr === '' ? 'Failed to spawn psc-ide-client' : stderr
+        const error = stderr === '' ? 'Failed to spawn purs ide client' : stderr
         return reject(new Error(error))
       }
 
@@ -187,7 +186,7 @@ function rebuild(psModule) {
       })
     })
 
-    debug('psc-ide-client stdin: %o', body);
+    debug('purs ide client stdin: %o', body);
 
     ideClient.stdin.write(JSON.stringify(body))
     ideClient.stdin.write('\n')
@@ -199,8 +198,7 @@ function rebuild(psModule) {
       file: psModule.srcPath,
     }
   })
-}
-module.exports.rebuild = rebuild;
+};
 
 function formatIdeResult(result, options, index, length) {
   let numAndErr = `[${index+1}/${length} ${result.errorCode}]`
index 047927c3aa4e6ccda62fba03683fa74b758d094f..799f8f9989dda69818b2191fad02186d0d5047b9 100644 (file)
@@ -1,15 +1,27 @@
 'use strict'
 
 const debug = require('debug')('purs-loader')
+
 const loaderUtils = require('loader-utils')
+
 const Promise = require('bluebird')
+
 const path = require('path')
-const PsModuleMap = require('./PsModuleMap');
-const Psc = require('./Psc');
-const PscIde = require('./PscIde');
+
+const PsModuleMap = require('./purs-module-map');
+
+const compile = require('./compile');
+
+const bundle = require('./bundle');
+
+const ide = require('./ide');
+
 const toJavaScript = require('./to-javascript');
+
 const dargs = require('./dargs');
+
 const spawn = require('cross-spawn').sync
+
 const eol = require('os').EOL
 
 module.exports = function purescriptLoader(source, map) {
@@ -34,9 +46,9 @@ module.exports = function purescriptLoader(source, map) {
   const defaultDeps = depsPaths(options.pscPackage)
   const defaultOptions = {
     context: config.context,
-    psc: 'psc',
+    psc: null,
     pscArgs: {},
-    pscBundle: 'psc-bundle',
+    pscBundle: null,
     pscBundleArgs: {},
     pscIde: false,
     pscIdeColors: options.psc === 'psa',
@@ -102,7 +114,7 @@ module.exports = function purescriptLoader(source, map) {
     });
   }
 
-  const psModuleName = PsModuleMap.match(source)
+  const psModuleName = PsModuleMap.matchModule(source)
   const psModule = {
     name: psModuleName,
     load: js => callback(null, js),
@@ -131,8 +143,8 @@ module.exports = function purescriptLoader(source, map) {
   }
 
   if (cache.rebuild) {
-    return PscIde.connect(psModule)
-      .then(PscIde.rebuild)
+    return ide.connect(psModule)
+      .then(ide.rebuild)
       .then(toJavaScript)
       .then(psModule.load)
       .catch(psModule.reject)
@@ -147,11 +159,21 @@ module.exports = function purescriptLoader(source, map) {
   cache.deferred.push(psModule)
 
   if (!cache.compilationStarted) {
-    return Psc.compile(psModule)
-       .then(() => PsModuleMap.makeMap(options.src).then(map => {
-         debug('rebuilt module map after compile');
-         cache.psModuleMap = map;
-       }))
+    cache.compilationStarted = true;
+
+    return compile(psModule)
+      .then(() => {
+        cache.compilationFinished = true;
+
+        const bundlePromise = options.bundle ? bundle(options, cache) : Promise.resolve();
+
+        return bundlePromise.then(() =>
+          PsModuleMap.makeMap(options.src).then(map => {
+            debug('rebuilt module map after compile');
+            cache.psModuleMap = map;
+          })
+        );
+      })
       .then(() => Promise.map(cache.deferred, psModule => {
         if (typeof cache.ideServer === 'object') cache.ideServer.kill()
         return toJavaScript(psModule).then(psModule.load)
similarity index 76%
rename from src/PsModuleMap.js
rename to src/purs-module-map.js
index 0ae687c0fc6b59dabd72a2e0940cbe58bf81c155..b906d08476591c6ef65400e90acf7b8db70a6ad8 100644 (file)
@@ -14,19 +14,17 @@ const srcModuleRegex = /(?:^|\n)module\s+([\w\.]+)/i;
 
 const importModuleRegex = /(?:^|\n)\s*import\s+([\w\.]+)/ig;
 
-function matchModule(str) {
+module.exports.matchModule = function matchModule(str) {
   const matches = str.match(srcModuleRegex);
   return matches && matches[1];
-}
-module.exports.match = matchModule;
+};
 
-function matchImports(str) {
+module.exports.matchImports = function matchImports(str) {
   const matches = str.match(importModuleRegex);
   return (matches || []).map(a => a.replace(/\n?\s*import\s+/i, ''));
-}
-module.exports.matchImports = matchImports;
+};
 
-function makeMapEntry(filePurs) {
+module.exports.makeMapEntry = function makeMapEntry(filePurs) {
   const dirname = path.dirname(filePurs);
 
   const basename = path.basename(filePurs, '.purs');
@@ -41,9 +39,9 @@ function makeMapEntry(filePurs) {
 
     const sourceJs = fileMap.fileJs;
 
-    const moduleName = matchModule(sourcePurs);
+    const moduleName = module.exports.matchModule(sourcePurs);
 
-    const imports = matchImports(sourcePurs);
+    const imports = module.exports.matchImports(sourcePurs);
 
     const map = {};
 
@@ -61,18 +59,16 @@ function makeMapEntry(filePurs) {
   });
 
   return result;
-}
-module.exports.makeMapEntry = makeMapEntry;
+};
 
-function makeMap(src) {
+module.exports.makeMap = function makeMap(src) {
   debug('loading PureScript source and FFI files from %o', src);
 
   const globs = [].concat(src);
 
   return globby(globs).then(paths =>
-    Promise.all(paths.map(makeMapEntry)).then(result =>
+    Promise.all(paths.map(module.exports.makeMapEntry)).then(result =>
       result.reduce(Object.assign, {})
     )
   );
-}
-module.exports.makeMap = makeMap;
+};