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