turtle 1.0.1 → 1.0.2
raw patch · 6 files changed
+100/−62 lines, 6 filesdep ~base
Dependency ranges changed: base
Files
- src/Turtle/Format.hs +8/−0
- src/Turtle/Pattern.hs +20/−3
- src/Turtle/Prelude.hs +12/−1
- src/Turtle/Shell.hs +1/−1
- src/Turtle/Tutorial.hs +57/−55
- turtle.cabal +2/−2
src/Turtle/Format.hs view
@@ -57,6 +57,7 @@ , e , g , s+ , fp -- * Utilities , repr@@ -67,6 +68,7 @@ import Data.String (IsString(..)) import Data.Text (Text, pack) import Data.Word (Word)+import Filesystem.Path.CurrentOS (FilePath, toText) import Numeric (showEFloat, showFFloat, showGFloat, showHex, showOct) import Prelude hiding ((.), id, FilePath) @@ -185,5 +187,11 @@ >>> repr (1,2) "(1,2)" -}++{-| `Format` a `Filesystem.Path.CurrentOS` into `Text`+-}+fp :: Format r (FilePath -> r)+fp = makeFormat (\fpath -> either id id (toText fpath))+ repr :: Show a => a -> Text repr = format w
src/Turtle/Pattern.hs view
@@ -92,6 +92,10 @@ , fixed , sepBy , sepBy1++ -- * High-efficiency primitives+ , chars+ , chars1 ) where import Control.Applicative@@ -450,7 +454,7 @@ ["A"] -} prefix :: Pattern a -> Pattern a-prefix p = p <* star anyChar+prefix p = p <* chars {-| Use this to match the suffix of a string @@ -460,7 +464,7 @@ ["C"] -} suffix :: Pattern a -> Pattern a-suffix p = star anyChar *> p+suffix p = chars *> p {-| Use this to match the interior of a string @@ -470,7 +474,7 @@ ["B"] -} has :: Pattern a -> Pattern a-has p = star anyChar *> p <* star anyChar+has p = chars *> p <* chars {-| Parse 0 or more occurrences of the given character @@ -478,6 +482,8 @@ ["123"] >>> match (star anyChar) "" [""]++ See also: `chars` -} star :: Pattern Char -> Pattern Text star p = fmap Text.pack (many p)@@ -488,6 +494,8 @@ ["123"] >>> match (plus anyChar) "" []++ See also: `chars1` -} plus :: Pattern Char -> Pattern Text plus p = fmap Text.pack (some p)@@ -612,3 +620,12 @@ -} sepBy1 :: Pattern a -> Pattern b -> Pattern [a] p `sepBy1` sep = (:) <$> p <*> many (sep *> p) ++-- | Like @star dot@ or @star anyChar@, except more efficient+chars :: Pattern Text+chars = Pattern (StateT (\txt ->+ reverse (zip (Text.inits txt) (Text.tails txt)) ))++-- | Like @plus dot@ or @plus anyChar@, except more efficient+chars1 :: Pattern Text+chars1 = Text.cons <$> dot <*> chars
src/Turtle/Prelude.hs view
@@ -378,7 +378,7 @@ ls path = Shell (\(FoldM step begin done) -> do x0 <- begin let path' = Filesystem.encodeString path- canRead <- fmap readable (getPermissions path')+ canRead <- fmap readable (getPermissions (deslash path')) #ifdef mingw32_HOST_OS reparse <- fmap reparsePoint (Win32.getFileAttributes path') if (canRead && not reparse)@@ -412,6 +412,17 @@ loop $! x0 ) else done x0 ) #endif++{-| This is used to remove the trailing slash from a path, because+ `getDirectoryPermissions` will fail if a path ends with a trailing slash+-}+deslash :: String -> String+deslash [] = []+deslash (c:cs) = c:go cs+ where+ go [] = []+ go ['\\'] = []+ go (c:cs) = c:go cs -- | Stream all recursive descendents of the given directory lstree :: FilePath -> Shell FilePath
src/Turtle/Shell.hs view
@@ -47,7 +47,7 @@ > -- For every shell `s`: > foldIO s (FoldM step begin done) = do-> x <- step+> x <- begin > x' <- foldIO s (FoldM step (return x) return) > done x'
src/Turtle/Tutorial.hs view
@@ -64,15 +64,15 @@ -- * Loops -- $loops - -- * External commands- -- $external- -- * Folds -- $folds -- * Input and output -- $io + -- * External commands+ -- $external+ -- * Patterns -- $patterns @@ -116,7 +116,9 @@ -- code to generate a native executable which will have a much faster startup -- time and improved performance: ----- > $ ghc -O2 example.hs # -O2 turns on all optimizations+-- > $ # `-O2` turns on all optimizations+-- > $ # `-threaded` helps with piping shell output in and out of Haskell+-- > $ ghc -O2 -threaded example.hs -- > $ ./example -- > Hello, world! --@@ -1000,56 +1002,6 @@ -- > FilePath "/tmp/ssh-vREYGbWGpiCa" -- > FilePath "/tmp/.ICE-unix" --- $external------ You can embed external shell commands as streams within your Haskell program.------ For example, suppose that we want to use the system's built in @ls@ command.--- We can just run:------ > Prelude Turtle> stdout (inshell "ls" empty)--- > .X11-unix--- > .X0-lock--- > pulse-PKdhtXMmr18n--- > pulse-xHYcZ3zmN3Fv--- > tracker-gabriel--- > pulse-PYi1hSlWgNj2--- > orbit-gabriel--- > ssh-vREYGbWGpiCa--- > .ICE-unix------ This works because type of `inshell` is:------ @--- `inshell`--- :: Text -- Command line--- -> Shell Text -- Standard input to feed to program--- -> Shell Text -- Standard output produced by program--- @------ This means you can use `inshell` to embed arbitrary external utilities as--- first class streams within your Haskell program:------ > Turtle Prelude> stdout (inshell "awk '{ print $1 }'" "123 456")--- > 123------ You should also check out the `inproc` command, which is less powerful but--- safer since it decreases the likelihood of code injection or malformed--- commands:------ @--- `inproc`--- :: Text -- Program--- -> [Text] -- Arguments--- -> Shell Text -- Standard input to feed to program--- -> Shell Text -- Standard output produced by program--- @------ Using `inproc`, you would write:------ > Turtle Prelude> stdout (inproc "awk" ["{ print $1 }"] "123 456")--- > 123- -- $folds -- -- There are other ways you can consume a `Shell` stream. For example, you can@@ -1092,7 +1044,7 @@ -- `stdout` :: Shell Text -> IO () -- `stdout` s = sh (do -- txt <- s--- liftIO (echo txt)+-- liftIO (echo txt) ) -- @ -- -- `stdout` outputs each `Text` value on its own line:@@ -1144,6 +1096,56 @@ -- ABC -- 42 -- @++-- $external+--+-- You can embed external shell commands as streams within your Haskell program.+--+-- For example, suppose that we want to use the system's built in @ls@ command.+-- We can just run:+--+-- > Prelude Turtle> stdout (inshell "ls" empty)+-- > .X11-unix+-- > .X0-lock+-- > pulse-PKdhtXMmr18n+-- > pulse-xHYcZ3zmN3Fv+-- > tracker-gabriel+-- > pulse-PYi1hSlWgNj2+-- > orbit-gabriel+-- > ssh-vREYGbWGpiCa+-- > .ICE-unix+--+-- This works because type of `inshell` is:+--+-- @+-- `inshell`+-- :: Text -- Command line+-- -> Shell Text -- Standard input to feed to program+-- -> Shell Text -- Standard output produced by program+-- @+--+-- This means you can use `inshell` to embed arbitrary external utilities as+-- first class streams within your Haskell program:+--+-- > Turtle Prelude> stdout (inshell "awk '{ print $1 }'" "123 456")+-- > 123+--+-- You should also check out the `inproc` command, which is less powerful but+-- safer since it decreases the likelihood of code injection or malformed+-- commands:+--+-- @+-- `inproc`+-- :: Text -- Program+-- -> [Text] -- Arguments+-- -> Shell Text -- Standard input to feed to program+-- -> Shell Text -- Standard output produced by program+-- @+--+-- Using `inproc`, you would write:+--+-- > Turtle Prelude> stdout (inproc "awk" ["{ print $1 }"] "123 456")+-- > 123 -- $patterns --
turtle.cabal view
@@ -1,5 +1,5 @@ Name: turtle-Version: 1.0.1+Version: 1.0.2 Cabal-Version: >=1.10 Build-Type: Simple License: BSD3@@ -46,7 +46,7 @@ Library HS-Source-Dirs: src Build-Depends:- base >= 4 && < 5 ,+ base >= 4.5 && < 5 , async >= 2.0.0.0 && < 2.1, clock >= 0.4.1.2 && < 0.5, directory < 1.3,