packages feed

aspell-pipe 0.3 → 0.4

raw patch · 4 files changed

+50/−60 lines, 4 filesdep +asyncPVP ok

version bump matches the API change (PVP)

Dependencies added: async

API changes (from Hackage documentation)

Files

+ CHANGELOG.md view
@@ -0,0 +1,34 @@++0.4+---++Misc changes:+ * The package now uses and depends on `async` instead of using raw+   `forkIO`.++0.3+---++Package changes:+ * Relaxed process lower bound to version 1.3.++API changes:+ * Added 'aspellDictionaries' to obtain the list of installed+   dictionaries.++Other changes:+ * startAspell now gracefully handles Aspell startup failures by+   reporting Aspell's standard error output in the event of a failed+   startup. It also sanity-checks the Aspell pipe mode identification+   string. (Fixes #2, #3.)+++0.2+---++* Relaxed base upper bound to < 5.++0.1+---++Initial release.
− ChangeLog.md
@@ -1,24 +0,0 @@--0.3------API changes:- * Added 'aspellDictionaries' to obtain the list of installed-   dictionaries.--Other changes:- * startAspell now gracefully handles Aspell startup failures by-   reporting Aspell's standard error output in the event of a failed-   startup. It also sanity-checks the Aspell pipe mode identification-   string. (Fixes #2, #3.)---0.2------* Relaxed base upper bound to < 5.--0.1------Initial release.
aspell-pipe.cabal view
@@ -1,5 +1,5 @@ name:                aspell-pipe-version:             0.3+version:             0.4 synopsis:            Pipe-based interface to the Aspell program description:         A pipe-based interface to the Aspell program (no                      dynamic linking required).@@ -10,8 +10,8 @@ copyright:           2017 Jonathan Daugherty category:            Text build-type:          Simple-extra-source-files:  ChangeLog.md-cabal-version:       >=1.10+extra-source-files:  CHANGELOG.md+cabal-version:       1.18  extra-doc-files:     README.md @@ -25,6 +25,7 @@    hs-source-dirs:      src   default-language:    Haskell2010-  build-depends:       base >=4.8 && <5,+  build-depends:       base    >= 4.8 && < 5,+                       async   >= 2.2 && < 2.3,                        process >= 1.3,                        text
src/Text/Aspell.hs view
@@ -24,8 +24,7 @@  import qualified Control.Exception as E import Control.Monad (forM, when, void)-import Control.Concurrent (forkIO, killThread)-import Control.Concurrent.MVar (takeMVar, newEmptyMVar, putMVar)+import qualified Control.Concurrent.Async as A import Data.Monoid ((<>)) import Data.Maybe (fromJust) import Text.Read (readMaybe)@@ -40,7 +39,7 @@     Aspell { aspellProcessHandle  :: P.ProcessHandle            , aspellStdin          :: Handle            , aspellStdout         :: Handle-           , aspellIdentification :: T.Text+           , aspellIdentification :: T.Text -- ^ startup-reported version string            }  instance Show Aspell where@@ -94,43 +93,23 @@              (Just inH, Just outH, Just errH, ph) <- P.createProcess proc -            -- Set up an mvar to hold the first available aspell output.-            -- In this we store the first available stdout or stderr-            -- line; if aspell dies immediately then we can expect a-            -- stderr read (the error message), but on success we expect-            -- a stdout read (the identification string). We fork two-            -- threads: one to read stdout, one stderr. Whichever one-            -- gets a result first tells us whether Aspell started-            -- successfully. If the stderr thread wins, the stdout-            -- thread will get an exception on hGetLine due to stdout-            -- being closed, so we have to handle that. If the stdout-            -- thread wins, the stderr thread will block forever and we-            -- need to kill it.-            initialResult <- newEmptyMVar+            errorAsync <- A.async (T.hGetLine errH) -            void $ forkIO $ do-                identResult <- E.try $ T.hGetLine outH-                case identResult of-                    -- A failure means aspell died, so the stderr thread-                    -- should have something to read.-                    Left (_::E.SomeException) -> return ()-                    Right ident -> putMVar initialResult $ Right ident+            -- If startup is unsuccessful, stdout will close without output.+            result <- E.try (T.hGetLine outH) :: IO (Either E.SomeException T.Text) -            errThread <- forkIO $ do-                err <- T.hGetLine errH-                putMVar initialResult $ Left err+            case result of+                Left{} -> do+                    e <- A.wait errorAsync+                    fail ("Error starting aspell: " <> T.unpack e) -            status <- takeMVar initialResult-            case status of-                Left e -> error $ "Error starting aspell: " <> show e                 Right ident -> do-                    killThread errThread-+                    A.cancel errorAsync                     -- Now that aspell has started and we got an                     -- identification string, we need to make sure it                     -- looks legitimate before we proceed.                     case validIdent ident of-                        False -> error $ "Unexpected identification string: " <> show ident+                        False -> fail ("Unexpected identification string: " <> T.unpack ident)                         True -> do                             let as = Aspell { aspellProcessHandle  = ph                                             , aspellStdin          = inH