, loaderFn
) where
-import Prelude (Unit(), ($), (<>), (>>=), (<$>), (++), bind, flip, id, pure, return, unit)
+import Prelude (Unit(), ($), (<>), (>>=), (<$>), (++), bind, flip, id, pure, return, unit, show)
import Control.Monad.Aff (Aff(), runAff)
import Control.Monad.Eff (Eff())
import Control.Monad.Eff.Class (liftEff)
-import Control.Monad.Eff.Exception (error)
+import Control.Monad.Eff.Exception (throwException, error, EXCEPTION())
import Data.Array ((!!), concat)
import Data.Function (Fn2(), mkFn2)
import Data.Maybe (Maybe(..), fromMaybe, maybe)
+import Data.Either (Either(..))
import Data.String (joinWith)
import Data.String.Regex (match, noFlags, regex, test)
import Data.Traversable (sequence)
+import Data.Foreign (F())
+import Data.Foreign.Class (read)
import PursLoader.ChildProcess (ChildProcess(), spawn)
import PursLoader.FS (FS(), writeFileUtf8, findFileUtf8)
import PursLoader.Glob (Glob(), globAll)
import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query, clearDependencies, addDependency, resourcePath)
import PursLoader.LoaderUtil (parseQuery)
-import PursLoader.Options (loaderFFIOption, loaderSrcOption, pscOptions)
+import PursLoader.Options (loaderFFIOption, loaderSrcOption, pscOptions, Options(), output)
-type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader | eff)
+type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader, err :: EXCEPTION | eff)
moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
foreign import resolve :: String -> String
+foreign import dirname :: String -> String
+
+foreign import joinPath :: String -> String -> String
+
mkPsci :: Array (Array String) -> Array (Array String) -> String
mkPsci srcs ffis = joinWith "\n" ((loadModule <$> concat srcs) <> (loadForeign <$> concat ffis))
where
let parsed = parseQuery $ query ref
srcs = fromMaybe [] (loaderSrcOption parsed)
ffis = fromMaybe [] (loaderFFIOption parsed)
- opts = pscOptions parsed
- srcss <- globAll srcs
- ffiss <- globAll ffis
+ case read parsed :: F Options of
+ Left e -> liftEff (throwException (error (show e)))
+ Right opts -> do
+ let pscOpts = pscOptions opts
+
+ srcss <- globAll srcs
+ ffiss <- globAll ffis
- let psciFile = mkPsci srcss ffiss
+ let psciFile = mkPsci srcss ffiss
- writeFileUtf8 psciFilename psciFile
+ writeFileUtf8 psciFilename psciFile
- let moduleName = match moduleRegex source >>= (!!!) 1 >>= id
- hasForeign = test foreignRegex source
- result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName
+ let moduleName = match moduleRegex source >>= (!!!) 1 >>= id
+ hasForeign = test foreignRegex source
+ outputDir = resolve (output opts)
+ resourceDir = dirname (resourcePath ref)
+ result = (\a -> "module.exports = require('" ++ relative resourceDir (joinPath outputDir a) ++ "');") <$> moduleName
- liftEff (clearDependencies ref)
- liftEff (addDependency ref (resourcePath ref))
- liftEff (sequence $ (\src -> addDependency ref (resolve src)) <$> concat srcss)
+ liftEff do
+ clearDependencies ref
+ addDependency ref (resourcePath ref)
+ sequence $ (\src -> addDependency ref (resolve src)) <$> concat srcss
- foreignPath <- if hasForeign
- then fromMaybe (pure Nothing) (findFFI ffiss <$> moduleName)
- else pure Nothing
+ foreignPath <- if hasForeign
+ then fromMaybe (pure Nothing) (findFFI ffiss <$> moduleName)
+ else pure Nothing
- fromMaybe (pure unit) ((\path -> liftEff (addDependency ref path)) <$> foreignPath)
+ fromMaybe (pure unit) ((\path -> liftEff (addDependency ref path)) <$> foreignPath)
- spawn pscCommand (srcs <> opts)
+ spawn pscCommand (srcs <> pscOpts)
- return result
+ return result
loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
loader ref source = do
( pscOptions
, loaderSrcOption
, loaderFFIOption
+ , Options()
+ , output
) where
-import Prelude (Unit(), (<>), (<$>), (<<<), (++), (<*>), const)
+import Prelude (Unit(), (<>), (<$>), (<<<), (++), (<*>), ($), const, id)
import Data.Array (concat)
import Data.Either (either)
, noTco :: NullOrUndefined Boolean
, verboseErrors :: NullOrUndefined Boolean
, comments :: NullOrUndefined Boolean
- , output :: NullOrUndefined String
+ , output :: String
, noPrefix :: NullOrUndefined Boolean
- , requirePath :: NullOrUndefined String
+ , requirePath :: String
, src :: NullOrUndefined (Array String)
, ffi :: NullOrUndefined (Array String)
}
+output :: Options -> String
+output (Options o) = o.output
+
instance isForeignOptions :: IsForeign Options where
read obj = Options <$> ({ noPrelude: _
, noOpts: _
, comments: _
, output: _
, noPrefix: _
- , requirePath: _
+ , requirePath: "../"
, src: _
, ffi: _
} <$> readProp noPreludeOpt obj
<*> readProp noTcoOpt obj
<*> readProp verboseErrorsOpt obj
<*> readProp commentsOpt obj
- <*> readProp outputOpt obj
+ <*> (maybe "output" id <<< runNullOrUndefined <$> readProp outputOpt obj)
<*> readProp noPrefixOpt obj
- <*> readProp requirePathOpt obj
<*> readProp srcOpt obj
<*> readProp ffiOpt obj)
opt key val = concat (opt key <$> (NullOrUndefined <<< Just)
<$> (fromMaybe [] (runNullOrUndefined val)))
-pscOptions :: Foreign -> Array String
-pscOptions query = either (const []) fold parsed
- where parsed = read query :: F Options
- fold (Options a) = opt noPreludeOpt a.noPrelude <>
- opt noOptsOpt a.noOpts <>
- opt noMagicDoOpt a.noMagicDo <>
- opt noTcoOpt a.noTco <>
- opt verboseErrorsOpt a.verboseErrors <>
- opt commentsOpt a.comments <>
- opt outputOpt a.output <>
- opt noPrefixOpt a.noPrefix <>
- opt requirePathOpt a.requirePath <>
- opt ffiOpt a.ffi
+pscOptions :: Options -> Array String
+pscOptions (Options a) = opt noPreludeOpt a.noPrelude <>
+ opt noOptsOpt a.noOpts <>
+ opt noMagicDoOpt a.noMagicDo <>
+ opt noTcoOpt a.noTco <>
+ opt verboseErrorsOpt a.verboseErrors <>
+ opt commentsOpt a.comments <>
+ opt outputOpt (NullOrUndefined $ Just a.output) <>
+ opt noPrefixOpt a.noPrefix <>
+ opt requirePathOpt (NullOrUndefined $ Just a.requirePath) <>
+ opt ffiOpt a.ffi
loaderSrcOption :: Foreign -> Maybe (Array String)
loaderSrcOption query = either (const Nothing) (\(Options a) -> runNullOrUndefined a.src) (read query)