From 1983893bf09a5c2ea1946e156be5da170075af7e Mon Sep 17 00:00:00 2001 From: eric thul Date: Sun, 5 Jul 2015 10:13:47 -0400 Subject: Updating for PureScript 0.7 Resolves #14 --- README.md | 50 ++++++++++++++++++++++- example/README.md | 2 +- example/bower.json | 2 +- example/package.json | 2 +- example/src/Foo.purs | 5 ++- example/src/Foo/Bar.purs | 2 + example/src/Test.purs | 2 +- example/src/entry.js | 6 ++- example/webpack.config.js | 21 ++++++++-- src/FS.purs | 45 -------------------- src/Glob.purs | 31 -------------- src/Loader.purs | 102 ++++++++-------------------------------------- src/LoaderRef.purs | 25 ------------ src/OS.purs | 3 -- src/Options.purs | 46 +++++++++++---------- src/Path.purs | 36 ---------------- 16 files changed, 123 insertions(+), 257 deletions(-) delete mode 100644 src/FS.purs delete mode 100644 src/Glob.purs delete mode 100644 src/OS.purs delete mode 100644 src/Path.purs diff --git a/README.md b/README.md index d243381..8a310d5 100644 --- a/README.md +++ b/README.md @@ -44,10 +44,58 @@ Sets `--output=` the specifies the output directory, `output` by default Toggles `--no-prefix` that does not include the comment header. +###### `requirePath` (String) + +Sets `--require-path=` that specifies the path prefix to use for `require()` calls in the generated JavaScript. + +###### `ffi` (String Array) + +Specifies the PureScript FFI files setting `--ffi=`. 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. 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 @@ ```bash bower install npm install -npm run-script webpack +npm run-script build npm run-script run ``` 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 @@ "name": "example", "private": true, "devDependencies": { - "purescript-maybe": "~0.2.1" + "purescript-prelude": "~0.1.0" } } diff --git a/example/package.json b/example/package.json index 915eb27..8a31dd8 100644 --- a/example/package.json +++ b/example/package.json @@ -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" }, 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 @@ module Foo (foo) where -import Data.Maybe +import Prelude + import qualified Foo.Bar as B foo = "b" + +foo' = "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 @@ module Foo.Bar (bar) where bar = "c" + +bar' = "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 @@ module Test (test) where -import Data.Maybe +import Prelude test = "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 @@ +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); 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 @@ 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 index 68fe2f9..0000000 --- a/src/FS.purs +++ /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 index 7bc9212..0000000 --- a/src/Glob.purs +++ /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) diff --git a/src/Loader.purs b/src/Loader.purs index fedc424..0235da9 100644 --- a/src/Loader.purs +++ b/src/Loader.purs @@ -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 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 , 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 index 590c3d6..0000000 --- a/src/OS.purs +++ /dev/null @@ -1,3 +0,0 @@ -module PursLoader.OS (eol) where - -foreign import eol "var eol = require('os').EOL;" :: String diff --git a/src/Options.purs b/src/Options.purs index c47bebc..be21877 100644 --- a/src/Options.purs +++ b/src/Options.purs @@ -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 index e071e35..0000000 --- a/src/Path.purs +++ /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 -- cgit v1.2.3 From bc4de0853bd1cbf63842b3b66bb30494c9ea778a Mon Sep 17 00:00:00 2001 From: eric thul Date: Mon, 6 Jul 2015 23:10:09 -0400 Subject: Ensure output directory exists Workaround for #15 --- example/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/example/package.json b/example/package.json index 8a31dd8..df3e74f 100644 --- a/example/package.json +++ b/example/package.json @@ -3,7 +3,7 @@ "version": "0.0.0", "private": true, "scripts": { - "build": "./node_modules/.bin/webpack", + "build": "mkdir -p output && ./node_modules/.bin/webpack", "run": "node bundle.js", "clean": "rm -rf bower_components && rm -rf bundle.js && rm -rf node_modules && rm -rf output" }, -- cgit v1.2.3 From 0e1221d7b15e578d5e9146b01e11a24007d4ba9b Mon Sep 17 00:00:00 2001 From: eric thul Date: Mon, 6 Jul 2015 23:49:47 -0400 Subject: 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' -- cgit v1.2.3 From 167c852f657b4746331c4f89e358a4a4876ced78 Mon Sep 17 00:00:00 2001 From: eric thul Date: Mon, 6 Jul 2015 23:57:59 -0400 Subject: Updating module documentation --- MODULE.md | 97 +++++++++------------------------------------------------------ 1 file changed, 14 insertions(+), 83 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 :: ! ``` -#### `readFileUtf8` +#### `writeFileUtf8` ``` purescript -readFileUtf8 :: forall eff. String -> Aff (fs :: FS | eff) String -``` - - -#### `readFileUtf8Sync` - -``` purescript -readFileUtf8Sync :: forall eff. String -> Eff (fs :: FS | eff) String +writeFileUtf8 :: forall eff. String -> String -> Aff (fs :: FS | eff) Unit ``` @@ -50,34 +43,34 @@ data Glob :: ! ``` -#### `glob` +#### `globAll` ``` purescript -glob :: forall eff. String -> Aff (glob :: Glob | eff) [String] +globAll :: forall eff. [String] -> Aff (glob :: Glob | eff) [[String]] ``` ## Module PursLoader.Loader -#### `LoaderEff` +#### `Effects` ``` purescript -type LoaderEff eff a = Eff (fs :: FS, cp :: ChildProcess, glob :: Glob, loader :: Loader | eff) a +type Effects eff = (loader :: Loader, glob :: Glob, fs :: FS, cp :: ChildProcess | eff) ``` #### `loader` ``` purescript -loader :: forall eff. LoaderRef -> String -> LoaderEff eff Unit +loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit ``` #### `loaderFn` ``` purescript -loaderFn :: forall eff. Fn2 LoaderRef String (LoaderEff eff Unit) +loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit) ``` @@ -112,27 +105,6 @@ cacheable :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit ``` -#### `clearDependencies` - -``` purescript -clearDependencies :: forall eff. LoaderRef -> Eff (loader :: Loader | eff) Unit -``` - - -#### `resourcePath` - -``` purescript -resourcePath :: LoaderRef -> String -``` - - -#### `addDependency` - -``` purescript -addDependency :: forall eff. LoaderRef -> String -> Eff (loader :: Loader | eff) Unit -``` - - #### `query` ``` purescript @@ -143,13 +115,6 @@ query :: LoaderRef -> String ## Module PursLoader.LoaderUtil -#### `getRemainingRequest` - -``` purescript -getRemainingRequest :: LoaderRef -> String -``` - - #### `parseQuery` ``` purescript @@ -158,16 +123,6 @@ parseQuery :: String -> Foreign -## Module PursLoader.OS - -#### `eol` - -``` purescript -eol :: String -``` - - - ## Module PursLoader.Options #### `isForeignOptions` @@ -191,17 +146,17 @@ instance stringLoaderOption :: LoaderOption String ``` -#### `pscMakeOutputOption` +#### `arrayLoaderOption` ``` purescript -pscMakeOutputOption :: Foreign -> Maybe String +instance arrayLoaderOption :: (LoaderOption a) => LoaderOption [a] ``` -#### `pscMakeOptions` +#### `pscOptions` ``` purescript -pscMakeOptions :: Foreign -> [String] +pscOptions :: Foreign -> [String] ``` @@ -212,34 +167,10 @@ loaderSrcOption :: Foreign -> Maybe [String] ``` - -## Module PursLoader.Path - -#### `dirname` - -``` purescript -dirname :: String -> String -``` - - -#### `join` - -``` purescript -join :: [String] -> String -``` - - -#### `relative` - -``` purescript -relative :: String -> String -> String -``` - - -#### `resolve` +#### `loaderFFIOption` ``` purescript -resolve :: String -> String +loaderFFIOption :: Foreign -> Maybe [String] ``` -- cgit v1.2.3