aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authoreric <thul.eric@gmail.com>2015-07-06 23:58:28 -0400
committereric <thul.eric@gmail.com>2015-07-06 23:58:28 -0400
commit1d771135e825feaa1fba5177b60796578766b240 (patch)
treea063817b17ee2df146228cf66c4205c2d80f05be
parent4558c6cf7879207166b1cc013e2e8112f558bb1d (diff)
parent167c852f657b4746331c4f89e358a4a4876ced78 (diff)
downloadpurs-loader-1d771135e825feaa1fba5177b60796578766b240.tar.gz
purs-loader-1d771135e825feaa1fba5177b60796578766b240.tar.zst
purs-loader-1d771135e825feaa1fba5177b60796578766b240.zip
Merge pull request #16 from ethul/topic/issue-11-and-14
Topic/issue 11 and 14
-rw-r--r--MODULE.md97
-rw-r--r--README.md54
-rw-r--r--example/README.md2
-rw-r--r--example/bower.json2
-rw-r--r--example/package.json2
-rw-r--r--example/src/Foo.purs5
-rw-r--r--example/src/Foo/Bar.purs2
-rw-r--r--example/src/Test.purs2
-rw-r--r--example/src/entry.js6
-rw-r--r--example/webpack.config.js21
-rw-r--r--package.json1
-rw-r--r--src/FS.purs35
-rw-r--r--src/Glob.purs22
-rw-r--r--src/Loader.purs126
-rw-r--r--src/LoaderRef.purs25
-rw-r--r--src/LoaderUtil.purs9
-rw-r--r--src/OS.purs3
-rw-r--r--src/Options.purs50
-rw-r--r--src/Path.purs36
-rw-r--r--webpack.config.js9
20 files changed, 206 insertions, 303 deletions
diff --git a/MODULE.md b/MODULE.md
index 2d54719..45f6cca 100644
--- a/MODULE.md
+++ b/MODULE.md
@@ -26,17 +26,10 @@ data FS :: !
26``` 26```
27 27
28 28
29#### `readFileUtf8` 29#### `writeFileUtf8`
30 30
31``` purescript 31``` purescript
32readFileUtf8 :: forall eff. String -> Aff (fs :: FS | eff) String 32writeFileUtf8 :: forall eff. String -> String -> Aff (fs :: FS | eff) Unit
33```
34
35
36#### `readFileUtf8Sync`
37
38``` purescript
39readFileUtf8Sync :: forall eff. String -> Eff (fs :: FS | eff) String
40``` 33```
41 34
42 35
@@ -50,34 +43,34 @@ data Glob :: !
50``` 43```
51 44
52 45
53#### `glob` 46#### `globAll`
54 47
55``` purescript 48``` purescript
56glob :: forall eff. String -> Aff (glob :: Glob | eff) [String] 49globAll :: forall eff. [String] -> Aff (glob :: Glob | eff) [[String]]
57``` 50```
58 51
59 52
60 53
61## Module PursLoader.Loader 54## Module PursLoader.Loader
62 55
63#### `LoaderEff` 56#### `Effects`
64 57
65``` purescript 58``` purescript
66type LoaderEff eff a = Eff (fs :: FS, cp :: ChildProcess, glob :: Glob, loader :: Loader | eff) a 59type Effects eff = (loader :: Loader, glob :: Glob, fs :: FS, cp :: ChildProcess | eff)
67``` 60```
68 61
69 62
70#### `loader` 63#### `loader`
71 64
72``` purescript 65``` purescript
73loader :: forall eff. LoaderRef -> String -> LoaderEff eff Unit 66loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
74``` 67```
75 68
76 69
77#### `loaderFn` 70#### `loaderFn`
78 71
79``` purescript 72``` purescript
80loaderFn :: forall eff. Fn2 LoaderRef String (LoaderEff eff Unit) 73loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
81``` 74```
82 75
83 76
@@ -112,27 +105,6 @@ cacheable :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit
112``` 105```
113 106
114 107
115#### `clearDependencies`
116
117``` purescript
118clearDependencies :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit
119```
120
121
122#### `resourcePath`
123
124``` purescript
125resourcePath :: LoaderRef -> String
126```
127
128
129#### `addDependency`
130
131``` purescript
132addDependency :: forall eff. LoaderRef -> String -> Eff (loader :: Loader | eff) Unit
133```
134
135
136#### `query` 108#### `query`
137 109
138``` purescript 110``` purescript
@@ -143,13 +115,6 @@ query :: LoaderRef -> String
143 115
144## Module PursLoader.LoaderUtil 116## Module PursLoader.LoaderUtil
145 117
146#### `getRemainingRequest`
147
148``` purescript
149getRemainingRequest :: LoaderRef -> String
150```
151
152
153#### `parseQuery` 118#### `parseQuery`
154 119
155``` purescript 120``` purescript
@@ -158,16 +123,6 @@ parseQuery :: String -> Foreign
158 123
159 124
160 125
161## Module PursLoader.OS
162
163#### `eol`
164
165``` purescript
166eol :: String
167```
168
169
170
171## Module PursLoader.Options 126## Module PursLoader.Options
172 127
173#### `isForeignOptions` 128#### `isForeignOptions`
@@ -191,17 +146,17 @@ instance stringLoaderOption :: LoaderOption String
191``` 146```
192 147
193 148
194#### `pscMakeOutputOption` 149#### `arrayLoaderOption`
195 150
196``` purescript 151``` purescript
197pscMakeOutputOption :: Foreign -> Maybe String 152instance arrayLoaderOption :: (LoaderOption a) => LoaderOption [a]
198``` 153```
199 154
200 155
201#### `pscMakeOptions` 156#### `pscOptions`
202 157
203``` purescript 158``` purescript
204pscMakeOptions :: Foreign -> [String] 159pscOptions :: Foreign -> [String]
205``` 160```
206 161
207 162
@@ -212,34 +167,10 @@ loaderSrcOption :: Foreign -> Maybe [String]
212``` 167```
213 168
214 169
215 170#### `loaderFFIOption`
216## Module PursLoader.Path
217
218#### `dirname`
219
220``` purescript
221dirname :: String -> String
222```
223
224
225#### `join`
226
227``` purescript
228join :: [String] -> String
229```
230
231
232#### `relative`
233
234``` purescript
235relative :: String -> String -> String
236```
237
238
239#### `resolve`
240 171
241``` purescript 172``` purescript
242resolve :: String -> String 173loaderFFIOption :: Foreign -> Maybe [String]
243``` 174```
244 175
245 176
diff --git a/README.md b/README.md
index d243381..a45573f 100644
--- a/README.md
+++ b/README.md
@@ -44,10 +44,62 @@ Sets `--output=<string>` the specifies the output directory, `output` by default
44 44
45Toggles `--no-prefix` that does not include the comment header. 45Toggles `--no-prefix` that does not include the comment header.
46 46
47###### `requirePath` (String)
48
49Sets `--require-path=<string>` that specifies the path prefix to use for `require()` calls in the generated JavaScript.
50
51###### `ffi` (String Array)
52
53Specifies the PureScript FFI files setting `--ffi=<string>`. Glob syntax is supported. This option is specified as `ffi[]=path`.
54
47###### `src` (String Array) 55###### `src` (String Array)
48 56
49Specifies PureScript source paths to be globbed for `.purs` files. By default, `bower_components` is search. Additional paths may be specified using this option. This option is specified as `src[]=path`. 57Specifies the PureScript source files. Glob syntax is supported. This option is specified as `src[]=path`.
50 58
51## Example 59## Example
52 60
61```js
62// webpack.config.js
63
64var path = require('path');
65
66var srcs = ['src[]=bower_components/purescript-*/src/**/*.purs', 'src[]=src/**/*.purs'];
67
68var ffis = ['ffi[]=bower_components/purescript-*/src/**/*.js'];
69
70var output = 'output';
71
72var modulesDirectories = [
73 'node_modules',
74 // The bower component for purescript-prelude is specified here to
75 // allow JavaScript files to require the 'Prelude' module globally.
76 'bower_components/purescript-prelude/src',
77 // The output directory is specified here to allow PureScript files in
78 // your source to import other PureScript modules in your source.
79 output
80];
81
82var config
83 = { entry: './src/entry'
84 , output: { path: __dirname
85 , pathinfo: true
86 , filename: 'bundle.js'
87 }
88 , module: { loaders: [ { test: /\.purs$/
89 , loader: 'purs-loader?output=' + output + '&' + srcs.concat(ffis).join('&')
90 } ] }
91 , resolve: { modulesDirectories: modulesDirectories
92 , extensions: ['', '.js', '.purs']
93 }
94 , resolveLoader: { root: path.join(__dirname, 'node_modules') }
95 }
96 ;
97
98module.exports = config;
99```
100
53See 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/example/README.md b/example/README.md
index 87b9bc7..bac4f6c 100644
--- a/example/README.md
+++ b/example/README.md
@@ -1,6 +1,6 @@
1```bash 1```bash
2bower install 2bower install
3npm install 3npm install
4npm run-script webpack 4npm run-script build
5npm run-script run 5npm run-script run
6``` 6```
diff --git a/example/bower.json b/example/bower.json
index b4a1c78..c83e735 100644
--- a/example/bower.json
+++ b/example/bower.json
@@ -2,6 +2,6 @@
2 "name": "example", 2 "name": "example",
3 "private": true, 3 "private": true,
4 "devDependencies": { 4 "devDependencies": {
5 "purescript-maybe": "~0.2.1" 5 "purescript-prelude": "~0.1.0"
6 } 6 }
7} 7}
diff --git a/example/package.json b/example/package.json
index 915eb27..df3e74f 100644
--- a/example/package.json
+++ b/example/package.json
@@ -3,7 +3,7 @@
3 "version": "0.0.0", 3 "version": "0.0.0",
4 "private": true, 4 "private": true,
5 "scripts": { 5 "scripts": {
6 "webpack": "./node_modules/.bin/webpack", 6 "build": "mkdir -p output && ./node_modules/.bin/webpack",
7 "run": "node bundle.js", 7 "run": "node bundle.js",
8 "clean": "rm -rf bower_components && rm -rf bundle.js && rm -rf node_modules && rm -rf output" 8 "clean": "rm -rf bower_components && rm -rf bundle.js && rm -rf node_modules && rm -rf output"
9 }, 9 },
diff --git a/example/src/Foo.purs b/example/src/Foo.purs
index 3e3a04c..b234e0d 100644
--- a/example/src/Foo.purs
+++ b/example/src/Foo.purs
@@ -1,6 +1,9 @@
1module Foo (foo) where 1module Foo (foo) where
2 2
3import Data.Maybe 3import Prelude
4
4import qualified Foo.Bar as B 5import qualified Foo.Bar as B
5 6
6foo = "b" 7foo = "b"
8
9foo' = "c"
diff --git a/example/src/Foo/Bar.purs b/example/src/Foo/Bar.purs
index 4ae100d..6932902 100644
--- a/example/src/Foo/Bar.purs
+++ b/example/src/Foo/Bar.purs
@@ -1,3 +1,5 @@
1module Foo.Bar (bar) where 1module Foo.Bar (bar) where
2 2
3bar = "c" 3bar = "c"
4
5bar' = "d"
diff --git a/example/src/Test.purs b/example/src/Test.purs
index 8a5cb88..d9f1b96 100644
--- a/example/src/Test.purs
+++ b/example/src/Test.purs
@@ -1,5 +1,5 @@
1module Test (test) where 1module Test (test) where
2 2
3import Data.Maybe 3import Prelude
4 4
5test = "a" 5test = "a"
diff --git a/example/src/entry.js b/example/src/entry.js
index cc09034..344d4c6 100644
--- a/example/src/entry.js
+++ b/example/src/entry.js
@@ -1,7 +1,11 @@
1var Prelude = require('Prelude');
2
1var test = require('./Test'); 3var test = require('./Test');
2 4
3var foo = require('./Foo'); 5var foo = require('./Foo');
4 6
5var baz = require('./Foo/Baz'); 7var baz = require('./Foo/Baz');
6 8
7console.log(test, foo, baz); 9var bar = require('./Foo/Bar');
10
11console.log(Prelude, test, foo, baz, bar);
diff --git a/example/webpack.config.js b/example/webpack.config.js
index f67e83a..9294904 100644
--- a/example/webpack.config.js
+++ b/example/webpack.config.js
@@ -1,14 +1,27 @@
1var path = require('path'); 1var path = require('path');
2 2
3var srcs = ['src[]=bower_components/purescript-*/src/**/*.purs', 'src[]=src/**/*.purs'];
4
5var ffis = ['ffi[]=bower_components/purescript-*/src/**/*.js'];
6
7var output = 'output';
8
9var modulesDirectories = [
10 'node_modules',
11 'bower_components/purescript-prelude/src',
12 output
13];
14
3var config 15var config
4 = { entry: './src/entry' 16 = { entry: './src/entry'
5 , output: { path: __dirname 17 , output: { path: __dirname
18 , pathinfo: true
6 , filename: 'bundle.js' 19 , filename: 'bundle.js'
7 } 20 }
8 , module: { loaders: [ { test: /\.purs$/, loader: 'purs-loader?src[]=src' } ] } 21 , module: { loaders: [ { test: /\.purs$/
9 , resolve: { modulesDirectories: [ 'node_modules', 22 , loader: 'purs-loader?output=' + output + '&' + srcs.concat(ffis).join('&')
10 'output' 23 } ] }
11 ] 24 , resolve: { modulesDirectories: modulesDirectories
12 , extensions: ['', '.js', '.purs'] 25 , extensions: ['', '.js', '.purs']
13 } 26 }
14 , resolveLoader: { root: path.join(__dirname, 'node_modules') } 27 , resolveLoader: { root: path.join(__dirname, 'node_modules') }
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
index 68fe2f9..a56fe26 100644
--- a/src/FS.purs
+++ b/src/FS.purs
@@ -1,7 +1,6 @@
1module PursLoader.FS 1module PursLoader.FS
2 ( FS() 2 ( FS()
3 , readFileUtf8 3 , writeFileUtf8
4 , readFileUtf8Sync
5 ) where 4 ) where
6 5
7import Control.Monad.Aff (Aff(), makeAff) 6import Control.Monad.Aff (Aff(), makeAff)
@@ -12,34 +11,22 @@ import Data.Function
12 11
13foreign import data FS :: ! 12foreign import data FS :: !
14 13
15readFileUtf8 :: forall eff. String -> Aff (fs :: FS | eff) String 14writeFileUtf8 :: forall eff. String -> String -> Aff (fs :: FS | eff) Unit
16readFileUtf8 filepath = makeAff $ runFn3 readFileUtf8Fn filepath 15writeFileUtf8 filepath contents = makeAff $ runFn4 writeFileUtf8Fn filepath contents
17 16
18readFileUtf8Sync :: forall eff. String -> Eff (fs :: FS | eff) String 17foreign import writeFileUtf8Fn """
19readFileUtf8Sync filepath = readFileUtf8SyncFn filepath 18function writeFileUtf8Fn(filepath, contents, errback, callback) {
20
21foreign import readFileUtf8Fn """
22function readFileUtf8Fn(filepath, errback, callback) {
23 return function(){ 19 return function(){
24 var fs = require('fs'); 20 var fs = require('fs');
25 21
26 fs.readFile(filepath, 'utf-8', function(e, data){ 22 fs.writeFile(filepath, contents, function(error){
27 if (e) errback(e)(); 23 if (error) errback(error)();
28 else callback(data)(); 24 else callback()();
29 }); 25 });
30 }; 26 };
31} 27}
32""" :: forall eff. Fn3 String 28""" :: forall eff. Fn4 String
29 String
33 (Error -> Eff (fs :: FS | eff) Unit) 30 (Error -> Eff (fs :: FS | eff) Unit)
34 (String -> Eff (fs :: FS | eff) Unit) 31 (Unit -> Eff (fs :: FS | eff) Unit)
35 (Eff (fs :: FS | eff) Unit) 32 (Eff (fs :: FS | eff) Unit)
36
37foreign import readFileUtf8SyncFn """
38function readFileUtf8SyncFn(filepath) {
39 return function(){
40 var fs = require('fs');
41
42 return fs.readFileSync(filepath, {encoding: 'utf-8'});
43 };
44}
45""" :: forall eff. String -> (Eff (fs :: FS | eff) String)
diff --git a/src/Glob.purs b/src/Glob.purs
index 7bc9212..392d9e4 100644
--- a/src/Glob.purs
+++ b/src/Glob.purs
@@ -1,6 +1,6 @@
1module PursLoader.Glob 1module PursLoader.Glob
2 ( Glob() 2 ( Glob()
3 , glob 3 , globAll
4 ) where 4 ) where
5 5
6import Control.Monad.Aff (Aff(), makeAff) 6import Control.Monad.Aff (Aff(), makeAff)
@@ -11,21 +11,23 @@ import Data.Function
11 11
12foreign import data Glob :: ! 12foreign import data Glob :: !
13 13
14glob :: forall eff. String -> Aff (glob :: Glob | eff) [String] 14globAll :: forall eff. [String] -> Aff (glob :: Glob | eff) [[String]]
15glob pattern = makeAff $ runFn3 globFn pattern 15globAll patterns = makeAff $ runFn3 globAllFn patterns
16 16
17foreign import globFn """ 17foreign import globAllFn """
18function globFn(pattern, errback, callback) { 18function globAllFn(patterns, errback, callback) {
19 return function(){ 19 return function(){
20 var glob = require('glob'); 20 var glob = require('glob');
21 21
22 glob(pattern, function(e, data){ 22 var async = require('async');
23 if (e) errback(e)(); 23
24 else callback(data)(); 24 async.map(patterns, glob, function(error, result){
25 if (error) errback(new Error(error))();
26 else callback(result)();
25 }); 27 });
26 }; 28 };
27} 29}
28""" :: forall eff. Fn3 String 30""" :: forall eff. Fn3 [String]
29 (Error -> Eff (glob :: Glob | eff) Unit) 31 (Error -> Eff (glob :: Glob | eff) Unit)
30 ([String] -> Eff (glob :: Glob | eff) Unit) 32 ([[String]] -> Eff (glob :: Glob | eff) Unit)
31 (Eff (glob :: Glob | eff) Unit) 33 (Eff (glob :: Glob | eff) Unit)
diff --git a/src/Loader.purs b/src/Loader.purs
index fedc424..872a51c 100644
--- a/src/Loader.purs
+++ b/src/Loader.purs
@@ -1,5 +1,5 @@
1module PursLoader.Loader 1module PursLoader.Loader
2 ( LoaderEff() 2 ( Effects()
3 , loader 3 , loader
4 , loaderFn 4 , loaderFn
5 ) where 5 ) where
@@ -9,113 +9,81 @@ 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 ((!!), catMaybes, concat, filter, null) 12import Data.Array ((!!), concat)
13import Data.Foldable (foldl)
14import Data.Function (Fn2(), mkFn2) 13import Data.Function (Fn2(), mkFn2)
15import Data.Maybe (Maybe(..), fromMaybe, maybe) 14import Data.Maybe (Maybe(..), fromMaybe, maybe)
16import Data.Set (Set(), empty, insert, member, toList, unions) 15import Data.String (joinWith)
17import Data.String (joinWith, split) 16import Data.String.Regex (match, noFlags, regex)
18import Data.String.Regex (Regex(), match, noFlags, regex)
19import Data.StrMap (StrMap(), fromList, lookup)
20import Data.Traversable (sequence)
21import Data.Tuple.Nested (tuple2)
22 17
23import PursLoader.ChildProcess (ChildProcess(), spawn) 18import PursLoader.ChildProcess (ChildProcess(), spawn)
24import PursLoader.FS (FS(), readFileUtf8, readFileUtf8Sync) 19import PursLoader.FS (FS(), writeFileUtf8)
25import PursLoader.Glob (Glob(), glob) 20import PursLoader.Glob (Glob(), globAll)
26import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, clearDependencies, addDependency, query, resourcePath) 21import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query)
27import PursLoader.LoaderUtil (getRemainingRequest, parseQuery) 22import PursLoader.LoaderUtil (parseQuery)
28import PursLoader.OS (eol) 23import PursLoader.Options (loaderFFIOption, loaderSrcOption, pscOptions)
29import PursLoader.Options (loaderSrcOption, pscMakeOptions, pscMakeDefaultOutput, pscMakeOutputOption)
30import PursLoader.Path (dirname, join, relative, resolve)
31 24
32foreign import cwd "var cwd = process.cwd();" :: String 25type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader | eff)
33 26
34moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true } 27moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
35 28
36importRegex = regex "^\\s*import\\s+(?:qualified\\s+)?([\\w\\.]+)" noFlags { ignoreCase = true } 29pscCommand = "psc"
37
38bowerPattern = join [ "bower_components", "purescript-*", "src" ]
39 30
40pscMakeCommand = "psc-make" 31psciCommand = "psci"
41 32
42indexFilename = "index.js" 33psciFilename = ".psci"
43 34
44(!!!) = flip (!!) 35(!!!) = flip (!!)
45 36
46pursPattern :: [String] -> String 37foreign import cwd "var cwd = process.cwd();" :: String
47pursPattern srcs = join [ "{" ++ joinWith "," ([ bowerPattern ] <> srcs) ++ "}"
48 , "**"
49 , "*.purs"
50 ]
51
52type GraphModule = { file :: String, imports :: [String] }
53 38
54type Graph = StrMap GraphModule 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
55 53
56mkGraph :: forall eff. [String] -> Eff (fs :: FS | eff) Graph 54 loadForeign :: String -> String
57mkGraph files = (fromList <<< catMaybes) <$> sequence (parse <$> files) 55 loadForeign a = ":f " ++ relative cwd a
58 where parse file = do source <- readFileUtf8Sync file
59 let key = match moduleRegex source >>= (!!!) 1
60 lines = split eol source
61 imports = catMaybes $ (\a -> match importRegex a >>= (!!!) 1) <$> lines
62 return $ (\a -> tuple2 a { file: file, imports: imports }) <$> key
63 56
64mkDeps :: forall eff. String -> Graph -> [String] 57loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String)
65mkDeps key graph = toList $ go empty key
66 where
67 go :: Set String -> String -> Set String
68 go acc key =
69 let node = fromMaybe {file: "", imports: []} (lookup key graph)
70 uniq = filter (not <<< flip member acc) node.imports
71 acc' = foldl (flip insert) acc node.imports
72 in if null uniq
73 then acc'
74 else unions $ go acc' <$> uniq
75
76addDeps :: forall eff. LoaderRef -> Graph -> [String] -> Eff (loader :: Loader | eff) Unit
77addDeps ref graph deps = const unit <$> (sequence $ add <$> deps)
78 where add dep = let res = lookup dep graph
79 path = (\a -> resolve a.file) <$> res
80 in maybe (pure unit) (addDependency ref) path
81
82type LoaderAff eff a = Aff (loader :: Loader, glob :: Glob, cp :: ChildProcess, fs :: FS | eff) a
83
84loader' :: forall eff. LoaderRef -> String -> LoaderAff eff (Maybe String)
85loader' ref source = do 58loader' ref source = do
86 liftEff $ cacheable ref 59 liftEff $ cacheable ref
87 60
88 let request = getRemainingRequest ref 61 let parsed = parseQuery $ query ref
89 parsed = parseQuery $ query ref 62 srcs = fromMaybe [] (loaderSrcOption parsed)
90 srcs = loaderSrcOption parsed 63 ffis = fromMaybe [] (loaderFFIOption parsed)
91 opts = pscMakeOptions parsed 64 opts = pscOptions parsed
92 pattern = pursPattern $ fromMaybe [] srcs 65
93 key = match moduleRegex source >>= (!!!) 1 66 spawn pscCommand (srcs <> opts)
94 67
95 files <- glob pattern 68 srcss <- globAll srcs
96 graph <- liftEff $ mkGraph files 69 ffiss <- globAll ffis
97 70
98 let deps = fromMaybe [] $ flip mkDeps graph <$> key 71 let psciFile = mkPsci srcss ffiss
99 outputPath = fromMaybe pscMakeDefaultOutput $ pscMakeOutputOption parsed
100 indexPath = (\a -> join [ outputPath, a, indexFilename ]) <$> key
101 72
102 liftEff $ clearDependencies ref 73 writeFileUtf8 psciFilename psciFile
103 liftEff $ addDependency ref (resourcePath ref)
104 liftEff $ addDeps ref graph deps
105 74
106 spawn pscMakeCommand (opts <> files) 75 let moduleName = match moduleRegex source >>= (!!!) 1
107 indexFile <- sequence $ readFileUtf8 <$> indexPath 76 result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName
108 return indexFile
109 77
110type LoaderEff eff a = Eff (loader :: Loader, glob :: Glob, cp :: ChildProcess, fs :: FS | eff) a 78 return result
111 79
112loader :: forall eff. LoaderRef -> String -> LoaderEff eff Unit 80loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
113loader ref source = do 81loader ref source = do
114 callback <- async ref 82 callback <- async ref
115 runAff (\e -> callback (Just e) "") 83 runAff (\e -> callback (Just e) "")
116 (maybe (callback (Just $ error "Loader has failed to run") "") 84 (maybe (callback (Just (error "Loader has failed to run")) "")
117 (callback Nothing)) 85 (callback Nothing))
118 (loader' ref source) 86 (loader' ref source)
119 87
120loaderFn :: forall eff. Fn2 LoaderRef String (LoaderEff eff Unit) 88loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
121loaderFn = mkFn2 loader 89loaderFn = mkFn2 loader
diff --git a/src/LoaderRef.purs b/src/LoaderRef.purs
index 2d62754..2567b1e 100644
--- a/src/LoaderRef.purs
+++ b/src/LoaderRef.purs
@@ -3,16 +3,12 @@ module PursLoader.LoaderRef
3 , Loader() 3 , Loader()
4 , async 4 , async
5 , cacheable 5 , cacheable
6 , clearDependencies
7 , resourcePath
8 , addDependency
9 , query 6 , query
10 ) where 7 ) where
11 8
12import Control.Monad.Eff (Eff()) 9import Control.Monad.Eff (Eff())
13import Control.Monad.Eff.Exception (Error()) 10import Control.Monad.Eff.Exception (Error())
14 11
15import Data.Foreign (Foreign())
16import Data.Function (Fn3(), runFn3) 12import Data.Function (Fn3(), runFn3)
17import Data.Maybe (Maybe(), fromMaybe, isJust) 13import Data.Maybe (Maybe(), fromMaybe, isJust)
18 14
@@ -48,27 +44,6 @@ function cacheable(ref){
48 }; 44 };
49}""" :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit 45}""" :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit
50 46
51foreign import clearDependencies """
52function clearDependencies(ref){
53 return function(){
54 return ref.clearDependencies();
55 };
56}""" :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit
57
58foreign import resourcePath """
59function resourcePath(ref){
60 return ref.resourcePath;
61}""" :: LoaderRef -> String
62
63foreign import addDependency """
64function addDependency(ref){
65 return function(dep){
66 return function(){
67 return ref.addDependency(dep);
68 };
69 };
70}""" :: forall eff. LoaderRef -> String -> Eff (loader :: Loader | eff) Unit
71
72foreign import query """ 47foreign import query """
73function query(ref){ 48function query(ref){
74 return ref.query; 49 return ref.query;
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/OS.purs b/src/OS.purs
deleted file mode 100644
index 590c3d6..0000000
--- a/src/OS.purs
+++ /dev/null
@@ -1,3 +0,0 @@
1module PursLoader.OS (eol) where
2
3foreign import eol "var eol = require('os').EOL;" :: String
diff --git a/src/Options.purs b/src/Options.purs
index c47bebc..51e9be5 100644
--- a/src/Options.purs
+++ b/src/Options.purs
@@ -1,17 +1,17 @@
1module PursLoader.Options 1module PursLoader.Options
2 ( pscMakeOptions 2 ( pscOptions
3 , pscMakeDefaultOutput
4 , pscMakeOutputOption
5 , loaderSrcOption 3 , loaderSrcOption
4 , loaderFFIOption
6 ) where 5 ) where
7 6
7import Data.Array (concat)
8import Data.Either (either) 8import Data.Either (either)
9 9
10import Data.Foreign (Foreign(), F()) 10import Data.Foreign (Foreign(), F())
11import Data.Foreign.Class (IsForeign, read, readProp) 11import Data.Foreign.Class (IsForeign, read, readProp)
12import Data.Foreign.NullOrUndefined (NullOrUndefined(), runNullOrUndefined) 12import Data.Foreign.NullOrUndefined (NullOrUndefined(..), runNullOrUndefined)
13 13
14import Data.Maybe (Maybe(..), maybe) 14import Data.Maybe (Maybe(..), maybe, fromMaybe)
15 15
16noPreludeOpt = "no-prelude" 16noPreludeOpt = "no-prelude"
17 17
@@ -29,9 +29,11 @@ commentsOpt = "comments"
29 29
30noPrefixOpt = "no-prefix" 30noPrefixOpt = "no-prefix"
31 31
32requirePathOpt = "require-path"
33
32srcOpt = "src" 34srcOpt = "src"
33 35
34pscMakeDefaultOutput = "output" 36ffiOpt = "ffi"
35 37
36newtype Options 38newtype Options
37 = Options { noPrelude :: NullOrUndefined Boolean 39 = Options { noPrelude :: NullOrUndefined Boolean
@@ -42,7 +44,9 @@ newtype Options
42 , comments :: NullOrUndefined Boolean 44 , comments :: NullOrUndefined Boolean
43 , output :: NullOrUndefined String 45 , output :: NullOrUndefined String
44 , noPrefix :: NullOrUndefined Boolean 46 , noPrefix :: NullOrUndefined Boolean
47 , requirePath :: NullOrUndefined String
45 , src :: NullOrUndefined [String] 48 , src :: NullOrUndefined [String]
49 , ffi :: NullOrUndefined [String]
46 } 50 }
47 51
48instance isForeignOptions :: IsForeign Options where 52instance isForeignOptions :: IsForeign Options where
@@ -54,7 +58,9 @@ instance isForeignOptions :: IsForeign Options where
54 , comments: _ 58 , comments: _
55 , output: _ 59 , output: _
56 , noPrefix: _ 60 , noPrefix: _
61 , requirePath: _
57 , src: _ 62 , src: _
63 , ffi: _
58 } <$> readProp noPreludeOpt obj 64 } <$> readProp noPreludeOpt obj
59 <*> readProp noOptsOpt obj 65 <*> readProp noOptsOpt obj
60 <*> readProp noMagicDoOpt obj 66 <*> readProp noMagicDoOpt obj
@@ -63,26 +69,25 @@ instance isForeignOptions :: IsForeign Options where
63 <*> readProp commentsOpt obj 69 <*> readProp commentsOpt obj
64 <*> readProp outputOpt obj 70 <*> readProp outputOpt obj
65 <*> readProp noPrefixOpt obj 71 <*> readProp noPrefixOpt obj
66 <*> readProp srcOpt obj) 72 <*> readProp requirePathOpt obj
73 <*> readProp srcOpt obj
74 <*> readProp ffiOpt obj)
67 75
68class LoaderOption a where 76class LoaderOption a where
69 opt :: String -> NullOrUndefined a -> [String] 77 opt :: String -> NullOrUndefined a -> [String]
70 78
71instance booleanLoaderOption :: LoaderOption Boolean where 79instance booleanLoaderOption :: LoaderOption Boolean where
72 opt key opt = maybe [] (\a -> if a then ["--" ++ key] else []) 80 opt key val = maybe [] (\a -> if a then ["--" ++ key] else []) (runNullOrUndefined val)
73 (runNullOrUndefined opt)
74 81
75instance stringLoaderOption :: LoaderOption String where 82instance stringLoaderOption :: LoaderOption String where
76 opt key opt = maybe [] (\a -> ["--" ++ key ++ "=" ++ a]) 83 opt key val = maybe [] (\a -> ["--" ++ key ++ "=" ++ a]) (runNullOrUndefined val)
77 (runNullOrUndefined opt)
78 84
79pscMakeOutputOption :: Foreign -> Maybe String 85instance arrayLoaderOption :: (LoaderOption a) => LoaderOption [a] where
80pscMakeOutputOption query = either (const Nothing) 86 opt key val = concat (opt key <$> (NullOrUndefined <<< Just)
81 (\(Options a) -> runNullOrUndefined a.output) 87 <$> (fromMaybe [] (runNullOrUndefined val)))
82 (read query)
83 88
84pscMakeOptions :: Foreign -> [String] 89pscOptions :: Foreign -> [String]
85pscMakeOptions query = either (const []) fold parsed 90pscOptions query = either (const []) fold parsed
86 where parsed = read query :: F Options 91 where parsed = read query :: F Options
87 fold (Options a) = opt noPreludeOpt a.noPrelude <> 92 fold (Options a) = opt noPreludeOpt a.noPrelude <>
88 opt noOptsOpt a.noOpts <> 93 opt noOptsOpt a.noOpts <>
@@ -91,9 +96,12 @@ pscMakeOptions query = either (const []) fold parsed
91 opt verboseErrorsOpt a.verboseErrors <> 96 opt verboseErrorsOpt a.verboseErrors <>
92 opt commentsOpt a.comments <> 97 opt commentsOpt a.comments <>
93 opt outputOpt a.output <> 98 opt outputOpt a.output <>
94 opt noPrefixOpt a.noPrefix 99 opt noPrefixOpt a.noPrefix <>
100 opt requirePathOpt a.requirePath <>
101 opt ffiOpt a.ffi
95 102
96loaderSrcOption :: Foreign -> Maybe [String] 103loaderSrcOption :: Foreign -> Maybe [String]
97loaderSrcOption query = either (const Nothing) 104loaderSrcOption query = either (const Nothing) (\(Options a) -> runNullOrUndefined a.src) (read query)
98 (\(Options a) -> runNullOrUndefined a.src) 105
99 (read query) 106loaderFFIOption :: Foreign -> Maybe [String]
107loaderFFIOption query = either (const Nothing) (\(Options a) -> runNullOrUndefined a.ffi) (read query)
diff --git a/src/Path.purs b/src/Path.purs
deleted file mode 100644
index e071e35..0000000
--- a/src/Path.purs
+++ /dev/null
@@ -1,36 +0,0 @@
1module PursLoader.Path
2 ( dirname
3 , join
4 , relative
5 , resolve
6 ) where
7
8foreign import dirname """
9function dirname(filepath) {
10 var path = require('path');
11 return path.dirname(filepath);
12}
13""" :: String -> String
14
15foreign import join """
16function join(parts) {
17 var path = require('path');
18 return path.join.apply(path, parts);
19}
20""" :: [String] -> String
21
22foreign import relative """
23function relative(from) {
24 return function(to){
25 var path = require('path');
26 return path.relative(from, to);
27 };
28}
29""" :: String -> String -> String
30
31foreign import resolve """
32function resolve(filepath) {
33 var path = require('path');
34 return path.resolve(filepath);
35}
36""" :: String -> String
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'