]> git.immae.eu Git - github/fretlink/purs-loader.git/blame - src/PursLoader/Loader.purs
Add all PureScript files as webpack dependencies
[github/fretlink/purs-loader.git] / src / PursLoader / Loader.purs
CommitLineData
c194f84c 1module PursLoader.Loader
1983893b 2 ( Effects()
c194f84c 3 , loader
4 , loaderFn
5 ) where
6
03b840cb 7import Prelude (Unit(), ($), (<>), (>>=), (<$>), (++), bind, flip, id, pure, return, unit)
8
c194f84c 9import Control.Monad.Aff (Aff(), runAff)
10import Control.Monad.Eff (Eff())
11import Control.Monad.Eff.Class (liftEff)
12import Control.Monad.Eff.Exception (error)
13
0e1221d7 14import Data.Array ((!!), concat)
c194f84c 15import Data.Function (Fn2(), mkFn2)
16import Data.Maybe (Maybe(..), fromMaybe, maybe)
0e1221d7 17import Data.String (joinWith)
3610dff1 18import Data.String.Regex (match, noFlags, regex, test)
07de44be 19import Data.Traversable (sequence)
c194f84c 20
21import PursLoader.ChildProcess (ChildProcess(), spawn)
3610dff1 22import PursLoader.FS (FS(), writeFileUtf8, findFileUtf8)
0e1221d7 23import PursLoader.Glob (Glob(), globAll)
3610dff1 24import PursLoader.LoaderRef (LoaderRef(), Loader(), async, cacheable, query, clearDependencies, addDependency, resourcePath)
0e1221d7 25import PursLoader.LoaderUtil (parseQuery)
26import PursLoader.Options (loaderFFIOption, loaderSrcOption, pscOptions)
c194f84c 27
0e1221d7 28type Effects eff = (cp :: ChildProcess, fs :: FS, glob :: Glob, loader :: Loader | eff)
c194f84c 29
30moduleRegex = regex "(?:^|\\n)module\\s+([\\w\\.]+)" noFlags { ignoreCase = true }
31
3610dff1 32foreignRegex = regex "(?:^|\\n)\\s*foreign import\\s+" noFlags { ignoreCase = true }
33
1983893b 34pscCommand = "psc"
c194f84c 35
0e1221d7 36psciCommand = "psci"
37
38psciFilename = ".psci"
39
c194f84c 40(!!!) = flip (!!)
41
03b840cb 42foreign import cwd :: String
0e1221d7 43
03b840cb 44foreign import relative :: String -> String -> String
0e1221d7 45
07de44be 46foreign import resolve :: String -> String
47
03b840cb 48mkPsci :: Array (Array String) -> Array (Array String) -> String
0e1221d7 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
03b840cb 57findFFI :: forall eff. Array (Array String) -> String -> Aff (fs :: FS | eff) (Maybe String)
3610dff1 58findFFI ffiss name = findFileUtf8 re (concat ffiss)
59 where
60 re = regex ("(?:^|\\n)//\\s*module\\s*" ++ name ++ "\\s*\\n") noFlags
61
1983893b 62loader' :: forall eff. LoaderRef -> String -> Aff (Effects eff) (Maybe String)
c194f84c 63loader' ref source = do
64 liftEff $ cacheable ref
65
0e1221d7 66 let parsed = parseQuery $ query ref
1983893b 67 srcs = fromMaybe [] (loaderSrcOption parsed)
0e1221d7 68 ffis = fromMaybe [] (loaderFFIOption parsed)
1983893b 69 opts = pscOptions parsed
c194f84c 70
1983893b 71 spawn pscCommand (srcs <> opts)
0e1221d7 72
73 srcss <- globAll srcs
74 ffiss <- globAll ffis
75
76 let psciFile = mkPsci srcss ffiss
77
78 writeFileUtf8 psciFilename psciFile
79
03b840cb 80 let moduleName = match moduleRegex source >>= (!!!) 1 >>= id
3610dff1 81 hasForeign = test foreignRegex source
0e1221d7 82 result = (\a -> "module.exports = require('" ++ a ++ "');") <$> moduleName
83
3610dff1 84 liftEff (clearDependencies ref)
85 liftEff (addDependency ref (resourcePath ref))
07de44be 86 liftEff (sequence $ (\src -> addDependency ref (resolve src)) <$> concat srcss)
3610dff1 87
88 foreignPath <- if hasForeign
89 then fromMaybe (pure Nothing) (findFFI ffiss <$> moduleName)
90 else pure Nothing
91
92 fromMaybe (pure unit) ((\path -> liftEff (addDependency ref path)) <$> foreignPath)
93
1983893b 94 return result
c194f84c 95
1983893b 96loader :: forall eff. LoaderRef -> String -> Eff (Effects eff) Unit
c194f84c 97loader ref source = do
98 callback <- async ref
99 runAff (\e -> callback (Just e) "")
1983893b 100 (maybe (callback (Just (error "Loader has failed to run")) "")
c194f84c 101 (callback Nothing))
102 (loader' ref source)
103
1983893b 104loaderFn :: forall eff. Fn2 LoaderRef String (Eff (Effects eff) Unit)
c194f84c 105loaderFn = mkFn2 loader