shh 0.7.2.0 → 0.7.2.1
raw patch · 9 files changed
+65/−29 lines, 9 filesdep +PyFbuild-type:Customsetup-changedPVP: major bump suggested
API removals or changes: PVP suggests a major version bump
Dependencies added: PyF
API changes (from Hackage documentation)
- Shh.Internal: instance Shh.Internal.ExecArg GHC.Integer.Type.Integer
+ Shh: captureWords :: Shell io => io [ByteString]
+ Shh.Internal: instance Shh.Internal.ExecArg GHC.Num.Integer.Integer
- Shh.Internal: dupHandleShh_ :: (IODevice dev, BufferedIO dev, Typeable dev) => dev -> FilePath -> Maybe (MVar Handle__) -> Handle__ -> Maybe HandleFinalizer -> IO Handle
+ Shh.Internal: dupHandleShh_ :: (RawIO dev, IODevice dev, BufferedIO dev, Typeable dev) => dev -> FilePath -> Maybe (MVar Handle__) -> Handle__ -> Maybe HandleFinalizer -> IO Handle
Files
- README.md +17/−2
- Setup.hs +2/−2
- app/Example.hs +1/−1
- app/shh-app.hs +1/−1
- shh.cabal +14/−5
- src/Shh.hs +1/−0
- src/Shh/Internal.hs +4/−6
- test/Readme.lhs +17/−2
- test/Test.hs +8/−10
README.md view
@@ -13,10 +13,12 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ExtendedDefaultRules #-}+{-# LANGUAGE QuasiQuotes #-} module Readme (test) where import Shh +import System.Environment import Control.Concurrent.Async import Prelude hiding (head) import Test.Tasty@@ -26,6 +28,7 @@ import qualified Data.ByteString.Lazy.Char8 as Char8 import Data.List (nub) import Data.Char+import PyF load SearchPath ["echo", "base64", "cat", "head", "sleep", "mktemp", "ls", "wc", "find", "tr", "users", "sha256sum", "false", "true"] @@ -178,6 +181,18 @@ might introduce a more succinct globbing feature, though it will always be explicit, and thus always more verbose than most other shells. +## String Interpolation/Expansion/Substitution++String interpolation, much like globbing, is left to an external library.+I lightweight, zero-dependency solution is to use [PyF](https://hackage.haskell.org/package/PyF),+which, since 0.10.0.1, has no dependencies other than ones included with GHC.++```haskell+greet = do+ user <- getEnv "USER"+ echo [fmt|Hello, {user}!|]+```+ ## Usage Some of the features in Shh require that you use the threaded runtime.@@ -191,7 +206,7 @@ {-# LANGUAGE ExtendedDefaultRules #-} $(loadEnv SearchPath) -You now have all your executables available as simple to Haskell+You now have all your executables available as simple Haskell functions. If you don't want to load your entire environment you can load specific commands directly: @@ -223,7 +238,7 @@ ```bash cabal new-install --lib shh-cabal new-install --lib ssh-extras+cabal new-install --lib shh-extras ``` The `shh` binary will look in your `$SHH_DIR` (defaults to `$HOME/.shh`) for
Setup.hs view
@@ -1,2 +1,2 @@-import Distribution.Simple-main = defaultMain+import Distribution.Extra.Doctest+main = defaultMainWithDoctests "shh-tests"
app/Example.hs view
@@ -12,7 +12,7 @@ import Control.Concurrent.Async -- Load everything...--- $(loadEnv)+-- $(loadEnv SearchPath) -- OR --
app/shh-app.hs view
@@ -111,7 +111,7 @@ shellMod <- getModificationTime "Shell.hs" hiMod <- getModificationTime "Shell.hi" pure (shellMod > hiMod)- ) (\e -> if (isDoesNotExistError e) then pure True else throwIO e)+ ) (\e -> if isDoesNotExistError e then pure True else throwIO e) when (outdated || pathDiff) $ do putStrLn "Rebuilding Shell.hs..." writeFile "paths" cp
shh.cabal view
@@ -1,5 +1,5 @@ name: shh-version: 0.7.2.0+version: 0.7.2.1 synopsis: Simple shell scripting from Haskell description: Provides a shell scripting environment for Haskell. It helps you use external binaries, and allows you to@@ -11,10 +11,16 @@ maintainer: lukec@themk.net copyright: (c) 2018 - 2021 Luke Clifton category: System-build-type: Simple+build-type: Custom extra-source-files: ChangeLog.md, README.md-cabal-version: >=1.10+cabal-version: 2.0 +custom-setup+ setup-depends:+ base+ , Cabal+ , cabal-doctest >=1.0.9 && <1.1+ source-repository head type: git location: https://github.com/luke-clifton/shh@@ -23,7 +29,7 @@ exposed-modules: Shh , Shh.Internal build-depends:- base >= 4.9 && < 4.16,+ base >= 4.9 && < 4.17, async >= 2.2.1 && < 2.3, bytestring >= 0.10.10 && < 0.12.0, deepseq >= 1.4.3 && < 1.5,@@ -33,7 +39,7 @@ process >= 1.6.3 && < 1.7, split >= 0.2.3 && < 0.3, stringsearch >= 0.3.6.6 && < 0.4,- template-haskell >= 2.13.0 && < 2.18,+ template-haskell >= 2.13.0 && < 2.19, containers >= 0.5.11 && < 0.7, unix >= 2.7.2 && < 2.8, utf8-string@@ -76,6 +82,7 @@ directory, doctest, filepath,+ PyF, tasty, tasty-quickcheck, tasty-hunit,@@ -86,3 +93,5 @@ main-is: Test.hs other-modules: Readme type: exitcode-stdio-1.0+ other-modules: Build_doctests+ autogen-modules: Build_doctests
src/Shh.hs view
@@ -53,6 +53,7 @@ , captureEndBy , captureEndBy0 , captureLines+ , captureWords -- | == Piping and Redirection , (|>) , (|!>)
src/Shh/Internal.hs view
@@ -35,7 +35,6 @@ import qualified Data.ByteString.Lazy.Search as Search import Data.ByteString.Lazy.UTF8 (toString) import Data.Char (isLower, isSpace, isAlphaNum, ord)-import Data.List (intercalate) import qualified Data.List.Split as Split import qualified Data.Map as Map import Data.Maybe (isJust)@@ -48,7 +47,6 @@ import GHC.IO.Handle hiding (hGetContents) import GHC.IO.Handle.Internals import GHC.IO.Handle.Types-import GHC.IO.Handle.Types (Handle(..)) import GHC.Stack import Language.Haskell.TH import qualified System.Directory as Dir@@ -105,7 +103,7 @@ show f = concat $ [ "Command `" ]- ++ [intercalate " " (toString (failureProg f) : map show (failureArgs f))]+ ++ [unwords (toString (failureProg f) : map show (failureArgs f))] ++ [ "` failed [exit " , show (failureCode f)@@ -150,7 +148,7 @@ concurrently a' b' --- | Use this to send the output of on process into the input of another.+-- | Use this to send the output of one process into the input of another. -- This is just like a shell's `|` operator. -- -- The result is polymorphic in its output, and can result in either@@ -170,7 +168,7 @@ infixl 1 |> --- | Similar to `|!>` except that it connects stderr to stdin of the+-- | Similar to `|>` except that it connects stderr to stdin of the -- next process in the chain. -- -- NB: The next command to be `|>` on will recapture the stdout of@@ -440,7 +438,7 @@ instance Shell Proc where runProc = id --- | Run's a `Proc` in `IO`. Like `runProc`, but you get to choose the handles.+-- | Runs a `Proc` in `IO`. Like `runProc`, but you get to choose the handles. -- This is UNSAFE to expose externally, because there are restrictions on what -- the Handle can be. Within shh, we never call `runProc'` with invalid handles, -- so we ignore that corner case (see `hDup`).
test/Readme.lhs view
@@ -13,10 +13,12 @@ {-# LANGUAGE TemplateHaskell #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE ExtendedDefaultRules #-}+{-# LANGUAGE QuasiQuotes #-} module Readme (test) where import Shh +import System.Environment import Control.Concurrent.Async import Prelude hiding (head) import Test.Tasty@@ -26,6 +28,7 @@ import qualified Data.ByteString.Lazy.Char8 as Char8 import Data.List (nub) import Data.Char+import PyF load SearchPath ["echo", "base64", "cat", "head", "sleep", "mktemp", "ls", "wc", "find", "tr", "users", "sha256sum", "false", "true"] @@ -178,6 +181,18 @@ might introduce a more succinct globbing feature, though it will always be explicit, and thus always more verbose than most other shells. +## String Interpolation/Expansion/Substitution++String interpolation, much like globbing, is left to an external library.+I lightweight, zero-dependency solution is to use [PyF](https://hackage.haskell.org/package/PyF),+which, since 0.10.0.1, has no dependencies other than ones included with GHC.++```haskell+greet = do+ user <- getEnv "USER"+ echo [fmt|Hello, {user}!|]+```+ ## Usage Some of the features in Shh require that you use the threaded runtime.@@ -191,7 +206,7 @@ {-# LANGUAGE ExtendedDefaultRules #-} $(loadEnv SearchPath) -You now have all your executables available as simple to Haskell+You now have all your executables available as simple Haskell functions. If you don't want to load your entire environment you can load specific commands directly: @@ -223,7 +238,7 @@ ```bash cabal new-install --lib shh-cabal new-install --lib ssh-extras+cabal new-install --lib shh-extras ``` The `shh` binary will look in your `$SHH_DIR` (defaults to `$HOME/.shh`) for
test/Test.hs view
@@ -20,7 +20,9 @@ import Control.Concurrent.Async import System.FilePath (takeFileName) import System.IO+import System.Environment +import Build_doctests (flags, pkgs, module_sources) import Readme load SearchPath@@ -35,12 +37,8 @@ putStrLn " failures, please check that it's not because" putStrLn " they are missing." putStrLn "################################################"- doctest ["--fast", "-isrc", "src/Shh/Internal.hs"- , "-package", "async"- , "-package", "stringsearch"- , "-package", "utf8-string"- , "-package", "split"- ]+ unsetEnv "GHC_ENVIRONMENT"+ doctest $ flags ++ pkgs ++ module_sources defaultMain tests tests :: TestTree@@ -238,16 +236,16 @@ s <- writeOutput "üか" |> cat |> capture toString s @?= "üか" , testCase "tryFailure capture 1" $ do- s <- (tryFailure (false |> capture)) |> capture+ s <- tryFailure (false |> capture) |> capture s @?= "" , testCase "tryFailure capture 2" $ do- s <- (tryFailure (false |> capture)) |!> capture+ s <- tryFailure (false |> capture) |!> capture s @?= "" , testCase "tryFailure capture 3" $ do- s <- (tryFailure (false |!> capture)) |> capture+ s <- tryFailure (false |!> capture) |> capture s @?= "" , testCase "tryFailure capture 4" $ do- s <- (tryFailure (false |!> capture)) |!> capture+ s <- tryFailure (false |!> capture) |!> capture s @?= "" , testCase "pipeErr" $ do s <- writeOutput "abcd" |> capture `pipeErr` capture