-- | Read and write JSMods.
module Haste.Module (writeModule, readModule) where
import Module (moduleNameSlashes, mkModuleName)
import qualified Data.ByteString.Lazy as B
import Control.Shell
import Control.Applicative
import Data.JSTarget
import Data.Binary
-- | The file extension to use for modules.
jsmodExt :: String
jsmodExt = "jsmod"
moduleFilePath :: FilePath -> String -> String -> FilePath
moduleFilePath basepath pkgid modname =
flip addExtension jsmodExt $
basepath </> pkgid </> (moduleNameSlashes $ mkModuleName modname)
-- | Write a module to file, with the extension specified in `fileExt`.
-- Assuming that fileExt = "jsmod", a module Foo.Bar is written to
-- basepath/Foo/Bar.jsmod
-- If any directory in the path where the module is to be written doesn't
-- exist, it gets created.
writeModule :: FilePath -> Module -> IO ()
writeModule basepath m@(Module pkgid modname _ _) =
fromRight "writeModule" . shell $ do
mkdir True (takeDirectory path)
liftIO $ B.writeFile path (encode m)
where
path = moduleFilePath basepath pkgid modname
-- | Read a module from file. If the module is not found at the specified path,
-- libpath/path is tried instead. Panics if the module is found on neither
-- path.
readModule :: FilePath -> String -> String -> IO (Maybe Module)
readModule basepath pkgid modname = fromRight "readModule" . shell $ do
x <- isFile path
let path' = if x then path else syspath
isF <- isFile path'
if isF
then Just . decode <$> liftIO (B.readFile path')
else return Nothing
where
path = moduleFilePath "." pkgid modname
syspath = moduleFilePath basepath pkgid modname
fromRight :: String -> IO (Either String b) -> IO b
fromRight from m = do
ex <- m
case ex of
Right x -> return x
Left e -> fail $ "shell expression failed in " ++ from ++ ": " ++ e