elm/server/Server.hs

100 lines
3.3 KiB
Haskell
Raw Normal View History

2012-04-19 06:32:10 +00:00
module Main where
import Control.Monad (msum,guard)
import Control.Monad.Trans (MonadIO(liftIO))
import Data.List (isPrefixOf, isSuffixOf, (\\))
2012-10-03 07:17:09 +00:00
import Data.Version (showVersion)
import Happstack.Server
2012-04-19 06:32:10 +00:00
import Happstack.Server.Compression
import System.Directory
2012-04-19 06:32:10 +00:00
import System.Environment
import System.Exit
import System.FilePath
import System.Process
import GHC.IO.Handle
import qualified Language.Elm as Elm
2012-10-03 06:47:46 +00:00
import Paths_elm_server
runtime = "/elm-runtime.js"
2012-04-19 06:32:10 +00:00
serve :: Int -> String -> IO ()
serve portNumber libLoc = do
putStrLn $ "Elm Server " ++ showVersion version ++
": running at <http://localhost:" ++ show portNumber ++ ">"
putStrLn "Just refresh a page to recompile it!"
simpleHTTP httpConf $ do
_ <- compressedResponseFilter
msum [ uriRest serveElm
, uriRest (serveLib libLoc)
2012-04-19 06:32:10 +00:00
, serveDirectory EnableBrowsing [] "."
]
where httpConf = nullConf { port = portNumber }
2012-04-19 06:32:10 +00:00
pageTitle :: String -> String
pageTitle = dropExtension . takeBaseName
serveElm :: FilePath -> ServerPartT IO Response
serveElm fp = do
guard (takeExtension fp == ".elm")
let file = tail fp
args = [ "--make" ,"--runtime=" ++ runtime, "--cache-dir=elm-server-cache", file ]
(_, stdout, _, handle) <- liftIO $ createProcess $ (proc "elm" args) { std_out = CreatePipe }
exitCode <- liftIO $ waitForProcess handle
liftIO $ removeDirectoryRecursive "elm-server-cache"
case (exitCode, stdout) of
(ExitFailure _, Just out) ->
do str <- liftIO $ hGetContents out
badRequest $ toResponse str
(ExitFailure _, Nothing) ->
badRequest $ toResponse "See command line for error message."
(ExitSuccess, _) ->
serveFile (asContentType "text/html") ("build" </> replaceExtension file "html")
2012-04-19 06:32:10 +00:00
serveLib :: FilePath -> [Char] -> ServerPartT IO Response
serveLib libLoc fp = do
guard (fp == runtime)
serveFile (asContentType "application/javascript") libLoc
2012-04-19 06:32:10 +00:00
main :: IO ()
2012-04-19 06:32:10 +00:00
main = getArgs >>= parse
parse :: [String] -> IO ()
2012-04-19 06:32:10 +00:00
parse ("--help":_) = putStrLn usage
2012-10-03 07:17:09 +00:00
parse ("--version":_) = putStrLn ("The Elm Server " ++ showVersion version)
parse args =
case null remainingArgs of
True -> serve portNumber =<< elmRuntime
False -> putStrLn usageMini
where
runtimeArg = filter (isPrefixOf "--runtime-location=") args
portArg = filter (isPrefixOf "--port=") args
remainingArgs = (args \\ runtimeArg) \\ portArg
argValue arg = tail $ dropWhile (/= '=') (head arg)
portNumber = if null portArg then 8000 else read (argValue portArg) :: Int
elmRuntime = if null runtimeArg then Elm.runtime else return $ argValue runtimeArg
2012-04-19 06:32:10 +00:00
usageMini :: String
2012-04-19 06:32:10 +00:00
usageMini =
"Usage: elm-server [OPTIONS]\n\
\Try `elm-server --help' for more information."
usage :: String
2012-04-19 06:32:10 +00:00
usage =
"Usage: elm-server [OPTIONS]\n\
\Compiles and serves .elm files from the current directory.\n\
\Example: elm-server\n\
\\n\
\Server configuration:\n\
\ --port set the port to listen on (default: 8000)\n\
\\n\
2012-04-19 06:32:10 +00:00
\Resource Locations:\n\
2012-10-03 06:47:46 +00:00
\ --runtime-location set the location of the Elm runtime\n\
2012-04-19 06:32:10 +00:00
\\n\
\Compiler Information:\n\
\ --version print the version information and exit\n\
\ --help display this help and exit\n\
\\n\
\Elm home page: <http://elm-lang.org>"