Merge branch 'master' into wai-2.0

Conflicts:
	yesod-bin/Devel.hs
This commit is contained in:
Michael Snoyman 2013-12-02 08:00:37 +02:00
commit a2851c929c
14 changed files with 79 additions and 44 deletions

4
.gitignore vendored
View File

@ -6,7 +6,9 @@ dist
client_session_key.aes client_session_key.aes
cabal-dev/ cabal-dev/
yesod/foobar/ yesod/foobar/
.virthualenv .hsenv/
.cabal-sandbox/
cabal.sandbox.config
/vendor/ /vendor/
/.shelly/ /.shelly/
/tarballs/ /tarballs/

View File

@ -1,14 +1,13 @@
{-# LANGUAGE CPP #-} {-# LANGUAGE CPP #-}
{-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE ScopedTypeVariables #-} {-# LANGUAGE ScopedTypeVariables #-}
{-# LANGUAGE TemplateHaskell #-}
module Devel module Devel
( devel ( devel
, DevelOpts(..) , DevelOpts(..)
, defaultDevelOpts , defaultDevelOpts
) where ) where
import Paths_yesod_bin
import qualified Distribution.Compiler as D import qualified Distribution.Compiler as D
import qualified Distribution.ModuleName as D import qualified Distribution.ModuleName as D
import qualified Distribution.PackageDescription as D import qualified Distribution.PackageDescription as D
@ -24,7 +23,7 @@ import Control.Concurrent.MVar (MVar, newEmptyMVar,
takeMVar, tryPutMVar) takeMVar, tryPutMVar)
import qualified Control.Exception as Ex import qualified Control.Exception as Ex
import Control.Monad (forever, unless, void, import Control.Monad (forever, unless, void,
when) when, forM)
import Control.Monad.IO.Class (liftIO) import Control.Monad.IO.Class (liftIO)
import Control.Monad.Trans.State (evalStateT, get) import Control.Monad.Trans.State (evalStateT, get)
import qualified Data.IORef as I import qualified Data.IORef as I
@ -83,6 +82,7 @@ import Network.Socket (sClose)
import Network.Wai (responseLBS) import Network.Wai (responseLBS)
import Network.Wai.Handler.Warp (run) import Network.Wai.Handler.Warp (run)
import SrcLoc (Located) import SrcLoc (Located)
import Data.FileEmbed (embedFile)
lockFile :: DevelOpts -> FilePath lockFile :: DevelOpts -> FilePath
lockFile _opts = "yesod-devel/devel-terminate" lockFile _opts = "yesod-devel/devel-terminate"
@ -131,7 +131,14 @@ reverseProxy opts iappPort = do
#else #else
manager <- newManager def manager <- newManager def
#endif #endif
let loop = forever $ do let refreshHtml = LB.fromStrict $(embedFile "refreshing.html")
let onExc _ _ = return $ responseLBS status200
[ ("content-type", "text/html")
, ("Refresh", "1")
]
refreshHtml
let runProxy =
run (develPort opts) $ waiProxyToSettings run (develPort opts) $ waiProxyToSettings
(const $ do (const $ do
appPort <- liftIO $ I.readIORef iappPort appPort <- liftIO $ I.readIORef iappPort
@ -150,20 +157,13 @@ reverseProxy opts iappPort = do
else Just (1000000 * proxyTimeout opts) else Just (1000000 * proxyTimeout opts)
} }
manager manager
putStrLn "Reverse proxy stopped, but it shouldn't" loop runProxy `Ex.onException` exitFailure
threadDelay 1000000
putStrLn "Restarting reverse proxy"
loop `Ex.onException` exitFailure
where where
onExc _ _ = do loop proxy = forever $ do
refreshing <- liftIO $ getDataFileName "refreshing.html" void proxy
html <- liftIO $ LB.readFile refreshing putStrLn "Reverse proxy stopped, but it shouldn't"
return $ responseLBS threadDelay 1000000
status200 putStrLn "Restarting reverse proxy"
[ ("content-type", "text/html")
, ("Refresh", "1")
]
html
checkPort :: Int -> IO Bool checkPort :: Int -> IO Bool
checkPort p = do checkPort p = do
@ -183,10 +183,12 @@ getPort _ p0 =
avail <- checkPort p avail <- checkPort p
if avail then return p else loop (succ p) if avail then return p else loop (succ p)
unlessM :: Monad m => m Bool -> m () -> m ()
unlessM c a = c >>= \res -> unless res a
devel :: DevelOpts -> [String] -> IO () devel :: DevelOpts -> [String] -> IO ()
devel opts passThroughArgs = withSocketsDo $ withManager $ \manager -> do devel opts passThroughArgs = withSocketsDo $ withManager $ \manager -> do
avail <- checkPort $ develPort opts unlessM (checkPort $ develPort opts) $ error "devel port unavailable"
unless avail $ error "devel port unavailable"
iappPort <- getPort opts 17834 >>= I.newIORef iappPort <- getPort opts 17834 >>= I.newIORef
when (useReverseProxy opts) $ void $ forkIO $ reverseProxy opts iappPort when (useReverseProxy opts) $ void $ forkIO $ reverseProxy opts iappPort
checkDevelFile checkDevelFile
@ -287,8 +289,8 @@ runBuildHook Nothing = return ()
-} -}
configure :: DevelOpts -> [String] -> IO Bool configure :: DevelOpts -> [String] -> IO Bool
configure opts extraArgs = configure opts extraArgs =
checkExit =<< (createProcess $ proc (cabalProgram opts) checkExit =<< createProcess (proc (cabalProgram opts) $
([ "configure" [ "configure"
, "-flibrary-only" , "-flibrary-only"
, "-fdevel" , "-fdevel"
, "--disable-library-profiling" , "--disable-library-profiling"
@ -296,7 +298,7 @@ configure opts extraArgs =
, "--with-ghc=yesod-ghc-wrapper" , "--with-ghc=yesod-ghc-wrapper"
, "--with-ar=yesod-ar-wrapper" , "--with-ar=yesod-ar-wrapper"
, "--with-hc-pkg=ghc-pkg" , "--with-hc-pkg=ghc-pkg"
] ++ extraArgs) ] ++ extraArgs
) )
removeFileIfExists :: FilePath -> IO () removeFileIfExists :: FilePath -> IO ()
@ -311,7 +313,7 @@ mkRebuild ghcVer cabalFile opts (ldPath, arPath)
| GHC.cProjectVersion /= ghcVer = | GHC.cProjectVersion /= ghcVer =
failWith "Yesod has been compiled with a different GHC version, please reinstall" failWith "Yesod has been compiled with a different GHC version, please reinstall"
| forceCabal opts = return (rebuildCabal opts) | forceCabal opts = return (rebuildCabal opts)
| otherwise = do | otherwise =
return $ do return $ do
ns <- mapM (cabalFile `isNewerThan`) ns <- mapM (cabalFile `isNewerThan`)
[ "yesod-devel/ghcargs.txt", "yesod-devel/arargs.txt", "yesod-devel/ldargs.txt" ] [ "yesod-devel/ghcargs.txt", "yesod-devel/arargs.txt", "yesod-devel/ldargs.txt" ]
@ -336,7 +338,7 @@ rebuildCabal opts = do
| otherwise = [ "build", "-v0" ] | otherwise = [ "build", "-v0" ]
try_ :: forall a. IO a -> IO () try_ :: forall a. IO a -> IO ()
try_ x = (Ex.try x :: IO (Either Ex.SomeException a)) >> return () try_ x = void (Ex.try x :: IO (Either Ex.SomeException a))
type FileList = Map.Map FilePath EpochTime type FileList = Map.Map FilePath EpochTime
@ -344,7 +346,7 @@ getFileList :: [FilePath] -> [FilePath] -> IO FileList
getFileList hsSourceDirs extraFiles = do getFileList hsSourceDirs extraFiles = do
(files, deps) <- getDeps hsSourceDirs (files, deps) <- getDeps hsSourceDirs
let files' = extraFiles ++ files ++ map fst (Map.toList deps) let files' = extraFiles ++ files ++ map fst (Map.toList deps)
fmap Map.fromList $ flip mapM files' $ \f -> do fmap Map.fromList $ forM files' $ \f -> do
efs <- Ex.try $ getFileStatus f efs <- Ex.try $ getFileStatus f
return $ case efs of return $ case efs of
Left (_ :: Ex.SomeException) -> (f, 0) Left (_ :: Ex.SomeException) -> (f, 0)

View File

@ -11,7 +11,7 @@ import Data.Char (isAlphaNum, isSpace, toLower)
import Data.List (foldl') import Data.List (foldl')
import Data.List.Split (splitOn) import Data.List.Split (splitOn)
import qualified Data.Map as M import qualified Data.Map as M
import Data.Maybe (catMaybes) import Data.Maybe (mapMaybe)
import Data.Monoid import Data.Monoid
import Options.Applicative import Options.Applicative
import Options.Applicative.Types import Options.Applicative.Types
@ -52,10 +52,10 @@ updateA env key upd a =
-- | really simple key/value file reader: x.y = z -> (["x","y"],"z") -- | really simple key/value file reader: x.y = z -> (["x","y"],"z")
configLines :: String -> [([String], String)] configLines :: String -> [([String], String)]
configLines = catMaybes . map (mkLine . takeWhile (/='#')) . lines configLines = mapMaybe (mkLine . takeWhile (/='#')) . lines
where where
trim = let f = reverse . dropWhile isSpace in f . f trim = let f = reverse . dropWhile isSpace in f . f
mkLine l | (k, ('=':v)) <- break (=='=') l = Just (splitOn "." (trim k), trim v) mkLine l | (k, '=':v) <- break (=='=') l = Just (splitOn "." (trim k), trim v)
| otherwise = Nothing | otherwise = Nothing
-- | inject the environment into the parser -- | inject the environment into the parser
@ -75,21 +75,22 @@ injectDefaultP env path p@(OptP o)
| (Option (FlagReader names a) _) <- o = | (Option (FlagReader names a) _) <- o =
p <|> if any ((==Just "1") . getEnvValue env path) names then pure a else empty p <|> if any ((==Just "1") . getEnvValue env path) names then pure a else empty
| otherwise = p | otherwise = p
where
#if MIN_VERSION_optparse_applicative(0,6,0)
right= ReadM . Right
left = ReadM . Left
either' f g (ReadM x) = either f g x
#else
right = Right
left = Left
either' = either
#endif
injectDefaultP env path (MultP p1 p2) = injectDefaultP env path (MultP p1 p2) =
MultP (injectDefaultP env path p1) (injectDefaultP env path p2) MultP (injectDefaultP env path p1) (injectDefaultP env path p2)
injectDefaultP env path (AltP p1 p2) = injectDefaultP env path (AltP p1 p2) =
AltP (injectDefaultP env path p1) (injectDefaultP env path p2) AltP (injectDefaultP env path p1) (injectDefaultP env path p2)
injectDefaultP _env _path b@(BindP {}) = b injectDefaultP _env _path b@(BindP {}) = b
#if MIN_VERSION_optparse_applicative(0,6,0)
right = ReadM . Right
left = ReadM . Left
either' f g (ReadM x) = either f g x
#else
right = Right
left = Left
either' = either
#endif
getEnvValue :: M.Map [String] String -> [String] -> OptName -> Maybe String getEnvValue :: M.Map [String] String -> [String] -> OptName -> Maybe String
getEnvValue env path (OptLong l) = M.lookup (path ++ [normalizeName l]) env getEnvValue env path (OptLong l) = M.lookup (path ++ [normalizeName l]) env

View File

@ -12,6 +12,8 @@ config/client_session_key.aes
.hsenv* .hsenv*
cabal-dev/ cabal-dev/
yesod-devel/ yesod-devel/
.cabal-sandbox
cabal.sandbox.config
{-# START_FILE Application.hs #-} {-# START_FILE Application.hs #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_GHC -fno-warn-orphans #-}

View File

@ -12,6 +12,8 @@ config/client_session_key.aes
.hsenv* .hsenv*
cabal-dev/ cabal-dev/
yesod-devel/ yesod-devel/
.cabal-sandbox
cabal.sandbox.config
{-# START_FILE Application.hs #-} {-# START_FILE Application.hs #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_GHC -fno-warn-orphans #-}

View File

@ -13,6 +13,8 @@ fay/Language/Fay/Yesod.hs
.hsenv* .hsenv*
cabal-dev/ cabal-dev/
yesod-devel/ yesod-devel/
.cabal-sandbox
cabal.sandbox.config
{-# START_FILE Application.hs #-} {-# START_FILE Application.hs #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_GHC -fno-warn-orphans #-}

View File

@ -12,6 +12,8 @@ config/client_session_key.aes
.hsenv* .hsenv*
cabal-dev/ cabal-dev/
yesod-devel/ yesod-devel/
.cabal-sandbox
cabal.sandbox.config
{-# START_FILE Application.hs #-} {-# START_FILE Application.hs #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_GHC -fno-warn-orphans #-}

View File

@ -12,6 +12,8 @@ config/client_session_key.aes
.hsenv* .hsenv*
cabal-dev/ cabal-dev/
yesod-devel/ yesod-devel/
.cabal-sandbox
cabal.sandbox.config
{-# START_FILE Application.hs #-} {-# START_FILE Application.hs #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_GHC -fno-warn-orphans #-}

View File

@ -12,6 +12,8 @@ config/client_session_key.aes
.hsenv* .hsenv*
cabal-dev/ cabal-dev/
yesod-devel/ yesod-devel/
.cabal-sandbox
cabal.sandbox.config
{-# START_FILE Application.hs #-} {-# START_FILE Application.hs #-}
{-# OPTIONS_GHC -fno-warn-orphans #-} {-# OPTIONS_GHC -fno-warn-orphans #-}

View File

@ -15,9 +15,10 @@ import Options (injectDefaults)
import qualified Paths_yesod_bin import qualified Paths_yesod_bin
import Scaffolding.Scaffolder import Scaffolding.Scaffolder
import Options.Applicative.Builder.Internal (Mod, OptionFields)
#if MIN_VERSION_optparse_applicative(0,6,0) #if MIN_VERSION_optparse_applicative(0,6,0)
import Options.Applicative.Types (ReadM (ReadM)) import Options.Applicative.Types (ReadM (ReadM))
#else
import Options.Applicative.Builder.Internal (Mod, OptionFields)
#endif #endif
#ifndef WINDOWS #ifndef WINDOWS

View File

@ -58,7 +58,8 @@
<h1>The application isnt built</h1> <h1>The application isnt built</h1>
<h2>Well keep trying to refresh every second</h2> <h2>Well keep trying to refresh every second</h2>
<div class="msgs"> <div class="msgs">
<p>Meanwhile, here are some motivational messages:</p> <script> document.getElementsByClassName("msgs")[0].style.display = "none"; </script>
<p>Meanwhile, here is a motivational message:</p>
<ul> <ul>
<li>You are a beautiful person making a beautiful web site.</li> <li>You are a beautiful person making a beautiful web site.</li>
<li>Keep going, youve nearly fixed the bug!</li> <li>Keep going, youve nearly fixed the bug!</li>
@ -66,7 +67,20 @@
<li>Get a glass of water, keep hydrated.</li> <li>Get a glass of water, keep hydrated.</li>
</ul> </ul>
</div> </div>
<footer><small><script>document.write(new Date())</script></small></footer> <script>
var msg = document.getElementsByClassName("msgs")[0];
var lis = Array.prototype.slice.call(msg.querySelectorAll("li"));
lis.forEach(function(li){ li.style.display = "none"; });
lis[Math.floor(Math.random() * lis.length)].style.display = "block";
msg.style.display = "block";
</script>
<footer>
<small>
<script>
document.write(new Date())
</script>
</small>
</footer>
</div> </div>
</body> </body>
</html> </html>

View File

@ -1,5 +1,5 @@
name: yesod-bin name: yesod-bin
version: 1.2.4 version: 1.2.4.1
license: MIT license: MIT
license-file: LICENSE license-file: LICENSE
author: Michael Snoyman <michael@snoyman.com> author: Michael Snoyman <michael@snoyman.com>

View File

@ -101,7 +101,7 @@ import Filesystem (createTree)
import qualified Data.Text.Lazy as TL import qualified Data.Text.Lazy as TL
import qualified Data.Text.Lazy.Encoding as TLE import qualified Data.Text.Lazy.Encoding as TLE
import Data.Default import Data.Default
import Text.Lucius (luciusRTMinified) --import Text.Lucius (luciusRTMinified)
import Network.Wai.Application.Static import Network.Wai.Application.Static
( StaticSettings (..) ( StaticSettings (..)
@ -478,10 +478,13 @@ data CombineSettings = CombineSettings
instance Default CombineSettings where instance Default CombineSettings where
def = CombineSettings def = CombineSettings
{ csStaticDir = "static" { csStaticDir = "static"
{- Disabled due to: https://github.com/yesodweb/yesod/issues/623
, csCssPostProcess = \fps -> , csCssPostProcess = \fps ->
either (error . (errorIntro fps)) (return . TLE.encodeUtf8) either (error . (errorIntro fps)) (return . TLE.encodeUtf8)
. flip luciusRTMinified [] . flip luciusRTMinified []
. TLE.decodeUtf8 . TLE.decodeUtf8
-}
, csCssPostProcess = const return
, csJsPostProcess = const return , csJsPostProcess = const return
-- FIXME The following borders on a hack. With combining of files, -- FIXME The following borders on a hack. With combining of files,
-- the final location of the CSS is no longer fixed, so relative -- the final location of the CSS is no longer fixed, so relative

View File

@ -1,5 +1,5 @@
name: yesod-static name: yesod-static
version: 1.2.1 version: 1.2.1.1
license: MIT license: MIT
license-file: LICENSE license-file: LICENSE
author: Michael Snoyman <michael@snoyman.com> author: Michael Snoyman <michael@snoyman.com>