Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 11 additions & 3 deletions src/Main.hs
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,8 @@ data Options = Options {
keepGoing :: Bool,
jobs :: Int,
shuffle :: Bool,
noColor :: Bool
noColor :: Bool,
quiet :: Bool
}

-- Redo default options:
Expand All @@ -51,7 +52,8 @@ defaultOptions = Options {
keepGoing = False,
jobs = 1,
shuffle = False,
noColor = False
noColor = False,
quiet = False
}

-- Define program options:
Expand All @@ -73,6 +75,7 @@ options =
, Option ['k'] ["keep-going"] (NoArg setKeepGoing) "keep building even if some targets fail"
, Option ['s'] ["shuffle"] (NoArg setShuffle) "randomize the build order to find dependency bugs"
, Option ['n'] ["no-color"] (NoArg setNoColor) "print plain text, disable ANSI terminal color output"
, Option ['q'] ["quiet"] (NoArg setQuiet) "suppress all output except errors"
]

-- Helper functions for setting the options:
Expand Down Expand Up @@ -106,6 +109,9 @@ setShuffle opt = return opt { shuffle = True }
setNoColor :: Options -> IO Options
setNoColor opt = return opt { noColor = True }

setQuiet :: Options -> IO Options
setQuiet opt = return opt { quiet = True }

-- Print the program version and license information:
printVersion :: Options -> IO Options
printVersion _ = do putStrLn versionString
Expand Down Expand Up @@ -152,13 +158,15 @@ main = do
keepGoing = keepGoing',
jobs = jobs',
shuffle = shuffle',
noColor = noColor'} = opts
noColor = noColor',
quiet = quiet'} = opts

-- Show help or version information if asked:
when help' (printHelp progName options [])
when keepGoing' (setEnv "REDO_KEEP_GOING" "TRUE")
when shuffle' (setEnv "REDO_SHUFFLE" "TRUE")
when noColor' (setEnv "REDO_NO_COLOR" "TRUE")
when quiet' (setEnv "REDO_QUIET" "TRUE")
when dashD1' (setEnv "REDO_DEBUG_1" "TRUE")
when dashD2' (setEnv "REDO_DEBUG_2" "TRUE")
when dashC' (setEnv "REDO_CHECK" "TRUE")
Expand Down
31 changes: 24 additions & 7 deletions src/PrettyPrint.hs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
module PrettyPrint(putRedoUnformatted, putRedoInfo, putRedoWarning, putInfoStrLn, putWarningStrLn, putErrorStrLn,
putStatusStrLn, putRedoStatus, putRedoError, putUnformattedStrLn, isColorTerminal, putStrBuffered) where

import Control.Monad (unless)
import System.IO (hPutStrLn, stderr, hFlush, hSetBuffering, BufferMode(..), stdout, hIsTerminalDevice)
import Data.Maybe (fromJust, isNothing, isJust, fromMaybe)
import System.Environment (lookupEnv)
Expand Down Expand Up @@ -51,13 +52,17 @@ putColorStrLn color string = do
putUnformattedStrLn :: String -> IO ()
putUnformattedStrLn = hPutStrLn stderr
putInfoStrLn :: String -> IO ()
putInfoStrLn = putColorStrLn green
putInfoStrLn string = do
quiet' <- isQuiet
unless quiet' $ putColorStrLn green string
putWarningStrLn :: String -> IO ()
putWarningStrLn = putColorStrLn yellow
putErrorStrLn :: String -> IO ()
putErrorStrLn = putColorStrLn red
putStatusStrLn :: String -> IO ()
putStatusStrLn = putColorStrLn cyan
putStatusStrLn string = do
quiet' <- isQuiet
unless quiet' $ putColorStrLn cyan string

-- Print a "redo" style string. This includes the target being built, indented
-- to the appropriate level, with an optional message ater
Expand Down Expand Up @@ -92,22 +97,34 @@ useColor = do
let noColor = fromMaybe "" noColor'
return $ noColor /= "TRUE"

-- Is quiet mode enabled? (suppress info and status output; warnings and errors always print)
isQuiet :: IO Bool
isQuiet = do
quiet' <- lookupEnv "REDO_QUIET"
return $ fromMaybe "" quiet' == "TRUE"

-- Put a "redo" style info string:
putRedoInfo :: Target -> IO ()
putRedoInfo target = putRedo green target ""
putRedoInfo target = do
quiet' <- isQuiet
unless quiet' $ putRedo green target ""

-- Put a "redo" style status string:
putRedoStatus :: Target -> String -> IO ()
putRedoStatus target string = putRedo cyan target ("- " ++ string)
putRedoStatus target string = do
quiet' <- isQuiet
unless quiet' $ putRedo cyan target ("- " ++ string)

-- Put a "redo" style warning string:
-- Put a "redo" style warning string (always printed, even in quiet mode):
putRedoWarning :: Target -> String -> IO ()
putRedoWarning target string = putRedo yellow target ("- " ++ string)

-- Put a "redo" style error string:
-- Put a "redo" style error string (always printed, even in quiet mode):
putRedoError :: Target -> String -> IO ()
putRedoError target string = putRedo red target ("- " ++ string)

-- Put a "redo" style unformatted string:
putRedoUnformatted :: Target -> String -> IO ()
putRedoUnformatted target string = putRedo "" target ("- " ++ string)
putRedoUnformatted target string = do
quiet' <- isQuiet
unless quiet' $ putRedo "" target ("- " ++ string)
139 changes: 139 additions & 0 deletions test/150-quiet/all.do
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
exec >&2
. ../skip-if-minimal-do.sh

# Test 1: With -q, successful build produces no output
echo "Test 1: quiet mode suppresses output on success"
rm -f target1
output=$(redo -q target1 2>&1)
if [ -n "$output" ]; then
echo "FAIL: expected no output with -q, got: $output" >&2
exit 1
fi
[ -e target1 ] || exit 2
echo " PASS"

# Test 2: Without -q, successful build produces output
echo "Test 2: normal mode shows output"
rm -f target1
output=$(redo target1 2>&1)
if [ -z "$output" ]; then
echo "FAIL: expected output without -q" >&2
exit 3
fi
echo " PASS"

# Test 3: With -q, errors are still printed
echo "Test 3: quiet mode still shows errors"
rm -f failme
set +e
output=$(redo -q failme 2>&1)
rc=$?
set -e
if [ "$rc" -eq 0 ]; then
echo "FAIL: expected non-zero exit" >&2
exit 4
fi
if [ -z "$output" ]; then
echo "FAIL: expected error output with -q on failure" >&2
exit 5
fi
case "$output" in
*Error*) ;; # good
*) echo "FAIL: expected 'Error' in output, got: $output" >&2; exit 6 ;;
esac
echo " PASS"

# Test 4: -q propagates to child redo processes (nested builds)
echo "Test 4: quiet mode propagates to nested builds"
rm -f outer inner
output=$(redo -q outer 2>&1)
if [ -n "$output" ]; then
echo "FAIL: expected no output from nested -q build, got: $output" >&2
exit 7
fi
[ -e outer ] || exit 8
[ -e inner ] || exit 9
echo " PASS"

# Test 5: --quiet long form works
echo "Test 5: --quiet long form"
rm -f target1
output=$(redo --quiet target1 2>&1)
if [ -n "$output" ]; then
echo "FAIL: expected no output with --quiet, got: $output" >&2
exit 10
fi
echo " PASS"

# Test 6: -q combined with other flags
echo "Test 6: -q combined with -k (keep-going)"
rm -f target1
output=$(redo -q -k target1 2>&1)
if [ -n "$output" ]; then
echo "FAIL: expected no output with -q -k, got: $output" >&2
exit 11
fi
echo " PASS"

# Test 7: -q with multiple targets
echo "Test 7: -q with multiple targets"
rm -f target1 inner
output=$(redo -q target1 inner 2>&1)
if [ -n "$output" ]; then
echo "FAIL: expected no output with -q and multiple targets, got: $output" >&2
exit 12
fi
[ -e target1 ] || exit 13
[ -e inner ] || exit 14
echo " PASS"

# Test 8: -q doesn't affect build correctness (target content is right)
echo "Test 8: -q doesn't affect build output content"
rm -f target1
redo -q target1
content=$(cat target1)
if [ "$content" != "built" ]; then
echo "FAIL: expected 'built' in target1, got: $content" >&2
exit 15
fi
echo " PASS"

# Test 9: Nested error in quiet mode still shows error chain
echo "Test 9: nested error in quiet mode shows error chain"
rm -f outer_fail inner_fail
set +e
output=$(redo -q outer_fail 2>&1)
rc=$?
set -e
if [ "$rc" -eq 0 ]; then
echo "FAIL: expected non-zero exit from outer_fail" >&2
exit 16
fi
case "$output" in
*Error*) ;; # good
*) echo "FAIL: expected error output, got: $output" >&2; exit 17 ;;
esac
echo " PASS"

# Test 10: Warnings are NOT suppressed by -q
echo "Test 10: quiet mode still shows warnings"
rm -f warnme
# First build warnme so redo knows it as a target
redo warnme
# Now remove and create as plain source file
rm -f warnme
echo "i am a source" > warnme
# Trying to redo it should produce a warning (source file exists)
set +e
output=$(redo -q warnme 2>&1)
set -e
if [ -z "$output" ]; then
echo "FAIL: expected warning output with -q, got nothing" >&2
exit 18
fi
case "$output" in
*Warning*) ;; # good — warning was printed
*) echo "FAIL: expected 'Warning' in output, got: $output" >&2; exit 19 ;;
esac
rm -f warnme
echo " PASS"
1 change: 1 addition & 0 deletions test/150-quiet/failme.do
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exit 1
1 change: 1 addition & 0 deletions test/150-quiet/inner.do
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
echo "inner" > "$3"
1 change: 1 addition & 0 deletions test/150-quiet/inner_fail.do
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
exit 1
2 changes: 2 additions & 0 deletions test/150-quiet/outer.do
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
redo-ifchange inner
echo "outer" > "$3"
2 changes: 2 additions & 0 deletions test/150-quiet/outer_fail.do
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
redo-ifchange inner_fail
echo "should not reach here" > "$3"
1 change: 1 addition & 0 deletions test/150-quiet/target1.do
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
echo "built" > "$3"
2 changes: 2 additions & 0 deletions test/150-quiet/warnme.do
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Build a target, then mark it as source so rebuilding triggers a warning
echo "built" > "$3"
Loading