]> git.immae.eu Git - github/fretlink/purs-loader.git/commitdiff
Updating for PureScript 0.7
authoreric thul <thul.eric@gmail.com>
Sun, 5 Jul 2015 14:13:47 +0000 (10:13 -0400)
committereric thul <thul.eric@gmail.com>
Tue, 7 Jul 2015 03:53:01 +0000 (23:53 -0400)
Resolves #14

16 files changed:
README.md
example/README.md
example/bower.json
example/package.json
example/src/Foo.purs
example/src/Foo/Bar.purs
example/src/Test.purs
example/src/entry.js
example/webpack.config.js
src/FS.purs [deleted file]
src/Glob.purs [deleted file]
src/Loader.purs
src/LoaderRef.purs
src/OS.purs [deleted file]
src/Options.purs
src/Path.purs [deleted file]

index d243381aa0b11dbe5131d78433920299f242bb76..8a310d5fdff3598a483dd3062e10b891a4937a6c 100644 (file)
--- a/README.md
+++ b/README.md
@@ -44,10 +44,58 @@ Sets `--output=<string>` the specifies the output directory, `output` by default
 
 Toggles `--no-prefix` that does not include the comment header.
 
+###### `requirePath` (String)
+
+Sets `--require-path=<string>` that specifies the path prefix to use for `require()` calls in the generated JavaScript.
+
+###### `ffi` (String Array)
+
+Specifies the PureScript FFI files setting `--ffi=<string>`. Glob syntax is supported. This option is specified as `ffi[]=path`.
+
 ###### `src` (String Array)
 
-Specifies 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`.
+Specifies the PureScript source files. Glob syntax is supported. This option is specified as `src[]=path`.
 
 ## Example
 
+```js
+// webpack.config.js
+
+var path = require('path');
+
+var srcs = ['src[]=bower_components/purescript-*/src/**/*.purs', 'src[]=src/**/*.purs'];
+
+var ffis = ['ffi[]=bower_components/purescript-*/src/**/*.js'];
+
+var output = 'output';
+
+var modulesDirectories = [
+  'node_modules',
+  // The bower component for purescript-prelude is specified here to
+  // allow JavaScript files to require the 'Prelude' module globally.
+  'bower_components/purescript-prelude/src',
+  // The output directory is specified here to allow PureScript files in
+  // your source to import other PureScript modules in your source.
+  output
+];
+
+var config
+  = { entry: './src/entry'
+    , output: { path: __dirname
+              , pathinfo: true
+              , filename: 'bundle.js'
+              }
+    , module: { loaders: [ { test: /\.purs$/
+                           , loader: 'purs-loader?output=' + output + '&' + srcs.concat(ffis).join('&')
+                           } ] }
+    , resolve: { modulesDirectories: modulesDirectories
+               , extensions: ['', '.js', '.purs']
+               }
+    , resolveLoader: { root: path.join(__dirname, 'node_modules') }
+    }
+    ;
+
+module.exports = config;
+```
+
 See the [example](https://github.com/ethul/purs-loader/tree/master/example) directory for a complete example.
index 87b9bc7c84c9b0c0429a50bd9e0062317e1608ea..bac4f6c47deea436a1487da649c83d03f88d2807 100644 (file)
@@ -1,6 +1,6 @@
 ```bash
 bower install
 npm install
-npm run-script webpack
+npm run-script build
 npm run-script run
 ```
index b4a1c7856e9adabfb90617730e18290ae6fd62c9..c83e7351cfdbf0c092c1e914521a285096b10ece 100644 (file)
@@ -2,6 +2,6 @@
   "name": "example",
   "private": true,
   "devDependencies": {
-    "purescript-maybe": "~0.2.1"
+    "purescript-prelude": "~0.1.0"
   }
 }
index 915eb27c6480b4457c9bb38f2b64eab32dc75113..8a31dd845500e04286ff9e7a92a4b55b18c6498f 100644 (file)
@@ -3,7 +3,7 @@
   "version": "0.0.0",
   "private": true,
   "scripts": {
-    "webpack": "./node_modules/.bin/webpack",
+    "build": "./node_modules/.bin/webpack",
     "run": "node bundle.js",
     "clean": "rm -rf bower_components && rm -rf bundle.js && rm -rf node_modules && rm -rf output"
   },
index 3e3a04c13b910cb9fc7953e43058d1269fcc4b1d..b234e0df06d456436d686fc10da11405b8edb5a6 100644 (file)
@@ -1,6 +1,9 @@
 module Foo (foo) where
 
-import Data.Maybe
+import Prelude
+
 import qualified Foo.Bar as B
 
 foo = "b"
+
+foo' = "c"
index 4ae100dfc89c6ca725606a9b275990717e1e057a..69329021696400f7296c9a77b3cd0c55832f893c 100644 (file)
@@ -1,3 +1,5 @@
 module Foo.Bar (bar) where
 
 bar = "c"
+
+bar' = "d"
index 8a5cb888d986343e19bd86c71b8404a1049a6e9e..d9f1b969273c8fd801d942a8319f2df4b4d8cd9a 100644 (file)
@@ -1,5 +1,5 @@
 module Test (test) where
 
-import Data.Maybe
+import Prelude
 
 test = "a"
index cc09034ab21b1bd4f97a40b67639ff5e8df7d970..344d4c6e24bb15d4e9055896f223e700d961e7e1 100644 (file)
@@ -1,7 +1,11 @@
+var Prelude = require('Prelude');
+
 var test = require('./Test');
 
 var foo = require('./Foo');
 
 var baz = require('./Foo/Baz');
 
-console.log(test, foo, baz);
+var bar = require('./Foo/Bar');
+
+console.log(Prelude, test, foo, baz, bar);
index f67e83ac24248fa4e2ffa6340b691b0167b62c2f..929490461820fc968f8a98146c2be0cc0c2b0a33 100644 (file)
@@ -1,14 +1,27 @@
 var path = require('path');
 
+var srcs = ['src[]=bower_components/purescript-*/src/**/*.purs', 'src[]=src/**/*.purs'];
+
+var ffis = ['ffi[]=bower_components/purescript-*/src/**/*.js'];
+
+var output = 'output';
+
+var modulesDirectories = [
+  'node_modules',
+  'bower_components/purescript-prelude/src',
+  output
+];
+
 var config
   = { entry: './src/entry'
     , output: { path: __dirname
+              , pathinfo: true
               , filename: 'bundle.js'
               }
-    , module: { loaders: [ { test: /\.purs$/, loader: 'purs-loader?src[]=src' } ] }
-    , resolve: { modulesDirectories: [ 'node_modules',
-                                       'output'
-                                     ]
+    , module: { loaders: [ { test: /\.purs$/
+                           , loader: 'purs-loader?output=' + output + '&' + srcs.concat(ffis).join('&')
+                           } ] }
+    , resolve: { modulesDirectories: modulesDirectories
                , extensions: ['', '.js', '.purs']
                }
     , resolveLoader: { root: path.join(__dirname, 'node_modules') }
diff --git a/src/FS.purs b/src/FS.purs
deleted file mode 100644 (file)
index 68fe2f9..0000000
+++ /dev/null
@@ -1,45 +0,0 @@
-module PursLoader.FS
-  ( FS()
-  , readFileUtf8
-  , readFileUtf8Sync
-  ) 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 :: !
-
-readFileUtf8 :: forall eff. String -> Aff (fs :: FS | eff) String
-readFileUtf8 filepath = makeAff $ runFn3 readFileUtf8Fn filepath
-
-readFileUtf8Sync :: forall eff. String -> Eff (fs :: FS | eff) String
-readFileUtf8Sync filepath = readFileUtf8SyncFn filepath
-
-foreign import readFileUtf8Fn """
-function readFileUtf8Fn(filepath, errback, callback) {
-  return function(){
-    var fs = require('fs');
-
-    fs.readFile(filepath, 'utf-8', function(e, data){
-      if (e) errback(e)();
-      else callback(data)();
-    });
-  };
-}
-""" :: forall eff. Fn3 String
-                       (Error -> Eff (fs :: FS | eff) Unit)
-                       (String -> Eff (fs :: FS | eff) Unit)
-                       (Eff (fs :: FS | eff) Unit)
-
-foreign import readFileUtf8SyncFn """
-function readFileUtf8SyncFn(filepath) {
-  return function(){
-    var fs = require('fs');
-
-    return fs.readFileSync(filepath, {encoding: 'utf-8'});
-  };
-}
-""" :: forall eff. String -> (Eff (fs :: FS | eff) String)
diff --git a/src/Glob.purs b/src/Glob.purs
deleted file mode 100644 (file)
index 7bc9212..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-module PursLoader.Glob
-  ( Glob()
-  , glob
-  ) 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 :: !
-
-glob :: forall eff. String -> Aff (glob :: Glob | eff) [String]
-glob pattern = makeAff $ runFn3 globFn pattern
-
-foreign import globFn """
-function globFn(pattern, errback, callback) {
-  return function(){
-    var glob = require('glob');
-
-    glob(pattern, function(e, data){
-      if (e) errback(e)();
-      else callback(data)();
-    });
-  };
-}
-""" :: forall eff. Fn3 String
-                       (Error -> Eff (glob :: Glob | eff) Unit)
-                       ([String] -> Eff (glob :: Glob | eff) Unit)
-                       (Eff (glob :: Glob | eff) Unit)
index fedc424be73f9503e8b987da7f8262a94dbb50fd..0235da91ed3df950fb52f963f0feb99293ca6254 100644 (file)
@@ -1,5 +1,5 @@
 module PursLoader.Loader
-  ( LoaderEff()
+  ( Effects()
   , loader
   , loaderFn
   ) where
@@ -9,113 +9,45 @@ import Control.Monad.Eff (Eff())
 import Control.Monad.Eff.Class (liftEff)
 import Control.Monad.Eff.Exception (error)
 
-import Data.Array ((!!), catMaybes, concat, filter, null)
-import Data.Foldable (foldl)
+import Data.Array ((!!))
 import Data.Function (Fn2(), mkFn2)
 import Data.Maybe (Maybe(..), fromMaybe, maybe)
-import Data.Set (Set(), empty, insert, member, toList, unions)
-import Data.String (joinWith, split)
-import Data.String.Regex (Regex(), match, noFlags, regex)
-import Data.StrMap (StrMap(), fromList, lookup)
-import Data.Traversable (sequence)
-import Data.Tuple.Nested (tuple2)
+import Data.String.Regex (match, noFlags, regex)
 
 import PursLoader.ChildProcess (ChildProcess(), spawn)
-import PursLoader.FS (FS(), readFileUtf8, readFileUtf8Sync)
-import PursLoader.Glob (Glob(), glob)
-import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, clearDependencies, addDependency, query, resourcePath)
+import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query)
 import PursLoader.LoaderUtil (getRemainingRequest, parseQuery)
-import PursLoader.OS (eol)
-import PursLoader.Options (loaderSrcOption, pscMakeOptions, pscMakeDefaultOutput, pscMakeOutputOption)
-import PursLoader.Path (dirname, join, relative, resolve)
+import PursLoader.Options (loaderSrcOption, pscOptions)
 
-foreign import cwd "var cwd = process.cwd();" :: String
+type Effects eff = (loader :: Loader, cp :: ChildProcess | eff)
 
 moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
 
-importRegex = regex "^\\s*import\\s+(?:qualified\\s+)?([\\w\\.]+)" noFlags { ignoreCase = true }
-
-bowerPattern = join [ "bower_components", "purescript-*", "src" ]
-
-pscMakeCommand = "psc-make"
-
-indexFilename = "index.js"
+pscCommand = "psc"
 
 (!!!) = flip (!!)
 
-pursPattern :: [String] -> String
-pursPattern srcs = join [ "{" ++ joinWith "," ([ bowerPattern ] <> srcs) ++ "}"
-                        , "**"
-                        , "*.purs"
-                        ]
-
-type GraphModule = { file :: String, imports :: [String] }
-
-type Graph = StrMap GraphModule
-
-mkGraph :: forall eff. [String] -> Eff (fs :: FS | eff) Graph
-mkGraph files = (fromList <<< catMaybes) <$> sequence (parse <$> files)
-  where parse file = do source <- readFileUtf8Sync file
-                        let key = match moduleRegex source >>= (!!!) 1
-                            lines = split eol source
-                            imports = catMaybes $ (\a -> match importRegex a >>= (!!!) 1) <$> lines
-                        return $ (\a -> tuple2 a { file: file, imports: imports }) <$> key
-
-mkDeps :: forall eff. String -> Graph -> [String]
-mkDeps key graph = toList $ go empty key
-  where
-    go :: Set String -> String -> Set String
-    go acc key =
-      let node = fromMaybe {file: "", imports: []} (lookup key graph)
-          uniq = filter (not <<< flip member acc) node.imports
-          acc' = foldl (flip insert) acc node.imports
-       in if null uniq
-             then acc'
-             else unions $ go acc' <$> uniq
-
-addDeps :: forall eff. LoaderRef -> Graph -> [String] -> Eff (loader :: Loader | eff) Unit
-addDeps ref graph deps = const unit <$> (sequence $ add <$> deps)
-  where add dep = let res = lookup dep graph
-                      path = (\a -> resolve a.file) <$> res
-                   in maybe (pure unit) (addDependency ref) path
-
-type LoaderAff eff a = Aff (loader :: Loader, glob :: Glob, cp :: ChildProcess, fs :: FS | eff) a
-
-loader' :: forall eff. LoaderRef -> String -> LoaderAff eff (Maybe String)
+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
-      srcs = loaderSrcOption parsed
-      opts = pscMakeOptions parsed
-      pattern = pursPattern $ fromMaybe [] srcs
-      key = match moduleRegex source >>= (!!!) 1
-
-  files <- glob pattern
-  graph <- liftEff $ mkGraph files
-
-  let deps = fromMaybe [] $ flip mkDeps graph <$> key
-      outputPath = fromMaybe pscMakeDefaultOutput $ pscMakeOutputOption parsed
-      indexPath = (\a -> join [ outputPath, a, indexFilename ]) <$> key
-
-  liftEff $ clearDependencies ref
-  liftEff $ addDependency ref (resourcePath ref)
-  liftEff $ addDeps ref graph deps
-
-  spawn pscMakeCommand (opts <> files)
-  indexFile <- sequence $ readFileUtf8 <$> indexPath
-  return indexFile
+      srcs = fromMaybe [] (loaderSrcOption parsed)
+      opts = pscOptions parsed
+      moduleName = match moduleRegex source >>= (!!!) 1
+      result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName
 
-type LoaderEff eff a = Eff (loader :: Loader, glob :: Glob, cp :: ChildProcess, fs :: FS | eff) a
+  spawn pscCommand (srcs <> opts)
+  return result
 
-loader :: forall eff. LoaderRef -> String -> LoaderEff eff Unit
+loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
 loader ref source = do
   callback <- async ref
   runAff (\e -> callback (Just e) "")
-         (maybe (callback (Just $ error "Loader has failed to run") "")
+         (maybe (callback (Just (error "Loader has failed to run")) "")
                 (callback Nothing))
          (loader' ref source)
 
-loaderFn :: forall eff. Fn2 LoaderRef String (LoaderEff eff Unit)
+loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
 loaderFn = mkFn2 loader
index 2d6275464cb856c3bc0a30768be30745148041fe..2567b1e77e0749a4a665a90318bb0b8de0a4f2ff 100644 (file)
@@ -3,16 +3,12 @@ module PursLoader.LoaderRef
   , Loader()
   , async
   , cacheable
-  , clearDependencies
-  , resourcePath
-  , addDependency
   , query
   ) where
 
 import Control.Monad.Eff (Eff())
 import Control.Monad.Eff.Exception (Error())
 
-import Data.Foreign (Foreign())
 import Data.Function (Fn3(), runFn3)
 import Data.Maybe (Maybe(), fromMaybe, isJust)
 
@@ -48,27 +44,6 @@ function cacheable(ref){
   };
 }""" :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit
 
-foreign import clearDependencies """
-function clearDependencies(ref){
-  return function(){
-    return ref.clearDependencies();
-  };
-}""" :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit
-
-foreign import resourcePath """
-function resourcePath(ref){
-  return ref.resourcePath;
-}""" :: LoaderRef -> String
-
-foreign import addDependency """
-function addDependency(ref){
-  return function(dep){
-    return function(){
-      return ref.addDependency(dep);
-    };
-  };
-}""" :: forall eff. LoaderRef -> String -> Eff (loader :: Loader | eff) Unit
-
 foreign import query """
 function query(ref){
   return ref.query;
diff --git a/src/OS.purs b/src/OS.purs
deleted file mode 100644 (file)
index 590c3d6..0000000
+++ /dev/null
@@ -1,3 +0,0 @@
-module PursLoader.OS (eol) where
-
-foreign import eol "var eol = require('os').EOL;" :: String
index c47bebc3749f79cf0f2953feb8bb7c5f869ba864..be218771a5e4426810d75123055de11fb2651f16 100644 (file)
@@ -1,17 +1,16 @@
 module PursLoader.Options
-  ( pscMakeOptions
-  , pscMakeDefaultOutput
-  , pscMakeOutputOption
+  ( pscOptions
   , loaderSrcOption
   ) where
 
+import Data.Array (concat)
 import Data.Either (either)
 
 import Data.Foreign (Foreign(), F())
 import Data.Foreign.Class (IsForeign, read, readProp)
-import Data.Foreign.NullOrUndefined (NullOrUndefined(), runNullOrUndefined)
+import Data.Foreign.NullOrUndefined (NullOrUndefined(..), runNullOrUndefined)
 
-import Data.Maybe (Maybe(..), maybe)
+import Data.Maybe (Maybe(..), maybe, fromMaybe)
 
 noPreludeOpt = "no-prelude"
 
@@ -29,9 +28,11 @@ commentsOpt = "comments"
 
 noPrefixOpt = "no-prefix"
 
+requirePathOpt = "require-path"
+
 srcOpt = "src"
 
-pscMakeDefaultOutput = "output"
+ffiOpt = "ffi"
 
 newtype Options
   = Options { noPrelude :: NullOrUndefined Boolean
@@ -42,7 +43,9 @@ newtype Options
             , comments :: NullOrUndefined Boolean
             , output :: NullOrUndefined String
             , noPrefix :: NullOrUndefined Boolean
+            , requirePath :: NullOrUndefined String
             , src :: NullOrUndefined [String]
+            , ffi :: NullOrUndefined [String]
             }
 
 instance isForeignOptions :: IsForeign Options where
@@ -54,7 +57,9 @@ instance isForeignOptions :: IsForeign Options where
                           , comments: _
                           , output: _
                           , noPrefix: _
+                          , requirePath: _
                           , src: _
+                          , ffi: _
                           } <$> readProp noPreludeOpt obj
                             <*> readProp noOptsOpt obj
                             <*> readProp noMagicDoOpt obj
@@ -63,26 +68,25 @@ instance isForeignOptions :: IsForeign Options where
                             <*> readProp commentsOpt obj
                             <*> readProp outputOpt obj
                             <*> readProp noPrefixOpt obj
-                            <*> readProp srcOpt obj)
+                            <*> readProp requirePathOpt obj
+                            <*> readProp srcOpt obj
+                            <*> readProp ffiOpt obj)
 
 class LoaderOption a where
   opt :: String -> NullOrUndefined a -> [String]
 
 instance booleanLoaderOption :: LoaderOption Boolean where
-  opt key opt = maybe [] (\a -> if a then ["--" ++ key] else [])
-                         (runNullOrUndefined opt)
+  opt key val = maybe [] (\a -> if a then ["--" ++ key] else []) (runNullOrUndefined val)
 
 instance stringLoaderOption :: LoaderOption String where
-  opt key opt = maybe [] (\a -> ["--" ++ key ++ "=" ++ a])
-                         (runNullOrUndefined opt)
+  opt key val = maybe [] (\a -> ["--" ++ key ++ "=" ++ a]) (runNullOrUndefined val)
 
-pscMakeOutputOption :: Foreign -> Maybe String
-pscMakeOutputOption query = either (const Nothing)
-                                   (\(Options a) -> runNullOrUndefined a.output)
-                                   (read query)
+instance arrayLoaderOption :: (LoaderOption a) => LoaderOption [a] where
+  opt key val = concat (opt key <$> (NullOrUndefined <<< Just)
+                                <$> (fromMaybe [] (runNullOrUndefined val)))
 
-pscMakeOptions :: Foreign -> [String]
-pscMakeOptions query = either (const []) fold parsed
+pscOptions :: Foreign -> [String]
+pscOptions query = either (const []) fold parsed
   where parsed = read query :: F Options
         fold (Options a) = opt noPreludeOpt a.noPrelude <>
                            opt noOptsOpt a.noOpts <>
@@ -91,9 +95,9 @@ pscMakeOptions query = either (const []) fold parsed
                            opt verboseErrorsOpt a.verboseErrors <>
                            opt commentsOpt a.comments <>
                            opt outputOpt a.output <>
-                           opt noPrefixOpt a.noPrefix
+                           opt noPrefixOpt a.noPrefix <>
+                           opt requirePathOpt a.requirePath <>
+                           opt ffiOpt a.ffi
 
 loaderSrcOption :: Foreign -> Maybe [String]
-loaderSrcOption query = either (const Nothing)
-                               (\(Options a) -> runNullOrUndefined a.src)
-                               (read query)
+loaderSrcOption query = either (const Nothing) (\(Options a) -> runNullOrUndefined a.src) (read query)
diff --git a/src/Path.purs b/src/Path.purs
deleted file mode 100644 (file)
index e071e35..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-module PursLoader.Path
-  ( dirname
-  , join
-  , relative
-  , resolve
-  ) where
-
-foreign import dirname """
-function dirname(filepath) {
-  var path = require('path');
-  return path.dirname(filepath);
-}
-""" :: String -> String
-
-foreign import join """
-function join(parts) {
-  var path = require('path');
-  return path.join.apply(path, parts);
-}
-""" :: [String] -> String
-
-foreign import relative """
-function relative(from) {
-  return function(to){
-    var path = require('path');
-    return path.relative(from, to);
-  };
-}
-""" :: String -> String -> String
-
-foreign import resolve """
-function resolve(filepath) {
-  var path = require('path');
-  return path.resolve(filepath);
-}
-""" :: String -> String