on master help sign in
Allow logging process stderr with different severity

Usually we want to log process stderr with Error severity, but there are legetimate cases (eg: git) where we don't.

commit4ce0ede745f72287d1957e793ac9712c4e50866f authorSridhar Ratnakumar <srid@srid.ca> dateSun 13 May 2018, 15:15 (8 years ago) parentbda2bab
5 files changed+29−19
lib/command/src/Obelisk/CLI.hs+1−1 lib/command/src/Obelisk/CLI/Process.hs+20−10 lib/command/src/Obelisk/Command/Deploy.hs+1−1 lib/command/src/Obelisk/Command/Project.hs+1−1 lib/command/src/Obelisk/Command/Thunk.hs+6−6
lib/command/src/Obelisk/CLI.hs+1−1
@@ -48,6 +48,6 @@ cliDemo = do
4848 output <- readProcessAndLogStderr Notice $ proc "ls" ["-l", "/"]
4949 putLog Notice $ "Output was: " <> T.pack output
5050 liftIO $ threadDelay 1000000
51− callProcessAndLogOutput Notice $ proc "ls" ["-l", "/does-not-exist"]
51+ callProcessAndLogOutput (Notice, Error) $ proc "ls" ["-l", "/does-not-exist"]
5252 liftIO $ threadDelay 1000000
5353 failWith "Something dangerous happened"
lib/command/src/Obelisk/CLI/Process.hs+20−10
@@ -3,6 +3,7 @@
33{-# LANGUAGE MultiParamTypeClasses #-}
44{-# LANGUAGE MultiWayIf #-}
55{-# LANGUAGE ScopedTypeVariables #-}
6+{-# LANGUAGE TupleSections #-}
67
78-- | An extension of `System.Process` that integrates with logging (`Obelisk.CLI.Logging`)
89-- and is thus spinner friendly.
@@ -12,7 +13,7 @@ module Obelisk.CLI.Process
1213 ) where
1314
1415import Control.Applicative (liftA2)
15−import Control.Monad (void)
16+import Control.Monad (void, (<=<))
1617import Control.Monad.Catch (MonadMask)
1718import Control.Monad.Fix (fix)
1819import Control.Monad.IO.Class (liftIO)
@@ -39,19 +40,24 @@ readProcessAndLogStderr
3940 => Severity -> CreateProcess -> m String
4041readProcessAndLogStderr sev process = do
4142 (out, _err) <- withProcess process $ \_out err -> do
42− streamToLog sev =<< liftIO (handleToInputStream err)
43+ streamToLog =<< liftIO (streamHandle sev err)
4344 -- TODO: Why are we using Text here?
4445 liftIO $ T.unpack . T.strip <$> T.hGetContents out
4546
46−-- | Like `System.Process.callProcess` but logs the combined output (stdout and stderr)
47+-- | Like `System.Process.callProcess` but logs the combined output, including stdout and stderr with the
48+-- corresponding severity.
49+--
50+-- Usually you would call this function as: `callProcessAndLogOutput (Notice, Error)`. However some processes
51+-- are known to spit out diagnostic or informative messages in stderr, in which case you are obviously
52+-- adviced to call it using something else like: `callProcessAndLogOutput (Debug, Debug)`.
4753callProcessAndLogOutput
4854 :: (MonadIO m, MonadMask m, MonadLog Output m)
49− => Severity -> CreateProcess -> m ()
50−callProcessAndLogOutput sev process = do
55+ => (Severity, Severity) -> CreateProcess -> m ()
56+callProcessAndLogOutput (sev_out, sev_err) process = do
5157 void $ withProcess process $ \out err -> do
5258 stream <- liftIO $ do
53− uncurry combineStream =<< liftA2 (,) (handleToInputStream out) (handleToInputStream err)
54− streamToLog sev stream
59+ uncurry combineStream =<< liftA2 (,) (streamHandle sev_out out) (streamHandle sev_err err)
60+ streamToLog stream
5561 where
5662 combineStream s1 s2 = concurrentMerge [s1, s2]
5763
@@ -71,11 +77,15 @@ withProcess process action = do
7177 failWith $ T.pack $ show (cmdspec process) <> " failed with exit code: " <> show code
7278 return (out, err) -- Return the handles
7379
80+-- Create an input stream from the file handle, associating each item with the severity.
81+streamHandle :: Severity -> Handle -> IO (InputStream (Severity, BSC.ByteString))
82+streamHandle sev = Streams.map (sev,) <=< handleToInputStream
83+
7484-- | Read from an input stream and log its contents
7585streamToLog
7686 :: (MonadIO m, MonadMask m, MonadLog Output m)
77− => Severity -> InputStream BSC.ByteString -> m ()
78−streamToLog sev stream = fix $ \loop -> do
87+ => InputStream (Severity, BSC.ByteString) -> m ()
88+streamToLog stream = fix $ \loop -> do
7989 liftIO (Streams.read stream) >>= \case
8090 Nothing -> return ()
81− Just line -> putLogRaw sev (decodeUtf8 line) >> loop
91+ Just (sev, line) -> putLogRaw sev (decodeUtf8 line) >> loop
lib/command/src/Obelisk/Command/Deploy.hs+1−1
@@ -29,7 +29,7 @@ deployInit thunkPtr configDir deployDir sshKeyPath hostnames = do
2929 createDirectoryIfMissing True deployDir
3030 doesDirectoryExist configDir
3131 when hasConfigDir $ do
32− callProcessAndLogOutput Notice $
32+ callProcessAndLogOutput (Notice, Error) $
3333 cp
3434 [ "-r"
3535 , "-T"
lib/command/src/Obelisk/Command/Project.hs+1−1
@@ -71,7 +71,7 @@ initProject source = do
7171 --TODO: We should probably handoff to the impl here
7272 skeleton <- nixBuildAttrWithCache implDir "skeleton" --TODO: I don't think there's actually any reason to cache this
7373 withSpinner "Copying project skeleton" $ do
74− callProcessAndLogOutput Notice $
74+ callProcessAndLogOutput (Notice, Error) $
7575 cp --TODO: Make this package depend on nix-prefetch-url properly
7676 [ "-r"
7777 , "--no-preserve=mode"
lib/command/src/Obelisk/Command/Thunk.hs+6−6
@@ -472,17 +472,17 @@ unpackThunk thunkDir = readThunk thunkDir >>= \case
472472 Nothing -> fail "Cannot determine clone URI for thunk source"
473473 Just c -> return $ T.unpack $ getUrl c
474474 withSpinner ("Retrieving thunk " <> T.pack thunkName <> " from GitHub") $ do
475− callProcessAndLogOutput Notice $
475+ callProcessAndLogOutput (Notice, Notice) $
476476 proc "hub" ["clone", "-n", githubURI, tmpRepo]
477477 let obGitDir = tmpRepo </> ".git" </> "obelisk"
478478 --If this directory already exists then something is weird and we should fail
479479 liftIO $ createDirectory obGitDir
480− callProcessAndLogOutput Notice $
480+ callProcessAndLogOutput (Notice, Error) $
481481 cp ["-r", "-T", thunkDir </> ".", obGitDir </> "orig-thunk"]
482482 withSpinner ("Preparing thunk in " <> T.pack thunkDir) $ do
483483 -- Checkout
484484 putLog Notice $ "Checking out " <> T.pack (show $ maybe "" untagName $ _gitHubSource_branch s)
485− callProcessAndLogOutput Debug $
485+ callProcessAndLogOutput (Notice, Notice) $
486486 proc "hub" $ concat
487487 [ ["-C", tmpRepo]
488488 , pure "checkout"
@@ -491,11 +491,11 @@ unpackThunk thunkDir = readThunk thunkDir >>= \case
491491 ]
492492 -- Set upstream branch
493493 forM_ (_gitHubSource_branch s) $ \branch ->
494− callProcessAndLogOutput Debug $
494+ callProcessAndLogOutput (Notice, Error) $
495495 proc "hub" ["-C", tmpRepo, "branch", "-u", "origin/" <> T.unpack (untagName branch)]
496− callProcessAndLogOutput Notice $
496+ callProcessAndLogOutput (Notice, Error) $
497497 proc "rm" ["-r", thunkDir]
498− callProcessAndLogOutput Notice $
498+ callProcessAndLogOutput (Notice, Error) $
499499 procWithPackages ["coreutils"] "mv"
500500 [ "-T"
501501 , tmpRepo