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