]> git.immae.eu Git - github/fretlink/purs-loader.git/blame_incremental - src/Loader.purs
Merge pull request #19 from ethul/topic/issue-17
[github/fretlink/purs-loader.git] / src / Loader.purs
... / ...
CommitLineData
1module PursLoader.Loader
2 ( Effects()
3 , loader
4 , loaderFn
5 ) where
6
7import Control.Monad.Aff (Aff(), runAff)
8import Control.Monad.Eff (Eff())
9import Control.Monad.Eff.Class (liftEff)
10import Control.Monad.Eff.Exception (error)
11
12import Data.Array ((!!), concat)
13import Data.Function (Fn2(), mkFn2)
14import Data.Maybe (Maybe(..), fromMaybe, maybe)
15import Data.String (joinWith)
16import Data.String.Regex (match, noFlags, regex)
17
18import PursLoader.ChildProcess (ChildProcess(), spawn)
19import PursLoader.FS (FS(), writeFileUtf8)
20import PursLoader.Glob (Glob(), globAll)
21import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query)
22import PursLoader.LoaderUtil (parseQuery)
23import PursLoader.Options (loaderFFIOption, loaderSrcOption, pscOptions)
24
25type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader | eff)
26
27moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
28
29pscCommand = "psc"
30
31psciCommand = "psci"
32
33psciFilename = ".psci"
34
35(!!!) = flip (!!)
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
57loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String)
58loader' ref source = do
59 liftEff $ cacheable ref
60
61 let parsed = parseQuery $ query ref
62 srcs = fromMaybe [] (loaderSrcOption parsed)
63 ffis = fromMaybe [] (loaderFFIOption parsed)
64 opts = pscOptions parsed
65
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
78 return result
79
80loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
81loader ref source = do
82 callback <- async ref
83 runAff (\e -> callback (Just e) "")
84 (maybe (callback (Just (error "Loader has failed to run")) "")
85 (callback Nothing))
86 (loader' ref source)
87
88loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
89loaderFn = mkFn2 loader