From 0e1221d7b15e578d5e9146b01e11a24007d4ba9b Mon Sep 17 00:00:00 2001 From: eric thul Date: Mon, 6 Jul 2015 23:49:47 -0400 Subject: [PATCH] Generate .psci file Resolves #11 --- README.md | 4 ++++ package.json | 1 + src/FS.purs | 32 ++++++++++++++++++++++++++++ src/Glob.purs | 33 ++++++++++++++++++++++++++++ src/Loader.purs | 52 ++++++++++++++++++++++++++++++++++++++------- src/LoaderUtil.purs | 9 +------- src/Options.purs | 4 ++++ webpack.config.js | 9 +++++--- 8 files changed, 125 insertions(+), 19 deletions(-) create mode 100644 src/FS.purs create mode 100644 src/Glob.purs diff --git a/README.md b/README.md index 8a310d5..a45573f 100644 --- a/README.md +++ b/README.md @@ -99,3 +99,7 @@ module.exports = config; ``` See the [example](https://github.com/ethul/purs-loader/tree/master/example) directory for a complete example. + +## Notes + +A `.psci` file is generated during each run of the loader. diff --git a/package.json b/package.json index 39c743b..f98769e 100644 --- a/package.json +++ b/package.json @@ -28,6 +28,7 @@ "webpack": "^1.8.4" }, "dependencies": { + "async": "^1.3.0", "glob": "^5.0.3", "loader-utils": "^0.2.6" } diff --git a/src/FS.purs b/src/FS.purs new file mode 100644 index 0000000..a56fe26 --- /dev/null +++ b/src/FS.purs @@ -0,0 +1,32 @@ +module PursLoader.FS + ( FS() + , writeFileUtf8 + ) where + +import Control.Monad.Aff (Aff(), makeAff) +import Control.Monad.Eff (Eff()) +import Control.Monad.Eff.Exception (Error()) + +import Data.Function + +foreign import data FS :: ! + +writeFileUtf8 :: forall eff. String -> String -> Aff (fs :: FS | eff) Unit +writeFileUtf8 filepath contents = makeAff $ runFn4 writeFileUtf8Fn filepath contents + +foreign import writeFileUtf8Fn """ +function writeFileUtf8Fn(filepath, contents, errback, callback) { + return function(){ + var fs = require('fs'); + + fs.writeFile(filepath, contents, function(error){ + if (error) errback(error)(); + else callback()(); + }); + }; +} +""" :: forall eff. Fn4 String + String + (Error -> Eff (fs :: FS | eff) Unit) + (Unit -> Eff (fs :: FS | eff) Unit) + (Eff (fs :: FS | eff) Unit) diff --git a/src/Glob.purs b/src/Glob.purs new file mode 100644 index 0000000..392d9e4 --- /dev/null +++ b/src/Glob.purs @@ -0,0 +1,33 @@ +module PursLoader.Glob + ( Glob() + , globAll + ) where + +import Control.Monad.Aff (Aff(), makeAff) +import Control.Monad.Eff (Eff()) +import Control.Monad.Eff.Exception (Error()) + +import Data.Function + +foreign import data Glob :: ! + +globAll :: forall eff. [String] -> Aff (glob :: Glob | eff) [[String]] +globAll patterns = makeAff $ runFn3 globAllFn patterns + +foreign import globAllFn """ +function globAllFn(patterns, errback, callback) { + return function(){ + var glob = require('glob'); + + var async = require('async'); + + async.map(patterns, glob, function(error, result){ + if (error) errback(new Error(error))(); + else callback(result)(); + }); + }; +} +""" :: forall eff. Fn3 [String] + (Error -> Eff (glob :: Glob | eff) Unit) + ([[String]] -> Eff (glob :: Glob | eff) Unit) + (Eff (glob :: Glob | eff) Unit) diff --git a/src/Loader.purs b/src/Loader.purs index 0235da9..872a51c 100644 --- a/src/Loader.purs +++ b/src/Loader.purs @@ -9,36 +9,72 @@ import Control.Monad.Eff (Eff()) import Control.Monad.Eff.Class (liftEff) import Control.Monad.Eff.Exception (error) -import Data.Array ((!!)) +import Data.Array ((!!), concat) import Data.Function (Fn2(), mkFn2) import Data.Maybe (Maybe(..), fromMaybe, maybe) +import Data.String (joinWith) import Data.String.Regex (match, noFlags, regex) import PursLoader.ChildProcess (ChildProcess(), spawn) +import PursLoader.FS (FS(), writeFileUtf8) +import PursLoader.Glob (Glob(), globAll) import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query) -import PursLoader.LoaderUtil (getRemainingRequest, parseQuery) -import PursLoader.Options (loaderSrcOption, pscOptions) +import PursLoader.LoaderUtil (parseQuery) +import PursLoader.Options (loaderFFIOption, loaderSrcOption, pscOptions) -type Effects eff = (loader :: Loader, cp :: ChildProcess | eff) +type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader | eff) moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true } pscCommand = "psc" +psciCommand = "psci" + +psciFilename = ".psci" + (!!!) = flip (!!) +foreign import cwd "var cwd = process.cwd();" :: String + +foreign import relative """ +function relative(from) { + return function(to){ + var path = require('path'); + return path.relative(from, to); + }; +} +""" :: String -> String -> String + +mkPsci :: [[String]] -> [[String]] -> String +mkPsci srcs ffis = joinWith "\n" ((loadModule <$> concat srcs) <> (loadForeign <$> concat ffis)) + where + loadModule :: String -> String + loadModule a = ":m " ++ relative cwd a + + loadForeign :: String -> String + loadForeign a = ":f " ++ relative cwd a + loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String) loader' ref source = do liftEff $ cacheable ref - let request = getRemainingRequest ref - parsed = parseQuery $ query ref + let parsed = parseQuery $ query ref srcs = fromMaybe [] (loaderSrcOption parsed) + ffis = fromMaybe [] (loaderFFIOption parsed) opts = pscOptions parsed - moduleName = match moduleRegex source >>= (!!!) 1 - result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName spawn pscCommand (srcs <> opts) + + srcss <- globAll srcs + ffiss <- globAll ffis + + let psciFile = mkPsci srcss ffiss + + writeFileUtf8 psciFilename psciFile + + let moduleName = match moduleRegex source >>= (!!!) 1 + result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName + return result loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit diff --git a/src/LoaderUtil.purs b/src/LoaderUtil.purs index f22be44..86be124 100644 --- a/src/LoaderUtil.purs +++ b/src/LoaderUtil.purs @@ -1,18 +1,11 @@ module PursLoader.LoaderUtil - ( getRemainingRequest - , parseQuery + ( parseQuery ) where import Data.Foreign (Foreign()) import PursLoader.LoaderRef (LoaderRef()) -foreign import getRemainingRequest """ -function getRemainingRequest(ref){ - var loaderUtils = require('loader-utils'); - return loaderUtils.getRemainingRequest(ref); -}""" :: LoaderRef -> String - foreign import parseQuery """ function parseQuery(query){ var loaderUtils = require('loader-utils'); diff --git a/src/Options.purs b/src/Options.purs index be21877..51e9be5 100644 --- a/src/Options.purs +++ b/src/Options.purs @@ -1,6 +1,7 @@ module PursLoader.Options ( pscOptions , loaderSrcOption + , loaderFFIOption ) where import Data.Array (concat) @@ -101,3 +102,6 @@ pscOptions query = either (const []) fold parsed loaderSrcOption :: Foreign -> Maybe [String] loaderSrcOption query = either (const Nothing) (\(Options a) -> runNullOrUndefined a.src) (read query) + +loaderFFIOption :: Foreign -> Maybe [String] +loaderFFIOption query = either (const Nothing) (\(Options a) -> runNullOrUndefined a.ffi) (read query) diff --git a/webpack.config.js b/webpack.config.js index 11b9069..a39832f 100644 --- a/webpack.config.js +++ b/webpack.config.js @@ -4,6 +4,8 @@ var path = require('path'); var webpack = require('webpack'); +var packageJson = require('./package.json'); + var noErrorsPlugin = webpack.NoErrorsPlugin; var dedupePlugin = webpack.optimize.DedupePlugin; @@ -12,9 +14,10 @@ var config = { cache: true , target: 'node' , entry: { index: './entry' } - , externals: { 'glob': 'commonjs glob' - , 'loader-utils': 'commonjs loader-utils' - } + , externals: Object.keys(packageJson.dependencies).reduce(function(b, a){ + b[a] = 'commonjs ' + a; + return b; + }, {}) , output: { path: __dirname , filename: '[name].js' , libraryTarget: 'commonjs2' -- 2.41.0