simple-cmd 0.2.1 → 0.2.2
raw patch · 6 files changed
+83/−66 lines, 6 filesdep +extraPVP ok
version bump matches the API change (PVP)
Dependencies added: extra
API changes (from Hackage documentation)
+ SimpleCmd: cmdStderrToStdout :: String -> [String] -> IO (ExitCode, String)
+ SimpleCmd.Git: gitBool :: String -> [String] -> IO Bool
Files
- ChangeLog.md +7/−0
- SimpleCmd.hs +52/−51
- SimpleCmd/Git.hs +17/−10
- SimpleCmd/Rpm.hs +1/−1
- TODO +1/−0
- simple-cmd.cabal +5/−4
ChangeLog.md view
@@ -1,5 +1,12 @@ # Revision history for simple-cmd +## 0.2.2 (2020-06-17)+- grep: no longer errors for no match+- add cmdStderrToStdout: redirects stderr to stdout+- add gitBool+- define gitBranch using "git rev-parse" (internal change)+- now export ifM and whenM from extra+ ## 0.2.1 (2019-12-12) - add cmdTry_: only runs if available - add ifM and whenM
SimpleCmd.hs view
@@ -39,6 +39,7 @@ cmdStdIn, cmdStdErr, cmdTry_,+ cmdStderrToStdout, error', egrep_, grep, grep_, ifM,@@ -59,18 +60,19 @@ #else import Control.Applicative ((<$>)) #endif-import Control.Monad+import Control.Monad.Extra import Data.List (stripPrefix) import Data.Maybe (isJust, isNothing, fromMaybe) import System.Directory (findExecutable) import System.Exit (ExitCode (..))-import System.IO (hGetContents, hPutStrLn, IOMode(ReadMode), stderr, withFile)+import System.IO (hGetContents, hPutStrLn, IOMode(ReadMode), stderr, stdout,+ withFile) import System.Posix.User (getEffectiveUserID) import System.Process (createProcess, proc, ProcessHandle, rawSystem, readProcess, readProcessWithExitCode, runProcess, showCommandForUser,- std_in, std_out, StdStream(CreatePipe, UseHandle),+ std_err, std_in, std_out, StdStream(CreatePipe, UseHandle), waitForProcess, withCreateProcess) removeTrailingNewline :: String -> String@@ -93,13 +95,13 @@ error' = error #endif --- | 'cmd c args' runs a command in a process and returns stdout+-- | @cmd c args@ runs a command in a process and returns stdout cmd :: String -- ^ command to run -> [String] -- ^ list of arguments -> IO String -- ^ stdout cmd c args = cmdStdIn c args "" --- | 'cmd_ c args' runs command in a process, output goes to stdout and stderr+-- | @cmd_ c args@ runs command in a process, output goes to stdout and stderr cmd_ :: String -> [String] -> IO () cmd_ c args = do ret <- rawSystem c args@@ -114,12 +116,12 @@ ExitSuccess -> return True ExitFailure _ -> return False --- | 'cmdBool c args' runs a command, and return Boolean status+-- | @cmdBool c args@ runs a command, and return Boolean status cmdBool :: String -> [String] -> IO Bool cmdBool c args = boolWrapper (rawSystem c args) --- | 'cmdMaybe c args' runs a command, maybe returning output if it succeeds+-- | @cmdMaybe c args@ runs a command, maybe returning output if it succeeds cmdMaybe :: String -> [String] -> IO (Maybe String) cmdMaybe c args = do (ret, out, _err) <- readProcessWithExitCode c args ""@@ -127,32 +129,33 @@ ExitSuccess -> return $ Just $ removeTrailingNewline out ExitFailure _ -> return Nothing --- | 'cmdLines c args' runs a command, and returns list of stdout lines+-- | @cmdLines c args@ runs a command, and returns list of stdout lines -- -- @since 0.1.1 cmdLines :: String -> [String] -> IO [String] cmdLines c args = lines <$> cmd c args --- | 'cmdStdIn c args inp' runs a command, passing input string as stdin, and returns stdout+-- | @cmdStdIn c args inp@ runs a command, passing input string as stdin, and returns stdout cmdStdIn :: String -> [String] -> String -> IO String cmdStdIn c args inp = removeTrailingNewline <$> readProcess c args inp --- | 'shell cs' runs a command string in a shell, and returns stdout+-- | @shell cs@ runs a command string in a shell, and returns stdout shell :: String -> IO String shell cs = cmd "sh" ["-c", cs] --- | 'shell_ cs' runs a command string in a shell, output goes to stdout+-- | @shell_ cs@ runs a command string in a shell, output goes to stdout shell_ :: String -> IO () shell_ cs = cmd_ "sh" ["-c", cs] --- | 'shellBool cs' runs a command string in a shell, output goes to stdout+-- | @shellBool cs@ runs a command string in a shell, output goes to stdout -- -- @since 0.2.0 shellBool :: String -> IO Bool shellBool cs = boolWrapper (rawSystem "sh" ["-c", cs]) --- | 'cmdLog c args' logs a command with a datestamp+-- FIXME cmdLog_+-- | @cmdLog c args@ logs a command with a datestamp -- -- @since 0.1.4 cmdLog :: String -> [String] -> IO ()@@ -160,27 +163,27 @@ logMsg $ unwords $ c:args cmd_ c args --- | 'cmdlog' deprecated alias for 'cmdLog' (will be removed in 0.3)+-- | @cmdlog@ deprecated alias for 'cmdLog' (will be removed in 0.3) cmdlog :: String -> [String] -> IO () cmdlog = cmdLog --- | 'logMsg msg' outputs message with a timestamp+-- | @logMsg msg@ outputs message with a timestamp logMsg :: String -> IO () logMsg msg = do date <- cmd "date" ["+%T"] putStrLn $ date +-+ msg --- | 'cmdN c args' dry-runs a command: prints command to stdout - more used for debugging+-- | @cmdN c args@ dry-runs a command: prints command to stdout - more used for debugging cmdN :: String -> [String] -> IO () cmdN c args = putStrLn $ unwords $ c:args --- | 'cmdStdErr c args' runs command in a process, returning stdout and stderr+-- | @cmdStdErr c args@ runs command in a process, returning stdout and stderr cmdStdErr :: String -> [String] -> IO (String, String) cmdStdErr c args = do (_ret, out, err) <- readProcessWithExitCode c args "" return (removeTrailingNewline out, removeTrailingNewline err) --- -- | 'cmdAssert msg c args' runs command, if it fails output msg as error'.+-- -- | @cmdAssert msg c args@ runs command, if it fails output msg as error'. -- cmdAssert :: String -> String -> [String] -> IO () -- cmdAssert msg c args = do -- ret <- rawSystem c args@@ -188,7 +191,7 @@ -- ExitSuccess -> return () -- ExitFailure _ -> error' msg --- | 'cmdQuiet c args' runs a command hiding stderr, if it succeeds returns stdout+-- | @cmdQuiet c args@ runs a command hiding stderr, if it succeeds returns stdout cmdQuiet :: String -> [String] -> IO String cmdQuiet c args = do (ret, out, err) <- readProcessWithExitCode c args ""@@ -196,7 +199,7 @@ ExitSuccess -> return $removeTrailingNewline out ExitFailure n -> error' $ quoteCmd c args +-+ "failed with status" +-+ show n ++ "\n" ++ err --- | 'cmdSilent c args' runs a command hiding stdout: stderr is only output if it fails.+-- | @cmdSilent c args@ runs a command hiding stdout: stderr is only output if it fails. cmdSilent :: String -> [String] -> IO () cmdSilent c args = do (ret, _, err) <- readProcessWithExitCode c args ""@@ -204,13 +207,13 @@ ExitSuccess -> return () ExitFailure n -> error' $ quoteCmd c args +-+ "failed with status" +-+ show n ++ "\n" ++ err --- | 'cmdIgnoreErr c args inp' runs a command with input, drops stderr, and return stdout+-- | @cmdIgnoreErr c args inp@ runs a command with input, drops stderr, and return stdout cmdIgnoreErr :: String -> [String] -> String -> IO String cmdIgnoreErr c args input = do- (_exit, out, _err) <- readProcessWithExitCode c args input+ (_ret, out, _err) <- readProcessWithExitCode c args input return out --- | 'cmdTry_ c args' runs the command if available+-- | @cmdTry_ c args@ runs the command if available -- -- @since 0.2.1 cmdTry_ :: String -> [String] -> IO ()@@ -219,26 +222,38 @@ when (isJust have) $ cmd_ c args --- | 'grep pat file' greps pattern in file, and returns list of matches+-- | Redirect stderr to stdout, ie with interleaved output ----- @since 0.1.2+-- @since 0.2.2+cmdStderrToStdout :: String -> [String] -> IO (ExitCode, String)+cmdStderrToStdout c args = do+ (_, Just hout, _, p) <- createProcess ((proc c args) {std_out = CreatePipe,+ std_err = UseHandle stdout})+ ret <- waitForProcess p+ out <- hGetContents hout+ return (ret,out)++-- | @grep pat file@ greps pattern in file, and returns list of matches+--+-- @since 0.1.2 (fixed not to error in 0.2.2) grep :: String -> FilePath -> IO [String]-grep pat file =- cmdLines "grep" [pat, file]+grep pat file = do+ mres <- cmdMaybe "grep" [pat, file]+ return $ maybe [] lines mres --- | 'grep_ pat file' greps pattern in file and returns Boolean status+-- | @grep_ pat file@ greps pattern in file and returns Boolean status grep_ :: String -- ^ pattern -> FilePath -- ^ file -> IO Bool -- ^ result grep_ pat file = cmdBool "grep" ["-q", pat, file] --- | 'egrep_ pat file' greps extended regexp in file, and returns Boolean status+-- | @egrep_ pat file@ greps extended regexp in file, and returns Boolean status egrep_ :: String -> FilePath -> IO Bool egrep_ pat file = cmdBool "grep" ["-q", "-e", pat, file] --- | 'sudo c args' runs a command as sudo returning stdout+-- | @sudo c args@ runs a command as sudo returning stdout -- -- Result type changed from IO () to IO String in 0.2.0 sudo :: String -- ^ command@@ -246,7 +261,7 @@ -> IO String sudo = sudoInternal cmd --- | 'sudo_ c args' runs a command as sudo+-- | @sudo_ c args@ runs a command as sudo -- -- @since 0.2.0 sudo_ :: String -- ^ command@@ -278,24 +293,24 @@ -- singleLine "" = "" -- singleLine s = (head . lines) s --- | 'removePrefix prefix original' removes prefix from string if present+-- | @removePrefix prefix original@ removes prefix from string if present removePrefix :: String -> String-> String removePrefix prefix orig = fromMaybe orig $ stripPrefix prefix orig --- | 'removeStrictPrefix prefix original' removes prefix, or fails with error'+-- | @removeStrictPrefix prefix original@ removes prefix, or fails with error' removeStrictPrefix :: String -> String -> String removeStrictPrefix prefix orig = fromMaybe (error' prefix +-+ "is not prefix of" +-+ orig) $ stripPrefix prefix orig --- | 'removeSuffix suffix original' removes suffix from string if present+-- | @removeSuffix suffix original@ removes suffix from string if present removeSuffix :: String -> String -> String removeSuffix suffix orig = fromMaybe orig $ stripSuffix suffix orig where stripSuffix sf str = reverse <$> stripPrefix (reverse sf) (reverse str) --- | 'warning' outputs to stderr+-- | @warning@ outputs to stderr -- -- @since 0.2.0 warning :: String -> IO ()@@ -371,26 +386,12 @@ void $ waitForProcess p1 void $ waitForProcess p2 --- | Monadic if--- @ifM test actTrue actFalse@--- (taken from protolude)------ @since 0.2.1-ifM :: Monad m => m Bool -> m a -> m a -> m a-ifM p x y = p >>= \b -> if b then x else y---- | Monadic when--- @whenM test action@------ @since 0.2.1-whenM :: Monad m => m Bool -> m () -> m ()-whenM p x = p >>= \b -> when b x- -- | Assert program in PATH+-- -- @needProgram progname@ -- -- @since 0.2.1 needProgram :: String -> IO () needProgram prog = do mx <- findExecutable prog- unless (isJust mx) $ error' $ "program needs " ++ prog+ unless (isJust mx) $ error' $ "missing program: " ++ prog
SimpleCmd/Git.hs view
@@ -5,50 +5,57 @@ module SimpleCmd.Git ( git, git_,+ gitBool, gitBranch, gitDiffQuiet, grepGitConfig, isGitDir, rwGitDir) where -import Data.List (isPrefixOf) import System.Directory (doesDirectoryExist) import System.FilePath ((</>)) -import SimpleCmd (cmd, cmd_, cmdBool, cmdLines, egrep_, removePrefix)+import SimpleCmd (cmd, cmd_, cmdBool, egrep_) #if (defined(MIN_VERSION_base) && MIN_VERSION_base(4,8,0)) #else import Control.Applicative ((<$>)) #endif --- | 'git c args' runs git command and return output+-- | @git c args@ runs git command and return output git :: String -- ^ git command -> [String] -- ^ arguments -> IO String -- ^ output git c args = cmd "git" (c:args) --- | 'git_ c args' run git command with output to stdout and stderr+-- | @git_ c args@ run git command with output to stdout and stderr git_ :: String -> [String] -> IO () git_ c args = cmd_ "git" (c:args) --- | 'isGitDir dir' checks if directory has a .git/ subdir+-- | @gitBool c args@ runs git command and return result+gitBool :: String -- ^ git command+ -> [String] -- ^ arguments+ -> IO Bool -- ^ result+gitBool c args =+ cmdBool "git" (c:args)++-- | @isGitDir dir@ checks if directory has a .git/ subdir isGitDir :: FilePath -> IO Bool isGitDir dir = doesDirectoryExist (dir </> ".git") --- | 'gitBranch' returns the git branch of the current directory+-- | @gitBranch@ returns the git branch of the current directory gitBranch :: IO String gitBranch =- removePrefix "* " . head . filter (isPrefixOf "* ") <$> cmdLines "git" ["branch"]+ git "rev-parse" ["--abbrev-ref", "HEAD"] --- | 'rwGitDir' checks if a git repo is under ssh+-- | @rwGitDir@ checks if a git repo is under ssh rwGitDir :: IO Bool rwGitDir = grepGitConfig "url = \\(ssh://\\|git@\\)" --- | 'grepGitConfig pat' greps ".git/config" for extended regexp+-- | @grepGitConfig pat@ greps ".git/config" for extended regexp -- -- @since 0.1.1 grepGitConfig :: String -> IO Bool@@ -58,7 +65,7 @@ then egrep_ key ".git/config" else return False --- | 'gitDiffQuiet' checks if unchanged+-- | @gitDiffQuiet@ checks if unchanged -- -- @since 0.1.3 gitDiffQuiet :: [String] -> IO Bool
SimpleCmd/Rpm.hs view
@@ -8,7 +8,7 @@ import SimpleCmd (cmdLines) --- | 'rpmspec args maybe-queryformat specfile' runs rpmspec query on file with optional args (a newline is appended to any queryformat)+-- | @rpmspec args mqueryformat specfile@ runs rpmspec query on file with optional args (a newline is appended to any queryformat) -- -- @since 0.1.1 rpmspec :: [String] -> Maybe String -> FilePath -> IO [String]
TODO view
@@ -1,2 +1,3 @@ - source headers - examples+- add cmdLog_ (api break)
simple-cmd.cabal view
@@ -1,9 +1,9 @@ name: simple-cmd-version: 0.2.1+version: 0.2.2 synopsis: Simple String-based process commands description: Simple wrappers over System.Process- (readProcess, readProcessWithExitCode, rawSystem, and createProcess). + (readProcess, readProcessWithExitCode, rawSystem, and createProcess). The idea is to provide some common idioms for calling out to commands from programs. For more advanced shell-scripting or streaming use turtle, shelly, command, etc.@@ -11,14 +11,14 @@ license-file: LICENSE author: Jens Petersen maintainer: juhpetersen@gmail.com-copyright: Jens Petersen <juhpetersen@gmail.com>+copyright: 2017-2020 Jens Petersen <juhpetersen@gmail.com> category: System build-type: Simple cabal-version: >=1.10 extra-source-files: README.md ChangeLog.md TODO tested-with: GHC == 7.4.2, GHC == 7.6.3, GHC == 7.8.4, GHC == 7.10.3, GHC == 8.0.2, GHC == 8.2.2, GHC == 8.4.4, GHC == 8.6.5,- GHC == 8.8.1+ GHC == 8.8.3, GHC == 8.10.1 source-repository head type: git@@ -30,6 +30,7 @@ SimpleCmd.Rpm build-depends: base < 5, directory,+ extra, filepath, process >= 1.4.3.0, unix