reflex-ghci 0.1.4.1 → 0.1.4.2
raw patch · 7 files changed
+58/−108 lines, 7 filesdep −dependent-sumdep −mtldep −primitivedep ~basedep ~bytestringdep ~reflex-vty
Dependencies removed: dependent-sum, mtl, primitive, ref-tf
Dependency ranges changed: base, bytestring, reflex-vty, text
Files
- ChangeLog.md +5/−0
- README.md +9/−10
- reflex-ghci.cabal +5/−14
- screenshot.png binary
- src/Reflex/Process/GHCi.hs +1/−1
- tests/lib-pkg/dist-newstyle/build/x86_64-linux/ghc-8.8.3/test-pkg2-0.1.0.0/build/autogen/Paths_test_pkg2.hs +0/−50
- tests/test.hs +38/−33
ChangeLog.md view
@@ -1,5 +1,10 @@ # Revision history for reflex-ghci +## 0.1.4.2++* Tests: Ensure proper shutdown.+* Tests: Fix tests for GHC 8.8.4+ ## 0.1.4.1 * Library: Require at least version 0.7.1 of `reflex`.
README.md view
@@ -1,20 +1,20 @@-reflex-ghci-==============+# reflex-ghci -[](https://hackage.haskell.org/package/reflex-ghci) [](https://matrix.hackage.haskell.org/#/package/reflex-ghci) [](https://travis-ci.org/reflex-frp/reflex-ghci)+[](https://haskell.org) [](https://hackage.haskell.org/package/reflex-ghci) [](https://matrix.hackage.haskell.org/#/package/reflex-ghci) [](https://travis-ci.org/reflex-frp/reflex-ghci) [](https://github.com/reflex-frp/reflex-ghci/blob/master/LICENSE) -+Run GHCi from within a [Reflex FRP](https://reflex-frp.org) application and interact with it using a functional reactive interface. -Library--------+++## Library+ A functional-reactive wrapper around GHCi that uses filesystem notifications to automatically reload haskell source files. `Reflex.Process.GHCi` provides the core GHCi process-running infrastructure. If you want to run your own GHCi, directly control when it reloads, or build your own custom interface, look there. `Reflex.Vty.GHCi` provides a few widgets that are useful when building a console GHCi interface. Use these components to assemble your own vty GHCi runner. -Executable-----------+## Executable This package includes a [reflex-vty](https://github.com/reflex-frp/reflex-vty)-based executable, shown above. Module information (errors, warnings, etc) is shown in a scrollable pane on the top half of the screen and the output of any expression you (optionally) choose to evaluate is shown in a scrollable pane on the bottom half. The panes are resizable using the mouse. @@ -34,6 +34,5 @@ ``` -Acknowledgements-----------------+## Acknowledgements Inspired by the fantastic [ghcid](https://github.com/ndmitchell/ghcid) project.
reflex-ghci.cabal view
@@ -1,12 +1,11 @@ cabal-version: 2.4 name: reflex-ghci-version: 0.1.4.1+version: 0.1.4.2 synopsis: A GHCi widget library for use in reflex applications description:- Run GHCi from within a reflex application and interact with it using a functional-reactive interface.+ Run GHCi from within a Reflex FRP (<https://reflex-frp.org>) application and interact with it using a functional reactive interface. . <<https://i.imgur.com/5y61Qx7.png>>- . bug-reports: https://github.com/reflex-frp/reflex-ghci/issues license: BSD-3-Clause license-file: LICENSE@@ -17,17 +16,16 @@ build-type: Simple extra-source-files: ChangeLog.md README.md- screenshot.png tests/**/*.hs tests/**/*.cabal-tested-with: GHC ==8.6.5+tested-with: GHC ==8.6.5 || ==8.8.4 library exposed-modules: Reflex.Process.GHCi Reflex.Vty.GHCi build-depends:- base >= 4.12 && < 4.13+ base >= 4.12 && < 4.14 , bytestring >= 0.10 && < 0.11 , directory >= 1.3 && < 1.4 , filepath >= 1.4 && < 1.5@@ -69,20 +67,13 @@ hs-source-dirs: tests build-depends: base- , bytestring- , dependent-sum >= 0.6 && < 0.7 , directory- , mtl >= 2.2 && < 2.3- , primitive >= 0.6.4 && < 0.8 , process- , ref-tf >= 0.4 && < 0.5 , reflex , reflex-ghci , reflex-process- , reflex-vty , temporary >= 1.3 && < 1.4- , text- ghc-options: -threaded -rtsopts+ ghc-options: -threaded -rtsopts -Wall default-language: Haskell2010 source-repository head
− screenshot.png
binary file changed (118766 → absent bytes)
src/Reflex/Process/GHCi.hs view
@@ -104,7 +104,7 @@ -- We need to know when ghci is initialized enough that it won't die when -- it receives an interrupt. We wait to see the version line in the output as -- a proxy for GHCi's readiness to be interrupted- ghciVersionMessage = "GHCi, version.*: http://www.haskell.org/ghc/" :: ByteString+ ghciVersionMessage = "GHCi, version.*: https?://www.haskell.org/ghc/" :: ByteString -- Inspect the output and determine what state GHCi is in
− tests/lib-pkg/dist-newstyle/build/x86_64-linux/ghc-8.8.3/test-pkg2-0.1.0.0/build/autogen/Paths_test_pkg2.hs
@@ -1,50 +0,0 @@-{-# LANGUAGE CPP #-}-{-# LANGUAGE NoRebindableSyntax #-}-{-# OPTIONS_GHC -fno-warn-missing-import-lists #-}-module Paths_test_pkg2 (- version,- getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir,- getDataFileName, getSysconfDir- ) where--import qualified Control.Exception as Exception-import Data.Version (Version(..))-import System.Environment (getEnv)-import Prelude--#if defined(VERSION_base)--#if MIN_VERSION_base(4,0,0)-catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a-#else-catchIO :: IO a -> (Exception.Exception -> IO a) -> IO a-#endif--#else-catchIO :: IO a -> (Exception.IOException -> IO a) -> IO a-#endif-catchIO = Exception.catch--version :: Version-version = Version [0,1,0,0] []-bindir, libdir, dynlibdir, datadir, libexecdir, sysconfdir :: FilePath--bindir = "/home/elliot/.cabal/bin"-libdir = "/home/elliot/.cabal/lib/x86_64-linux-ghc-8.8.3/test-pkg2-0.1.0.0-inplace"-dynlibdir = "/home/elliot/.cabal/lib/x86_64-linux-ghc-8.8.3"-datadir = "/home/elliot/.cabal/share/x86_64-linux-ghc-8.8.3/test-pkg2-0.1.0.0"-libexecdir = "/home/elliot/.cabal/libexec/x86_64-linux-ghc-8.8.3/test-pkg2-0.1.0.0"-sysconfdir = "/home/elliot/.cabal/etc"--getBinDir, getLibDir, getDynLibDir, getDataDir, getLibexecDir, getSysconfDir :: IO FilePath-getBinDir = catchIO (getEnv "test_pkg2_bindir") (\_ -> return bindir)-getLibDir = catchIO (getEnv "test_pkg2_libdir") (\_ -> return libdir)-getDynLibDir = catchIO (getEnv "test_pkg2_dynlibdir") (\_ -> return dynlibdir)-getDataDir = catchIO (getEnv "test_pkg2_datadir") (\_ -> return datadir)-getLibexecDir = catchIO (getEnv "test_pkg2_libexecdir") (\_ -> return libexecdir)-getSysconfDir = catchIO (getEnv "test_pkg2_sysconfdir") (\_ -> return sysconfdir)--getDataFileName :: FilePath -> IO FilePath-getDataFileName name = do- dir <- getDataDir- return (dir ++ "/" ++ name)
tests/test.hs view
@@ -3,22 +3,19 @@ {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ScopedTypeVariables #-} -import Reflex-import Reflex.Host.Headless-import Reflex.Process.GHCi-import Reflex.Vty-import Reflex.Vty.GHCi-import Reflex.Workflow -import Control.Monad (void) import Control.Monad.Fix (MonadFix)-import Control.Monad.IO.Class (liftIO, MonadIO)-import Data.ByteString (ByteString)+import Control.Monad.IO.Class (MonadIO, liftIO)+import Reflex+import Reflex.Host.Headless (runHeadlessApp)+import Reflex.Workflow (Workflow (..), workflow)+import System.Directory (copyFile, getCurrentDirectory, withCurrentDirectory)+import System.IO.Temp (withSystemTempDirectory) import qualified System.Process as P-import System.Directory-import System.Environment-import System.IO.Temp +import Reflex.Process.GHCi+import Reflex.Vty.GHCi+ ghciExe :: FilePath ghciExe = "ghci" @@ -36,7 +33,7 @@ -- | testExprFinished | Status_LoadSucceeded | Status_ExecutionSucceeded | main :: IO ()-main = withSystemTempDirectory "reflex-ghci-test" $ \tmpdir -> do+main = do src <- getCurrentDirectory let cmd path load = P.proc ghciExe ["-i" <> src <> path, load] putStrLn "Testing lib-pkg"@@ -98,9 +95,9 @@ Status_LoadSucceeded -> Just True Status_LoadFailed -> Just False _ -> Nothing- void $ shutdown $ g <$ loaded- return ( Failed . show <$> ffilter not loaded- , testExprErr cmd <$ ffilter id loaded+ done <- afterShutdown g loaded+ return ( Failed . show <$> ffilter not done+ , testExprErr cmd <$ ffilter id done ) testExprErr@@ -121,9 +118,9 @@ Status_ExecutionFailed -> Just True Status_ExecutionSucceeded -> Just False _ -> Nothing- void $ shutdown $ g <$ exception- return ( Failed . show <$> ffilter not exception- , testExprNotFound cmd <$ ffilter id exception+ done <- afterShutdown g exception+ return ( Failed . show <$> ffilter not done+ , testExprNotFound cmd <$ ffilter id done ) testExprNotFound@@ -141,12 +138,12 @@ liftIO $ putStrLn "testExprNotFound" g <- ghciWatch cmd $ Just "notTheFunctionYoureLookingFor" let exception = fforMaybe (updated $ _ghci_status g) $ \case- Status_ExecutionFailed -> Just True- Status_ExecutionSucceeded -> Just False- _ -> Nothing- void $ shutdown $ g <$ exception- return ( Failed . show <$> ffilter not exception- , testExprFinished cmd <$ ffilter id exception+ Status_ExecutionFailed -> Just True+ Status_ExecutionSucceeded -> Just False+ _ -> Nothing+ done <- afterShutdown g exception+ return ( Failed . show <$> ffilter not done+ , testExprFinished cmd <$ ffilter id done ) testExprFinished@@ -163,11 +160,11 @@ testExprFinished cmd = Workflow $ do liftIO $ putStrLn "testExprFinished" g <- ghciWatch cmd $ Just "done"- let done = fforMaybe (updated $ _ghci_status g) $ \case- Status_ExecutionFailed -> Just False- Status_ExecutionSucceeded -> Just True- _ -> Nothing- void $ shutdown $ g <$ done+ let finished = fforMaybe (updated $ _ghci_status g) $ \case+ Status_ExecutionFailed -> Just False+ Status_ExecutionSucceeded -> Just True+ _ -> Nothing+ done <- afterShutdown g finished return ( outcome done , never )@@ -203,8 +200,9 @@ if x > 1 then Just $ error "Too many failures." else Nothing- return $ gate ((>= 1) <$> current numFailures) loadSucceeded + afterShutdown g $ gate ((>= 1) <$> current numFailures) loadSucceeded+ testModuleLoadFailed :: ( MonadIO m , TriggerEvent t m@@ -223,8 +221,15 @@ Status_LoadSucceeded -> Just False Status_LoadFailed -> Just True _ -> Nothing- void $ shutdown $ g <$ loaded- return $ ffor loaded $ \x ->+ done <- afterShutdown g loaded+ return $ ffor done $ \x -> if x then Succeeded else Failed "testModuleFailed: lib-pkg-err shouldn't have loaded"++-- | Utility to help use an 'Event' for stopping the network, but not until the shutdown is complete.+afterShutdown :: (PerformEvent t m, MonadIO (Performable m), MonadHold t m) => Ghci t -> Event t b -> m (Event t b)+afterShutdown g e = do+ eValue <- hold Nothing $ Just <$> e+ after <- shutdown $ g <$ e+ pure $ fmapMaybe id $ tag eValue after