aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--README.md4
-rw-r--r--package.json1
-rw-r--r--src/FS.purs32
-rw-r--r--src/Glob.purs33
-rw-r--r--src/Loader.purs52
-rw-r--r--src/LoaderUtil.purs9
-rw-r--r--src/Options.purs4
-rw-r--r--webpack.config.js9
8 files changed, 125 insertions, 19 deletions
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;
99``` 99```
100 100
101See the [example](https://github.com/ethul/purs-loader/tree/master/example) directory for a complete example. 101See the [example](https://github.com/ethul/purs-loader/tree/master/example) directory for a complete example.
102
103## Notes
104
105A `.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 @@
28 "webpack": "^1.8.4" 28 "webpack": "^1.8.4"
29 }, 29 },
30 "dependencies": { 30 "dependencies": {
31 "async": "^1.3.0",
31 "glob": "^5.0.3", 32 "glob": "^5.0.3",
32 "loader-utils": "^0.2.6" 33 "loader-utils": "^0.2.6"
33 } 34 }
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 @@
1module PursLoader.FS
2 ( FS()
3 , writeFileUtf8
4 ) where
5
6import Control.Monad.Aff (Aff(), makeAff)
7import Control.Monad.Eff (Eff())
8import Control.Monad.Eff.Exception (Error())
9
10import Data.Function
11
12foreign import data FS :: !
13
14writeFileUtf8 :: forall eff. String -> String -> Aff (fs :: FS | eff) Unit
15writeFileUtf8 filepath contents = makeAff $ runFn4 writeFileUtf8Fn filepath contents
16
17foreign import writeFileUtf8Fn """
18function writeFileUtf8Fn(filepath, contents, errback, callback) {
19 return function(){
20 var fs = require('fs');
21
22 fs.writeFile(filepath, contents, function(error){
23 if (error) errback(error)();
24 else callback()();
25 });
26 };
27}
28""" :: forall eff. Fn4 String
29 String
30 (Error -> Eff (fs :: FS | eff) Unit)
31 (Unit -> Eff (fs :: FS | eff) Unit)
32 (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 @@
1module PursLoader.Glob
2 ( Glob()
3 , globAll
4 ) where
5
6import Control.Monad.Aff (Aff(), makeAff)
7import Control.Monad.Eff (Eff())
8import Control.Monad.Eff.Exception (Error())
9
10import Data.Function
11
12foreign import data Glob :: !
13
14globAll :: forall eff. [String] -> Aff (glob :: Glob | eff) [[String]]
15globAll patterns = makeAff $ runFn3 globAllFn patterns
16
17foreign import globAllFn """
18function globAllFn(patterns, errback, callback) {
19 return function(){
20 var glob = require('glob');
21
22 var async = require('async');
23
24 async.map(patterns, glob, function(error, result){
25 if (error) errback(new Error(error))();
26 else callback(result)();
27 });
28 };
29}
30""" :: forall eff. Fn3 [String]
31 (Error -> Eff (glob :: Glob | eff) Unit)
32 ([[String]] -> Eff (glob :: Glob | eff) Unit)
33 (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())
9import Control.Monad.Eff.Class (liftEff) 9import Control.Monad.Eff.Class (liftEff)
10import Control.Monad.Eff.Exception (error) 10import Control.Monad.Eff.Exception (error)
11 11
12import Data.Array ((!!)) 12import Data.Array ((!!), concat)
13import Data.Function (Fn2(), mkFn2) 13import Data.Function (Fn2(), mkFn2)
14import Data.Maybe (Maybe(..), fromMaybe, maybe) 14import Data.Maybe (Maybe(..), fromMaybe, maybe)
15import Data.String (joinWith)
15import Data.String.Regex (match, noFlags, regex) 16import Data.String.Regex (match, noFlags, regex)
16 17
17import PursLoader.ChildProcess (ChildProcess(), spawn) 18import PursLoader.ChildProcess (ChildProcess(), spawn)
19import PursLoader.FS (FS(), writeFileUtf8)
20import PursLoader.Glob (Glob(), globAll)
18import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query) 21import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query)
19import PursLoader.LoaderUtil (getRemainingRequest, parseQuery) 22import PursLoader.LoaderUtil (parseQuery)
20import PursLoader.Options (loaderSrcOption, pscOptions) 23import PursLoader.Options (loaderFFIOption, loaderSrcOption, pscOptions)
21 24
22type Effects eff = (loader :: Loader, cp :: ChildProcess | eff) 25type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader | eff)
23 26
24moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true } 27moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
25 28
26pscCommand = "psc" 29pscCommand = "psc"
27 30
31psciCommand = "psci"
32
33psciFilename = ".psci"
34
28(!!!) = flip (!!) 35(!!!) = flip (!!)
29 36
37foreign import cwd "var cwd = process.cwd();" :: String
38
39foreign import relative """
40function relative(from) {
41 return function(to){
42 var path = require('path');
43 return path.relative(from, to);
44 };
45}
46""" :: String -> String -> String
47
48mkPsci :: [[String]] -> [[String]] -> String
49mkPsci srcs ffis = joinWith "\n" ((loadModule <$> concat srcs) <> (loadForeign <$> concat ffis))
50 where
51 loadModule :: String -> String
52 loadModule a = ":m " ++ relative cwd a
53
54 loadForeign :: String -> String
55 loadForeign a = ":f " ++ relative cwd a
56
30loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String) 57loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String)
31loader' ref source = do 58loader' ref source = do
32 liftEff $ cacheable ref 59 liftEff $ cacheable ref
33 60
34 let request = getRemainingRequest ref 61 let parsed = parseQuery $ query ref
35 parsed = parseQuery $ query ref
36 srcs = fromMaybe [] (loaderSrcOption parsed) 62 srcs = fromMaybe [] (loaderSrcOption parsed)
63 ffis = fromMaybe [] (loaderFFIOption parsed)
37 opts = pscOptions parsed 64 opts = pscOptions parsed
38 moduleName = match moduleRegex source >>= (!!!) 1
39 result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName
40 65
41 spawn pscCommand (srcs <> opts) 66 spawn pscCommand (srcs <> opts)
67
68 srcss <- globAll srcs
69 ffiss <- globAll ffis
70
71 let psciFile = mkPsci srcss ffiss
72
73 writeFileUtf8 psciFilename psciFile
74
75 let moduleName = match moduleRegex source >>= (!!!) 1
76 result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName
77
42 return result 78 return result
43 79
44loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit 80loader :: 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 @@
1module PursLoader.LoaderUtil 1module PursLoader.LoaderUtil
2 ( getRemainingRequest 2 ( parseQuery
3 , parseQuery
4 ) where 3 ) where
5 4
6import Data.Foreign (Foreign()) 5import Data.Foreign (Foreign())
7 6
8import PursLoader.LoaderRef (LoaderRef()) 7import PursLoader.LoaderRef (LoaderRef())
9 8
10foreign import getRemainingRequest """
11function getRemainingRequest(ref){
12 var loaderUtils = require('loader-utils');
13 return loaderUtils.getRemainingRequest(ref);
14}""" :: LoaderRef -> String
15
16foreign import parseQuery """ 9foreign import parseQuery """
17function parseQuery(query){ 10function parseQuery(query){
18 var loaderUtils = require('loader-utils'); 11 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 @@
1module PursLoader.Options 1module PursLoader.Options
2 ( pscOptions 2 ( pscOptions
3 , loaderSrcOption 3 , loaderSrcOption
4 , loaderFFIOption
4 ) where 5 ) where
5 6
6import Data.Array (concat) 7import Data.Array (concat)
@@ -101,3 +102,6 @@ pscOptions query = either (const []) fold parsed
101 102
102loaderSrcOption :: Foreign -> Maybe [String] 103loaderSrcOption :: Foreign -> Maybe [String]
103loaderSrcOption query = either (const Nothing) (\(Options a) -> runNullOrUndefined a.src) (read query) 104loaderSrcOption query = either (const Nothing) (\(Options a) -> runNullOrUndefined a.src) (read query)
105
106loaderFFIOption :: Foreign -> Maybe [String]
107loaderFFIOption 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');
4 4
5var webpack = require('webpack'); 5var webpack = require('webpack');
6 6
7var packageJson = require('./package.json');
8
7var noErrorsPlugin = webpack.NoErrorsPlugin; 9var noErrorsPlugin = webpack.NoErrorsPlugin;
8 10
9var dedupePlugin = webpack.optimize.DedupePlugin; 11var dedupePlugin = webpack.optimize.DedupePlugin;
@@ -12,9 +14,10 @@ var config
12 = { cache: true 14 = { cache: true
13 , target: 'node' 15 , target: 'node'
14 , entry: { index: './entry' } 16 , entry: { index: './entry' }
15 , externals: { 'glob': 'commonjs glob' 17 , externals: Object.keys(packageJson.dependencies).reduce(function(b, a){
16 , 'loader-utils': 'commonjs loader-utils' 18 b[a] = 'commonjs ' + a;
17 } 19 return b;
20 }, {})
18 , output: { path: __dirname 21 , output: { path: __dirname
19 , filename: '[name].js' 22 , filename: '[name].js'
20 , libraryTarget: 'commonjs2' 23 , libraryTarget: 'commonjs2'