packages feed

buildbox 2.1.4.3 → 2.1.6.1

raw patch · 26 files changed

+1114/−1117 lines, 26 filesdep ~basedep ~randomdep ~timePVP: major bump suggested

API removals or changes: PVP suggests a major version bump

Dependency ranges changed: base, random, time

API changes (from Hackage documentation)

- BuildBox: buildErrorCmd :: BuildError -> String
- BuildBox: buildErrorCode :: BuildError -> ExitCode
- BuildBox: buildErrorStderr :: BuildError -> Log
- BuildBox: buildErrorStdout :: BuildError -> Log
- BuildBox.Build: buildErrorCmd :: BuildError -> String
- BuildBox.Build: buildErrorCode :: BuildError -> ExitCode
- BuildBox.Build: buildErrorStderr :: BuildError -> Log
- BuildBox.Build: buildErrorStdout :: BuildError -> Log
- BuildBox.Build: buildStateId :: BuildState -> Integer
- BuildBox.Build: buildStateLogSystem :: BuildState -> Maybe Handle
- BuildBox.Build: buildStateScratchDir :: BuildState -> FilePath
- BuildBox.Build: buildStateSeq :: BuildState -> Integer
- BuildBox.Build.Benchmark: benchResultIteration :: BenchResult result -> Int
- BuildBox.Build.Benchmark: benchResultName :: BenchResult result -> String
- BuildBox.Build.Benchmark: benchResultTime :: BenchResult result -> Seconds
- BuildBox.Build.Benchmark: benchResultValue :: BenchResult result -> result
- BuildBox.Build.Benchmark: benchmarkCheck :: Benchmark result -> a -> Build result
- BuildBox.Build.Benchmark: benchmarkCommand :: Benchmark result -> Build a
- BuildBox.Build.Benchmark: benchmarkName :: Benchmark result -> String
- BuildBox.Build.Benchmark: benchmarkSetup :: Benchmark result -> Build ()
- BuildBox.Command.Darcs: darcsAuthor :: DarcsPatch -> EmailAddress
- BuildBox.Command.Darcs: darcsComment :: DarcsPatch -> Log
- BuildBox.Command.Darcs: darcsTimestamp :: DarcsPatch -> LocalTime
- BuildBox.Command.Darcs: instance Show DarcsPatch
- BuildBox.Command.Environment: environmentPlatform :: Environment -> Platform
- BuildBox.Command.Environment: environmentVersions :: Environment -> [(String, String)]
- BuildBox.Command.Environment: instance Pretty Environment
- BuildBox.Command.Environment: instance Pretty Platform
- BuildBox.Command.Environment: instance Read Environment
- BuildBox.Command.Environment: instance Read Platform
- BuildBox.Command.Environment: instance Show Environment
- BuildBox.Command.Environment: instance Show Platform
- BuildBox.Command.Environment: platformHostArch :: Platform -> String
- BuildBox.Command.Environment: platformHostName :: Platform -> String
- BuildBox.Command.Environment: platformHostOS :: Platform -> String
- BuildBox.Command.Environment: platformHostProcessor :: Platform -> String
- BuildBox.Command.Environment: platformHostRelease :: Platform -> String
- BuildBox.Command.File: instance Show PropFile
- BuildBox.Command.File: instance Testable PropFile
- BuildBox.Command.Mail: instance Show Mail
- BuildBox.Command.Mail: instance Show Mailer
- BuildBox.Command.Mail: mailBody :: Mail -> String
- BuildBox.Command.Mail: mailFrom :: Mail -> String
- BuildBox.Command.Mail: mailMessageId :: Mail -> String
- BuildBox.Command.Mail: mailSubject :: Mail -> String
- BuildBox.Command.Mail: mailTime :: Mail -> UTCTime
- BuildBox.Command.Mail: mailTimeZone :: Mail -> TimeZone
- BuildBox.Command.Mail: mailTo :: Mail -> String
- BuildBox.Command.Mail: mailerExtraFlags :: Mailer -> [String]
- BuildBox.Command.Mail: mailerPath :: Mailer -> FilePath
- BuildBox.Command.Mail: mailerPort :: Mailer -> Maybe Int
- BuildBox.Command.Network: instance Show PropNetwork
- BuildBox.Command.Network: instance Testable PropNetwork
- BuildBox.Control.Gang: instance Eq GangState
- BuildBox.Control.Gang: instance Show GangState
- BuildBox.Data.Comparison: comparisonBaseline :: Comparison a -> a
- BuildBox.Data.Comparison: comparisonNew :: Comparison a -> a
- BuildBox.Data.Comparison: comparisonRecent :: Comparison a -> a
- BuildBox.Data.Comparison: comparisonSwing :: Comparison a -> Double
- BuildBox.Data.Comparison: instance Pretty a => Pretty (Comparison a)
- BuildBox.Data.Comparison: instance Read a => Read (Comparison a)
- BuildBox.Data.Comparison: instance Show a => Show (Comparison a)
- BuildBox.Data.Detail: instance Enum Sized
- BuildBox.Data.Detail: instance Enum Timed
- BuildBox.Data.Detail: instance Enum Used
- BuildBox.Data.Detail: instance Eq Detail
- BuildBox.Data.Detail: instance Eq Sized
- BuildBox.Data.Detail: instance Eq Timed
- BuildBox.Data.Detail: instance Eq Used
- BuildBox.Data.Detail: instance Ord Detail
- BuildBox.Data.Detail: instance Ord Sized
- BuildBox.Data.Detail: instance Ord Timed
- BuildBox.Data.Detail: instance Ord Used
- BuildBox.Data.Detail: instance Pretty Sized
- BuildBox.Data.Detail: instance Pretty Timed
- BuildBox.Data.Detail: instance Pretty Used
- BuildBox.Data.Detail: instance Read Detail
- BuildBox.Data.Detail: instance Read Sized
- BuildBox.Data.Detail: instance Read Timed
- BuildBox.Data.Detail: instance Read Used
- BuildBox.Data.Detail: instance Show Detail
- BuildBox.Data.Detail: instance Show Sized
- BuildBox.Data.Detail: instance Show Timed
- BuildBox.Data.Detail: instance Show Used
- BuildBox.Data.Dividable: instance Dividable Float
- BuildBox.Data.Dividable: instance Dividable Integer
- BuildBox.Data.Physical: instance Dividable Bytes
- BuildBox.Data.Physical: instance Dividable Seconds
- BuildBox.Data.Physical: instance Eq Bytes
- BuildBox.Data.Physical: instance Eq Seconds
- BuildBox.Data.Physical: instance Num Bytes
- BuildBox.Data.Physical: instance Num Seconds
- BuildBox.Data.Physical: instance Ord Bytes
- BuildBox.Data.Physical: instance Ord Seconds
- BuildBox.Data.Physical: instance Pretty Bytes
- BuildBox.Data.Physical: instance Pretty Seconds
- BuildBox.Data.Physical: instance Read Bytes
- BuildBox.Data.Physical: instance Read Seconds
- BuildBox.Data.Physical: instance Real Bytes
- BuildBox.Data.Physical: instance Real Seconds
- BuildBox.Data.Physical: instance Show Bytes
- BuildBox.Data.Physical: instance Show Seconds
- BuildBox.Data.Range: instance Functor Range
- BuildBox.Data.Range: instance Pretty a => Pretty (Range a)
- BuildBox.Data.Range: instance Read a => Read (Range a)
- BuildBox.Data.Range: instance Show a => Show (Range a)
- BuildBox.Data.Range: rangeAvg :: Range a -> a
- BuildBox.Data.Range: rangeMax :: Range a -> a
- BuildBox.Data.Range: rangeMin :: Range a -> a
- BuildBox.Data.Schedule: eventLastEnded :: Event -> Maybe UTCTime
- BuildBox.Data.Schedule: eventLastStarted :: Event -> Maybe UTCTime
- BuildBox.Data.Schedule: eventName :: Event -> EventName
- BuildBox.Data.Schedule: eventWhen :: Event -> When
- BuildBox.Data.Schedule: eventWhenModifier :: Event -> Maybe WhenModifier
- BuildBox.Data.Schedule: instance Eq Event
- BuildBox.Data.Schedule: instance Eq When
- BuildBox.Data.Schedule: instance Eq WhenModifier
- BuildBox.Data.Schedule: instance Read Event
- BuildBox.Data.Schedule: instance Read NominalDiffTime
- BuildBox.Data.Schedule: instance Read When
- BuildBox.Data.Schedule: instance Read WhenModifier
- BuildBox.Data.Schedule: instance Show Event
- BuildBox.Data.Schedule: instance Show When
- BuildBox.Data.Schedule: instance Show WhenModifier
- BuildBox.Pretty: instance [incoherent] Pretty Doc
- BuildBox.Pretty: instance [incoherent] Pretty Float
- BuildBox.Pretty: instance [incoherent] Pretty Int
- BuildBox.Pretty: instance [incoherent] Pretty Integer
- BuildBox.Pretty: instance [incoherent] Pretty String
- BuildBox.Pretty: instance [incoherent] Pretty UTCTime
- BuildBox.Pretty: instance [incoherent] Pretty a => Pretty [a]
+ BuildBox: [buildErrorCmd] :: BuildError -> String
+ BuildBox: [buildErrorCode] :: BuildError -> ExitCode
+ BuildBox: [buildErrorStderr] :: BuildError -> Log
+ BuildBox: [buildErrorStdout] :: BuildError -> Log
+ BuildBox.Build: [buildErrorCmd] :: BuildError -> String
+ BuildBox.Build: [buildErrorCode] :: BuildError -> ExitCode
+ BuildBox.Build: [buildErrorStderr] :: BuildError -> Log
+ BuildBox.Build: [buildErrorStdout] :: BuildError -> Log
+ BuildBox.Build: [buildStateId] :: BuildState -> Integer
+ BuildBox.Build: [buildStateLogSystem] :: BuildState -> Maybe Handle
+ BuildBox.Build: [buildStateScratchDir] :: BuildState -> FilePath
+ BuildBox.Build: [buildStateSeq] :: BuildState -> Integer
+ BuildBox.Build.Benchmark: [benchResultIteration] :: BenchResult result -> Int
+ BuildBox.Build.Benchmark: [benchResultName] :: BenchResult result -> String
+ BuildBox.Build.Benchmark: [benchResultTime] :: BenchResult result -> Seconds
+ BuildBox.Build.Benchmark: [benchResultValue] :: BenchResult result -> result
+ BuildBox.Build.Benchmark: [benchmarkCheck] :: Benchmark result -> a -> Build result
+ BuildBox.Build.Benchmark: [benchmarkCommand] :: Benchmark result -> Build a
+ BuildBox.Build.Benchmark: [benchmarkName] :: Benchmark result -> String
+ BuildBox.Build.Benchmark: [benchmarkSetup] :: Benchmark result -> Build ()
+ BuildBox.Command.Darcs: [darcsAuthor] :: DarcsPatch -> EmailAddress
+ BuildBox.Command.Darcs: [darcsComment] :: DarcsPatch -> Log
+ BuildBox.Command.Darcs: [darcsTimestamp] :: DarcsPatch -> LocalTime
+ BuildBox.Command.Darcs: instance GHC.Show.Show BuildBox.Command.Darcs.DarcsPatch
+ BuildBox.Command.Environment: [environmentPlatform] :: Environment -> Platform
+ BuildBox.Command.Environment: [environmentVersions] :: Environment -> [(String, String)]
+ BuildBox.Command.Environment: [platformHostArch] :: Platform -> String
+ BuildBox.Command.Environment: [platformHostName] :: Platform -> String
+ BuildBox.Command.Environment: [platformHostOS] :: Platform -> String
+ BuildBox.Command.Environment: [platformHostProcessor] :: Platform -> String
+ BuildBox.Command.Environment: [platformHostRelease] :: Platform -> String
+ BuildBox.Command.Environment: instance BuildBox.Pretty.Pretty BuildBox.Command.Environment.Environment
+ BuildBox.Command.Environment: instance BuildBox.Pretty.Pretty BuildBox.Command.Environment.Platform
+ BuildBox.Command.Environment: instance GHC.Read.Read BuildBox.Command.Environment.Environment
+ BuildBox.Command.Environment: instance GHC.Read.Read BuildBox.Command.Environment.Platform
+ BuildBox.Command.Environment: instance GHC.Show.Show BuildBox.Command.Environment.Environment
+ BuildBox.Command.Environment: instance GHC.Show.Show BuildBox.Command.Environment.Platform
+ BuildBox.Command.File: instance BuildBox.Build.Testable.Testable BuildBox.Command.File.PropFile
+ BuildBox.Command.File: instance GHC.Show.Show BuildBox.Command.File.PropFile
+ BuildBox.Command.Mail: [mailBody] :: Mail -> String
+ BuildBox.Command.Mail: [mailFrom] :: Mail -> String
+ BuildBox.Command.Mail: [mailMessageId] :: Mail -> String
+ BuildBox.Command.Mail: [mailSubject] :: Mail -> String
+ BuildBox.Command.Mail: [mailTimeZone] :: Mail -> TimeZone
+ BuildBox.Command.Mail: [mailTime] :: Mail -> UTCTime
+ BuildBox.Command.Mail: [mailTo] :: Mail -> String
+ BuildBox.Command.Mail: [mailerExtraFlags] :: Mailer -> [String]
+ BuildBox.Command.Mail: [mailerPath] :: Mailer -> FilePath
+ BuildBox.Command.Mail: [mailerPort] :: Mailer -> Maybe Int
+ BuildBox.Command.Mail: instance GHC.Show.Show BuildBox.Command.Mail.Mail
+ BuildBox.Command.Mail: instance GHC.Show.Show BuildBox.Command.Mail.Mailer
+ BuildBox.Command.Network: instance BuildBox.Build.Testable.Testable BuildBox.Command.Network.PropNetwork
+ BuildBox.Command.Network: instance GHC.Show.Show BuildBox.Command.Network.PropNetwork
+ BuildBox.Control.Gang: instance GHC.Classes.Eq BuildBox.Control.Gang.GangState
+ BuildBox.Control.Gang: instance GHC.Show.Show BuildBox.Control.Gang.GangState
+ BuildBox.Data.Comparison: [comparisonBaseline] :: Comparison a -> a
+ BuildBox.Data.Comparison: [comparisonNew] :: Comparison a -> a
+ BuildBox.Data.Comparison: [comparisonRecent] :: Comparison a -> a
+ BuildBox.Data.Comparison: [comparisonSwing] :: Comparison a -> Double
+ BuildBox.Data.Comparison: instance BuildBox.Pretty.Pretty a => BuildBox.Pretty.Pretty (BuildBox.Data.Comparison.Comparison a)
+ BuildBox.Data.Comparison: instance GHC.Read.Read a => GHC.Read.Read (BuildBox.Data.Comparison.Comparison a)
+ BuildBox.Data.Comparison: instance GHC.Show.Show a => GHC.Show.Show (BuildBox.Data.Comparison.Comparison a)
+ BuildBox.Data.Detail: instance BuildBox.Pretty.Pretty BuildBox.Data.Detail.Sized
+ BuildBox.Data.Detail: instance BuildBox.Pretty.Pretty BuildBox.Data.Detail.Timed
+ BuildBox.Data.Detail: instance BuildBox.Pretty.Pretty BuildBox.Data.Detail.Used
+ BuildBox.Data.Detail: instance GHC.Classes.Eq BuildBox.Data.Detail.Detail
+ BuildBox.Data.Detail: instance GHC.Classes.Eq BuildBox.Data.Detail.Sized
+ BuildBox.Data.Detail: instance GHC.Classes.Eq BuildBox.Data.Detail.Timed
+ BuildBox.Data.Detail: instance GHC.Classes.Eq BuildBox.Data.Detail.Used
+ BuildBox.Data.Detail: instance GHC.Classes.Ord BuildBox.Data.Detail.Detail
+ BuildBox.Data.Detail: instance GHC.Classes.Ord BuildBox.Data.Detail.Sized
+ BuildBox.Data.Detail: instance GHC.Classes.Ord BuildBox.Data.Detail.Timed
+ BuildBox.Data.Detail: instance GHC.Classes.Ord BuildBox.Data.Detail.Used
+ BuildBox.Data.Detail: instance GHC.Enum.Enum BuildBox.Data.Detail.Sized
+ BuildBox.Data.Detail: instance GHC.Enum.Enum BuildBox.Data.Detail.Timed
+ BuildBox.Data.Detail: instance GHC.Enum.Enum BuildBox.Data.Detail.Used
+ BuildBox.Data.Detail: instance GHC.Read.Read BuildBox.Data.Detail.Detail
+ BuildBox.Data.Detail: instance GHC.Read.Read BuildBox.Data.Detail.Sized
+ BuildBox.Data.Detail: instance GHC.Read.Read BuildBox.Data.Detail.Timed
+ BuildBox.Data.Detail: instance GHC.Read.Read BuildBox.Data.Detail.Used
+ BuildBox.Data.Detail: instance GHC.Show.Show BuildBox.Data.Detail.Detail
+ BuildBox.Data.Detail: instance GHC.Show.Show BuildBox.Data.Detail.Sized
+ BuildBox.Data.Detail: instance GHC.Show.Show BuildBox.Data.Detail.Timed
+ BuildBox.Data.Detail: instance GHC.Show.Show BuildBox.Data.Detail.Used
+ BuildBox.Data.Dividable: instance BuildBox.Data.Dividable.Dividable GHC.Integer.Type.Integer
+ BuildBox.Data.Dividable: instance BuildBox.Data.Dividable.Dividable GHC.Types.Float
+ BuildBox.Data.Physical: instance BuildBox.Data.Dividable.Dividable BuildBox.Data.Physical.Bytes
+ BuildBox.Data.Physical: instance BuildBox.Data.Dividable.Dividable BuildBox.Data.Physical.Seconds
+ BuildBox.Data.Physical: instance BuildBox.Pretty.Pretty BuildBox.Data.Physical.Bytes
+ BuildBox.Data.Physical: instance BuildBox.Pretty.Pretty BuildBox.Data.Physical.Seconds
+ BuildBox.Data.Physical: instance GHC.Classes.Eq BuildBox.Data.Physical.Bytes
+ BuildBox.Data.Physical: instance GHC.Classes.Eq BuildBox.Data.Physical.Seconds
+ BuildBox.Data.Physical: instance GHC.Classes.Ord BuildBox.Data.Physical.Bytes
+ BuildBox.Data.Physical: instance GHC.Classes.Ord BuildBox.Data.Physical.Seconds
+ BuildBox.Data.Physical: instance GHC.Num.Num BuildBox.Data.Physical.Bytes
+ BuildBox.Data.Physical: instance GHC.Num.Num BuildBox.Data.Physical.Seconds
+ BuildBox.Data.Physical: instance GHC.Read.Read BuildBox.Data.Physical.Bytes
+ BuildBox.Data.Physical: instance GHC.Read.Read BuildBox.Data.Physical.Seconds
+ BuildBox.Data.Physical: instance GHC.Real.Real BuildBox.Data.Physical.Bytes
+ BuildBox.Data.Physical: instance GHC.Real.Real BuildBox.Data.Physical.Seconds
+ BuildBox.Data.Physical: instance GHC.Show.Show BuildBox.Data.Physical.Bytes
+ BuildBox.Data.Physical: instance GHC.Show.Show BuildBox.Data.Physical.Seconds
+ BuildBox.Data.Range: [rangeAvg] :: Range a -> a
+ BuildBox.Data.Range: [rangeMax] :: Range a -> a
+ BuildBox.Data.Range: [rangeMin] :: Range a -> a
+ BuildBox.Data.Range: instance BuildBox.Pretty.Pretty a => BuildBox.Pretty.Pretty (BuildBox.Data.Range.Range a)
+ BuildBox.Data.Range: instance GHC.Base.Functor BuildBox.Data.Range.Range
+ BuildBox.Data.Range: instance GHC.Read.Read a => GHC.Read.Read (BuildBox.Data.Range.Range a)
+ BuildBox.Data.Range: instance GHC.Show.Show a => GHC.Show.Show (BuildBox.Data.Range.Range a)
+ BuildBox.Data.Schedule: [eventLastEnded] :: Event -> Maybe UTCTime
+ BuildBox.Data.Schedule: [eventLastStarted] :: Event -> Maybe UTCTime
+ BuildBox.Data.Schedule: [eventName] :: Event -> EventName
+ BuildBox.Data.Schedule: [eventWhenModifier] :: Event -> Maybe WhenModifier
+ BuildBox.Data.Schedule: [eventWhen] :: Event -> When
+ BuildBox.Data.Schedule: instance GHC.Classes.Eq BuildBox.Data.Schedule.Event
+ BuildBox.Data.Schedule: instance GHC.Classes.Eq BuildBox.Data.Schedule.When
+ BuildBox.Data.Schedule: instance GHC.Classes.Eq BuildBox.Data.Schedule.WhenModifier
+ BuildBox.Data.Schedule: instance GHC.Read.Read BuildBox.Data.Schedule.Event
+ BuildBox.Data.Schedule: instance GHC.Read.Read BuildBox.Data.Schedule.When
+ BuildBox.Data.Schedule: instance GHC.Read.Read BuildBox.Data.Schedule.WhenModifier
+ BuildBox.Data.Schedule: instance GHC.Read.Read Data.Time.Clock.UTC.NominalDiffTime
+ BuildBox.Data.Schedule: instance GHC.Show.Show BuildBox.Data.Schedule.Event
+ BuildBox.Data.Schedule: instance GHC.Show.Show BuildBox.Data.Schedule.When
+ BuildBox.Data.Schedule: instance GHC.Show.Show BuildBox.Data.Schedule.WhenModifier
+ BuildBox.Pretty: instance BuildBox.Pretty.Pretty Data.Time.Clock.UTC.UTCTime
+ BuildBox.Pretty: instance BuildBox.Pretty.Pretty GHC.Base.String
+ BuildBox.Pretty: instance BuildBox.Pretty.Pretty GHC.Integer.Type.Integer
+ BuildBox.Pretty: instance BuildBox.Pretty.Pretty GHC.Types.Float
+ BuildBox.Pretty: instance BuildBox.Pretty.Pretty GHC.Types.Int
+ BuildBox.Pretty: instance BuildBox.Pretty.Pretty Text.PrettyPrint.HughesPJ.Doc
+ BuildBox.Pretty: instance BuildBox.Pretty.Pretty a => BuildBox.Pretty.Pretty [a]

Files

BuildBox.hs view
@@ -1,6 +1,6 @@  module BuildBox-	( Build+        ( Build          -- * Building         , runBuild
BuildBox/Build.hs view
@@ -1,34 +1,34 @@  -- | Defines the main `Build` monad and common utils. module BuildBox.Build -	( module BuildBox.Build.Testable-	, module BuildBox.Build.BuildState-	, Build+        ( module BuildBox.Build.Testable+        , module BuildBox.Build.BuildState+        , Build -	-- * Building-	, runBuild-	, runBuildWithState-	, runBuildPrint-	, runBuildPrintWithState-	, successfully+        -- * Building+        , runBuild+        , runBuildWithState+        , runBuildPrint+        , runBuildPrintWithState+        , successfully -	-- * Errors+        -- * Errors         , BuildError    (..)-	, throw+        , throw         , catch-	, needs+        , needs -	-- * Utils-	, io-	, whenM+        -- * Utils+        , io+        , whenM -	-- * Output-	, out-	, outLn-	, outBlank-	, outLine-	, outLINE-	, logSystem)+        -- * Output+        , out+        , outLn+        , outBlank+        , outLine+        , outLINE+        , logSystem)  where import BuildBox.Build.Base@@ -43,12 +43,12 @@ -- | Log a system command to the handle in our `BuildConfig`, if any. logSystem :: String -> Build () logSystem cmd- = do	mHandle	<- gets buildStateLogSystem-	case mHandle of-	 Nothing	-> return ()-	 Just handle	-	  -> do	io $ hPutStr   handle "buildbox system: "-		io $ hPutStrLn handle cmd-		return ()+ = do   mHandle <- gets buildStateLogSystem+        case mHandle of+         Nothing        -> return ()+         Just handle    +          -> do io $ hPutStr   handle "buildbox system: "+                io $ hPutStrLn handle cmd+                return ()  
BuildBox/Build/Base.hs view
@@ -13,7 +13,7 @@  -- | The builder monad encapsulates and IO action that can fail with an error,  --   and also read some global configuration info.-type Build a 	= ErrorT BuildError (StateT BuildState IO) a+type Build a    = ErrorT BuildError (StateT BuildState IO) a   -- Build ------------------------------------------------------------------------------------------@@ -21,65 +21,65 @@ --   temporary files (like \"/tmp\") runBuild :: FilePath -> Build a -> IO (Either BuildError a) runBuild scratchDir build- = do	uid	<- getUniqueId-	let s	= buildStateDefault uid scratchDir-	evalStateT (runErrorT build) s+ = do   uid     <- getUniqueId+        let s   = buildStateDefault uid scratchDir+        evalStateT (runErrorT build) s   -- | Like 'runBuild`, but report whether it succeeded to the console. --   If it succeeded then return Just the result, else Nothing. runBuildPrint :: FilePath -> Build a -> IO (Maybe a) runBuildPrint scratchDir build- = do	uid	<- getUniqueId-	let s	= buildStateDefault uid scratchDir-	runBuildPrintWithState s build+ = do   uid     <- getUniqueId+        let s   = buildStateDefault uid scratchDir+        runBuildPrintWithState s build   -- | Like `runBuild` but also takes a `BuildState`. runBuildWithState :: BuildState -> Build a -> IO (Maybe a) runBuildWithState s build- = do	result	<- evalStateT (runErrorT build) s-	case result of-	 Left err-	  -> do	putStrLn $ render $ ppr err-		return $ Nothing-		-	 Right x-	  -> do	return $ Just x+ = do   result  <- evalStateT (runErrorT build) s+        case result of+         Left err+          -> do putStrLn $ render $ ppr err+                return $ Nothing+                +         Right x+          -> do return $ Just x   -- | Like `runBuildPrint` but also takes a `BuildState`. runBuildPrintWithState :: BuildState -> Build a -> IO (Maybe a) runBuildPrintWithState s build- = do	result	<- evalStateT (runErrorT build) s-	case result of-	 Left err-	  -> do	putStrLn "\nBuild failed"-		putStr   "  due to "-		putStrLn $ render $ ppr err-		return $ Nothing-		-	 Right x-	  -> do	putStrLn "Build succeeded."-		return $ Just x+ = do   result  <- evalStateT (runErrorT build) s+        case result of+         Left err+          -> do putStrLn "\nBuild failed"+                putStr   "  due to "+                putStrLn $ render $ ppr err+                return $ Nothing+                +         Right x+          -> do putStrLn "Build succeeded."+                return $ Just x   -- | Discard the resulting value of a compuation. --   Used like @successfully . runBuild ...@ successfully :: IO a -> IO ()-successfully f 	= f >> return ()+successfully f  = f >> return ()   -- | Get a unique(ish) id for this process. --   The random seeds the global generator with the cpu time in psecs, which should be good enough. getUniqueId :: IO Integer getUniqueId- 	= randomRIO (0, 1000000000)	+        = randomRIO (0, 1000000000)       -- Errors ----------------------------------------------------------------------------------------- -- | Throw an error in the build monad. throw :: BuildError -> Build a-throw	= throwError+throw   = throwError   -- | Run a build command, catching any exceptions it sends.@@ -98,12 +98,12 @@ --   created. needs :: FilePath -> Build () needs filePath- = do	isFile	<- io $ doesFileExist filePath-	isDir	<- io $ doesDirectoryExist filePath-	-	if isFile || isDir-	 then return ()-	 else throw $ ErrorNeeds filePath+ = do   isFile  <- io $ doesFileExist filePath+        isDir   <- io $ doesDirectoryExist filePath+        +        if isFile || isDir+         then return ()+         else throw $ ErrorNeeds filePath   -- Utils ------------------------------------------------------------------------------------------@@ -112,45 +112,45 @@ --   `ErrorIOError` exceptions in our `Build` monad. io :: IO a -> Build a io x- = do	-- catch IOError exceptions-	result	<- liftIO $ try x-	-	case result of-	 Left err	-> throw $ ErrorIOError err-	 Right res	-> return res+ = do   -- catch IOError exceptions+        result  <- liftIO $ try x+        +        case result of+         Left err       -> throw $ ErrorIOError err+         Right res      -> return res   -- | Like `when`, but with teh monadz. whenM :: Monad m => m Bool -> m () -> m () whenM cb cx- = do	b	<- cb-	if b then cx else return ()+ = do   b       <- cb+        if b then cx else return ()   -- Output ----------------------------------------------------------------------------------------- -- | Print some text to stdout. out :: Pretty a => a -> Build ()-out str	+out str   = io - $ do	putStr   $ render $ ppr str-	hFlush stdout+ $ do   putStr   $ render $ ppr str+        hFlush stdout  -- | Print some text to stdout followed by a newline. outLn :: Pretty a => a -> Build ()-outLn str	= io $ putStrLn $ render $ ppr str+outLn str       = io $ putStrLn $ render $ ppr str   -- | Print a blank line to stdout outBlank :: Build ()-outBlank	= out $ text "\n"+outBlank        = out $ text "\n"   -- | Print a @-----@ line to stdout  outLine :: Build ()-outLine 	= io $ putStr (replicate 80 '-' ++ "\n")+outLine         = io $ putStr (replicate 80 '-' ++ "\n")   -- | Print a @=====@ line to stdout outLINE :: Build ()-outLINE		= io $ putStr (replicate 80 '=' ++ "\n")-	+outLINE         = io $ putStr (replicate 80 '=' ++ "\n")+        
BuildBox/Build/BuildError.hs view
@@ -2,38 +2,38 @@ {-# OPTIONS_HADDOCK hide #-}  module BuildBox.Build.BuildError-	(BuildError(..))+        (BuildError(..)) where import BuildBox.Pretty import System.Exit import Control.Monad.Error-import BuildBox.Data.Log		(Log)-import qualified BuildBox.Data.Log	as Log+import BuildBox.Data.Log                (Log)+import qualified BuildBox.Data.Log      as Log   -- BuildError ------------------------------------------------------------------------------------- -- | The errors we recognise. data BuildError-	-- | Some generic error-	= ErrorOther String+        -- | Some generic error+        = ErrorOther String -	-- | Some system command fell over, and it barfed out the given stdout and stderr.-	| ErrorSystemCmdFailed-		{ buildErrorCmd 	:: String-		, buildErrorCode	:: ExitCode-		, buildErrorStdout	:: Log-		, buildErrorStderr	:: Log }-		-	-- | Some miscellanous IO action failed.-	| ErrorIOError IOError+        -- | Some system command fell over, and it barfed out the given stdout and stderr.+        | ErrorSystemCmdFailed+                { buildErrorCmd         :: String+                , buildErrorCode        :: ExitCode+                , buildErrorStdout      :: Log+                , buildErrorStderr      :: Log }+                +        -- | Some miscellanous IO action failed.+        | ErrorIOError IOError -	-- | Some property `check` was supposed to return the given boolean value, but it didn't.-	| forall prop. Show prop => ErrorCheckFailed Bool prop	+        -- | Some property `check` was supposed to return the given boolean value, but it didn't.+        | forall prop. Show prop => ErrorCheckFailed Bool prop   -	-- | A build command needs the following file to continue.-	--   This can be used for writing make-like bots.-	| ErrorNeeds FilePath-	+        -- | A build command needs the following file to continue.+        --   This can be used for writing make-like bots.+        | ErrorNeeds FilePath+          instance Error BuildError where  strMsg s = ErrorOther s@@ -41,39 +41,39 @@ instance Pretty BuildError where  ppr err   = case err of-	ErrorOther str-	 -> text "Other error: " <> text str+        ErrorOther str+         -> text "Other error: " <> text str -	ErrorSystemCmdFailed{}-	 -> vcat -	 $ 	[ text "System command failure."-		, text "    command: " <> (text $ buildErrorCmd err)-		, text "  exit code: " <> (text $ show $ buildErrorCode err)-		, blank ] +        ErrorSystemCmdFailed{}+         -> vcat +         $      [ text "System command failure."+                , text "    command: " <> (text $ buildErrorCmd err)+                , text "  exit code: " <> (text $ show $ buildErrorCode err)+                , blank ]            ++ (if (not $ Log.null $ buildErrorStdout err)-	     then [ text "-- stdout (last 10 lines) ------------------------------------------------------"-		  , text $ Log.toString $ Log.lastLines 10 $ buildErrorStdout err]-	     else [])+             then [ text "-- stdout (last 10 lines) ------------------------------------------------------"+                  , text $ Log.toString $ Log.lastLines 10 $ buildErrorStdout err]+             else [])           ++ (if (not $ Log.null $ buildErrorStderr err)-	     then [ text "-- stderr (last 10 lines) ------------------------------------------------------"-		  , text $ Log.toString $ Log.lastLines 10 $ buildErrorStderr err ]-	     else [])+             then [ text "-- stderr (last 10 lines) ------------------------------------------------------"+                  , text $ Log.toString $ Log.lastLines 10 $ buildErrorStderr err ]+             else []) -	 ++ (if (  (not $ Log.null $ buildErrorStdout err)+         ++ (if (  (not $ Log.null $ buildErrorStdout err)                || (not $ Log.null $ buildErrorStderr err))              then [ text "--------------------------------------------------------------------------------" ]              else [])-	-	ErrorIOError ioerr-	 -> text "IO error: " <> (text $ show ioerr)+        +        ErrorIOError ioerr+         -> text "IO error: " <> (text $ show ioerr) -	ErrorCheckFailed expected prop-	 -> text "Check failure: " <> (text $ show prop) <> (text " expected ") <> (text $ show expected)+        ErrorCheckFailed expected prop+         -> text "Check failure: " <> (text $ show prop) <> (text " expected ") <> (text $ show expected) -	ErrorNeeds filePath-	 -> text "Build needs: " <> text filePath+        ErrorNeeds filePath+         -> text "Build needs: " <> text filePath   instance Show BuildError where
BuildBox/Build/BuildState.hs view
@@ -1,36 +1,36 @@ {-# OPTIONS_HADDOCK hide #-}  module BuildBox.Build.BuildState-	( BuildState(..)-	, buildStateDefault)+        ( BuildState(..)+        , buildStateDefault) where import System.IO  -- BuildConfig ------------------------------------------------------------------------------------ -- | Global builder configuration. data BuildState-	= BuildState-	{ -- | Log all system commands executed to this file handle.-	  buildStateLogSystem	:: Maybe Handle-	-	  -- | Uniqueish id for this build process.-	  --   On POSIX we'd use the PID, but that doesn't work on Windows.-	  --   The id is initialised by the Haskell random number generator on startup.-	, buildStateId		:: Integer-	-	  -- | Sequence number for generating fresh file names.-	, buildStateSeq		:: Integer -	-	  -- | Scratch directory for making temp files.-	, buildStateScratchDir	:: FilePath }+        = BuildState+        { -- | Log all system commands executed to this file handle.+          buildStateLogSystem   :: Maybe Handle+        +          -- | Uniqueish id for this build process.+          --   On POSIX we'd use the PID, but that doesn't work on Windows.+          --   The id is initialised by the Haskell random number generator on startup.+        , buildStateId          :: Integer+        +          -- | Sequence number for generating fresh file names.+        , buildStateSeq         :: Integer +        +          -- | Scratch directory for making temp files.+        , buildStateScratchDir  :: FilePath }   -- | The default build config. buildStateDefault :: Integer -> FilePath -> BuildState buildStateDefault uniqId scratchDir -	= BuildState-	{ buildStateLogSystem	= Nothing-	, buildStateId		= uniqId-	, buildStateSeq		= 0 -	, buildStateScratchDir	= scratchDir }+        = BuildState+        { buildStateLogSystem   = Nothing+        , buildStateId          = uniqId+        , buildStateSeq         = 0 +        , buildStateScratchDir  = scratchDir } 
BuildBox/Build/Testable.hs view
@@ -3,13 +3,13 @@ -- --   They have `Show` instances so we can make nice error messages if a `check` fails. module BuildBox.Build.Testable-	( Testable(..)-	, check-	, checkFalse-	, outCheckOk-	, outCheckFalseOk)+        ( Testable(..)+        , check+        , checkFalse+        , outCheckOk+        , outCheckFalseOk) where-import BuildBox.Build.Base	+import BuildBox.Build.Base       import BuildBox.Build.BuildError import Control.Monad.Error @@ -22,38 +22,38 @@ --   If the check returns false then throw an error. check :: (Show prop, Testable prop) => prop -> Build () check prop- = do	result	<- test prop-	if result-	 then return ()-	 else throwError $ ErrorCheckFailed True prop+ = do   result  <- test prop+        if result+         then return ()+         else throwError $ ErrorCheckFailed True prop   -- | Testable properties are checkable. --   If the check returns true then throw an error. checkFalse :: (Show prop, Testable prop) => prop -> Build () checkFalse prop- = do	result	<- test prop-	if result-	 then throwError $ ErrorCheckFailed False prop-	 else return ()-	+ = do   result  <- test prop+        if result+         then throwError $ ErrorCheckFailed False prop+         else return ()+          -- | Check some property while printing what we're doing. outCheckOk -	:: (Show prop, Testable prop) -	=> String -> prop -> Build ()+        :: (Show prop, Testable prop) +        => String -> prop -> Build ()  outCheckOk str prop- = do	outLn str-	check prop+ = do   outLn str+        check prop   -- | Check some property while printing what we're doing. outCheckFalseOk -	:: (Show prop, Testable prop) -	=> String -> prop -> Build ()+        :: (Show prop, Testable prop) +        => String -> prop -> Build ()  outCheckFalseOk str prop- = do	outLn str-	checkFalse prop+ = do   outLn str+        checkFalse prop 
BuildBox/Command/Darcs.hs view
@@ -11,7 +11,6 @@ -- standard libraries import Data.Time import Data.Maybe-import System.Locale import qualified Data.Sequence          as Seq import qualified Data.ByteString.Char8  as B 
BuildBox/Command/Environment.hs view
@@ -1,22 +1,22 @@  -- | Gathering information about the build environment. module BuildBox.Command.Environment-	( -- * Build Environment-	  Environment(..)-	, getEnvironmentWith-	-	  -- * Build platform-	, Platform(..)-	, getHostPlatform-	, getHostName-	, getHostArch-	, getHostProcessor-	, getHostOS-	, getHostRelease-	-	  -- * Software versions-	, getVersionGHC-	, getVersionGCC)+        ( -- * Build Environment+          Environment(..)+        , getEnvironmentWith+        +          -- * Build platform+        , Platform(..)+        , getHostPlatform+        , getHostName+        , getHostArch+        , getHostProcessor+        , getHostOS+        , getHostRelease+        +          -- * Software versions+        , getVersionGHC+        , getVersionGCC) where import BuildBox.Build import BuildBox.Command.System@@ -27,134 +27,134 @@ -- Environment ------------------------------------------------------------------------------------ -- | The environment consists of the `Platform`, and some tool versions. data Environment -	= Environment-	{ environmentPlatform	:: Platform-	, environmentVersions	:: [(String, String)] }-	deriving (Show, Read)+        = Environment+        { environmentPlatform   :: Platform+        , environmentVersions   :: [(String, String)] }+        deriving (Show, Read)   instance Pretty Environment where  ppr env-	= hang (ppr "Environment") 2 $ vcat-	[ ppr 	$ environmentPlatform env-	, hang (ppr "Versions") 2 -		$ vcat -		$ map (\(name, ver) -> ppr name <+> ppr ver) -		$ environmentVersions env ]+        = hang (ppr "Environment") 2 $ vcat+        [ ppr   $ environmentPlatform env+        , hang (ppr "Versions") 2 +                $ vcat +                $ map (\(name, ver) -> ppr name <+> ppr ver) +                $ environmentVersions env ]    -- | Get the current environment, including versions of these tools. getEnvironmentWith -	:: [(String, Build String)]	-- ^ List of tool names and commands to get their versions.-	-> Build Environment-	+        :: [(String, Build String)]     -- ^ List of tool names and commands to get their versions.+        -> Build Environment+         getEnvironmentWith nameGets - = do	platform	<- getHostPlatform+ = do   platform        <- getHostPlatform -	versions	<- mapM (\(name, get) -> do-					ver	<- get-					return	(name, ver))-			$  nameGets-			-	return	$ Environment-		{ environmentPlatform	= platform -		, environmentVersions	= versions }-	+        versions        <- mapM (\(name, get) -> do+                                        ver     <- get+                                        return  (name, ver))+                        $  nameGets+                        +        return  $ Environment+                { environmentPlatform   = platform +                , environmentVersions   = versions }+           -- Platform --------------------------------------------------------------------------------------- -- | Generic information about the platform we're running on. data Platform-	= Platform-	{ platformHostName 	:: String-	, platformHostArch	:: String-	, platformHostProcessor	:: String-	, platformHostOS	:: String-	, platformHostRelease	:: String }-	deriving (Show, Read)-	-	+        = Platform+        { platformHostName      :: String+        , platformHostArch      :: String+        , platformHostProcessor :: String+        , platformHostOS        :: String+        , platformHostRelease   :: String }+        deriving (Show, Read)+        +         instance Pretty Platform where  ppr plat-	= hang (ppr "Platform") 2 $ vcat-	[ ppr "host:      " <> (ppr $ platformHostName plat)-	, ppr "arch:      " <> (ppr $ platformHostArch plat)-	, ppr "processor: " <> (ppr $ platformHostProcessor plat)-	, ppr "system:    " <> (ppr $ platformHostOS plat) <+> (ppr $ platformHostRelease plat) ]+        = hang (ppr "Platform") 2 $ vcat+        [ ppr "host:      " <> (ppr $ platformHostName plat)+        , ppr "arch:      " <> (ppr $ platformHostArch plat)+        , ppr "processor: " <> (ppr $ platformHostProcessor plat)+        , ppr "system:    " <> (ppr $ platformHostOS plat) <+> (ppr $ platformHostRelease plat) ]   -- | Get information about the host platform. getHostPlatform :: Build Platform getHostPlatform - = do	name		<- getHostName-	arch		<- getHostArch-	processor	<- getHostProcessor-	os		<- getHostOS-	release		<- getHostRelease-	-	return	$ Platform-		{ platformHostName	= name-		, platformHostArch	= arch-		, platformHostProcessor	= processor-		, platformHostOS	= os-		, platformHostRelease	= release }-		+ = do   name            <- getHostName+        arch            <- getHostArch+        processor       <- getHostProcessor+        os              <- getHostOS+        release         <- getHostRelease+        +        return  $ Platform+                { platformHostName      = name+                , platformHostArch      = arch+                , platformHostProcessor = processor+                , platformHostOS        = os+                , platformHostRelease   = release }+                  -- Platform Tests --------------------------------------------------------------------------------- -- | Get the name of this host, using @uname@. getHostName :: Build String getHostName- = do	check $ HasExecutable "uname"-	name   <- sesystemq "uname -n"-	return	$ init name+ = do   check $ HasExecutable "uname"+        name   <- sesystemq "uname -n"+        return  $ init name   -- | Get the host architecture, using @uname@. getHostArch :: Build String getHostArch- = do	check $ HasExecutable "arch"-	name   <- sesystemq "arch"-	return	$ init name+ = do   check $ HasExecutable "arch"+        name   <- sesystemq "arch"+        return  $ init name   -- | Get the host processor name, using @uname@. getHostProcessor :: Build String getHostProcessor- = do	check $ HasExecutable "uname"-	name   <- sesystemq "uname -p"-	return	$ init name+ = do   check $ HasExecutable "uname"+        name   <- sesystemq "uname -p"+        return  $ init name   -- | Get the host operating system, using @uname@. getHostOS :: Build String getHostOS- = do	check $ HasExecutable "uname"-	name   <- sesystemq "uname -s"-	return	$ init name+ = do   check $ HasExecutable "uname"+        name   <- sesystemq "uname -s"+        return  $ init name   -- | Get the host operating system release, using @uname@. getHostRelease :: Build String getHostRelease- = do	check $ HasExecutable "uname"-	str    <- sesystemq "uname -r"-	return	$ init str+ = do   check $ HasExecutable "uname"+        str    <- sesystemq "uname -r"+        return  $ init str   -- Software version tests ------------------------------------------------------------------------- -- | Get the version of this GHC, or throw an error if it can't be found. getVersionGHC :: FilePath -> Build String getVersionGHC path- = do	check $ HasExecutable path-	str	<- sesystemq $ path ++ " --version"-	return	$ init str-	+ = do   check $ HasExecutable path+        str     <- sesystemq $ path ++ " --version"+        return  $ init str+         -- | Get the version of this GCC, or throw an error if it can't be found.  getVersionGCC :: FilePath -> Build String getVersionGCC path- = do	check $ HasExecutable path- 	str	<- sesystemq $ path ++ " --version"-	return	$ head $ lines str+ = do   check $ HasExecutable path+        str     <- sesystemq $ path ++ " --version"+        return  $ head $ lines str  
BuildBox/Command/File.hs view
@@ -1,13 +1,13 @@  -- | Working with the file system. module BuildBox.Command.File-	( PropFile(..)-	, inDir-	, inScratchDir-	, clobberDir-	, ensureDir-	, withTempFile-	, atomicWriteFile+        ( PropFile(..)+        , inDir+        , inScratchDir+        , clobberDir+        , ensureDir+        , withTempFile+        , atomicWriteFile         , exe ) where import BuildBox.Build@@ -19,51 +19,51 @@ -- | Properties of the file system we can test for. data PropFile -	-- | Some executable is in the current path.-	= HasExecutable	String+        -- | Some executable is in the current path.+        = HasExecutable String -	-- | Some file exists.-	| HasFile	FilePath+        -- | Some file exists.+        | HasFile       FilePath -	-- | Some directory exists.-	| HasDir  	FilePath+        -- | Some directory exists.+        | HasDir        FilePath -	-- | Some file is empty.-	| FileEmpty 	FilePath-	deriving Show+        -- | Some file is empty.+        | FileEmpty     FilePath+        deriving Show   instance Testable PropFile where  test prop   = case prop of-	HasExecutable name-	 -> do	bin <- io $ findExecutable name-		return $ case bin of-		 Just _	 	-> True-		 Nothing 	-> False+        HasExecutable name+         -> do  bin <- io $ findExecutable name+                return $ case bin of+                 Just _         -> True+                 Nothing        -> False -	HasFile path-	 -> io $ doesFileExist path+        HasFile path+         -> io $ doesFileExist path -	HasDir  path-	 -> io $ doesDirectoryExist path+        HasDir  path+         -> io $ doesDirectoryExist path -	FileEmpty  path-	 -> do	contents	<- io $ readFile path-		return (null contents)+        FileEmpty  path+         -> do  contents        <- io $ readFile path+                return (null contents)   -- | Run a command in a different working directory. Throws an error if the directory doesn't exist. inDir :: FilePath -> Build a -> Build a inDir name build- = do	check $ HasDir name-	oldDir	<- io $ getCurrentDirectory+ = do   check $ HasDir name+        oldDir  <- io $ getCurrentDirectory -	io $ setCurrentDirectory name-	x	<- build-	io $ setCurrentDirectory oldDir+        io $ setCurrentDirectory name+        x       <- build+        io $ setCurrentDirectory oldDir -	return x+        return x  -- | Create a new directory with the given name, run a command within it, --   then change out and recursively delete the directory. Throws an error if a directory@@ -71,100 +71,100 @@ inScratchDir :: FilePath -> Build a -> Build a inScratchDir name build  = do-	-- Make sure a dir with this name doesn't already exist.-	checkFalse $ HasDir name+        -- Make sure a dir with this name doesn't already exist.+        checkFalse $ HasDir name -	ensureDir name-	x	<- inDir name build-	clobberDir name+        ensureDir name+        x       <- inDir name build+        clobberDir name -	return x+        return x   -- | Delete a dir recursively if it's there, otherwise do nothing. clobberDir :: FilePath -> Build () clobberDir path- = do	e <- io $ try $ removeDirectoryRecursive path- 	case (e :: Either SomeException ()) of- 	 _	-> return ()+ = do   e <- io $ try $ removeDirectoryRecursive path+        case (e :: Either SomeException ()) of+         _      -> return ()   -- | Create a new directory if it isn't already there, or return successfully if it is. ensureDir :: FilePath -> Build () ensureDir path- = do	already	<- io $ doesDirectoryExist path-	if already-	 then return ()-	 else do e <- io $ try $ createDirectoryIfMissing True path-	 	 case (e :: Either SomeException ()) of-		  _	-> return ()+ = do   already <- io $ doesDirectoryExist path+        if already+         then return ()+         else do e <- io $ try $ createDirectoryIfMissing True path+                 case (e :: Either SomeException ()) of+                  _     -> return ()   -- | Create a temp file, pass it to some command, then delete the file after the command finishes. withTempFile :: (FilePath -> Build a) -> Build a withTempFile build- = do	fileName	<- newTempFile+ = do   fileName        <- newTempFile -	-- run the real command-	result	<- build fileName+        -- run the real command+        result  <- build fileName -	-- cleanup-	io $ removeFile fileName+        -- cleanup+        io $ removeFile fileName -	return result+        return result   -- | Allocate a new temporary file name newTempFile :: Build FilePath newTempFile- = do	buildDir	<- gets buildStateScratchDir-	buildId		<- gets buildStateId-	buildSeq	<- gets buildStateSeq+ = do   buildDir        <- gets buildStateScratchDir+        buildId         <- gets buildStateId+        buildSeq        <- gets buildStateSeq -	-- Increment the sequence number.-	modify $ \s -> s { buildStateSeq = buildStateSeq s + 1 }+        -- Increment the sequence number.+        modify $ \s -> s { buildStateSeq = buildStateSeq s + 1 }          -- Ensure the build directory exists, or canonicalizePath will fail         ensureDir buildDir -	-- Build the file name we'll try to use.-	-- We need to account for a blank scratch directory, otherwise there is-	-- no way to use the CD as a scratch on Windows.-	let fileName	 = (if (null buildDir) then "" else (buildDir ++ "/"))-		++ "buildbox-" ++ show buildId ++ "-" ++ show buildSeq+        -- Build the file name we'll try to use.+        -- We need to account for a blank scratch directory, otherwise there is+        -- no way to use the CD as a scratch on Windows.+        let fileName     = (if (null buildDir) then "" else (buildDir ++ "/"))+                ++ "buildbox-" ++ show buildId ++ "-" ++ show buildSeq                                                 -- TODO: normalise path -	-- If it already exists then something has gone badly wrong.-	--   Maybe the unique Id for the process wasn't as unique as we thought.-	exists		<- io $ doesFileExist fileName-	when exists-	 $ error "buildbox: panic, supposedly fresh file already exists."+        -- If it already exists then something has gone badly wrong.+        --   Maybe the unique Id for the process wasn't as unique as we thought.+        exists          <- io $ doesFileExist fileName+        when exists+         $ error "buildbox: panic, supposedly fresh file already exists." -	-- Touch the file for good measure.-	--   If the unique id wasn't then we want to detect this.-	io $ writeFile fileName ""+        -- Touch the file for good measure.+        --   If the unique id wasn't then we want to detect this.+        io $ writeFile fileName "" -	io $ canonicalizePath fileName+        io $ canonicalizePath fileName   -- | Atomically write a file by first writing it to a tmp file then renaming it. --   This prevents concurrent processes from reading half-written files. atomicWriteFile :: FilePath -> String -> Build () atomicWriteFile filePath str- = do	tmp	<- newTempFile-	io $ writeFile tmp str-	e <- io $ try $ renameFile tmp filePath+ = do   tmp     <- newTempFile+        io $ writeFile tmp str+        e <- io $ try $ renameFile tmp filePath -	-- renameFile may not be able to rename files across physical devices, -	-- depending on the implementation. If renameFile fails then try copyFile.-	case (e :: Either SomeException ()) of-	 Right _ 	   - 	  -> return ()+        -- renameFile may not be able to rename files across physical devices, +        -- depending on the implementation. If renameFile fails then try copyFile.+        case (e :: Either SomeException ()) of+         Right _           +          -> return () -	 Left _- 	  -> do	io $ copyFile tmp filePath-		io $ removeFile tmp-		return ()+         Left _+          -> do io $ copyFile tmp filePath+                io $ removeFile tmp+                return ()   -- | The file extension for an executable on the current system.
BuildBox/Command/Mail.hs view
@@ -4,17 +4,16 @@ --   Otherwise, the stand-alone @msmtp@ server is easy to set up. --   Get @msmtp@ here: <http://msmtp.sourceforge.net> module BuildBox.Command.Mail-	( Mail(..)-	, Mailer(..)-	, createMailWithCurrentTime-	, renderMail-	, sendMailWithMailer)+        ( Mail(..)+        , Mailer(..)+        , createMailWithCurrentTime+        , renderMail+        , sendMailWithMailer) where import BuildBox.Build import BuildBox.Pretty import BuildBox.Command.Environment import BuildBox.Command.System-import System.Locale	(defaultTimeLocale) import Data.Time.Clock import Data.Time.LocalTime import Data.Time.Format@@ -23,34 +22,34 @@  -- | An email message that we can send. data Mail-	= Mail-	{ mailFrom		:: String-	, mailTo		:: String-	, mailSubject		:: String-	, mailTime		:: UTCTime-	, mailTimeZone		:: TimeZone-	, mailMessageId		:: String-	, mailBody		:: String }-	deriving Show+        = Mail+        { mailFrom              :: String+        , mailTo                :: String+        , mailSubject           :: String+        , mailTime              :: UTCTime+        , mailTimeZone          :: TimeZone+        , mailMessageId         :: String+        , mailBody              :: String }+        deriving Show   -- | An external mailer that can send messages.---   	Also contains mail server info if needed.+--      Also contains mail server info if needed. data Mailer-	-- | Send the mail by writing to the stdin of this command.-	--   On many systems the command 'sendmail' will be aliased to an appropriate-	--   wrapper for whatever Mail Transfer Agent (MTA) you have installed.-	= MailerSendmail-	{ mailerPath		:: FilePath-	, mailerExtraFlags	:: [String] }+        -- | Send the mail by writing to the stdin of this command.+        --   On many systems the command 'sendmail' will be aliased to an appropriate+        --   wrapper for whatever Mail Transfer Agent (MTA) you have installed.+        = MailerSendmail+        { mailerPath            :: FilePath+        , mailerExtraFlags      :: [String] } -	-- | Send mail via MSMTP, which is a stand-alone SMTP sender.-	--   This might be be easier to set up if you don't have a real MTA installed.-	--   Get it from http://msmtp.sourceforge.net/-	| MailerMSMTP-	{ mailerPath		:: FilePath-	, mailerPort		:: Maybe Int }-	deriving Show+        -- | Send mail via MSMTP, which is a stand-alone SMTP sender.+        --   This might be be easier to set up if you don't have a real MTA installed.+        --   Get it from http://msmtp.sourceforge.net/+        | MailerMSMTP+        { mailerPath            :: FilePath+        , mailerPort            :: Maybe Int }+        deriving Show   -- | Create a mail with a given from, to, subject and body.@@ -58,68 +57,68 @@ --   Valid dates and message ids are needed to prevent the mail --   being bounced by anti-spam systems. createMailWithCurrentTime -	:: String 	-- ^ ''from'' field. Should be an email address.-	-> String	-- ^ ''to'' field. Should be an email address.-	-> String	-- ^ Subject line.-	-> String	-- ^ Message  body.-	-> Build Mail+        :: String       -- ^ ''from'' field. Should be an email address.+        -> String       -- ^ ''to'' field. Should be an email address.+        -> String       -- ^ Subject line.+        -> String       -- ^ Message  body.+        -> Build Mail  createMailWithCurrentTime from to subject body  = do-	-- We need to add the date otherwise our messages will get marked as spam.-	-- Use RFC 2822 format timestamp.-	utime		<- io $ getCurrentTime-	zone		<- io $ getCurrentTimeZone+        -- We need to add the date otherwise our messages will get marked as spam.+        -- Use RFC 2822 format timestamp.+        utime           <- io $ getCurrentTime+        zone            <- io $ getCurrentTimeZone -	-- Generate a messageid based on the clock time.-	hostName	<- getHostName-	let dayNum	= toModifiedJulianDay $ utctDay utime-	let secTime	= utctDayTime utime-	let messageId	=  "<" ++ show dayNum ++ "." ++ (init $ show secTime)-			++ "@" ++ hostName ++ ">"-		-	return	$ Mail-		{ mailFrom	= from-		, mailTo	= to-		, mailSubject	= subject-		, mailTime	= utime-		, mailTimeZone	= zone-		, mailMessageId	= messageId-		, mailBody	= body }+        -- Generate a messageid based on the clock time.+        hostName        <- getHostName+        let dayNum      = toModifiedJulianDay $ utctDay utime+        let secTime     = utctDayTime utime+        let messageId   =  "<" ++ show dayNum ++ "." ++ (init $ show secTime)+                        ++ "@" ++ hostName ++ ">"+                +        return  $ Mail+                { mailFrom      = from+                , mailTo        = to+                , mailSubject   = subject+                , mailTime      = utime+                , mailTimeZone  = zone+                , mailMessageId = messageId+                , mailBody      = body }   -- | Render an email message as a string. renderMail :: Mail -> Doc renderMail mail  = vcat-	[ ppr "From: "		<> ppr (mailFrom mail)-	, ppr "To: "		<> ppr (mailTo   mail)-	, ppr "Subject: "	<> ppr (mailSubject mail)-	, ppr "Date: "		<> (ppr $ formatTime defaultTimeLocale "%a, %e %b %Y %H:%M:%S %z"-					$ utcToZonedTime (mailTimeZone mail) (mailTime mail))+        [ ppr "From: "          <> ppr (mailFrom mail)+        , ppr "To: "            <> ppr (mailTo   mail)+        , ppr "Subject: "       <> ppr (mailSubject mail)+        , ppr "Date: "          <> (ppr $ formatTime defaultTimeLocale "%a, %e %b %Y %H:%M:%S %z"+                                        $ utcToZonedTime (mailTimeZone mail) (mailTime mail)) -	, ppr "Message-Id: " 	<> ppr (mailMessageId mail)-	, ppr ""-	, ppr (mailBody mail) ]+        , ppr "Message-Id: "    <> ppr (mailMessageId mail)+        , ppr ""+        , ppr (mailBody mail) ]   -- | Send a mail message. sendMailWithMailer :: Mail -> Mailer -> Build () sendMailWithMailer mail mailer  = case mailer of-	MailerSendmail{}	-	 -> ssystemTee False-		(mailerPath mailer-			++ " -t ") -- read recipients from the mail-		(render $ renderMail mail)+        MailerSendmail{}        +         -> ssystemTee False+                (mailerPath mailer+                        ++ " -t ") -- read recipients from the mail+                (render $ renderMail mail) -	MailerMSMTP{}	-	 -> ssystemTee False-		(mailerPath mailer -			++ " -t " -- read recipients from the mail-			++ (maybe "" (\port -> " --port=" ++ show port) $ mailerPort mailer))-		(render $ renderMail mail)-		+        MailerMSMTP{}   +         -> ssystemTee False+                (mailerPath mailer +                        ++ " -t " -- read recipients from the mail+                        ++ (maybe "" (\port -> " --port=" ++ show port) $ mailerPort mailer))+                (render $ renderMail mail)+                   
BuildBox/Command/Network.hs view
@@ -1,46 +1,46 @@  -- | Working with the network. module BuildBox.Command.Network-	(PropNetwork(..))+        (PropNetwork(..)) where import BuildBox.Build import BuildBox.Command.File import BuildBox.Command.System -type HostName	= String-type URL	= String+type HostName   = String+type URL        = String  data PropNetwork -	-- | The given host is reachable with @ping@.-	= HostReachable	HostName+        -- | The given host is reachable with @ping@.+        = HostReachable HostName -	-- | Use @wget@ to check if a web-page is gettable.-	--   The page is deleted after downloading.-	| UrlGettable	URL+        -- | Use @wget@ to check if a web-page is gettable.+        --   The page is deleted after downloading.+        | UrlGettable   URL -	deriving Show-	+        deriving Show+         instance Testable PropNetwork where  test prop   = case prop of -	-- Works on OSX 10.6.2-	-- -o               exit successfully after recieving one reply packet.-	HostReachable hostName-	 -> do	check	$ HasExecutable "ping"-		(code, _, _) <- systemq $ "ping -o " ++ hostName-		return $ code == ExitSuccess-		-	-- Works on OSX 10.6.2, wget 1.12-	--  -q              quiet-	--  --delete-after  delete page after downloading.-	UrlGettable url-	 -> do	check	$ HasExecutable "wget"-		(code, _, _) <- systemq $ "wget -q --delete-after " ++ url-		return	$ code == ExitSuccess-		+        -- Works on OSX 10.6.2+        -- -o               exit successfully after recieving one reply packet.+        HostReachable hostName+         -> do  check   $ HasExecutable "ping"+                (code, _, _) <- systemq $ "ping -o " ++ hostName+                return $ code == ExitSuccess+                +        -- Works on OSX 10.6.2, wget 1.12+        --  -q              quiet+        --  --delete-after  delete page after downloading.+        UrlGettable url+         -> do  check   $ HasExecutable "wget"+                (code, _, _) <- systemq $ "wget -q --delete-after " ++ url+                return  $ code == ExitSuccess+                  -	+         
BuildBox/Command/Sleep.hs view
@@ -1,8 +1,8 @@  -- | What do build 'bots dream about? module BuildBox.Command.Sleep-	( sleep-	, msleep)+        ( sleep+        , msleep) where import BuildBox.Build import Control.Concurrent@@ -10,11 +10,11 @@  -- | Sleep for a given number of seconds. sleep :: Int -> Build ()-sleep secs	-	= io $ threadDelay $ secs * 1000000+sleep secs      +        = io $ threadDelay $ secs * 1000000 -	+         -- | Sleep for a given number of milliseconds. msleep :: Int -> Build () msleep msecs-	= io $ threadDelay $ msecs * 1000+        = io $ threadDelay $ msecs * 1000
BuildBox/Command/System.hs view
@@ -8,22 +8,22 @@ --   buildbots, and we usually need all the versions...  module BuildBox.Command.System -	( module System.Exit+        ( module System.Exit -	-- * Wrappers-	, system-	, systemq-	, ssystem-	, ssystemq-	, sesystem-	, sesystemq-	, systemTee-	, systemTeeLog-	, ssystemTee-	, systemTeeIO+        -- * Wrappers+        , system+        , systemq+        , ssystem+        , ssystemq+        , sesystem+        , sesystemq+        , systemTee+        , systemTeeLog+        , ssystemTee+        , systemTeeIO -	-- * The real function-	, systemTeeLogIO)+        -- * The real function+        , systemTeeLogIO) where import BuildBox.Command.System.Internals import BuildBox.Build@@ -33,16 +33,16 @@ import Control.Monad.STM import System.Exit import System.IO-import Data.ByteString.Char8		(ByteString)-import BuildBox.Data.Log		(Log)-import System.Process			hiding (system)-import qualified BuildBox.Data.Log	as Log+import Data.ByteString.Char8            (ByteString)+import BuildBox.Data.Log                (Log)+import System.Process                   hiding (system)+import qualified BuildBox.Data.Log      as Log  debug :: Bool-debug	= False+debug   = False  trace :: String -> IO ()-trace s	= when debug $ putStrLn s+trace s = when debug $ putStrLn s   -- Wrappers ---------------------------------------------------------------------------------------@@ -50,15 +50,15 @@ --   returning its exit code and what it wrote to @stdout@ and @stderr@. system :: String -> Build (ExitCode, String, String) system cmd- = do	(code, logOut, logErr)    <- systemTeeLog True cmd Log.empty-	return (code, Log.toString logOut, Log.toString logErr)+ = do   (code, logOut, logErr)    <- systemTeeLog True cmd Log.empty+        return (code, Log.toString logOut, Log.toString logErr)   -- | Quietly run a system command, --   returning its exit code and what it wrote to @stdout@ and @stderr@. systemq :: String -> Build (ExitCode, String, String) systemq cmd- = do	(code, logOut, logErr)    <- systemTeeLog False cmd Log.empty+ = do   (code, logOut, logErr)    <- systemTeeLog False cmd Log.empty         return (code, Log.toString logOut, Log.toString logErr)  @@ -68,12 +68,12 @@ --   If the exit code is `ExitFailure` then throw an error in the `Build` monad. ssystem :: String -> Build (String, String) ssystem cmd- = do	(code, logOut, logErr)    <- systemTeeLog True cmd Log.empty+ = do   (code, logOut, logErr)    <- systemTeeLog True cmd Log.empty          when (code /= ExitSuccess)          $ throw $ ErrorSystemCmdFailed cmd code logOut logErr -	return (Log.toString logOut, Log.toString logErr)+        return (Log.toString logOut, Log.toString logErr)   -- | Quietly run a successful system command,@@ -95,11 +95,11 @@ --   then throw an error in the `Build` monad. sesystem :: String -> Build String sesystem cmd- = do	(code, logOut, logErr)	<- systemTeeLog True cmd Log.empty-	when (code /= ExitSuccess || (not $ Log.null logErr))-	 $ throw $ ErrorSystemCmdFailed cmd code logOut logErr+ = do   (code, logOut, logErr)  <- systemTeeLog True cmd Log.empty+        when (code /= ExitSuccess || (not $ Log.null logErr))+         $ throw $ ErrorSystemCmdFailed cmd code logOut logErr -	return $ Log.toString logOut+        return $ Log.toString logOut  -- | Quietly run a successful system command, returning what it wrote to its @stdout@. --   If anything was written to @stderr@ then treat that as failure. @@ -107,11 +107,11 @@ --   then throw an error in the `Build` monad. sesystemq :: String -> Build String sesystemq cmd- = do	(code, logOut, logErr)	<- systemTeeLog False cmd Log.empty-	when (code /= ExitSuccess || (not $ Log.null logErr))-	 $ throw $ ErrorSystemCmdFailed cmd code logOut logErr+ = do   (code, logOut, logErr)  <- systemTeeLog False cmd Log.empty+        when (code /= ExitSuccess || (not $ Log.null logErr))+         $ throw $ ErrorSystemCmdFailed cmd code logOut logErr -	return $ Log.toString logOut+        return $ Log.toString logOut   @@ -120,114 +120,114 @@ -- | Like `systemTeeIO`, but in the `Build` monad. systemTee :: Bool -> String -> String -> Build (ExitCode, String, String) systemTee tee cmd strIn- = do	logSystem cmd-	io $ systemTeeIO tee cmd strIn+ = do   logSystem cmd+        io $ systemTeeIO tee cmd strIn  -- | Like `systemTeeLogIO`, but in the `Build` monad. systemTeeLog :: Bool -> String -> Log -> Build (ExitCode, Log, Log) systemTeeLog tee cmd logIn- = do	logSystem cmd-	io $ systemTeeLogIO tee cmd logIn+ = do   logSystem cmd+        io $ systemTeeLogIO tee cmd logIn   -- | Like `systemTeeIO`, but in the `Build` monad and throw an error if it returns `ExitFailure`. ssystemTee  :: Bool -> String -> String -> Build () ssystemTee tee cmd strIn- = do	(code, logOut, logErr)	<- systemTeeLog tee cmd (Log.fromString strIn)-	when (code /= ExitSuccess)-	 $ throw $ ErrorSystemCmdFailed cmd code logOut logErr+ = do   (code, logOut, logErr)  <- systemTeeLog tee cmd (Log.fromString strIn)+        when (code /= ExitSuccess)+         $ throw $ ErrorSystemCmdFailed cmd code logOut logErr   -- | Like `systemTeeLogIO`, but with strings. systemTeeIO :: Bool -> String -> String -> IO (ExitCode, String, String) systemTeeIO tee cmd strIn- = do	(code, logOut, logErr)	<- systemTeeLogIO tee cmd $ Log.fromString strIn-	return	(code, Log.toString logOut, Log.toString logErr)+ = do   (code, logOut, logErr)  <- systemTeeLogIO tee cmd $ Log.fromString strIn+        return  (code, Log.toString logOut, Log.toString logErr)   -- | Run a system command, returning its `ExitCode` and what was written to @stdout@ and @stderr@. systemTeeLogIO-	:: Bool 	-- ^ Whether @stdout@ and @stderr@ should be forwarded to the parent process.-	-> String 	-- ^ Command to run.-	-> Log		-- ^ What to pass to the command's @stdin@.-	-> IO (ExitCode, Log, Log)+        :: Bool         -- ^ Whether @stdout@ and @stderr@ should be forwarded to the parent process.+        -> String       -- ^ Command to run.+        -> Log          -- ^ What to pass to the command's @stdin@.+        -> IO (ExitCode, Log, Log)  systemTeeLogIO tee cmd logIn- = do	trace $ "systemTeeIO " ++ show tee ++ ": " ++ cmd+ = do   trace $ "systemTeeIO " ++ show tee ++ ": " ++ cmd -	-- Create some new pipes for the process to write its stdout and stderr to.-	trace $ "systemTeeIO: Creating process"-	(Just hInWrite, Just hOutRead, Just hErrRead, phProc)-	 	<- createProcess -		$  CreateProcess-			{ cmdspec	= ShellCommand cmd-			, cwd		= Nothing-			, env		= Nothing-			, std_in	= CreatePipe-			, std_out	= CreatePipe-			, std_err	= CreatePipe-			, close_fds	= False +        -- Create some new pipes for the process to write its stdout and stderr to.+        trace $ "systemTeeIO: Creating process"+        (Just hInWrite, Just hOutRead, Just hErrRead, phProc)+                <- createProcess +                $  CreateProcess+                        { cmdspec       = ShellCommand cmd+                        , cwd           = Nothing+                        , env           = Nothing+                        , std_in        = CreatePipe+                        , std_out       = CreatePipe+                        , std_err       = CreatePipe+                        , close_fds     = False                          , create_group  = False                         , delegate_ctlc = False } -	-- Push input into in handle. Close the handle afterwards to ensure the-	-- process gets sent the EOF character.-	hPutStr hInWrite $ Log.toString logIn-	hClose  hInWrite-			-	-- To implement the tee-like behavior we'll fork some threads that read lines from the-	-- processes stdout and stderr and write them to these channels. -	-- 	When they hit EOF they signal this via the semaphores.-	chanOut		<- newTChanIO-	chanErr		<- newTChanIO-	semOut		<- newQSem 0-	semErr		<- newQSem 0+        -- Push input into in handle. Close the handle afterwards to ensure the+        -- process gets sent the EOF character.+        hPutStr hInWrite $ Log.toString logIn+        hClose  hInWrite+                        +        -- To implement the tee-like behavior we'll fork some threads that read lines from the+        -- processes stdout and stderr and write them to these channels. +        --      When they hit EOF they signal this via the semaphores.+        chanOut         <- newTChanIO+        chanErr         <- newTChanIO+        semOut          <- newQSem 0+        semErr          <- newQSem 0 -	-- Make duplicates of the above, which will store everything-	-- written to them. This gives us the copy to return from the fn.-	chanOutAcc	<- atomically $ dupTChan chanOut-	chanErrAcc	<- atomically $ dupTChan chanErr+        -- Make duplicates of the above, which will store everything+        -- written to them. This gives us the copy to return from the fn.+        chanOutAcc      <- atomically $ dupTChan chanOut+        chanErrAcc      <- atomically $ dupTChan chanErr -	-- Fork threads to read from the process handles and write to our channels.-	_tidOut		<- forkIO $ streamIn hOutRead chanOut-	_tidErr		<- forkIO $ streamIn hErrRead chanErr+        -- Fork threads to read from the process handles and write to our channels.+        _tidOut         <- forkIO $ streamIn hOutRead chanOut+        _tidErr         <- forkIO $ streamIn hErrRead chanErr -	-- If tee-like behavior is turned on, we forward what the process writes to-	--	its stdout and stderr to the parent.-	_tidStream	<- forkIO $ streamOuts-				[ (chanOut, if tee then Just stdout else Nothing, semOut)-				, (chanErr, if tee then Just stderr else Nothing, semErr) ]+        -- If tee-like behavior is turned on, we forward what the process writes to+        --      its stdout and stderr to the parent.+        _tidStream      <- forkIO $ streamOuts+                                [ (chanOut, if tee then Just stdout else Nothing, semOut)+                                , (chanErr, if tee then Just stderr else Nothing, semErr) ] -	-- Wait for the main process to complete.-	code		<- waitForProcess phProc-	trace $ "systemTeeIO: Process done, code = " ++ show code+        -- Wait for the main process to complete.+        code            <- waitForProcess phProc+        trace $ "systemTeeIO: Process done, code = " ++ show code -	trace $ "systemTeeIO: Waiting for sems"-	-- Wait for the tee processes to finish.-	--	We need to do this to avoid corrupted output on the console due to our forwarding-	--	threads writing at the same time as successing Build commands.-	mapM_ waitQSem [semOut, semErr]+        trace $ "systemTeeIO: Waiting for sems"+        -- Wait for the tee processes to finish.+        --      We need to do this to avoid corrupted output on the console due to our forwarding+        --      threads writing at the same time as successing Build commands.+        mapM_ waitQSem [semOut, semErr] -	trace $ "systemTeeIO: Getting output"-	-- Get what was written to its stdout and stderr.-	--	getChanContents is a lazy read, so don't pull from the channel after-	--	seeing a Nothing else we'll block forever.-	logOut		<- slurpChan chanOutAcc Log.empty-	logErr		<- slurpChan chanErrAcc Log.empty+        trace $ "systemTeeIO: Getting output"+        -- Get what was written to its stdout and stderr.+        --      getChanContents is a lazy read, so don't pull from the channel after+        --      seeing a Nothing else we'll block forever.+        logOut          <- slurpChan chanOutAcc Log.empty+        logErr          <- slurpChan chanErrAcc Log.empty -	trace $ "systemTeeIO stdout: " ++ Log.toString logOut-	trace $ "systemTeeIO stderr: " ++ Log.toString logErr+        trace $ "systemTeeIO stdout: " ++ Log.toString logOut+        trace $ "systemTeeIO stderr: " ++ Log.toString logErr -	trace $ "systemTeeIO: All done"-	hClose hOutRead-	hClose hErrRead-	code `seq` logOut `seq` logErr `seq` -		return	(code, logOut, logErr)+        trace $ "systemTeeIO: All done"+        hClose hOutRead+        hClose hErrRead+        code `seq` logOut `seq` logErr `seq` +                return  (code, logOut, logErr)  slurpChan :: TChan (Maybe ByteString) -> Log -> IO Log slurpChan !chan !ll- = do	mStr	<- atomically $ readTChan chan-	case mStr of-	 Nothing	-> return ll-	 Just str	-> slurpChan chan (ll Log.|> str)+ = do   mStr    <- atomically $ readTChan chan+        case mStr of+         Nothing        -> return ll+         Just str       -> slurpChan chan (ll Log.|> str) 
BuildBox/Command/System/Internals.hs view
@@ -1,7 +1,7 @@ {-# LANGUAGE PatternGuards, BangPatterns, NamedFieldPuns #-} module BuildBox.Command.System.Internals-	( streamIn-	, streamOuts)+        ( streamIn+        , streamOuts) where import System.IO import Control.Concurrent@@ -12,9 +12,9 @@ import Data.IORef import Data.Char import Data.Word-import Data.ByteString.Char8		(ByteString)+import Data.ByteString.Char8            (ByteString) import qualified Data.ByteString.Internal       as BS-import qualified Data.ByteString.Char8	        as BS	+import qualified Data.ByteString.Char8          as BS     import GHC.IO.Handle.Internals import GHC.IO.Handle.Types@@ -86,53 +86,53 @@ streamOuts !chans   = streamOuts' False [] chans -	-- There doesn't seem to be a way to perform a unix-style "select" on channels.-	-- We want to wait until any of the channels becomes available for reading.-	-- We're doing this just by polling them each in turn, and waiting a bit-	--	if none of them had any data.-		- where	-- we're done.-	streamOuts' _ []   []	-		= return ()+        -- There doesn't seem to be a way to perform a unix-style "select" on channels.+        -- We want to wait until any of the channels becomes available for reading.+        -- We're doing this just by polling them each in turn, and waiting a bit+        --      if none of them had any data.+                + where  -- we're done.+        streamOuts' _ []   []   +                = return () -	-- play it again, sam.-	streamOuts' True prev []	-	 = 	streamOuts' False [] prev+        -- play it again, sam.+        streamOuts' True prev []        +         =      streamOuts' False [] prev -	streamOuts' False prev []-	 = do   threadDelay 1000+        streamOuts' False prev []+         = do   threadDelay 1000                 yield-		streamOuts' False [] prev+                streamOuts' False [] prev  -	-- try to read from the current chan.-	streamOuts' !active !prev (!x@(!chan, !mHandle, !qsem) : rest)-	 = do	-		-- try and read a string from the channel, but don't block-		-- if there aren't any.-		mStr	<- atomically-			$  do	isEmpty	<- isEmptyTChan chan-				if isEmpty -				 then    return (False, Nothing)+        -- try to read from the current chan.+        streamOuts' !active !prev (!x@(!chan, !mHandle, !qsem) : rest)+         = do   +                -- try and read a string from the channel, but don't block+                -- if there aren't any.+                mStr    <- atomically+                        $  do   isEmpty <- isEmptyTChan chan+                                if isEmpty +                                 then    return (False, Nothing) -				 else do mStr	<- readTChan chan-					 return (True, mStr)-				-		case mStr of-		 (False, _)-		  -> streamOuts' active (prev ++ [x]) rest+                                 else do mStr   <- readTChan chan+                                         return (True, mStr)+                                +                case mStr of+                 (False, _)+                  -> streamOuts' active (prev ++ [x]) rest -		 (True, Nothing)-		  -> do	signalQSem qsem-			streamOuts' active prev rest+                 (True, Nothing)+                  -> do signalQSem qsem+                        streamOuts' active prev rest -		 (True, Just str)-		  | Just h	<- mHandle-		  -> do	BS.hPutStr h str-			hPutChar   h '\n'-			streamOuts' True (prev ++ [x]) rest+                 (True, Just str)+                  | Just h      <- mHandle+                  -> do BS.hPutStr h str+                        hPutChar   h '\n'+                        streamOuts' True (prev ++ [x]) rest -		  | otherwise-		  -> 	streamOuts' True (prev ++ [x]) rest					+                  | otherwise+                  ->    streamOuts' True (prev ++ [x]) rest                                        -- Code hacked out of Data.ByteString library.
BuildBox/Control/Cron.hs view
@@ -3,8 +3,8 @@  -- | A simple ''cron'' loop. Used for running commands according to a given schedule. module BuildBox.Control.Cron-	( module BuildBox.Data.Schedule-	, cronLoop )+        ( module BuildBox.Data.Schedule+        , cronLoop ) where import BuildBox.Build import BuildBox.Data.Schedule@@ -18,26 +18,26 @@ -- cronLoop :: Schedule (Build ())-> Build () cronLoop schedule- = do	startTime	<- io $ getCurrentTime+ = do   startTime       <- io $ getCurrentTime -	case earliestEventToStartAt startTime $ eventsOfSchedule schedule of-	 Nothing -	  -> do	sleep 1-		cronLoop schedule-		-	 Just event -	  -> do	let Just build	= lookupCommandOfSchedule (eventName event) schedule-		build-		endTime		<- io $ getCurrentTime+        case earliestEventToStartAt startTime $ eventsOfSchedule schedule of+         Nothing +          -> do sleep 1+                cronLoop schedule+                +         Just event +          -> do let Just build  = lookupCommandOfSchedule (eventName event) schedule+                build+                endTime         <- io $ getCurrentTime -		let event'	= event-				{ eventLastStarted	= Just startTime-				, eventLastEnded	= Just endTime }+                let event'      = event+                                { eventLastStarted      = Just startTime+                                , eventLastEnded        = Just endTime } -		let schedule'	= adjustEventOfSchedule event' schedule-	-		cronLoop schedule'-				-		-		-	+                let schedule'   = adjustEventOfSchedule event' schedule+        +                cronLoop schedule'+                                +                +                +        
BuildBox/Control/Gang.hs view
@@ -2,79 +2,79 @@ -- | A gang consisting of a fixed number of threads that can run actions in parallel. --   Good for constructing parallel test frameworks. module BuildBox.Control.Gang-	( Gang-	, GangState(..)+        ( Gang+        , GangState(..) -	, forkGangActions-	, joinGang-	, pauseGang-	, resumeGang-	, flushGang-	, killGang-	-	, getGangState-	, waitForGangState)+        , forkGangActions+        , joinGang+        , pauseGang+        , resumeGang+        , flushGang+        , killGang+        +        , getGangState+        , waitForGangState) where import Control.Concurrent import Data.IORef-import qualified Data.Set	as Set-import Data.Set			(Set)+import qualified Data.Set       as Set+import Data.Set                 (Set)  -- Gang ----------------------------------------------------------------------- -- | Abstract gang of threads. data Gang-	= Gang -	{ gangThreads		:: Int-	, gangThreadsAvailable	:: QSemN-	, gangState		:: IORef GangState-	, gangActionsRunning	:: IORef Int -	, gangThreadsRunning	:: IORef (Set ThreadId) }+        = Gang +        { gangThreads           :: Int+        , gangThreadsAvailable  :: QSemN+        , gangState             :: IORef GangState+        , gangActionsRunning    :: IORef Int +        , gangThreadsRunning    :: IORef (Set ThreadId) }   data GangState-	= -- | Gang is running and starting new actions.-	  GangRunning+        = -- | Gang is running and starting new actions.+          GangRunning -	-- | Gang may be running already started actions, -	--   but no new ones are being started.-	| GangPaused+        -- | Gang may be running already started actions, +        --   but no new ones are being started.+        | GangPaused -	-- | Gang is waiting for currently running actions to finish, -	--   but not starting new ones.-	| GangFlushing+        -- | Gang is waiting for currently running actions to finish, +        --   but not starting new ones.+        | GangFlushing -	-- | Gang is finished, all the actions have completed.-	| GangFinished-	-	-- | Gang was killed, all the threads are dead (or dying).-	| GangKilled-	deriving (Show, Eq)+        -- | Gang is finished, all the actions have completed.+        | GangFinished+        +        -- | Gang was killed, all the threads are dead (or dying).+        | GangKilled+        deriving (Show, Eq)   -- | Get the state of a gang. getGangState :: Gang -> IO GangState getGangState gang-	= readIORef (gangState gang)+        = readIORef (gangState gang)   -- | Block until all actions have finished executing, --   or the gang is killed. joinGang :: Gang -> IO () joinGang gang- = do	state	<- readIORef (gangState gang)-	if state == GangFinished || state == GangKilled-	 then return ()-	 else do-		threadDelay 1000-		joinGang gang+ = do   state   <- readIORef (gangState gang)+        if state == GangFinished || state == GangKilled+         then return ()+         else do+                threadDelay 1000+                joinGang gang   -- | Block until already started actions have completed, but don't start any more. --   Gang state changes to `GangFlushing`. flushGang :: Gang -> IO () flushGang gang- = do	writeIORef (gangState gang) GangFlushing-	waitForGangState gang GangFinished+ = do   writeIORef (gangState gang) GangFlushing+        waitForGangState gang GangFinished   -- | Pause a gang. Actions that have already been started continue to run, @@ -82,34 +82,34 @@ --   Gang state changes to `GangPaused`. pauseGang :: Gang -> IO () pauseGang gang- 	= writeIORef (gangState gang) GangPaused+        = writeIORef (gangState gang) GangPaused   -- | Resume a paused gang, which allows it to continue starting new actions. --   Gang state changes to `GangRunning`. resumeGang :: Gang -> IO () resumeGang gang-	= writeIORef (gangState gang) GangRunning+        = writeIORef (gangState gang) GangRunning   -- | Kill all the threads in a gang. --   Gang stage changes to `GangKilled`. killGang :: Gang -> IO () killGang gang- = do	writeIORef (gangState gang) GangKilled-	tids	<- readIORef (gangThreadsRunning gang) -	mapM_ killThread $ Set.toList tids+ = do   writeIORef (gangState gang) GangKilled+        tids    <- readIORef (gangThreadsRunning gang) +        mapM_ killThread $ Set.toList tids   -- | Block until the gang is in the given state. waitForGangState :: Gang -> GangState -> IO () waitForGangState gang waitState- = do	state	<- readIORef (gangState gang)-	if state == waitState-	 then return ()-	 else do-		threadDelay 1000-		waitForGangState gang waitState+ = do   state   <- readIORef (gangState gang)+        if state == waitState+         then return ()+         else do+                threadDelay 1000+                waitForGangState gang waitState   -- | Fork a new gang to run the given actions.@@ -117,95 +117,95 @@ --   Gang state starts as `GangRunning` then transitions to `GangFinished`. --   To block until all the actions are finished use `joinGang`. forkGangActions-	:: Int 			-- ^ Number of worker threads in the gang \/ maximum number-				--   of actions to execute concurrenty.-	-> [IO ()] 		-- ^ Actions to run. They are started in-order, but may finish-				--   out-of-order depending on the run time of the individual action.-	-> IO Gang+        :: Int                  -- ^ Number of worker threads in the gang \/ maximum number+                                --   of actions to execute concurrenty.+        -> [IO ()]              -- ^ Actions to run. They are started in-order, but may finish+                                --   out-of-order depending on the run time of the individual action.+        -> IO Gang  forkGangActions threads actions- = do	semThreads		<- newQSemN threads-	refState		<- newIORef GangRunning-	refActionsRunning	<- newIORef 0-	refThreadsRunning	<- newIORef (Set.empty)-	let gang	-		= Gang-		{ gangThreads		= threads-		, gangThreadsAvailable	= semThreads -		, gangState 		= refState-		, gangActionsRunning	= refActionsRunning -		, gangThreadsRunning	= refThreadsRunning }+ = do   semThreads              <- newQSemN threads+        refState                <- newIORef GangRunning+        refActionsRunning       <- newIORef 0+        refThreadsRunning       <- newIORef (Set.empty)+        let gang        +                = Gang+                { gangThreads           = threads+                , gangThreadsAvailable  = semThreads +                , gangState             = refState+                , gangActionsRunning    = refActionsRunning +                , gangThreadsRunning    = refThreadsRunning } -	_ <- forkIO $ gangLoop gang actions-	return gang-	+        _ <- forkIO $ gangLoop gang actions+        return gang+          -- | Run actions on a gang. gangLoop :: Gang -> [IO ()] -> IO () gangLoop gang []- = do	-- Wait for all the threads to finish.-	waitQSemN -		(gangThreadsAvailable gang) -		(gangThreads gang)-		-	-- Signal that the gang is finished running actions.-	writeIORef (gangState gang) GangFinished+ = do   -- Wait for all the threads to finish.+        waitQSemN +                (gangThreadsAvailable gang) +                (gangThreads gang)+                +        -- Signal that the gang is finished running actions.+        writeIORef (gangState gang) GangFinished   gangLoop gang actions@(action:actionsRest)- = do	state	<- readIORef (gangState gang)-	case state of-	 GangRunning -	  -> do	-- Wait for a worker thread to become available.-		waitQSemN (gangThreadsAvailable gang) 1-		gangLoop_withWorker gang action actionsRest+ = do   state   <- readIORef (gangState gang)+        case state of+         GangRunning +          -> do -- Wait for a worker thread to become available.+                waitQSemN (gangThreadsAvailable gang) 1+                gangLoop_withWorker gang action actionsRest -	 GangPaused-	  -> do	threadDelay 1000-	 	gangLoop gang actions-			-	 GangFlushing-	  -> do	actionsRunning	<- readIORef (gangActionsRunning gang)-		if actionsRunning == 0-		 then	writeIORef (gangState gang) GangFinished-		 else do	-			threadDelay 1000-			gangLoop gang []+         GangPaused+          -> do threadDelay 1000+                gangLoop gang actions+                        +         GangFlushing+          -> do actionsRunning  <- readIORef (gangActionsRunning gang)+                if actionsRunning == 0+                 then   writeIORef (gangState gang) GangFinished+                 else do        +                        threadDelay 1000+                        gangLoop gang [] -	 GangFinished	-> return ()-	 GangKilled	-> return ()+         GangFinished   -> return ()+         GangKilled     -> return ()  -- we have an available worker gangLoop_withWorker :: Gang -> IO () -> [IO ()] -> IO () gangLoop_withWorker gang action actionsRest- = do	-- See if we're supposed to be starting actions or not.-	state	<- readIORef (gangState gang)-	case state of-	 GangRunning-	  -> do	-- fork off the first action-		tid <- forkOS $ do-			-- run the action (and wait for it to complete)-			action+ = do   -- See if we're supposed to be starting actions or not.+        state   <- readIORef (gangState gang)+        case state of+         GangRunning+          -> do -- fork off the first action+                tid <- forkOS $ do+                        -- run the action (and wait for it to complete)+                        action -			-- signal that a new worker is available-			signalQSemN (gangThreadsAvailable gang) 1-			-			-- remove our ThreadId from the set of running ThreadIds.-			tid	<- myThreadId-			atomicModifyIORef (gangThreadsRunning gang)-				(\tids -> (Set.delete tid tids, ()))-	-		-- Add the ThreadId of the freshly forked thread to the set-		-- of running ThreadIds. We'll need this set if we want to kill-		-- the gang.-		atomicModifyIORef (gangThreadsRunning gang)-			(\tids -> (Set.insert tid tids, ()))-	-		-- handle the rest of the actions.-		gangLoop gang actionsRest+                        -- signal that a new worker is available+                        signalQSemN (gangThreadsAvailable gang) 1+                        +                        -- remove our ThreadId from the set of running ThreadIds.+                        tid     <- myThreadId+                        atomicModifyIORef (gangThreadsRunning gang)+                                (\tids -> (Set.delete tid tids, ()))+        +                -- Add the ThreadId of the freshly forked thread to the set+                -- of running ThreadIds. We'll need this set if we want to kill+                -- the gang.+                atomicModifyIORef (gangThreadsRunning gang)+                        (\tids -> (Set.insert tid tids, ()))+        +                -- handle the rest of the actions.+                gangLoop gang actionsRest -	 -- someone issued flush or pause command while we-	 -- were waiting for a worker, so don't start next action.-	 _ -> do-		signalQSemN (gangThreadsAvailable gang) 1-		gangLoop gang (action:actionsRest)+         -- someone issued flush or pause command while we+         -- were waiting for a worker, so don't start next action.+         _ -> do+                signalQSemN (gangThreadsAvailable gang) 1+                gangLoop gang (action:actionsRest)
BuildBox/Data/Comparison.hs view
@@ -1,46 +1,46 @@  module BuildBox.Data.Comparison-	( -- * Comparisons-	  Comparison	(..)-	, makeComparison)+        ( -- * Comparisons+          Comparison    (..)+        , makeComparison) where import BuildBox.Pretty import Text.Printf   -- | The comparison of two values.-data Comparison a	-	-- | Comparison of a recent value with a baseline.-	= Comparison-	{ comparisonBaseline	:: a-	, comparisonRecent	:: a-	, comparisonSwing	:: Double }-	-	-- | A new value that doesn't have a baseline.-	| ComparisonNew-	{ comparisonNew		:: a }-	-	deriving (Read, Show)+data Comparison a       +        -- | Comparison of a recent value with a baseline.+        = Comparison+        { comparisonBaseline    :: a+        , comparisonRecent      :: a+        , comparisonSwing       :: Double }+        +        -- | A new value that doesn't have a baseline.+        | ComparisonNew+        { comparisonNew         :: a }+        +        deriving (Read, Show)  instance Pretty a => Pretty (Comparison a) where-	ppr (Comparison _ recent ratio)-		| abs ratio < 0.01	-		= text $ printf "%s (----)"-				(render $ ppr recent)+        ppr (Comparison _ recent ratio)+                | abs ratio < 0.01      +                = text $ printf "%s (----)"+                                (render $ ppr recent) -		| otherwise		-		= text $ printf "%s (%+4.0f)"-				(render $ ppr recent)-				(ratio * 100)+                | otherwise             +                = text $ printf "%s (%+4.0f)"+                                (render $ ppr recent)+                                (ratio * 100) -	ppr (ComparisonNew new)-		= (padL 10 $ ppr new)-		+        ppr (ComparisonNew new)+                = (padL 10 $ ppr new)+                  -- | Make a comparison from two values. makeComparison :: Real a => a -> a -> Comparison a makeComparison base recent-	= Comparison base recent swing-	where	dBase	= fromRational $ toRational base-		dRecent	= fromRational $ toRational recent-		swing = ((dRecent - dBase) / dBase)+        = Comparison base recent swing+        where   dBase   = fromRational $ toRational base+                dRecent = fromRational $ toRational recent+                swing = ((dRecent - dBase) / dBase)
BuildBox/Data/Detail.hs view
@@ -1,63 +1,63 @@  -- | The detail is the name of an `Aspect` seprate from its data. module BuildBox.Data.Detail-	( Detail (..)-	, Timed	 (..)-	, Used	 (..)-	, Sized	 (..))+        ( Detail (..)+        , Timed  (..)+        , Used   (..)+        , Sized  (..)) where import BuildBox.Pretty  data Detail-	= DetailTimed Timed-	| DetailUsed   Used-	| DetailSized  Sized-	deriving (Eq, Ord, Show, Read)-	+        = DetailTimed Timed+        | DetailUsed   Used+        | DetailSized  Sized+        deriving (Eq, Ord, Show, Read)+          -- | Something that takes time to evaluate. data Timed-	= TotalWall-	| TotalCpu-	| TotalSys-	| KernelWall-	| KernelCpu -	| KernelSys-	deriving (Eq, Ord, Show, Read, Enum)-	+        = TotalWall+        | TotalCpu+        | TotalSys+        | KernelWall+        | KernelCpu +        | KernelSys+        deriving (Eq, Ord, Show, Read, Enum)+         instance Pretty Timed where  ppr timed   = case timed of-	TotalWall	-> text "runtime        (wall clock)"-	TotalCpu	-> text "runtime        (cpu usage)"-	TotalSys	-> text "runtime        (sys usage)"+        TotalWall       -> text "runtime        (wall clock)"+        TotalCpu        -> text "runtime        (cpu usage)"+        TotalSys        -> text "runtime        (sys usage)" -	KernelWall	-> text "kernel runtime (wall clock)"-	KernelCpu	-> text "kernel runtime (cpu usage)"-	KernelSys	-> text "kernel runtime (sys usage)"-		+        KernelWall      -> text "kernel runtime (wall clock)"+        KernelCpu       -> text "kernel runtime (cpu usage)"+        KernelSys       -> text "kernel runtime (sys usage)"+                  -- | Some resource used during execution. data Used-	= HeapMax-	| HeapAlloc-	deriving (Eq, Ord, Show, Read, Enum)-	+        = HeapMax+        | HeapAlloc+        deriving (Eq, Ord, Show, Read, Enum)+         instance Pretty Used where  ppr used   = case used of-	HeapMax		-> text "maximum heap usage"-	HeapAlloc	-> text "heap allocation"-	-	+        HeapMax         -> text "maximum heap usage"+        HeapAlloc       -> text "heap allocation"+        +         -- | Some static size of the benchmark that isn't affected during the run. data Sized-	= ExeSize-	deriving (Eq, Ord, Show, Read, Enum)-	+        = ExeSize+        deriving (Eq, Ord, Show, Read, Enum)+         instance Pretty Sized where  ppr sized   = case sized of-	ExeSize		-> text "executable size"-	-	+        ExeSize         -> text "executable size"+        +        
BuildBox/Data/Dividable.hs view
@@ -1,13 +1,13 @@  module BuildBox.Data.Dividable-	(Dividable(..))+        (Dividable(..)) where  class Dividable a where-	divide :: a -> a -> a-	+        divide :: a -> a -> a+         instance Dividable Integer where-	divide	= div+        divide  = div  instance Dividable Float where-	divide	= (/)+        divide  = (/)
BuildBox/Data/Log.hs view
@@ -2,28 +2,28 @@  -- | When the output of a command is long, keeping it as a `String` is a bad idea. module BuildBox.Data.Log-	( Log-	, Line-	, empty-	, null-	, toString-	, fromString-	, (<|)-	, (|>)-	, (><)-	, firstLines-	, lastLines)+        ( Log+        , Line+        , empty+        , null+        , toString+        , fromString+        , (<|)+        , (|>)+        , (><)+        , firstLines+        , lastLines) where-import Data.ByteString.Char8		(ByteString)-import Data.Sequence			(Seq)-import qualified Data.ByteString.Char8 	as BS-import qualified Data.Sequence		as Seq-import qualified Data.Foldable		as F-import Prelude				hiding (null)+import Data.ByteString.Char8            (ByteString)+import Data.Sequence                    (Seq)+import qualified Data.ByteString.Char8  as BS+import qualified Data.Sequence          as Seq+import qualified Data.Foldable          as F+import Prelude                          hiding (null)  -- | A sequence of lines, without newline charaters on the end.-type Log 	= Seq Line-type Line	= ByteString+type Log        = Seq Line+type Line       = ByteString   -- | O(1) No logs here.@@ -36,39 +36,39 @@  -- | O(n) Convert a `Log` to a `String`. toString :: Log -> String-toString ll	-	= BS.unpack -	$ BS.intercalate (BS.pack "\n") -	$ F.toList ll+toString ll     +        = BS.unpack +        $ BS.intercalate (BS.pack "\n") +        $ F.toList ll  -- | O(n) Convert a `String` to a `Log`. fromString :: String -> Log-fromString str	-	= Seq.fromList -	$ BS.splitWith (== '\n')-	$ BS.pack str+fromString str  +        = Seq.fromList +        $ BS.splitWith (== '\n')+        $ BS.pack str   -- | O(1) Add a `Line` to the start of a `Log`. (<|):: Line -> Log -> Log-(<|)	= (Seq.<|)+(<|)    = (Seq.<|)  -- | O(1) Add a `Line` to the end of a `Log`.-(|>)	:: Log -> Line -> Log-(|>)	= (Seq.|>)+(|>)    :: Log -> Line -> Log+(|>)    = (Seq.|>)  -- | O(log(min(n1,n2))) Concatenate two `Log`s.-(><)	:: Log -> Log -> Log-(><)	= (Seq.><)+(><)    :: Log -> Log -> Log+(><)    = (Seq.><)   -- | O(n) Take the first m lines from a log firstLines :: Int -> Log -> Log firstLines m ll-	= Seq.take m ll+        = Seq.take m ll  -- | O(n) Take the last m lines from a log lastLines :: Int -> Log -> Log lastLines m ll-	= Seq.drop (Seq.length ll - m) ll-	+        = Seq.drop (Seq.length ll - m) ll+        
BuildBox/Data/Range.hs view
@@ -1,25 +1,25 @@  module BuildBox.Data.Range-	( Range	(..)-	, makeRange-	, flattenRange)+        ( Range (..)+        , makeRange+        , flattenRange) where import BuildBox.Pretty import BuildBox.Data.Dividable  -- | A range extracted from many-valued data.-data Range a	-	= Range-	{ rangeMin	:: a-	, rangeAvg	:: a-	, rangeMax	:: a }-	deriving (Read, Show)+data Range a    +        = Range+        { rangeMin      :: a+        , rangeAvg      :: a+        , rangeMax      :: a }+        deriving (Read, Show)  instance Pretty a => Pretty (Range a) where-	ppr (Range mi av mx)-		=   (ppr mi) <+> text "/" -		<+> (ppr av) <+> text "/"-		<+> (ppr mx)+        ppr (Range mi av mx)+                =   (ppr mi) <+> text "/" +                <+> (ppr av) <+> text "/"+                <+> (ppr mx)  instance Functor Range where  fmap f (Range mi av mx)@@ -29,9 +29,9 @@ -- | Make statistics from a list of values. makeRange :: (Real a, Dividable a) => [a] -> Range a makeRange xs-	= Range (minimum xs)-		(sum xs `divide` (fromIntegral $ length xs)) -		(maximum xs)+        = Range (minimum xs)+                (sum xs `divide` (fromIntegral $ length xs)) +                (maximum xs)   -- | Flatten a `Range` into a list of its min, avg and max values.
BuildBox/Data/Schedule.hs view
@@ -3,112 +3,112 @@  -- | A schedule of commands that should be run at a certain time. module BuildBox.Data.Schedule-	( -	-- * Time Periods-	  second, minute, hour, day+        ( +        -- * Time Periods+          second, minute, hour, day -	-- * When-	, When		(..)-	, WhenModifier	(..)+        -- * When+        , When          (..)+        , WhenModifier  (..) -	-- * Events-	, EventName-	, Event		(..)-	, earliestEventToStartAt-	, eventCouldStartAt+        -- * Events+        , EventName+        , Event         (..)+        , earliestEventToStartAt+        , eventCouldStartAt -	-- * Schedules-	, Schedule	(..)-	, makeSchedule-	, lookupEventOfSchedule-	, lookupCommandOfSchedule-	, adjustEventOfSchedule-	, eventsOfSchedule)+        -- * Schedules+        , Schedule      (..)+        , makeSchedule+        , lookupEventOfSchedule+        , lookupCommandOfSchedule+        , adjustEventOfSchedule+        , eventsOfSchedule) where import Data.Time import Data.List import Data.Function import Data.Maybe import Control.Monad-import Data.Map			(Map)-import qualified Data.Map	as Map+import Data.Map                 (Map)+import qualified Data.Map       as Map  instance Read NominalDiffTime where  readsPrec n str-  = let	[(secs :: Double, rest)] = readsPrec n str-    in	case rest of-		's' : rest'	-> [(fromRational $ toRational secs, rest')]-		_		-> []+  = let [(secs :: Double, rest)] = readsPrec n str+    in  case rest of+                's' : rest'     -> [(fromRational $ toRational secs, rest')]+                _               -> []  second, minute, hour, day :: NominalDiffTime-second	= 1+second  = 1 minute  = 60-hour	= 60 * minute-day	= 24 * hour+hour    = 60 * minute+day     = 24 * hour   -- When ------------------------------------------------------------------------------------------- -- | When to invoke some event. data When-	-- | Just keep doing it.-	= Always+        -- | Just keep doing it.+        = Always -	-- | Don't do it, ever.-	| Never+        -- | Don't do it, ever.+        | Never -	-- | Do it some time after we last started it.-	| Every NominalDiffTime-	-	-- | Do it some time after it last finished.-	| After NominalDiffTime-	-	-- | Do it each day at this time. The ''days'' are UTC days, not local ones.-	| Daily TimeOfDay-	deriving (Read, Show, Eq)+        -- | Do it some time after we last started it.+        | Every NominalDiffTime+        +        -- | Do it some time after it last finished.+        | After NominalDiffTime+        +        -- | Do it each day at this time. The ''days'' are UTC days, not local ones.+        | Daily TimeOfDay+        deriving (Read, Show, Eq)   -- | Modifier to when. data WhenModifier-	-- | If the event hasn't been invoked before then do it immediately-	--   when we start the cron process.-	= Immediate+        -- | If the event hasn't been invoked before then do it immediately+        --   when we start the cron process.+        = Immediate -	-- | Wait until after this time before doing it first.-	| WaitUntil UTCTime-	deriving (Read, Show, Eq)+        -- | Wait until after this time before doing it first.+        | WaitUntil UTCTime+        deriving (Read, Show, Eq)   -- Event -------------------------------------------------------------------------------------------type EventName	= String+type EventName  = String  -- | Records when an event should start, and when it last ran. data Event-	= Event-	{ -- | A unique name for this event.-	  --   Used when writing the schedule to a file.-	  eventName		:: EventName+        = Event+        { -- | A unique name for this event.+          --   Used when writing the schedule to a file.+          eventName             :: EventName -	  -- | When to run the command.-	, eventWhen		:: When+          -- | When to run the command.+        , eventWhen             :: When -	  -- | Modifier to the previous.-	, eventWhenModifier	:: Maybe WhenModifier+          -- | Modifier to the previous.+        , eventWhenModifier     :: Maybe WhenModifier -	  -- | When the event was last started, if any.-	, eventLastStarted	:: Maybe UTCTime-		-	  -- | When the event last finished, if any.-	, eventLastEnded	:: Maybe UTCTime }-	deriving (Read, Show, Eq)-	+          -- | When the event was last started, if any.+        , eventLastStarted      :: Maybe UTCTime+                +          -- | When the event last finished, if any.+        , eventLastEnded        :: Maybe UTCTime }+        deriving (Read, Show, Eq)+          -- | Given the current time and a list of events, determine which one should be started now. --   If several events are avaliable then take the one with the earliest start time. earliestEventToStartAt :: UTCTime -> [Event] -> Maybe Event earliestEventToStartAt curTime events- = let	eventsStartable	= filter (eventCouldStartAt curTime)   events-	eventsSorted	= sortBy (compare `on` eventLastStarted) eventsStartable-   in	listToMaybe eventsSorted+ = let  eventsStartable = filter (eventCouldStartAt curTime)   events+        eventsSorted    = sortBy (compare `on` eventLastStarted) eventsStartable+   in   listToMaybe eventsSorted   -- | Given the current time, decide whether an event could be started.@@ -116,95 +116,95 @@ --   The `SkipFirst` modifier is ignored, as this is handled separately. eventCouldStartAt :: UTCTime -> Event -> Bool eventCouldStartAt curTime event-	-- If the event has never started or ended, and is marked as immediate,-	-- then start it right away.-	| Nothing		<- eventLastStarted  event-	, Nothing		<- eventLastEnded    event-	, Just Immediate	<- eventWhenModifier event-	= True+        -- If the event has never started or ended, and is marked as immediate,+        -- then start it right away.+        | Nothing               <- eventLastStarted  event+        , Nothing               <- eventLastEnded    event+        , Just Immediate        <- eventWhenModifier event+        = True -	-- If the current end time is before the start time, then the most-	-- recent iteration is still running, so don't start it again.-	| Just lastStarted	<- eventLastStarted event- 	, Just lastEnded	<- eventLastEnded   event- 	, lastEnded < lastStarted-	= False+        -- If the current end time is before the start time, then the most+        -- recent iteration is still running, so don't start it again.+        | Just lastStarted      <- eventLastStarted event+        , Just lastEnded        <- eventLastEnded   event+        , lastEnded < lastStarted+        = False -	-- Keep waiting if there's a seconday wait modifier.-	| Just (WaitUntil waitTime)	<- eventWhenModifier event-	, curTime < waitTime-	= False+        -- Keep waiting if there's a seconday wait modifier.+        | Just (WaitUntil waitTime)     <- eventWhenModifier event+        , curTime < waitTime+        = False -	-- Otherwise we have to look at the real schedule.-	| otherwise-	= case eventWhen event of-		Always		-> True-		Never		-> False+        -- Otherwise we have to look at the real schedule.+        | otherwise+        = case eventWhen event of+                Always          -> True+                Never           -> False -		Every diffTime	-	 	 -> maybe True-			(\lastTime -> (curTime `diffUTCTime` lastTime ) > diffTime)-			(eventLastStarted event)+                Every diffTime  +                 -> maybe True+                        (\lastTime -> (curTime `diffUTCTime` lastTime ) > diffTime)+                        (eventLastStarted event) -		After diffTime	-	 	 -> maybe True-			(\lastTime -> (curTime `diffUTCTime` lastTime ) > diffTime)-			(eventLastEnded event)-	-		Daily timeOfDay-		 -- If it's been less than a day since we last started it, then don't do it yet.-		 | Just lastStarted	<- eventLastStarted event-		 , (curTime `diffUTCTime` lastStarted) < day-		 -> False-		-		 | otherwise-		 -> let	-- If we were going to run it today, this is when it would be.-			startTimeToday-				= curTime-				{ utctDayTime	= timeOfDayToTime timeOfDay }-				-			-- If it's after that time then quit fooling around..-		    in	curTime > startTimeToday+                After diffTime  +                 -> maybe True+                        (\lastTime -> (curTime `diffUTCTime` lastTime ) > diffTime)+                        (eventLastEnded event)+        +                Daily timeOfDay+                 -- If it's been less than a day since we last started it, then don't do it yet.+                 | Just lastStarted     <- eventLastStarted event+                 , (curTime `diffUTCTime` lastStarted) < day+                 -> False+                +                 | otherwise+                 -> let -- If we were going to run it today, this is when it would be.+                        startTimeToday+                                = curTime+                                { utctDayTime   = timeOfDayToTime timeOfDay }+                                +                        -- If it's after that time then quit fooling around..+                    in  curTime > startTimeToday   -- Schedule ------------------------------------------------------------------------------------------ | Map of event names to their details and build commands.	+-- | Map of event names to their details and build commands.     data Schedule cmd-	= Schedule (Map EventName (Event, cmd))+        = Schedule (Map EventName (Event, cmd))   -- | Get the list of events in a schedule, ignoring the build commands. eventsOfSchedule :: Schedule cmd -> [Event] eventsOfSchedule (Schedule sched)-	= map fst $ Map.elems sched+        = map fst $ Map.elems sched   -- | A nice way to produce a schedule. makeSchedule :: [(EventName, When, Maybe WhenModifier, cmd)] -> Schedule cmd makeSchedule tuples- = let	makeSched (name, whn, mMod, cmd)-	  =	(name, (Event name whn mMod Nothing Nothing, cmd))-   in	Schedule $ Map.fromList $ map makeSched tuples+ = let  makeSched (name, whn, mMod, cmd)+          =     (name, (Event name whn mMod Nothing Nothing, cmd))+   in   Schedule $ Map.fromList $ map makeSched tuples   -- | Given an event name, lookup the associated event from a schedule. lookupEventOfSchedule :: EventName -> Schedule cmd -> Maybe Event lookupEventOfSchedule name (Schedule sched)-	= liftM fst $ Map.lookup name sched-	-	+        = liftM fst $ Map.lookup name sched+        +         -- | Given an event name, lookup the associated build command from a schedule. lookupCommandOfSchedule :: EventName -> Schedule cmd -> Maybe cmd lookupCommandOfSchedule name (Schedule sched)-	= liftM snd $ Map.lookup name sched+        = liftM snd $ Map.lookup name sched   -- | Given a new version of an event, update any matching event in the schedule. --   If the event not already there then return the original schedule. adjustEventOfSchedule :: Event -> Schedule cmd -> Schedule cmd adjustEventOfSchedule event (Schedule sched)-	= Schedule -	$ Map.adjust -		(\(_, build) -> (event, build))-		(eventName event) -		sched+        = Schedule +        $ Map.adjust +                (\(_, build) -> (event, build))+                (eventName event) +                sched
BuildBox/IO/Directory.hs view
@@ -1,73 +1,73 @@  -- | Directory utils that don't need to be in the Build monad. module BuildBox.IO.Directory-	( lsFilesIn-	, lsDirsIn-	, traceFilesFrom)+        ( lsFilesIn+        , lsDirsIn+        , traceFilesFrom) where import System.Directory import Control.Monad import Control.Monad.Trans import Data.List-import Data.Sequence		(Seq)-import qualified Data.Sequence	as Seq+import Data.Sequence            (Seq)+import qualified Data.Sequence  as Seq   -- | Get the names of all files in a directory. --   This filters out the fake files like '.' and '..' lsFilesIn :: MonadIO m => String -> m [String] lsFilesIn path- = do 	contents <- liftIO $ getDirectoryContents path-	-	-- filter out directories-	files	<- filterM (\p -> liftM not $ liftIO $ doesDirectoryExist p) -		$ map (\f -> path ++ "/" ++ f)-		$ dropDotPaths contents+ = do   contents <- liftIO $ getDirectoryContents path+        +        -- filter out directories+        files   <- filterM (\p -> liftM not $ liftIO $ doesDirectoryExist p) +                $ map (\f -> path ++ "/" ++ f)+                $ dropDotPaths contents -	return	$ sort files+        return  $ sort files   -- | Get the names of all the dirs in this one. --   This filters out the fake files like '.' and '..'-lsDirsIn :: MonadIO m => String	 -> m [String]+lsDirsIn :: MonadIO m => String  -> m [String] lsDirsIn path  = do - 	contents <- liftIO $ getDirectoryContents path-	-	-- only keep directories-	dirs	<- filterM (liftIO . doesDirectoryExist)-		$  map (\f -> path ++ "/" ++ f)-		$  dropDotPaths contents+        contents <- liftIO $ getDirectoryContents path+        +        -- only keep directories+        dirs    <- filterM (liftIO . doesDirectoryExist)+                $  map (\f -> path ++ "/" ++ f)+                $  dropDotPaths contents -	return	$ sort dirs+        return  $ sort dirs   -- | Get all the files reachable from this directory traceFilesFrom :: FilePath -> IO (Seq FilePath) traceFilesFrom path- = do	isDir	<- doesDirectoryExist path-	isFile	<- doesFileExist      path+ = do   isDir   <- doesDirectoryExist path+        isFile  <- doesFileExist      path -	let result-		| isDir 	-		= do	contents <- liftM dropDotPaths-			 	 $  getDirectoryContents path+        let result+                | isDir         +                = do    contents <- liftM dropDotPaths+                                 $  getDirectoryContents path -			liftM (join  . Seq.fromList)-				$ mapM traceFilesFrom -				$ map (\f -> path ++ "/" ++ f) -				$ contents+                        liftM (join  . Seq.fromList)+                                $ mapM traceFilesFrom +                                $ map (\f -> path ++ "/" ++ f) +                                $ contents -		| isFile-		=	return	$ Seq.singleton path-		-		| otherwise-		=	return	$ Seq.empty-	-	result+                | isFile+                =       return  $ Seq.singleton path+                +                | otherwise+                =       return  $ Seq.empty+        +        result   -- | Drop out the fake '.' and '..' dirst from a list of paths. dropDotPaths :: [FilePath] -> [FilePath] dropDotPaths xx-	= filter (\f -> f /= "." && f /= "..") xx+        = filter (\f -> f /= "." && f /= "..") xx
BuildBox/Pretty.hs view
@@ -1,15 +1,15 @@ {-# LANGUAGE ScopedTypeVariables, TypeSynonymInstances, FlexibleInstances,-             OverlappingInstances, IncoherentInstances #-}+             IncoherentInstances #-}  -- | Pretty printing utils. module BuildBox.Pretty-	( module Text.PrettyPrint-	, Pretty(..)-	, padRc, padR-	, padLc, padL-	, blank-	, pprEngDouble-	, pprEngInteger)+        ( module Text.PrettyPrint+        , Pretty(..)+        , padRc, padR+        , padLc, padL+        , blank+        , pprEngDouble+        , pprEngInteger) where import Text.PrettyPrint import Text.Printf@@ -18,52 +18,52 @@  -- Things that can be pretty printed class Pretty a where- 	ppr :: a -> Doc+        ppr :: a -> Doc  -- Basic instances instance Pretty Doc where-	ppr = id-	+        ppr = id+         instance Pretty Float where-	ppr = text . show+        ppr = text . show  instance Pretty Int where-	ppr = int-	+        ppr = int+         instance Pretty Integer where-	ppr = text . show+        ppr = text . show  instance Pretty UTCTime where-	ppr = text . show-	+        ppr = text . show+         instance Pretty a => Pretty [a] where-	ppr xx -		= lbrack <> (hcat $ punctuate (text ", ") (map ppr xx)) <> rbrack+        ppr xx +                = lbrack <> (hcat $ punctuate (text ", ") (map ppr xx)) <> rbrack  instance Pretty String where-	ppr = text+        ppr = text   -- | Right justify a doc, padding with a given character. padRc :: Int -> Char -> Doc -> Doc padRc n c str-	= (text $ replicate (n - length (render str)) c) <> str-	+        = (text $ replicate (n - length (render str)) c) <> str+          -- | Right justify a string with spaces. padR :: Int -> Doc -> Doc-padR n str	= padRc n ' ' str+padR n str      = padRc n ' ' str   -- | Left justify a string, padding with a given character. padLc :: Int -> Char -> Doc -> Doc padLc n c str-	= str <> (text $ replicate (n - length (render str)) c)+        = str <> (text $ replicate (n - length (render str)) c)   -- | Left justify a string with spaces. padL :: Int -> Doc -> Doc-padL n str	= padLc n ' ' str+padL n str      = padLc n ' ' str  -- | Blank text. This is different different from `empty` because it comes out a a newline when used in a `vcat`. blank :: Doc@@ -74,8 +74,8 @@ --   Good for units where fractional values might not make sense (like bytes). pprEngInteger :: String -> Integer -> Maybe Doc pprEngInteger unit k-    | k < 0	 = liftM (text "-" <>) $ pprEngInteger unit (-k)-    | k > 1000	 = pprEngDouble unit (fromRational $ toRational k)+    | k < 0      = liftM (text "-" <>) $ pprEngInteger unit (-k)+    | k > 1000   = pprEngDouble unit (fromRational $ toRational k)     | otherwise  = Just $ text $ printf "%5d%s " k unit  @@ -114,7 +114,7 @@     | k >= 1e-27 = Nothing     | otherwise  = Just $ text $ printf "%5.0f%s " k unit      where with (t :: Double) (u :: String)-		| t >= 1e3  = text $ printf "%.0f%s" t u-		| t >= 1e2  = text $ printf "%.1f%s" t u-		| t >= 1e1  = text $ printf "%.2f%s" t u-		| otherwise = text $ printf "%.3f%s" t u+                | t >= 1e3  = text $ printf "%.0f%s" t u+                | t >= 1e2  = text $ printf "%.1f%s" t u+                | t >= 1e1  = text $ printf "%.2f%s" t u+                | otherwise = text $ printf "%.3f%s" t u
BuildBox/Time.hs view
@@ -1,82 +1,81 @@  -- | Time utils useful for writing buildbots. module BuildBox.Time-	( module Data.Time-	, readLocalTimeOfDayAsUTC-	, getStampyTime-	, getMidnightTodayLocal-	, getMidnightTodayUTC-	, getMidnightTomorrowLocal-	, getMidnightTomorrowUTC)+        ( module Data.Time+        , readLocalTimeOfDayAsUTC+        , getStampyTime+        , getMidnightTodayLocal+        , getMidnightTodayUTC+        , getMidnightTomorrowLocal+        , getMidnightTomorrowUTC) where import Data.Time-import System.Locale   -- | Read a time of day string like @17:34:05@ in the local time zone --   and convert that to a UTC time of day. Good for parsing command line args to buildbots. readLocalTimeOfDayAsUTC :: String -> IO TimeOfDay readLocalTimeOfDayAsUTC str- = do	-	-- Get the current timeZone.-	curTime	<- getZonedTime+ = do   +        -- Get the current timeZone.+        curTime <- getZonedTime -	-- Convert the time of day to what it would be as UTC.-	let (_, timeOfDayUTC)-		=  localToUTCTimeOfDay -			(zonedTimeZone curTime)-			(read str) +        -- Convert the time of day to what it would be as UTC.+        let (_, timeOfDayUTC)+                =  localToUTCTimeOfDay +                        (zonedTimeZone curTime)+                        (read str)  -	return timeOfDayUTC+        return timeOfDayUTC   -- | Get a local time stamp with format YYYYMMDD_HHMMSS. Good for naming files with. getStampyTime :: IO String getStampyTime- = do	time	<- getZonedTime-	return	$  formatTime defaultTimeLocale "%0Y%0m%0d_%0k%0M%0S" time+ = do   time    <- getZonedTime+        return  $  formatTime defaultTimeLocale "%0Y%0m%0d_%0k%0M%0S" time   -- | Get the local midnight we've just had as a `LocalTime`. getMidnightTodayLocal :: IO LocalTime getMidnightTodayLocal- = do	curTime	<- getZonedTime-	return	$ LocalTime-		{ localDay		= localDay $ zonedTimeToLocalTime curTime-		, localTimeOfDay	= midnight }+ = do   curTime <- getZonedTime+        return  $ LocalTime+                { localDay              = localDay $ zonedTimeToLocalTime curTime+                , localTimeOfDay        = midnight }   -- | Get the local midnight that we've just had, as a `UTCTime`. getMidnightTodayUTC :: IO UTCTime  getMidnightTodayUTC- = do	curTime	<- getZonedTime-	return	$ zonedTimeToUTC-		$ ZonedTime-			(LocalTime	-				{ localDay		= localDay $ zonedTimeToLocalTime curTime-				, localTimeOfDay	= midnight })-			(zonedTimeZone curTime)+ = do   curTime <- getZonedTime+        return  $ zonedTimeToUTC+                $ ZonedTime+                        (LocalTime      +                                { localDay              = localDay $ zonedTimeToLocalTime curTime+                                , localTimeOfDay        = midnight })+                        (zonedTimeZone curTime)   -- | Get the local midnight we're about to have as a `LocalTime`. getMidnightTomorrowLocal :: IO LocalTime getMidnightTomorrowLocal- = do	curTime	<- getZonedTime-	return	$ LocalTime-		{ localDay		= addDays 1 (localDay (zonedTimeToLocalTime curTime)) -		, localTimeOfDay	= midnight }+ = do   curTime <- getZonedTime+        return  $ LocalTime+                { localDay              = addDays 1 (localDay (zonedTimeToLocalTime curTime)) +                , localTimeOfDay        = midnight }  -- | Get the local midnight we're about to have as a `UTCTime`.-getMidnightTomorrowUTC 	 :: IO UTCTime+getMidnightTomorrowUTC   :: IO UTCTime getMidnightTomorrowUTC- = do	curTime	<- getZonedTime-	return	$ zonedTimeToUTC-		$ ZonedTime-		  	(LocalTime-				{ localDay		= addDays 1 (localDay (zonedTimeToLocalTime curTime)) -				, localTimeOfDay	= midnight })-			(zonedTimeZone curTime)+ = do   curTime <- getZonedTime+        return  $ zonedTimeToUTC+                $ ZonedTime+                        (LocalTime+                                { localDay              = addDays 1 (localDay (zonedTimeToLocalTime curTime)) +                                , localTimeOfDay        = midnight })+                        (zonedTimeZone curTime)  -	-	+        +        
buildbox.cabal view
@@ -1,5 +1,5 @@ Name:                buildbox-Version:             2.1.4.3+Version:             2.1.6.1 License:             BSD3 License-file:        LICENSE Author:              Ben Lippmeier@@ -17,21 +17,21 @@         Rehackable components for writing buildbots and test harnesses.  Tested-with:-        GHC == 7.8.2+        GHC == 7.0.3  Library   Build-Depends: -        base           >= 4.4 && < 4.8,+        base           >= 4.4 && < 4.9,         containers     >= 0.4 && < 0.6,-        time           >= 1.2 && < 1.5,+        time           >= 1.2 && < 1.6,         directory      >= 1.1 && < 1.3,         bytestring     >= 0.9 && < 0.11,-        mtl            == 2.2.*,-        old-locale     == 1.0.*,+        mtl            >= 2.2 && < 2.3,+        old-locale     >= 1.0 && < 1.1,         process        >= 1.2 && < 1.3,-        random         == 1.0.*,-        pretty         == 1.1.*,-        stm            == 2.4.*+        random         >= 1.0 && < 1.2,+        pretty         >= 1.1 && < 1.2,+        stm            >= 2.4 && < 2.5    ghc-options:         -Wall