
What about this interface for user-supplied command hooks. The Bool in "test" is for whether or not they have provided the --post-inst flag or something. This is so they can have different test suites depending on whether or not the package has been installed. For each of the pre-functions, a Maybe PackageDescription is returned. If Nothing, then it gets the description from the file or the default description you passed in. If (Just p), then it uses the description returned by the pre-functions. The post-commands return ExitCode, and if they are failure codes, then that command will die with that code. data UserFunctions = UserFunctions { runTests :: Bool -> IO ExitCode, -- ^Used for './setup test {--post-inst}' preConf :: IO (Maybe PackageDescription), postConf :: IO ExitCode, preBuild :: IO (Maybe PackageDescription), postBuild :: IO ExitCode, preClean :: IO (Maybe PackageDescription), postClean :: IO ExitCode, preCopy :: IO (Maybe PackageDescription), postCopy :: IO ExitCode, preInst :: IO (Maybe PackageDescription), postInst :: IO ExitCode, -- ^guaranteed to be run on target preSDist :: IO (Maybe PackageDescription), postSDist :: IO ExitCode, preReg :: IO (Maybe PackageDescription), postReg :: IO ExitCode, preUnreg :: IO (Maybe PackageDescription), postUnreg :: IO ExitCode } I don't particularly like the idea of: {{system "runhaskell" ["postinst.hs"]}} because it seems like a less elegant IO ExitCode. runhaskell doesn't exist, and it relies on more moving parts. peace, isaac