crunghc 0.1.0.0 → 0.1.1.1
raw patch · 2 files changed
+56/−5 lines, 2 files
Files
- crunghc.cabal +6/−1
- main.hs +50/−4
crunghc.cabal view
@@ -2,7 +2,7 @@ -- documentation, see http://haskell.org/cabal/users-guide/ name: crunghc-version: 0.1.0.0+version: 0.1.1.1 synopsis: A runghc replacement with transparent caching description: crunghc is a program that acts like runghc. When it executes a Haskell script, it automatically stores a@@ -18,6 +18,10 @@ -- extra-source-files: cabal-version: >=1.10 +source-repository head+ type: git+ location: https://github.com/takano-akio/crunghc.git+ executable crunghc main-is: main.hs -- other-modules: @@ -27,6 +31,7 @@ transformers >= 0.3, filelock >= 0.0, time >= 1.4 -- hs-source-dirs: default-language: Haskell2010+ ghc-options: -threaded if !os(windows) build-depends: unix
main.hs view
@@ -1,4 +1,5 @@ {-# LANGUAGE CPP #-}+{-# LANGUAGE DeriveDataTypeable #-} import Control.Applicative import qualified Control.Exception as E@@ -10,11 +11,12 @@ import Data.Char import qualified Data.Digest.Pure.SHA as SHA import Data.List+import Data.Maybe+import Data.Monoid import qualified Data.Text as T import qualified Data.Text.Encoding as T import Data.Time.Clock-import Data.Maybe-import Data.Monoid+import Data.Typeable import System.Directory import System.Environment import System.Exit@@ -25,7 +27,9 @@ import System.Process #if USE_UNIX+import Control.Concurrent (myThreadId) import System.Posix.Files (createLink)+import qualified System.Posix.Signals as Sig #endif data Config = Config@@ -47,10 +51,22 @@ main :: IO () main = do+ installSignalHandlers config <- fromRightIO . parseConfig =<< getArgs plan <- chooseCachePlan config createDirectoryIfMissing True $ cpCachedir plan- (tempExeCopy, cleanup) <- withFileLock (lockfile plan) Exclusive $ \_ -> do+ E.bracket+ (prepareExecutable config plan)+ snd -- cleanup+ (runTemp config . fst)+ `E.catch` \(KilledBySignal _) -> exitFailure++-- | Prepare a cached executable by rebuilding it if necessary.+-- Return a fresh copy or link of the executable and a cleanup action.+prepareExecutable+ :: Config -> CachePlan -> IO (FilePath, IO ())+prepareExecutable config plan =+ withFileLock (lockfile plan) Exclusive $ \_ -> do needRecomp <- testRecompilationNeeded config plan when needRecomp $ recompile config plan @@ -61,7 +77,6 @@ -- the cached executable after we unlock it and before we execute it. -- 2. on Windows you cannot replace an executable while it's running. makeTemporaryExeCopy plan- runTemp config tempExeCopy `E.finally` cleanup parseConfig :: [String] -> Either String Config parseConfig args = case span ("-" `isPrefixOf`) args of@@ -221,6 +236,37 @@ looksLikeSourceFile = ".hs" `isSuffixOf` ln || ".lhs" `isSuffixOf` ln++----------+-- signals++newtype KilledBySignal = KilledBySignal Signal+ deriving (Show, Typeable)++instance E.Exception KilledBySignal++#if USE_UNIX+type Signal = Sig.Signal+#else+type Signal = ()+#endif++-- | Install signal handlers that turn signals into KilledBySignal exceptions.+installSignalHandlers :: IO ()+#if USE_UNIX+installSignalHandlers = do+ tid <- myThreadId+ forM_ [Sig.softwareTermination] $ \sig ->+ void $ Sig.installHandler sig (handler tid sig) Nothing+ where+ handler tid sig = Sig.Catch $ do+ E.throwTo tid $ KilledBySignal sig+#else+installSignalHandlers = return ()+#endif++------------+-- utilities takeWhileEnd :: (a -> Bool) -> [a] -> [a] takeWhileEnd p = reverse . takeWhile p . reverse