packages feed

turtle 1.5.14 → 1.5.15

raw patch · 7 files changed

+213/−19 lines, 7 filesdep +faildep +streaming-commonsdep ~basedep ~textdep ~time

Dependencies added: fail, streaming-commons

Dependency ranges changed: base, text, time

Files

CHANGELOG.md view
@@ -1,3 +1,11 @@+1.5.15++* Add `toLines`+* Add `Turtle.Bytes.{fromUTF8,toUTF8}`+* Add `Turtle.Bytes.{compress,decompress}`+* Always expose a `MonadFail` instance, relying on the `fail` package+  where needed. Related GHC 8.8 preparedness.+ 1.5.14  * Fix `cptree` to copy symlinks instead of descending into them
src/Turtle/Bytes.hs view
@@ -16,6 +16,12 @@     , append     , stderr     , strict+    , compress+    , decompress+    , WindowBits(..)+    , Zlib.defaultWindowBits+    , fromUTF8+    , toUTF8      -- * Subprocess management     , proc@@ -43,7 +49,9 @@ import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.Managed (MonadManaged(..)) import Data.ByteString (ByteString)+import Data.Streaming.Zlib (Inflate, Popper, PopperRes(..), WindowBits(..)) import Data.Text (Text)+import Data.Text.Encoding (Decoding(..)) import Filesystem.Path (FilePath) import Prelude hiding (FilePath) import System.Exit (ExitCode(..))@@ -61,7 +69,10 @@ import qualified Control.Monad import qualified Control.Monad.Managed         as Managed import qualified Data.ByteString+import qualified Data.Streaming.Zlib           as Zlib import qualified Data.Text+import qualified Data.Text.Encoding            as Encoding+import qualified Data.Text.Encoding.Error      as Encoding.Error import qualified Foreign import qualified System.IO import qualified System.Process                as Process@@ -657,3 +668,136 @@     -> Shell (Either ByteString ByteString)     -- ^ Chunks of either output (`Right`) or error (`Left`) inshellWithErr cmd = streamWithErr (Process.shell (Data.Text.unpack cmd))++-- | Internal utility used by both `compress` and `decompress`+fromPopper :: Popper -> Shell ByteString+fromPopper popper = loop+  where+    loop = do+        result <- liftIO popper++        case result of+            PRDone ->+                empty+            PRNext compressedByteString ->+                return compressedByteString <|> loop+            PRError exception ->+                liftIO (Exception.throwIO exception)++{-| Compress a stream using @zlib@++    Note that this can decompress streams that are the concatenation of+    multiple compressed streams (just like @gzip@)++>>> let compressed = select [ "ABC", "DEF" ] & compress 0 defaultWindowBits+>>> compressed & decompress defaultWindowBits & view+"ABCDEF"+>>> (compressed <|> compressed) & decompress defaultWindowBits & view+"ABCDEF"+"ABCDEF"+-}+compress+    :: Int+    -- ^ Compression level+    -> WindowBits+    -- ^+    -> Shell ByteString+    -- ^+    -> Shell ByteString+compress compressionLevel windowBits bytestrings = do+    deflate <- liftIO (Zlib.initDeflate compressionLevel windowBits)++    let loop = do+            bytestring <- bytestrings++            popper <- liftIO (Zlib.feedDeflate deflate bytestring)++            fromPopper popper++    let wrapUp = do+            let popper = liftIO (Zlib.finishDeflate deflate)++            fromPopper popper++    loop <|> wrapUp++data DecompressionState = Uninitialized | Decompressing Inflate++-- | Decompress a stream using @zlib@ (just like the @gzip@ command)+decompress :: WindowBits -> Shell ByteString -> Shell ByteString+decompress windowBits (Shell k) = Shell k'+  where+    k' (FoldShell step begin done) = k (FoldShell step' begin' done')+      where+        begin' = (begin, Uninitialized)++        step' (x0, Uninitialized) compressedByteString = do+            inflate <- Zlib.initInflate windowBits++            step' (x0, Decompressing inflate) compressedByteString+        step' (x0, Decompressing inflate) compressedByteString = do+            popper <- Zlib.feedInflate inflate compressedByteString++            let loop x = do+                    result <- popper++                    case result of+                        PRDone -> do+                            compressedByteString' <- Zlib.getUnusedInflate inflate++                            if Data.ByteString.null compressedByteString'+                                then return (x, Decompressing inflate)+                                else do+                                    decompressedByteString <- Zlib.finishInflate inflate++                                    x' <- step x decompressedByteString++                                    step' (x', Uninitialized) compressedByteString'+                        PRNext decompressedByteString -> do+                            x' <- step x decompressedByteString++                            loop x'+                        PRError exception -> do+                            Exception.throwIO exception++            loop x0++        done' (x0, Uninitialized) = do+            done x0+        done' (x0, Decompressing inflate) = do+            decompressedByteString <- Zlib.finishInflate inflate++            x0' <- step x0 decompressedByteString++            done' (x0', Uninitialized)++{-| Decode a stream of bytes as UTF8 `Text`++    NOTE: This function will throw a pure exception (i.e. an `error`) if UTF8+    decoding fails (mainly due to limitations in the @text@ package's stream+    decoding API)+-}+toUTF8 :: Shell ByteString -> Shell Text+toUTF8 (Shell k) = Shell k'+  where+    k' (FoldShell step begin done) =+        k (FoldShell step' begin' done')+      where+        begin' =+            (mempty, Encoding.streamDecodeUtf8With Encoding.Error.strictDecode, begin)++        step' (prefix, decoder, x) suffix = do+            let bytes = prefix <> suffix++            let Some text prefix' decoder' = decoder bytes ++            x' <- step x text++            return (prefix', decoder', x')++        done' (_, _, x) = do+            done x++-- | Encode a stream of bytes as UTF8 `Text`+fromUTF8 :: Shell Text -> Shell ByteString+fromUTF8 = fmap Encoding.encodeUtf8
src/Turtle/Prelude.hs view
@@ -206,6 +206,7 @@     , sort     , sortOn     , sortBy+    , toLines      -- * Folds     , countChars@@ -300,7 +301,7 @@ import Control.Foldl (Fold(..), genericLength, handles, list, premap) import qualified Control.Foldl import qualified Control.Foldl.Text-import Control.Monad (guard, liftM, msum, when, unless, (>=>), mfilter)+import Control.Monad (foldM, guard, liftM, msum, when, unless, (>=>), mfilter) import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.Managed (MonadManaged(..), managed, managed_, runManaged) #ifdef mingw32_HOST_OS@@ -308,6 +309,8 @@ #endif import Data.IORef (newIORef, readIORef, writeIORef) import qualified Data.List as List+import Data.List.NonEmpty (NonEmpty(..))+import qualified Data.List.NonEmpty as NonEmpty import Data.Monoid ((<>)) import Data.Ord (comparing) import qualified Data.Set as Set@@ -354,7 +357,7 @@     touchFile ) import System.Posix.Files (createSymbolicLink)       #endif-import Prelude hiding (FilePath)+import Prelude hiding (FilePath, lines)  import Turtle.Pattern (Pattern, anyChar, chars, match, selfless, sepBy) import Turtle.Shell@@ -2166,3 +2169,39 @@ -- [(1,'a'),(2,'c'),(3,'d'),(3,'e'),(4,'b'),(7,'f')] sortBy :: (Functor io, MonadIO io) => (a -> a -> Ordering) -> Shell a -> io [a] sortBy f s = List.sortBy f <$> fold s list++{-| Group an arbitrary stream of `Text` into newline-delimited `Line`s++>>> stdout (toLines ("ABC" <|> "DEF" <|> "GHI")+ABCDEFGHI+>>> stdout (toLines empty)  -- Note that this always emits at least 1 `Line`++>>> stdout (toLines ("ABC\nDEF" <|> "" <|> "GHI\nJKL"))+ABC+DEFGHI+JKL+-}+toLines :: Shell Text -> Shell Line+toLines (Shell k) = Shell k'+  where+    k' (FoldShell step begin done) =+        k (FoldShell step' begin' done')+      where+        step' (Pair x prefix) text = do+            let suffix :| lines = Turtle.Line.textToLines text++            let line = prefix <> suffix++            let lines' = line :| lines++            x' <- foldM step x (NonEmpty.init lines')++            let prefix' = NonEmpty.last lines'++            return (Pair x' prefix')++        begin' = (Pair begin "")++        done' (Pair x prefix) = do+            x' <- step x prefix+            done x'
src/Turtle/Shell.hs view
@@ -81,9 +81,7 @@ import Control.Monad.Catch (MonadThrow(..), MonadCatch(..)) import Control.Monad.IO.Class (MonadIO(..)) import Control.Monad.Managed (MonadManaged(..), with)-#if MIN_VERSION_base(4,9,0) import qualified Control.Monad.Fail as Fail-#endif import Control.Foldl (Fold(..), FoldM(..)) import qualified Control.Foldl as Foldl import Data.Foldable (Foldable)@@ -182,7 +180,9 @@         let step1 x a = _foldShell (f a) (FoldShell step0 x return)         _foldShell m (FoldShell step1 begin0 done0) ) -    fail _ = mzero+#if!(MIN_VERSION_base(4,13,0))+    fail = Fail.fail+#endif  instance Alternative Shell where     empty = Shell (\(FoldShell _ begin done) -> done begin)@@ -213,10 +213,8 @@ instance MonadCatch Shell where     m `catch` k = Shell (\f-> _foldShell m f `catch` (\e -> _foldShell (k e) f)) -#if MIN_VERSION_base(4,9,0) instance Fail.MonadFail Shell where-    fail = Prelude.fail-#endif+    fail _ = mzero  #if __GLASGOW_HASKELL__ >= 804 instance Monoid a => Semigroup (Shell a) where
src/Turtle/Tutorial.hs view
@@ -1490,10 +1490,10 @@  -- $monadio ----- If you are sick of having type `liftIO` everywhere, you can omit it.  This--- is because all subroutines in @turtle@ are overloaded using the `MonadIO`--- type class, like our original `pwd` command where we first encountered the--- the `MonadIO` type:+-- If you are sick of having to type `liftIO` everywhere, you can omit it.+-- This is because all subroutines in @turtle@ are overloaded using the+-- `MonadIO` type class, like our original `pwd` command where we first+-- encountered the the `MonadIO` type: -- -- @ -- Prelude Turtle> :type pwd
test/cptree.hs view
@@ -3,10 +3,11 @@ import Turtle import Filesystem.Path.CurrentOS () import System.IO.Temp (withSystemTempDirectory)+import qualified Control.Monad.Fail as Fail import Control.Monad (unless)  check :: String -> Bool-> IO ()-check errorMessage successs = unless successs $ fail errorMessage+check errorMessage successs = unless successs $ Fail.fail errorMessage  main :: IO () main = withSystemTempDirectory "tempDir" (runTest . fromString)
turtle.cabal view
@@ -1,5 +1,5 @@ Name: turtle-Version: 1.5.14+Version: 1.5.15 Cabal-Version: >=1.10 Build-Type: Simple License: BSD3@@ -53,7 +53,7 @@         ansi-wl-pprint       >= 0.6     && < 0.7 ,         async                >= 2.0.0.0 && < 2.3 ,         bytestring           >= 0.9.1.8 && < 0.11,-        clock                >= 0.4.1.2 && < 0.8 ,+        clock                >= 0.4.1.2 && < 0.9 ,         containers           >= 0.5.0.0 && < 0.7 ,         directory            >= 1.0.7   && < 1.4 ,         exceptions           >= 0.4     && < 0.11,@@ -61,21 +61,24 @@         hostname                           < 1.1 ,         managed              >= 1.0.3   && < 1.1 ,         process              >= 1.0.1.1 && < 1.7 ,-        semigroups           >= 0.5.0   && < 0.19,+        semigroups           >= 0.5.0   && < 0.20,         system-filepath      >= 0.3.1   && < 0.5 ,         system-fileio        >= 0.2.1   && < 0.4 ,         stm                                < 2.6 ,+        streaming-commons                  < 0.3 ,         temporary                          < 1.4 ,-        text                               < 1.3 ,-        time                               < 1.9 ,+        text                 >= 1.0.0   && < 1.3 ,+        time                               < 1.10,         transformers         >= 0.2.0.0 && < 0.6 ,-        optparse-applicative >= 0.13    && < 0.15,+        optparse-applicative >= 0.13    && < 0.16,         optional-args        >= 1.0     && < 2.0 ,         unix-compat          >= 0.4     && < 0.6     if os(windows)         Build-Depends: Win32 >= 2.2.0.1 && < 2.9     else         Build-Depends: unix  >= 2.5.1.0 && < 2.8+    if !impl(ghc >= 8.0)+        Build-Depends: fail  >= 4.9.0.0 && < 4.10     Exposed-Modules:         Turtle,         Turtle.Bytes,@@ -129,6 +132,7 @@     Default-Language: Haskell2010     Build-Depends:         base   >= 4 && < 5,+        fail,         temporary,         system-filepath >= 0.4,         turtle