-----------------------------------------------------------------------------
-- |
-- Module      :  Distribution.Simple.Setup
-- Copyright   :  Isaac Jones 2003-2004
--                Duncan Coutts 2007
--
-- Maintainer  :  cabal-devel@haskell.org
-- Portability :  portable
--
-- This is a big module, but not very complicated. The code is very regular
-- and repetitive. It defines the command line interface for all the Cabal
-- commands. For each command (like @configure@, @build@ etc) it defines a type
-- that holds all the flags, the default set of flags and a 'CommandUI' that
-- maps command line flags to and from the corresponding flags type.
--
-- All the flags types are instances of 'Monoid', see
-- <http://www.haskell.org/pipermail/cabal-devel/2007-December/001509.html>
-- for an explanation.
--
-- The types defined here get used in the front end and especially in
-- @cabal-install@ which has to do quite a bit of manipulating sets of command
-- line flags.
--
-- This is actually relatively nice, it works quite well. The main change it
-- needs is to unify it with the code for managing sets of fields that can be
-- read and written from files. This would allow us to save configure flags in
-- config files.

{- All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are
met:

    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.

    * Redistributions in binary form must reproduce the above
      copyright notice, this list of conditions and the following
      disclaimer in the documentation and/or other materials provided
      with the distribution.

    * Neither the name of Isaac Jones nor the names of other
      contributors may be used to endorse or promote products derived
      from this software without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -}

module Distribution.Simple.Setup (

  GlobalFlags(..),   emptyGlobalFlags,   defaultGlobalFlags,   globalCommand,
  ConfigFlags(..),   emptyConfigFlags,   defaultConfigFlags,   configureCommand,
  CopyFlags(..),     emptyCopyFlags,     defaultCopyFlags,     copyCommand,
  InstallFlags(..),  emptyInstallFlags,  defaultInstallFlags,  installCommand,
  HaddockFlags(..),  emptyHaddockFlags,  defaultHaddockFlags,  haddockCommand,
  HscolourFlags(..), emptyHscolourFlags, defaultHscolourFlags, hscolourCommand,
  BuildFlags(..),    emptyBuildFlags,    defaultBuildFlags,    buildCommand,
  buildVerbose,
  CleanFlags(..),    emptyCleanFlags,    defaultCleanFlags,    cleanCommand,
  RegisterFlags(..), emptyRegisterFlags, defaultRegisterFlags, registerCommand,
                                                               unregisterCommand,
  SDistFlags(..),    emptySDistFlags,    defaultSDistFlags,    sdistCommand,
  TestFlags(..),     emptyTestFlags,     defaultTestFlags,     testCommand,
  TestShowDetails(..),
  CopyDest(..),
  configureArgs, configureOptions, configureCCompiler, configureLinker,
  installDirsOptions,

  defaultDistPref,

  Flag(..),
  toFlag,
  fromFlag,
  fromFlagOrDefault,
  flagToMaybe,
  flagToList,
  boolOpt, boolOpt', trueArg, falseArg, optionVerbosity ) where

import Distribution.Compiler ()
import Distribution.ReadE
import Distribution.Text
         ( Text(..), display )
import qualified Distribution.Compat.ReadP as Parse
import qualified Text.PrettyPrint as Disp
import Distribution.Package ( Dependency(..) )
import Distribution.PackageDescription
         ( FlagName(..), FlagAssignment )
import Distribution.Simple.Command hiding (boolOpt, boolOpt')
import qualified Distribution.Simple.Command as Command
import Distribution.Simple.Compiler
         ( CompilerFlavor(..), defaultCompilerFlavor, PackageDB(..)
         , OptimisationLevel(..), flagToOptimisationLevel )
import Distribution.Simple.Utils
         ( wrapLine, lowercase, intercalate )
import Distribution.Simple.Program (Program(..), ProgramConfiguration,
                             requireProgram,
                             programInvocation, progInvokePath, progInvokeArgs,
                             knownPrograms,
                             addKnownProgram, emptyProgramConfiguration,
                             haddockProgram, ghcProgram, gccProgram, ldProgram)
import Distribution.Simple.InstallDirs
         ( InstallDirs(..), CopyDest(..),
           PathTemplate, toPathTemplate, fromPathTemplate )
import Distribution.Verbosity

import Data.List   ( sort )
import Data.Char   ( isSpace, isAlpha )
import Data.Monoid ( Monoid(..) )

-- FIXME Not sure where this should live
defaultDistPref :: FilePath
defaultDistPref = "dist"

-- ------------------------------------------------------------
-- * Flag type
-- ------------------------------------------------------------

-- | All flags are monoids, they come in two flavours:
--
-- 1. list flags eg
--
-- > --ghc-option=foo --ghc-option=bar
--
-- gives us all the values ["foo", "bar"]
--
-- 2. singular value flags, eg:
--
-- > --enable-foo --disable-foo
--
-- gives us Just False
-- So this Flag type is for the latter singular kind of flag.
-- Its monoid instance gives us the behaviour where it starts out as
-- 'NoFlag' and later flags override earlier ones.
--
data Flag a = Flag a | NoFlag deriving (D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow, D:Read ::
  (Int -> ReadS a)
  -> ReadS [a]
  -> ReadPrec a
  -> ReadPrec [a]
  -> T:Read aRead, D:Eq :: (a -> a -> Bool) -> (a -> a -> Bool) -> T:Eq aEq)

instance D:Functor ::
  (forall a b. (a -> b) -> f a -> f b)
  -> (forall a b. a -> f b -> f a)
  -> T:Functor fFunctor Flag where
  fmap f (Flag x) = Flag :: a -> Flag aFlag (f :: a -> bf x :: ax)
  fmap _ NoFlag  = NoFlag :: Flag aNoFlag

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid (Flag a) where
  mempty = NoFlag :: Flag aNoFlag
  _ `mappend` f@(Flag _) = f :: a -> bf
  f `mappend` NoFlag    = f :: a -> bf

instance ($cminBound) :: Bounded a => Flag aBounded a => Bounded (Flag a) where
  minBound = toFlag :: a -> Flag atoFlag minBound :: Bounded a => aminBound
  maxBound = toFlag :: a -> Flag atoFlag maxBound :: Bounded a => amaxBound

instance D:Enum ::
  (a -> a)
  -> (a -> a)
  -> (Int -> a)
  -> (a -> Int)
  -> (a -> [a])
  -> (a -> a -> [a])
  -> (a -> a -> [a])
  -> (a -> a -> a -> [a])
  -> T:Enum aEnum a => Enum (Flag a) where
  fromEnum = fromEnum :: Enum a => a -> IntfromEnum (.) :: (b -> c) -> (a -> b) -> a -> c. fromFlag :: Flag a -> afromFlag
  toEnum   = toFlag :: a -> Flag atoFlag   (.) :: (b -> c) -> (a -> b) -> a -> c. toEnum :: Enum a => Int -> atoEnum
  enumFrom (Flag a) = map :: (a -> b) -> [a] -> [b]map toFlag :: a -> Flag atoFlag (.) :: (b -> c) -> (a -> b) -> a -> c. enumFrom :: Enum a => a -> [a]enumFrom ($) :: (a -> b) -> a -> b$ a :: aa
  enumFrom _        = [] :: [a][]
  enumFromThen (Flag a) (Flag b) = toFlag :: a -> Flag atoFlag map :: (a -> b) -> [a] -> [b]`map` enumFromThen :: Enum a => a -> a -> [a]enumFromThen a :: aa b :: ab
  enumFromThen _        _        = [] :: [a][]
  enumFromTo   (Flag a) (Flag b) = toFlag :: a -> Flag atoFlag map :: (a -> b) -> [a] -> [b]`map` enumFromTo :: Enum a => a -> a -> [a]enumFromTo a :: aa b :: ab
  enumFromTo   _        _        = [] :: [a][]
  enumFromThenTo (Flag a) (Flag b) (Flag c) = toFlag :: a -> Flag atoFlag map :: (a -> b) -> [a] -> [b]`map` enumFromThenTo :: Enum a => a -> a -> a -> [a]enumFromThenTo a :: aa b :: ab c :: ac
  enumFromThenTo _        _        _        = [] :: [a][]

toFlag :: a -> Flag a
toFlag = Flag :: a -> Flag aFlag

fromFlag :: Flag a -> a
fromFlag (Flag x) = x :: ax
fromFlag NoFlag   = error :: [Char] -> aerror "fromFlag NoFlag. Use fromFlagOrDefault"

fromFlagOrDefault :: a -> Flag a -> a
fromFlagOrDefault _   (Flag x) = x :: ax
fromFlagOrDefault def NoFlag   = def :: adef

flagToMaybe :: Flag a -> Maybe a
flagToMaybe (Flag x) = Just :: a -> Maybe aJust x :: ax
flagToMaybe NoFlag   = Nothing :: Maybe aNothing

flagToList :: Flag a -> [a]
flagToList (Flag x) = [x :: ax]
flagToList NoFlag   = [] :: [a][]

-- ------------------------------------------------------------
-- * Global flags
-- ------------------------------------------------------------

-- In fact since individual flags types are monoids and these are just sets of
-- flags then they are also monoids pointwise. This turns out to be really
-- useful. The mempty is the set of empty flags and mappend allows us to
-- override specific flags. For example we can start with default flags and
-- override with the ones we get from a file or the command line, or both.

-- | Flags that apply at the top level, not to any sub-command.
data globalNumericVersion :: Flag BoolGlobalFlags = GlobalFlags {
    globalVersion        :: Flag Bool,
    globalNumericVersion :: Flag Bool
  }

defaultGlobalFlags :: GlobalFlags
defaultGlobalFlags  = GlobalFlags {
    globalVersion        = Flag :: a -> Flag aFlag False :: BoolFalse,
    globalNumericVersion = Flag :: a -> Flag aFlag False :: BoolFalse
  }

globalCommand :: CommandUI GlobalFlags
globalCommand = CommandUI {
    commandName         = "",
    commandSynopsis     = "",
    commandUsage        = \_ ->
         "This Setup program uses the Haskell Cabal Infrastructure.\n"
      (++) :: [a] -> [a] -> [a]++ "See http://www.haskell.org/cabal/ for more information.\n",
    commandDescription  = Just :: a -> Maybe aJust ($) :: (a -> b) -> a -> b$ \pname ->
         "For more information about a command use\n"
      (++) :: [a] -> [a] -> [a]++ "  " (++) :: [a] -> [a] -> [a]++ pname :: [Char]pname (++) :: [a] -> [a] -> [a]++ " COMMAND --help\n\n"
      (++) :: [a] -> [a] -> [a]++ "Typical steps for installing Cabal packages:\n"
      (++) :: [a] -> [a] -> [a]++ concat :: [[a]] -> [a]concat [ "  " (++) :: [a] -> [a] -> [a]++ pname :: [Char]pname (++) :: [a] -> [a] -> [a]++ " " (++) :: [a] -> [a] -> [a]++ x :: ax (++) :: [a] -> [a] -> [a]++ "\n"
                | x <- ["configure", "build", "install"]],
    commandDefaultFlags = defaultGlobalFlags :: GlobalFlagsdefaultGlobalFlags,
    commandOptions      = \_ ->
      [option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption ['V'] ["version"]
         "Print version information"
         globalVersion :: GlobalFlags -> Flag BoolglobalVersion (\v flags -> flags :: TestFlagsflags { globalVersion = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg
      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption [] :: [a][] ["numeric-version"]
         "Print just the version number"
         globalNumericVersion :: GlobalFlags -> Flag BoolglobalNumericVersion (\v flags -> flags :: TestFlagsflags { globalNumericVersion = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg
      ]
  }

emptyGlobalFlags :: GlobalFlags
emptyGlobalFlags = mempty :: Monoid a => amempty

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid GlobalFlags where
  mempty = GlobalFlags {
    globalVersion        = mempty :: Monoid a => amempty,
    globalNumericVersion = mempty :: Monoid a => amempty
  }
  mappend a b = GlobalFlags {
    globalVersion        = combine :: (GlobalFlags -> a) -> acombine globalVersion :: GlobalFlags -> Flag BoolglobalVersion,
    globalNumericVersion = combine :: (GlobalFlags -> a) -> acombine globalNumericVersion :: GlobalFlags -> Flag BoolglobalNumericVersion
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

-- ------------------------------------------------------------
-- * Config flags
-- ------------------------------------------------------------

-- | Flags to @configure@ command
data configInstallDirs :: InstallDirs (Flag PathTemplate)ConfigFlags = ConfigFlags {
    --FIXME: the configPrograms is only here to pass info through to configure
    -- because the type of configure is constrained by the UserHooks.
    -- when we change UserHooks next we should pass the initial
    -- ProgramConfiguration directly and not via ConfigFlags
    configPrograms      :: ProgramConfiguration, -- ^All programs that cabal may run

    configProgramPaths  :: [(String, FilePath)], -- ^user specifed programs paths
    configProgramArgs   :: [(String, [String])], -- ^user specifed programs args
    configHcFlavor      :: Flag CompilerFlavor, -- ^The \"flavor\" of the compiler, sugh as GHC or Hugs.
    configHcPath        :: Flag FilePath, -- ^given compiler location
    configHcPkg         :: Flag FilePath, -- ^given hc-pkg location
    configVanillaLib    :: Flag Bool,     -- ^Enable vanilla library
    configProfLib       :: Flag Bool,     -- ^Enable profiling in the library
    configSharedLib     :: Flag Bool,     -- ^Build shared library
    configDynExe        :: Flag Bool,     -- ^Enable dynamic linking of the executables.
    configProfExe       :: Flag Bool,     -- ^Enable profiling in the executables.
    configConfigureArgs :: [String],      -- ^Extra arguments to @configure@
    configOptimization  :: Flag OptimisationLevel,  -- ^Enable optimization.
    configProgPrefix    :: Flag PathTemplate, -- ^Installed executable prefix.
    configProgSuffix    :: Flag PathTemplate, -- ^Installed executable suffix.
    configInstallDirs   :: InstallDirs (Flag PathTemplate), -- ^Installation paths
    configScratchDir    :: Flag FilePath,
    configExtraLibDirs  :: [FilePath],   -- ^ path to search for extra libraries
    configExtraIncludeDirs :: [FilePath],   -- ^ path to search for header files

    configDistPref :: Flag FilePath, -- ^"dist" prefix
    configVerbosity :: Flag Verbosity, -- ^verbosity level
    configUserInstall :: Flag Bool,    -- ^The --user\/--global flag
    configPackageDB :: Flag PackageDB, -- ^Which package DB to use
    configGHCiLib   :: Flag Bool,      -- ^Enable compiling library for GHCi
    configSplitObjs :: Flag Bool,      -- ^Enable -split-objs with GHC
    configStripExes :: Flag Bool,      -- ^Enable executable stripping
    configConstraints :: [Dependency], -- ^Additional constraints for
                                       -- dependencies
    configConfigurationsFlags :: FlagAssignment,
    configTests :: Flag Bool,     -- ^Enable test suite compilation
    configLibCoverage :: Flag Bool    -- ^ Enable test suite program coverage
  }
  deriving (D:Read ::
  (Int -> ReadS a)
  -> ReadS [a]
  -> ReadPrec a
  -> ReadPrec [a]
  -> T:Read aRead,D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow)

defaultConfigFlags :: ProgramConfiguration -> ConfigFlags
defaultConfigFlags progConf = emptyConfigFlags :: ConfigFlagsemptyConfigFlags {
    configPrograms     = progConf :: ProgramConfigurationprogConf,
    configHcFlavor     = maybe :: b -> (a -> b) -> Maybe a -> bmaybe NoFlag :: Flag aNoFlag Flag :: a -> Flag aFlag defaultCompilerFlavor :: Maybe CompilerFlavordefaultCompilerFlavor,
    configVanillaLib   = Flag :: a -> Flag aFlag True :: BoolTrue,
    configProfLib      = Flag :: a -> Flag aFlag False :: BoolFalse,
    configSharedLib    = Flag :: a -> Flag aFlag False :: BoolFalse,
    configDynExe       = Flag :: a -> Flag aFlag False :: BoolFalse,
    configProfExe      = Flag :: a -> Flag aFlag False :: BoolFalse,
    configOptimization = Flag :: a -> Flag aFlag NormalOptimisation :: OptimisationLevelNormalOptimisation,
    configProgPrefix   = Flag :: a -> Flag aFlag (toPathTemplate :: FilePath -> PathTemplatetoPathTemplate ""),
    configProgSuffix   = Flag :: a -> Flag aFlag (toPathTemplate :: FilePath -> PathTemplatetoPathTemplate ""),
    configDistPref     = Flag :: a -> Flag aFlag defaultDistPref :: FilePathdefaultDistPref,
    configVerbosity    = Flag :: a -> Flag aFlag normal :: Verbositynormal,
    configUserInstall  = Flag :: a -> Flag aFlag False :: BoolFalse,           --TODO: reverse this
    configGHCiLib      = Flag :: a -> Flag aFlag True :: BoolTrue,
    configSplitObjs    = Flag :: a -> Flag aFlag False :: BoolFalse, -- takes longer, so turn off by default
    configStripExes    = Flag :: a -> Flag aFlag True :: BoolTrue,
    configTests  = Flag :: a -> Flag aFlag False :: BoolFalse,
    configLibCoverage = Flag :: a -> Flag aFlag False :: BoolFalse
  }

configureCommand :: ProgramConfiguration -> CommandUI ConfigFlags
configureCommand progConf = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultFlags :: ConfigFlagsdefaultFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "configure"
    shortDesc  = "Prepare to build the package."
    longDesc   = Just :: a -> Maybe aJust (\_ -> programFlagsDescription :: ProgramConfiguration -> StringprogramFlagsDescription progConf :: ProgramConfigurationprogConf)
    defaultFlags = defaultConfigFlags :: ProgramConfiguration -> ConfigFlagsdefaultConfigFlags progConf :: ProgramConfigurationprogConf
    options showOrParseArgs =
         configureOptions :: ShowOrParseArgs -> [OptionField ConfigFlags]configureOptions showOrParseArgs :: ShowOrParseArgsshowOrParseArgs
      (++) :: [a] -> [a] -> [a]++ programConfigurationPaths ::
  ProgramConfiguration
  -> ShowOrParseArgs
  -> (flags -> [(String, FilePath)])
  -> ([(String, FilePath)] -> flags -> flags)
  -> [OptionField flags]programConfigurationPaths   progConf :: ProgramConfigurationprogConf showOrParseArgs :: ShowOrParseArgsshowOrParseArgs
           configProgramPaths :: ConfigFlags -> [(String, FilePath)]configProgramPaths (\v fs -> fs :: ConfigFlagsfs { configProgramPaths = v :: Flag [PathTemplate]v })
      (++) :: [a] -> [a] -> [a]++ programConfigurationOptions ::
  ProgramConfiguration
  -> ShowOrParseArgs
  -> (flags -> [(String, [String])])
  -> ([(String, [String])] -> flags -> flags)
  -> [OptionField flags]programConfigurationOptions progConf :: ProgramConfigurationprogConf showOrParseArgs :: ShowOrParseArgsshowOrParseArgs
           configProgramArgs :: ConfigFlags -> [(String, [String])]configProgramArgs (\v fs -> fs :: ConfigFlagsfs { configProgramArgs = v :: Flag [PathTemplate]v })


configureOptions :: ShowOrParseArgs -> [OptionField ConfigFlags]
configureOptions showOrParseArgs =
      [optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity configVerbosity :: ConfigFlags -> Flag VerbosityconfigVerbosity (\v flags -> flags :: TestFlagsflags { configVerbosity = v :: Flag [PathTemplate]v })
      ,optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
         configDistPref :: ConfigFlags -> Flag FilePathconfigDistPref (\d flags -> flags :: TestFlagsflags { configDistPref = d :: Flag FilePathd })
         showOrParseArgs :: ShowOrParseArgsshowOrParseArgs

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption [] :: [a][] ["compiler"] "compiler"
         configHcFlavor :: ConfigFlags -> Flag CompilerFlavorconfigHcFlavor (\v flags -> flags :: TestFlagsflags { configHcFlavor = v :: Flag [PathTemplate]v })
         (choiceOpt ::
  Eq b =>
  [(b, OptFlags, Description)] -> MkOptDescr (a -> b) (b -> a -> a) achoiceOpt [ (Flag :: a -> Flag aFlag GHC :: CompilerFlavorGHC, ("g", ["ghc"]), "compile with GHC")
                    , (Flag :: a -> Flag aFlag NHC :: CompilerFlavorNHC, ([] :: [a][] , ["nhc98"]), "compile with NHC")
                    , (Flag :: a -> Flag aFlag JHC :: CompilerFlavorJHC, ([] :: [a][] , ["jhc"]), "compile with JHC")
                    , (Flag :: a -> Flag aFlag LHC :: CompilerFlavorLHC, ([] :: [a][] , ["lhc"]), "compile with LHC")
                    , (Flag :: a -> Flag aFlag Hugs :: CompilerFlavorHugs,([] :: [a][] , ["hugs"]), "compile with Hugs")
                    , (Flag :: a -> Flag aFlag UHC :: CompilerFlavorUHC, ([] :: [a][] , ["uhc"]), "compile with UHC")])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "w" ["with-compiler"]
         "give the path to a particular compiler"
         configHcPath :: ConfigFlags -> Flag FilePathconfigHcPath (\v flags -> flags :: TestFlagsflags { configHcPath = v :: Flag [PathTemplate]v })
         (reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "PATH")

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["with-hc-pkg"]
         "give the path to the package tool"
         configHcPkg :: ConfigFlags -> Flag FilePathconfigHcPkg (\v flags -> flags :: TestFlagsflags { configHcPkg = v :: Flag [PathTemplate]v })
         (reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "PATH")
      ]
   (++) :: [a] -> [a] -> [a]++ map :: (a -> b) -> [a] -> [b]map liftInstallDirs ::
  OptionField (InstallDirs (Flag PathTemplate))
  -> OptionField ConfigFlagsliftInstallDirs installDirsOptions ::
  [OptionField (InstallDirs (Flag PathTemplate))]installDirsOptions
   (++) :: [a] -> [a] -> [a]++ [option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "b" ["scratchdir"]
         "directory to receive the built package (hugs-only)"
         configScratchDir :: ConfigFlags -> Flag FilePathconfigScratchDir (\v flags -> flags :: TestFlagsflags { configScratchDir = v :: Flag [PathTemplate]v })
         (reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "DIR")
      --TODO: eliminate scratchdir flag

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["program-prefix"]
          "prefix to be applied to installed executables"
          configProgPrefix :: ConfigFlags -> Flag PathTemplateconfigProgPrefix
          (\v flags -> flags :: TestFlagsflags { configProgPrefix = v :: Flag [PathTemplate]v })
          (reqPathTemplateArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr breqPathTemplateArgFlag "PREFIX")

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["program-suffix"]
          "suffix to be applied to installed executables"
          configProgSuffix :: ConfigFlags -> Flag PathTemplateconfigProgSuffix (\v flags -> flags :: TestFlagsflags { configProgSuffix = v :: Flag [PathTemplate]v } )
          (reqPathTemplateArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr breqPathTemplateArgFlag "SUFFIX")

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["library-vanilla"]
         "Vanilla libraries"
         configVanillaLib :: ConfigFlags -> Flag BoolconfigVanillaLib (\v flags -> flags :: TestFlagsflags { configVanillaLib = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt [] :: [a][] [] :: [a][])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "p" ["library-profiling"]
         "Library profiling"
         configProfLib :: ConfigFlags -> Flag BoolconfigProfLib (\v flags -> flags :: TestFlagsflags { configProfLib = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt "p" [] :: [a][])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["shared"]
         "Shared library"
         configSharedLib :: ConfigFlags -> Flag BoolconfigSharedLib (\v flags -> flags :: TestFlagsflags { configSharedLib = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt [] :: [a][] [] :: [a][])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["executable-dynamic"]
         "Executable dynamic linking"
         configDynExe :: ConfigFlags -> Flag BoolconfigDynExe (\v flags -> flags :: TestFlagsflags { configDynExe = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt [] :: [a][] [] :: [a][])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["executable-profiling"]
         "Executable profiling"
         configProfExe :: ConfigFlags -> Flag BoolconfigProfExe (\v flags -> flags :: TestFlagsflags { configProfExe = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt [] :: [a][] [] :: [a][])

      ,multiOption ::
  Name -> get -> set -> [get -> set -> OptDescr a] -> OptionField amultiOption "optimization"
         configOptimization :: ConfigFlags -> Flag OptimisationLevelconfigOptimization (\v flags -> flags :: TestFlagsflags { configOptimization = v :: Flag [PathTemplate]v })
         [optArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (Maybe String -> b)
  -> (b -> [Maybe String])
  -> MkOptDescr (a -> b) (b -> a -> a) aoptArg' "n" (Flag :: a -> Flag aFlag (.) :: (b -> c) -> (a -> b) -> a -> c. flagToOptimisationLevel :: Maybe String -> OptimisationLevelflagToOptimisationLevel)
                     (\f -> case f :: a -> bf of
                              Flag NoOptimisation      -> [] :: [a][]
                              Flag NormalOptimisation  -> [Nothing :: Maybe aNothing]
                              Flag MaximumOptimisation -> [Just :: a -> Maybe aJust "2"]
                              _                        -> [] :: [a][])
                 "O" ["enable-optimization","enable-optimisation"]
                 "Build with optimization (n is 0--2, default is 1)",
          noArg ::
  (Eq b, Monoid b) => b -> MkOptDescr (a -> b) (b -> a -> a) anoArg (Flag :: a -> Flag aFlag NoOptimisation :: OptimisationLevelNoOptimisation) [] :: [a][]
                ["disable-optimization","disable-optimisation"]
                "Build without optimization"
         ]

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["library-for-ghci"]
         "compile library for use with GHCi"
         configGHCiLib :: ConfigFlags -> Flag BoolconfigGHCiLib (\v flags -> flags :: TestFlagsflags { configGHCiLib = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt [] :: [a][] [] :: [a][])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["split-objs"]
         "split library into smaller objects to reduce binary sizes (GHC 6.6+)"
         configSplitObjs :: ConfigFlags -> Flag BoolconfigSplitObjs (\v flags -> flags :: TestFlagsflags { configSplitObjs = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt [] :: [a][] [] :: [a][])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["executable-stripping"]
         "strip executables upon installation to reduce binary sizes"
         configStripExes :: ConfigFlags -> Flag BoolconfigStripExes (\v flags -> flags :: TestFlagsflags { configStripExes = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt [] :: [a][] [] :: [a][])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["configure-option"]
         "Extra option for configure"
         configConfigureArgs :: ConfigFlags -> [String]configConfigureArgs (\v flags -> flags :: TestFlagsflags { configConfigureArgs = v :: Flag [PathTemplate]v })
         (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "OPT" (\x -> [x :: ax]) id :: a -> aid)

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["user-install"]
         "doing a per-user installation"
         configUserInstall :: ConfigFlags -> Flag BoolconfigUserInstall (\v flags -> flags :: TestFlagsflags { configUserInstall = v :: Flag [PathTemplate]v })
         (boolOpt' ::
  OptFlags
  -> OptFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt' ([] :: [a][],["user"]) ([] :: [a][], ["global"]))

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["package-db"]
         "Use a specific package database (to satisfy dependencies and register in)"
         configPackageDB :: ConfigFlags -> Flag PackageDBconfigPackageDB (\v flags -> flags :: TestFlagsflags { configPackageDB = v :: Flag [PathTemplate]v })
         (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "PATH" (Flag :: a -> Flag aFlag (.) :: (b -> c) -> (a -> b) -> a -> c. SpecificPackageDB :: FilePath -> PackageDBSpecificPackageDB)
                        (\f -> case f :: a -> bf of
                                 Flag (SpecificPackageDB db) -> [db :: FilePathdb]
                                 _ -> [] :: [a][]))

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "f" ["flags"]
         "Force values for the given flags in Cabal conditionals in the .cabal file.  E.g., --flags=\"debug -usebytestrings\" forces the flag \"debug\" to true and \"usebytestrings\" to false."
         configConfigurationsFlags :: ConfigFlags -> FlagAssignmentconfigConfigurationsFlags (\v flags -> flags :: TestFlagsflags { configConfigurationsFlags = v :: Flag [PathTemplate]v })
         (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "FLAGS" readFlagList :: String -> FlagAssignmentreadFlagList showFlagList :: FlagAssignment -> [String]showFlagList)

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["extra-include-dirs"]
         "A list of directories to search for header files"
         configExtraIncludeDirs :: ConfigFlags -> [FilePath]configExtraIncludeDirs (\v flags -> flags :: TestFlagsflags {configExtraIncludeDirs = v :: Flag [PathTemplate]v})
         (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "PATH" (\x -> [x :: ax]) id :: a -> aid)

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["extra-lib-dirs"]
         "A list of directories to search for external libraries"
         configExtraLibDirs :: ConfigFlags -> [FilePath]configExtraLibDirs (\v flags -> flags :: TestFlagsflags {configExtraLibDirs = v :: Flag [PathTemplate]v})
         (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "PATH" (\x -> [x :: ax]) id :: a -> aid)
      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["constraint"]
         "A list of additional constraints on the dependencies."
         configConstraints :: ConfigFlags -> [Dependency]configConstraints (\v flags -> flags :: TestFlagsflags { configConstraints = v :: Flag [PathTemplate]v})
         (reqArg ::
  Monoid b =>
  ArgPlaceHolder
  -> ReadE b
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg "DEPENDENCY"
                 (readP_to_E :: (String -> ErrorMsg) -> ReadP a a -> ReadE areadP_to_E (const :: a -> b -> aconst "dependency expected") ((\x -> [x :: ax]) fmap :: Functor f => forall a b. (a -> b) -> f a -> f b`fmap` parse :: Text a => forall r. ReadP r aparse))
                 (map :: (a -> b) -> [a] -> [b]map (\x -> display :: Text a => a -> Stringdisplay x :: ax)))
      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["tests"]
         "dependency checking and compilation for test suites listed in the package description file."
         configTests :: ConfigFlags -> Flag BoolconfigTests (\v flags -> flags :: TestFlagsflags { configTests = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt [] :: [a][] [] :: [a][])
      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["library-coverage"]
         "build library and test suites with Haskell Program Coverage enabled. (GHC only)"
         configLibCoverage :: ConfigFlags -> Flag BoolconfigLibCoverage (\v flags -> flags :: TestFlagsflags { configLibCoverage = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt [] :: [a][] [] :: [a][])
      ]
  where
    readFlagList :: String -> FlagAssignment
    readFlagList = map :: (a -> b) -> [a] -> [b]map tagWithValue :: [Char] -> (FlagName, Bool)tagWithValue (.) :: (b -> c) -> (a -> b) -> a -> c. words :: String -> [String]words
      where tagWithValue ('-':fname) = (FlagName :: String -> FlagNameFlagName (lowercase :: String -> Stringlowercase fname :: [Char]fname), False :: BoolFalse)
            tagWithValue fname       = (FlagName :: String -> FlagNameFlagName (lowercase :: String -> Stringlowercase fname :: [Char]fname), True :: BoolTrue)

    showFlagList :: FlagAssignment -> [String]
    showFlagList fs = [ if not :: Bool -> Boolnot set :: Boolset then '-'(:) :: a -> [a] -> [a]:fname :: [Char]fname else fname :: [Char]fname
                      | (FlagName fname, set) <- fs :: ConfigFlagsfs]

    liftInstallDirs =
      liftOption ::
  (b -> a) -> (a -> b -> b) -> OptionField a -> OptionField bliftOption configInstallDirs :: ConfigFlags -> InstallDirs (Flag PathTemplate)configInstallDirs (\v flags -> flags :: TestFlagsflags { configInstallDirs = v :: Flag [PathTemplate]v })

    reqPathTemplateArgFlag title _sf _lf d get set =
      reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag title :: ArgPlaceHoldertitle _sf :: SFlags_sf _lf :: LFlags_lf d :: Flag FilePathd
        (fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap fromPathTemplate :: PathTemplate -> FilePathfromPathTemplate (.) :: (b -> c) -> (a -> b) -> a -> c. get :: b -> Flag PathTemplateget) (set :: Boolset (.) :: (b -> c) -> (a -> b) -> a -> c. fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap toPathTemplate :: FilePath -> PathTemplatetoPathTemplate)

installDirsOptions :: [OptionField (InstallDirs (Flag PathTemplate))]
installDirsOptions =
  [ option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["prefix"]
      "bake this prefix in preparation of installation"
      prefix :: InstallDirs dir -> dirprefix (\v flags -> flags :: TestFlagsflags { prefix = v :: Flag [PathTemplate]v })
      installDirArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr binstallDirArg

  , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["bindir"]
      "installation directory for executables"
      bindir :: InstallDirs dir -> dirbindir (\v flags -> flags :: TestFlagsflags { bindir = v :: Flag [PathTemplate]v })
      installDirArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr binstallDirArg

  , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["libdir"]
      "installation directory for libraries"
      libdir :: InstallDirs dir -> dirlibdir (\v flags -> flags :: TestFlagsflags { libdir = v :: Flag [PathTemplate]v })
      installDirArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr binstallDirArg

  , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["libsubdir"]
      "subdirectory of libdir in which libs are installed"
      libsubdir :: InstallDirs dir -> dirlibsubdir (\v flags -> flags :: TestFlagsflags { libsubdir = v :: Flag [PathTemplate]v })
      installDirArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr binstallDirArg

  , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["libexecdir"]
      "installation directory for program executables"
      libexecdir :: InstallDirs dir -> dirlibexecdir (\v flags -> flags :: TestFlagsflags { libexecdir = v :: Flag [PathTemplate]v })
      installDirArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr binstallDirArg

  , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["datadir"]
      "installation directory for read-only data"
      datadir :: InstallDirs dir -> dirdatadir (\v flags -> flags :: TestFlagsflags { datadir = v :: Flag [PathTemplate]v })
      installDirArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr binstallDirArg

  , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["datasubdir"]
      "subdirectory of datadir in which data files are installed"
      datasubdir :: InstallDirs dir -> dirdatasubdir (\v flags -> flags :: TestFlagsflags { datasubdir = v :: Flag [PathTemplate]v })
      installDirArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr binstallDirArg

  , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["docdir"]
      "installation directory for documentation"
      docdir :: InstallDirs dir -> dirdocdir (\v flags -> flags :: TestFlagsflags { docdir = v :: Flag [PathTemplate]v })
      installDirArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr binstallDirArg

  , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["htmldir"]
      "installation directory for HTML documentation"
      htmldir :: InstallDirs dir -> dirhtmldir (\v flags -> flags :: TestFlagsflags { htmldir = v :: Flag [PathTemplate]v })
      installDirArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr binstallDirArg

  , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["haddockdir"]
      "installation directory for haddock interfaces"
      haddockdir :: InstallDirs dir -> dirhaddockdir (\v flags -> flags :: TestFlagsflags { haddockdir = v :: Flag [PathTemplate]v })
      installDirArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag PathTemplate)
  -> (Flag PathTemplate -> b -> b)
  -> OptDescr binstallDirArg
  ]
  where
    installDirArg _sf _lf d get set =
      reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "DIR" _sf :: SFlags_sf _lf :: LFlags_lf d :: Flag FilePathd
        (fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap fromPathTemplate :: PathTemplate -> FilePathfromPathTemplate (.) :: (b -> c) -> (a -> b) -> a -> c. get :: b -> Flag PathTemplateget) (set :: Boolset (.) :: (b -> c) -> (a -> b) -> a -> c. fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap toPathTemplate :: FilePath -> PathTemplatetoPathTemplate)

emptyConfigFlags :: ConfigFlags
emptyConfigFlags = mempty :: Monoid a => amempty

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid ConfigFlags where
  mempty = ConfigFlags {
    configPrograms      = error :: [Char] -> aerror "FIXME: remove configPrograms",
    configProgramPaths  = mempty :: Monoid a => amempty,
    configProgramArgs   = mempty :: Monoid a => amempty,
    configHcFlavor      = mempty :: Monoid a => amempty,
    configHcPath        = mempty :: Monoid a => amempty,
    configHcPkg         = mempty :: Monoid a => amempty,
    configVanillaLib    = mempty :: Monoid a => amempty,
    configProfLib       = mempty :: Monoid a => amempty,
    configSharedLib     = mempty :: Monoid a => amempty,
    configDynExe        = mempty :: Monoid a => amempty,
    configProfExe       = mempty :: Monoid a => amempty,
    configConfigureArgs = mempty :: Monoid a => amempty,
    configOptimization  = mempty :: Monoid a => amempty,
    configProgPrefix    = mempty :: Monoid a => amempty,
    configProgSuffix    = mempty :: Monoid a => amempty,
    configInstallDirs   = mempty :: Monoid a => amempty,
    configScratchDir    = mempty :: Monoid a => amempty,
    configDistPref      = mempty :: Monoid a => amempty,
    configVerbosity     = mempty :: Monoid a => amempty,
    configUserInstall   = mempty :: Monoid a => amempty,
    configPackageDB     = mempty :: Monoid a => amempty,
    configGHCiLib       = mempty :: Monoid a => amempty,
    configSplitObjs     = mempty :: Monoid a => amempty,
    configStripExes     = mempty :: Monoid a => amempty,
    configExtraLibDirs  = mempty :: Monoid a => amempty,
    configConstraints   = mempty :: Monoid a => amempty,
    configExtraIncludeDirs    = mempty :: Monoid a => amempty,
    configConfigurationsFlags = mempty :: Monoid a => amempty,
    configTests   = mempty :: Monoid a => amempty,
    configLibCoverage = mempty :: Monoid a => amempty
  }
  mappend a b =  ConfigFlags {
    configPrograms      = configPrograms :: ConfigFlags -> ProgramConfigurationconfigPrograms b :: ab,
    configProgramPaths  = combine :: (GlobalFlags -> a) -> acombine configProgramPaths :: ConfigFlags -> [(String, FilePath)]configProgramPaths,
    configProgramArgs   = combine :: (GlobalFlags -> a) -> acombine configProgramArgs :: ConfigFlags -> [(String, [String])]configProgramArgs,
    configHcFlavor      = combine :: (GlobalFlags -> a) -> acombine configHcFlavor :: ConfigFlags -> Flag CompilerFlavorconfigHcFlavor,
    configHcPath        = combine :: (GlobalFlags -> a) -> acombine configHcPath :: ConfigFlags -> Flag FilePathconfigHcPath,
    configHcPkg         = combine :: (GlobalFlags -> a) -> acombine configHcPkg :: ConfigFlags -> Flag FilePathconfigHcPkg,
    configVanillaLib    = combine :: (GlobalFlags -> a) -> acombine configVanillaLib :: ConfigFlags -> Flag BoolconfigVanillaLib,
    configProfLib       = combine :: (GlobalFlags -> a) -> acombine configProfLib :: ConfigFlags -> Flag BoolconfigProfLib,
    configSharedLib     = combine :: (GlobalFlags -> a) -> acombine configSharedLib :: ConfigFlags -> Flag BoolconfigSharedLib,
    configDynExe        = combine :: (GlobalFlags -> a) -> acombine configDynExe :: ConfigFlags -> Flag BoolconfigDynExe,
    configProfExe       = combine :: (GlobalFlags -> a) -> acombine configProfExe :: ConfigFlags -> Flag BoolconfigProfExe,
    configConfigureArgs = combine :: (GlobalFlags -> a) -> acombine configConfigureArgs :: ConfigFlags -> [String]configConfigureArgs,
    configOptimization  = combine :: (GlobalFlags -> a) -> acombine configOptimization :: ConfigFlags -> Flag OptimisationLevelconfigOptimization,
    configProgPrefix    = combine :: (GlobalFlags -> a) -> acombine configProgPrefix :: ConfigFlags -> Flag PathTemplateconfigProgPrefix,
    configProgSuffix    = combine :: (GlobalFlags -> a) -> acombine configProgSuffix :: ConfigFlags -> Flag PathTemplateconfigProgSuffix,
    configInstallDirs   = combine :: (GlobalFlags -> a) -> acombine configInstallDirs :: ConfigFlags -> InstallDirs (Flag PathTemplate)configInstallDirs,
    configScratchDir    = combine :: (GlobalFlags -> a) -> acombine configScratchDir :: ConfigFlags -> Flag FilePathconfigScratchDir,
    configDistPref      = combine :: (GlobalFlags -> a) -> acombine configDistPref :: ConfigFlags -> Flag FilePathconfigDistPref,
    configVerbosity     = combine :: (GlobalFlags -> a) -> acombine configVerbosity :: ConfigFlags -> Flag VerbosityconfigVerbosity,
    configUserInstall   = combine :: (GlobalFlags -> a) -> acombine configUserInstall :: ConfigFlags -> Flag BoolconfigUserInstall,
    configPackageDB     = combine :: (GlobalFlags -> a) -> acombine configPackageDB :: ConfigFlags -> Flag PackageDBconfigPackageDB,
    configGHCiLib       = combine :: (GlobalFlags -> a) -> acombine configGHCiLib :: ConfigFlags -> Flag BoolconfigGHCiLib,
    configSplitObjs     = combine :: (GlobalFlags -> a) -> acombine configSplitObjs :: ConfigFlags -> Flag BoolconfigSplitObjs,
    configStripExes     = combine :: (GlobalFlags -> a) -> acombine configStripExes :: ConfigFlags -> Flag BoolconfigStripExes,
    configExtraLibDirs  = combine :: (GlobalFlags -> a) -> acombine configExtraLibDirs :: ConfigFlags -> [FilePath]configExtraLibDirs,
    configConstraints   = combine :: (GlobalFlags -> a) -> acombine configConstraints :: ConfigFlags -> [Dependency]configConstraints,
    configExtraIncludeDirs    = combine :: (GlobalFlags -> a) -> acombine configExtraIncludeDirs :: ConfigFlags -> [FilePath]configExtraIncludeDirs,
    configConfigurationsFlags = combine :: (GlobalFlags -> a) -> acombine configConfigurationsFlags :: ConfigFlags -> FlagAssignmentconfigConfigurationsFlags,
    configTests = combine :: (GlobalFlags -> a) -> acombine configTests :: ConfigFlags -> Flag BoolconfigTests,
    configLibCoverage = combine :: (GlobalFlags -> a) -> acombine configLibCoverage :: ConfigFlags -> Flag BoolconfigLibCoverage
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

-- ------------------------------------------------------------
-- * Copy flags
-- ------------------------------------------------------------

-- | Flags to @copy@: (destdir, copy-prefix (backwards compat), verbosity)
data copyVerbosity :: Flag VerbosityCopyFlags = CopyFlags {
    copyDest      :: Flag CopyDest,
    copyDistPref  :: Flag FilePath,
    copyVerbosity :: Flag Verbosity
  }
  deriving D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow

defaultCopyFlags :: CopyFlags
defaultCopyFlags  = CopyFlags {
    copyDest      = Flag :: a -> Flag aFlag NoCopyDest :: CopyDestNoCopyDest,
    copyDistPref  = Flag :: a -> Flag aFlag defaultDistPref :: FilePathdefaultDistPref,
    copyVerbosity = Flag :: a -> Flag aFlag normal :: Verbositynormal
  }

copyCommand :: CommandUI CopyFlags
copyCommand = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultCopyFlags :: CopyFlagsdefaultCopyFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "copy"
    shortDesc  = "Copy the files into the install locations."
    longDesc   = Just :: a -> Maybe aJust ($) :: (a -> b) -> a -> b$ \_ ->
          "Does not call register, and allows a prefix at install time\n"
       (++) :: [a] -> [a] -> [a]++ "Without the --destdir flag, configure determines location.\n"
    options showOrParseArgs =
      [optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity copyVerbosity :: CopyFlags -> Flag VerbositycopyVerbosity (\v flags -> flags :: TestFlagsflags { copyVerbosity = v :: Flag [PathTemplate]v })

      ,optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
         copyDistPref :: CopyFlags -> Flag FilePathcopyDistPref (\d flags -> flags :: TestFlagsflags { copyDistPref = d :: Flag FilePathd })
         showOrParseArgs :: ShowOrParseArgsshowOrParseArgs

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["destdir"]
         "directory to copy files to, prepended to installation directories"
         copyDest :: CopyFlags -> Flag CopyDestcopyDest (\v flags -> flags :: TestFlagsflags { copyDest = v :: Flag [PathTemplate]v })
         (reqArg ::
  Monoid b =>
  ArgPlaceHolder
  -> ReadE b
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg "DIR" (succeedReadE :: (String -> a) -> ReadE asucceedReadE (Flag :: a -> Flag aFlag (.) :: (b -> c) -> (a -> b) -> a -> c. CopyTo :: FilePath -> CopyDestCopyTo))
                       (\f -> case f :: a -> bf of Flag (CopyTo p) -> [p :: FilePathp]; _ -> [] :: [a][]))
      ]

emptyCopyFlags :: CopyFlags
emptyCopyFlags = mempty :: Monoid a => amempty

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid CopyFlags where
  mempty = CopyFlags {
    copyDest      = mempty :: Monoid a => amempty,
    copyDistPref  = mempty :: Monoid a => amempty,
    copyVerbosity = mempty :: Monoid a => amempty
  }
  mappend a b = CopyFlags {
    copyDest      = combine :: (GlobalFlags -> a) -> acombine copyDest :: CopyFlags -> Flag CopyDestcopyDest,
    copyDistPref  = combine :: (GlobalFlags -> a) -> acombine copyDistPref :: CopyFlags -> Flag FilePathcopyDistPref,
    copyVerbosity = combine :: (GlobalFlags -> a) -> acombine copyVerbosity :: CopyFlags -> Flag VerbositycopyVerbosity
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

-- ------------------------------------------------------------
-- * Install flags
-- ------------------------------------------------------------

-- | Flags to @install@: (package db, verbosity)
data installPackageDB :: Flag PackageDBInstallFlags = InstallFlags {
    installPackageDB :: Flag PackageDB,
    installDistPref  :: Flag FilePath,
    installUseWrapper :: Flag Bool,
    installInPlace    :: Flag Bool,
    installVerbosity :: Flag Verbosity
  }
  deriving D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow

defaultInstallFlags :: InstallFlags
defaultInstallFlags  = InstallFlags {
    installPackageDB = NoFlag :: Flag aNoFlag,
    installDistPref  = Flag :: a -> Flag aFlag defaultDistPref :: FilePathdefaultDistPref,
    installUseWrapper = Flag :: a -> Flag aFlag False :: BoolFalse,
    installInPlace    = Flag :: a -> Flag aFlag False :: BoolFalse,
    installVerbosity = Flag :: a -> Flag aFlag normal :: Verbositynormal
  }

installCommand :: CommandUI InstallFlags
installCommand = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultInstallFlags :: InstallFlagsdefaultInstallFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "install"
    shortDesc  = "Copy the files into the install locations. Run register."
    longDesc   = Just :: a -> Maybe aJust ($) :: (a -> b) -> a -> b$ \_ ->
         "Unlike the copy command, install calls the register command.\n"
      (++) :: [a] -> [a] -> [a]++ "If you want to install into a location that is not what was\n"
      (++) :: [a] -> [a] -> [a]++ "specified in the configure step, use the copy command.\n"
    options showOrParseArgs =
      [optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity installVerbosity :: InstallFlags -> Flag VerbosityinstallVerbosity (\v flags -> flags :: TestFlagsflags { installVerbosity = v :: Flag [PathTemplate]v })
      ,optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
         installDistPref :: InstallFlags -> Flag FilePathinstallDistPref (\d flags -> flags :: TestFlagsflags { installDistPref = d :: Flag FilePathd })
         showOrParseArgs :: ShowOrParseArgsshowOrParseArgs

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["inplace"]
         "install the package in the install subdirectory of the dist prefix, so it can be used without being installed"
         installInPlace :: InstallFlags -> Flag BoolinstallInPlace (\v flags -> flags :: TestFlagsflags { installInPlace = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["shell-wrappers"]
         "using shell script wrappers around executables"
         installUseWrapper :: InstallFlags -> Flag BoolinstallUseWrapper (\v flags -> flags :: TestFlagsflags { installUseWrapper = v :: Flag [PathTemplate]v })
         (boolOpt ::
  SFlags
  -> SFlags
  -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) aboolOpt [] :: [a][] [] :: [a][])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["package-db"] ""
         installPackageDB :: InstallFlags -> Flag PackageDBinstallPackageDB (\v flags -> flags :: TestFlagsflags { installPackageDB = v :: Flag [PathTemplate]v })
         (choiceOpt ::
  Eq b =>
  [(b, OptFlags, Description)] -> MkOptDescr (a -> b) (b -> a -> a) achoiceOpt [ (Flag :: a -> Flag aFlag UserPackageDB :: PackageDBUserPackageDB, ([] :: [a][],["user"]),
                      "upon configuration register this package in the user's local package database")
                    , (Flag :: a -> Flag aFlag GlobalPackageDB :: PackageDBGlobalPackageDB, ([] :: [a][],["global"]),
                      "(default) upon configuration register this package in the system-wide package database")])
      ]

emptyInstallFlags :: InstallFlags
emptyInstallFlags = mempty :: Monoid a => amempty

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid InstallFlags where
  mempty = InstallFlags{
    installPackageDB = mempty :: Monoid a => amempty,
    installDistPref  = mempty :: Monoid a => amempty,
    installUseWrapper = mempty :: Monoid a => amempty,
    installInPlace    = mempty :: Monoid a => amempty,
    installVerbosity = mempty :: Monoid a => amempty
  }
  mappend a b = InstallFlags{
    installPackageDB = combine :: (GlobalFlags -> a) -> acombine installPackageDB :: InstallFlags -> Flag PackageDBinstallPackageDB,
    installDistPref  = combine :: (GlobalFlags -> a) -> acombine installDistPref :: InstallFlags -> Flag FilePathinstallDistPref,
    installUseWrapper = combine :: (GlobalFlags -> a) -> acombine installUseWrapper :: InstallFlags -> Flag BoolinstallUseWrapper,
    installInPlace    = combine :: (GlobalFlags -> a) -> acombine installInPlace :: InstallFlags -> Flag BoolinstallInPlace,
    installVerbosity = combine :: (GlobalFlags -> a) -> acombine installVerbosity :: InstallFlags -> Flag VerbosityinstallVerbosity
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

-- ------------------------------------------------------------
-- * SDist flags
-- ------------------------------------------------------------

-- | Flags to @sdist@: (snapshot, verbosity)
data sDistVerbosity :: Flag VerbositySDistFlags = SDistFlags {
    sDistSnapshot  :: Flag Bool,
    sDistDirectory :: Flag FilePath,
    sDistDistPref  :: Flag FilePath,
    sDistVerbosity :: Flag Verbosity
  }
  deriving D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow

defaultSDistFlags :: SDistFlags
defaultSDistFlags = SDistFlags {
    sDistSnapshot  = Flag :: a -> Flag aFlag False :: BoolFalse,
    sDistDirectory = mempty :: Monoid a => amempty,
    sDistDistPref  = Flag :: a -> Flag aFlag defaultDistPref :: FilePathdefaultDistPref,
    sDistVerbosity = Flag :: a -> Flag aFlag normal :: Verbositynormal
  }

sdistCommand :: CommandUI SDistFlags
sdistCommand = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultSDistFlags :: SDistFlagsdefaultSDistFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "sdist"
    shortDesc  = "Generate a source distribution file (.tar.gz)."
    longDesc   = Nothing :: Maybe aNothing
    options showOrParseArgs =
      [optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity sDistVerbosity :: SDistFlags -> Flag VerbositysDistVerbosity (\v flags -> flags :: TestFlagsflags { sDistVerbosity = v :: Flag [PathTemplate]v })
      ,optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
         sDistDistPref :: SDistFlags -> Flag FilePathsDistDistPref (\d flags -> flags :: TestFlagsflags { sDistDistPref = d :: Flag FilePathd })
         showOrParseArgs :: ShowOrParseArgsshowOrParseArgs

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["snapshot"]
         "Produce a snapshot source distribution"
         sDistSnapshot :: SDistFlags -> Flag BoolsDistSnapshot (\v flags -> flags :: TestFlagsflags { sDistSnapshot = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["output-directory"]
         "Generate a source distribution in the given directory"
         sDistDirectory :: SDistFlags -> Flag FilePathsDistDirectory (\v flags -> flags :: TestFlagsflags { sDistDirectory = v :: Flag [PathTemplate]v })
         (reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "DIR")
      ]

emptySDistFlags :: SDistFlags
emptySDistFlags = mempty :: Monoid a => amempty

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid SDistFlags where
  mempty = SDistFlags {
    sDistSnapshot  = mempty :: Monoid a => amempty,
    sDistDirectory = mempty :: Monoid a => amempty,
    sDistDistPref  = mempty :: Monoid a => amempty,
    sDistVerbosity = mempty :: Monoid a => amempty
  }
  mappend a b = SDistFlags {
    sDistSnapshot  = combine :: (GlobalFlags -> a) -> acombine sDistSnapshot :: SDistFlags -> Flag BoolsDistSnapshot,
    sDistDirectory = combine :: (GlobalFlags -> a) -> acombine sDistDirectory :: SDistFlags -> Flag FilePathsDistDirectory,
    sDistDistPref  = combine :: (GlobalFlags -> a) -> acombine sDistDistPref :: SDistFlags -> Flag FilePathsDistDistPref,
    sDistVerbosity = combine :: (GlobalFlags -> a) -> acombine sDistVerbosity :: SDistFlags -> Flag VerbositysDistVerbosity
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

-- ------------------------------------------------------------
-- * Register flags
-- ------------------------------------------------------------

-- | Flags to @register@ and @unregister@: (user package, gen-script,
-- in-place, verbosity)
data regGenPkgConf :: Flag (Maybe FilePath)RegisterFlags = RegisterFlags {
    regPackageDB   :: Flag PackageDB,
    regGenScript   :: Flag Bool,
    regGenPkgConf  :: Flag (Maybe FilePath),
    regInPlace     :: Flag Bool,
    regDistPref    :: Flag FilePath,
    regVerbosity   :: Flag Verbosity
  }
  deriving D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow

defaultRegisterFlags :: RegisterFlags
defaultRegisterFlags = RegisterFlags {
    regPackageDB   = NoFlag :: Flag aNoFlag,
    regGenScript   = Flag :: a -> Flag aFlag False :: BoolFalse,
    regGenPkgConf  = NoFlag :: Flag aNoFlag,
    regInPlace     = Flag :: a -> Flag aFlag False :: BoolFalse,
    regDistPref    = Flag :: a -> Flag aFlag defaultDistPref :: FilePathdefaultDistPref,
    regVerbosity   = Flag :: a -> Flag aFlag normal :: Verbositynormal
  }

registerCommand :: CommandUI RegisterFlags
registerCommand = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultRegisterFlags :: RegisterFlagsdefaultRegisterFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "register"
    shortDesc  = "Register this package with the compiler."
    longDesc   = Nothing :: Maybe aNothing
    options showOrParseArgs =
      [optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity regVerbosity :: RegisterFlags -> Flag VerbosityregVerbosity (\v flags -> flags :: TestFlagsflags { regVerbosity = v :: Flag [PathTemplate]v })
      ,optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
         regDistPref :: RegisterFlags -> Flag FilePathregDistPref (\d flags -> flags :: TestFlagsflags { regDistPref = d :: Flag FilePathd })
         showOrParseArgs :: ShowOrParseArgsshowOrParseArgs

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["packageDB"] ""
         regPackageDB :: RegisterFlags -> Flag PackageDBregPackageDB (\v flags -> flags :: TestFlagsflags { regPackageDB = v :: Flag [PathTemplate]v })
         (choiceOpt ::
  Eq b =>
  [(b, OptFlags, Description)] -> MkOptDescr (a -> b) (b -> a -> a) achoiceOpt [ (Flag :: a -> Flag aFlag UserPackageDB :: PackageDBUserPackageDB, ([] :: [a][],["user"]),
                                "upon registration, register this package in the user's local package database")
                    , (Flag :: a -> Flag aFlag GlobalPackageDB :: PackageDBGlobalPackageDB, ([] :: [a][],["global"]),
                                "(default)upon registration, register this package in the system-wide package database")])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["inplace"]
         "register the package in the build location, so it can be used without being installed"
         regInPlace :: RegisterFlags -> Flag BoolregInPlace (\v flags -> flags :: TestFlagsflags { regInPlace = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["gen-script"]
         "instead of registering, generate a script to register later"
         regGenScript :: RegisterFlags -> Flag BoolregGenScript (\v flags -> flags :: TestFlagsflags { regGenScript = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["gen-pkg-config"]
         "instead of registering, generate a package registration file"
         regGenPkgConf :: RegisterFlags -> Flag (Maybe FilePath)regGenPkgConf (\v flags -> flags :: TestFlagsflags { regGenPkgConf  = v :: Flag [PathTemplate]v })
         (optArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (Maybe String -> b)
  -> (b -> [Maybe String])
  -> MkOptDescr (a -> b) (b -> a -> a) aoptArg' "PKG" Flag :: a -> Flag aFlag flagToList :: Flag a -> [a]flagToList)
      ]

unregisterCommand :: CommandUI RegisterFlags
unregisterCommand = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultRegisterFlags :: RegisterFlagsdefaultRegisterFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "unregister"
    shortDesc  = "Unregister this package with the compiler."
    longDesc   = Nothing :: Maybe aNothing
    options showOrParseArgs =
      [optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity regVerbosity :: RegisterFlags -> Flag VerbosityregVerbosity (\v flags -> flags :: TestFlagsflags { regVerbosity = v :: Flag [PathTemplate]v })
      ,optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
         regDistPref :: RegisterFlags -> Flag FilePathregDistPref (\d flags -> flags :: TestFlagsflags { regDistPref = d :: Flag FilePathd })
          showOrParseArgs :: ShowOrParseArgsshowOrParseArgs

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["user"] ""
         regPackageDB :: RegisterFlags -> Flag PackageDBregPackageDB (\v flags -> flags :: TestFlagsflags { regPackageDB = v :: Flag [PathTemplate]v })
         (choiceOpt ::
  Eq b =>
  [(b, OptFlags, Description)] -> MkOptDescr (a -> b) (b -> a -> a) achoiceOpt [ (Flag :: a -> Flag aFlag UserPackageDB :: PackageDBUserPackageDB, ([] :: [a][],["user"]),
                              "unregister this package in the user's local package database")
                    , (Flag :: a -> Flag aFlag GlobalPackageDB :: PackageDBGlobalPackageDB, ([] :: [a][],["global"]),
                              "(default) unregister this package in the  system-wide package database")])

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["gen-script"]
         "Instead of performing the unregister command, generate a script to unregister later"
         regGenScript :: RegisterFlags -> Flag BoolregGenScript (\v flags -> flags :: TestFlagsflags { regGenScript = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg
      ]

emptyRegisterFlags :: RegisterFlags
emptyRegisterFlags = mempty :: Monoid a => amempty

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid RegisterFlags where
  mempty = RegisterFlags {
    regPackageDB   = mempty :: Monoid a => amempty,
    regGenScript   = mempty :: Monoid a => amempty,
    regGenPkgConf  = mempty :: Monoid a => amempty,
    regInPlace     = mempty :: Monoid a => amempty,
    regDistPref    = mempty :: Monoid a => amempty,
    regVerbosity   = mempty :: Monoid a => amempty
  }
  mappend a b = RegisterFlags {
    regPackageDB   = combine :: (GlobalFlags -> a) -> acombine regPackageDB :: RegisterFlags -> Flag PackageDBregPackageDB,
    regGenScript   = combine :: (GlobalFlags -> a) -> acombine regGenScript :: RegisterFlags -> Flag BoolregGenScript,
    regGenPkgConf  = combine :: (GlobalFlags -> a) -> acombine regGenPkgConf :: RegisterFlags -> Flag (Maybe FilePath)regGenPkgConf,
    regInPlace     = combine :: (GlobalFlags -> a) -> acombine regInPlace :: RegisterFlags -> Flag BoolregInPlace,
    regDistPref    = combine :: (GlobalFlags -> a) -> acombine regDistPref :: RegisterFlags -> Flag FilePathregDistPref,
    regVerbosity   = combine :: (GlobalFlags -> a) -> acombine regVerbosity :: RegisterFlags -> Flag VerbosityregVerbosity
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

-- ------------------------------------------------------------
-- * HsColour flags
-- ------------------------------------------------------------

data hscolourVerbosity :: Flag VerbosityHscolourFlags = HscolourFlags {
    hscolourCSS         :: Flag FilePath,
    hscolourExecutables :: Flag Bool,
    hscolourDistPref    :: Flag FilePath,
    hscolourVerbosity   :: Flag Verbosity,
    hscolourAnnotFile   :: Flag FilePath
  }
  deriving D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow

emptyHscolourFlags :: HscolourFlags
emptyHscolourFlags = mempty :: Monoid a => amempty

defaultHscolourFlags :: HscolourFlags
defaultHscolourFlags = HscolourFlags {
    hscolourCSS         = NoFlag :: Flag aNoFlag,
    hscolourExecutables = Flag :: a -> Flag aFlag False :: BoolFalse,
    hscolourDistPref    = Flag :: a -> Flag aFlag defaultDistPref :: FilePathdefaultDistPref,
    hscolourVerbosity   = Flag :: a -> Flag aFlag normal :: Verbositynormal,
    hscolourAnnotFile   = NoFlag :: Flag aNoFlag
  }

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid HscolourFlags where
  mempty = HscolourFlags {
    hscolourCSS         = mempty :: Monoid a => amempty,
    hscolourExecutables = mempty :: Monoid a => amempty,
    hscolourDistPref    = mempty :: Monoid a => amempty,
    hscolourVerbosity   = mempty :: Monoid a => amempty,
    hscolourAnnotFile   = mempty :: Monoid a => amempty
  }
  mappend a b = HscolourFlags {
    hscolourCSS         = combine :: (GlobalFlags -> a) -> acombine hscolourCSS :: HscolourFlags -> Flag FilePathhscolourCSS,
    hscolourExecutables = combine :: (GlobalFlags -> a) -> acombine hscolourExecutables :: HscolourFlags -> Flag BoolhscolourExecutables,
    hscolourDistPref    = combine :: (GlobalFlags -> a) -> acombine hscolourDistPref :: HscolourFlags -> Flag FilePathhscolourDistPref,
    hscolourVerbosity   = combine :: (GlobalFlags -> a) -> acombine hscolourVerbosity :: HscolourFlags -> Flag VerbosityhscolourVerbosity,
    hscolourAnnotFile   = combine :: (GlobalFlags -> a) -> acombine hscolourAnnotFile :: HscolourFlags -> Flag FilePathhscolourAnnotFile
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

hscolourCommand :: CommandUI HscolourFlags
hscolourCommand = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultHscolourFlags :: HscolourFlagsdefaultHscolourFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "hscolour"
    shortDesc  = "Generate HsColour colourised code, in HTML format."
    longDesc   = Just :: a -> Maybe aJust (\_ -> "Requires hscolour.\n")
    options showOrParseArgs =
      [optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity hscolourVerbosity :: HscolourFlags -> Flag VerbosityhscolourVerbosity (\v flags -> flags :: TestFlagsflags { hscolourVerbosity = v :: Flag [PathTemplate]v })
      ,optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
         hscolourDistPref :: HscolourFlags -> Flag FilePathhscolourDistPref (\d flags -> flags :: TestFlagsflags { hscolourDistPref = d :: Flag FilePathd })
         showOrParseArgs :: ShowOrParseArgsshowOrParseArgs

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["executables"]
         "Run hscolour for Executables targets"
         hscolourExecutables :: HscolourFlags -> Flag BoolhscolourExecutables (\v flags -> flags :: TestFlagsflags { hscolourExecutables = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["css"]
         "Use a cascading style sheet"
         hscolourCSS :: HscolourFlags -> Flag FilePathhscolourCSS (\v flags -> flags :: TestFlagsflags { hscolourCSS = v :: Flag [PathTemplate]v })
         (reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "PATH")

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["annot"]
         "Generate mouseover annotations with specified file"
         hscolourAnnotFile :: HscolourFlags -> Flag FilePathhscolourAnnotFile (\v flags -> flags :: TestFlagsflags { hscolourAnnotFile = v :: Flag [PathTemplate]v })
         (reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "PATH")
      ]

-- ------------------------------------------------------------
-- * Haddock flags
-- ------------------------------------------------------------

data haddockProgramPaths :: [(String, FilePath)]HaddockFlags = HaddockFlags {
    haddockProgramPaths :: [(String, FilePath)],
    haddockProgramArgs  :: [(String, [String])],
    haddockHoogle       :: Flag Bool,
    haddockHtml         :: Flag Bool,
    haddockAnnot        :: Flag Bool,
    haddockHtmlLocation :: Flag String,
    haddockExecutables  :: Flag Bool,
    haddockInternal     :: Flag Bool,
    haddockCss          :: Flag FilePath,
    haddockHscolour     :: Flag Bool,
    haddockHscolourCss  :: Flag FilePath,
    haddockDistPref     :: Flag FilePath,
    haddockVerbosity    :: Flag Verbosity
  }
  deriving D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow

defaultHaddockFlags :: HaddockFlags
defaultHaddockFlags  = HaddockFlags {
    haddockProgramPaths = mempty :: Monoid a => amempty,
    haddockProgramArgs  = [] :: [a][],
    haddockHoogle       = Flag :: a -> Flag aFlag False :: BoolFalse,
    haddockHtml         = Flag :: a -> Flag aFlag False :: BoolFalse,
    haddockAnnot        = Flag :: a -> Flag aFlag False :: BoolFalse,
    haddockHtmlLocation = NoFlag :: Flag aNoFlag,
    haddockExecutables  = Flag :: a -> Flag aFlag False :: BoolFalse,
    haddockInternal     = Flag :: a -> Flag aFlag False :: BoolFalse,
    haddockCss          = NoFlag :: Flag aNoFlag,
    haddockHscolour     = Flag :: a -> Flag aFlag False :: BoolFalse,
    haddockHscolourCss  = NoFlag :: Flag aNoFlag,
    haddockDistPref     = Flag :: a -> Flag aFlag defaultDistPref :: FilePathdefaultDistPref,
    haddockVerbosity    = Flag :: a -> Flag aFlag normal :: Verbositynormal
  }

haddockCommand :: CommandUI HaddockFlags
haddockCommand = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultHaddockFlags :: HaddockFlagsdefaultHaddockFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "haddock"
    shortDesc  = "Generate Haddock HTML documentation."
    longDesc   = Just :: a -> Maybe aJust ($) :: (a -> b) -> a -> b$ \_ -> "Requires the program haddock, either version 0.x or 2.x.\n"
    options showOrParseArgs =
      [optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity haddockVerbosity :: HaddockFlags -> Flag VerbosityhaddockVerbosity (\v flags -> flags :: TestFlagsflags { haddockVerbosity = v :: Flag [PathTemplate]v })
      ,optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
         haddockDistPref :: HaddockFlags -> Flag FilePathhaddockDistPref (\d flags -> flags :: TestFlagsflags { haddockDistPref = d :: Flag FilePathd })
         showOrParseArgs :: ShowOrParseArgsshowOrParseArgs

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["hoogle"]
         "Generate a hoogle database"
         haddockHoogle :: HaddockFlags -> Flag BoolhaddockHoogle (\v flags -> flags :: TestFlagsflags { haddockHoogle = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["html"]
         "Generate HTML documentation (the default)"
         haddockHtml :: HaddockFlags -> Flag BoolhaddockHtml (\v flags -> flags :: TestFlagsflags { haddockHtml = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["annot"]
         "Generate mouseover type annotations for source (using haddock/HsColour)"
         haddockAnnot :: HaddockFlags -> Flag BoolhaddockAnnot (\v flags -> flags :: TestFlagsflags { haddockAnnot = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["html-location"]
         "Location of HTML documentation for pre-requisite packages"
         haddockHtmlLocation :: HaddockFlags -> Flag StringhaddockHtmlLocation (\v flags -> flags :: TestFlagsflags { haddockHtmlLocation = v :: Flag [PathTemplate]v })
         (reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "URL")

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["executables"]
         "Run haddock for Executables targets"
         haddockExecutables :: HaddockFlags -> Flag BoolhaddockExecutables (\v flags -> flags :: TestFlagsflags { haddockExecutables = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["internal"]
         "Run haddock for internal modules and include all symbols"
         haddockInternal :: HaddockFlags -> Flag BoolhaddockInternal (\v flags -> flags :: TestFlagsflags { haddockInternal = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["css"]
         "Use PATH as the haddock stylesheet"
         haddockCss :: HaddockFlags -> Flag FilePathhaddockCss (\v flags -> flags :: TestFlagsflags { haddockCss = v :: Flag [PathTemplate]v })
         (reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "PATH")

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["hyperlink-source","hyperlink-sources"]
         "Hyperlink the documentation to the source code (using HsColour)"
         haddockHscolour :: HaddockFlags -> Flag BoolhaddockHscolour (\v flags -> flags :: TestFlagsflags { haddockHscolour = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["hscolour-css"]
         "Use PATH as the HsColour stylesheet"
         haddockHscolourCss :: HaddockFlags -> Flag FilePathhaddockHscolourCss (\v flags -> flags :: TestFlagsflags { haddockHscolourCss = v :: Flag [PathTemplate]v })
         (reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "PATH")
      ]
      (++) :: [a] -> [a] -> [a]++ programConfigurationPaths ::
  ProgramConfiguration
  -> ShowOrParseArgs
  -> (flags -> [(String, FilePath)])
  -> ([(String, FilePath)] -> flags -> flags)
  -> [OptionField flags]programConfigurationPaths   progConf :: ProgramConfigurationprogConf ParseArgs :: ShowOrParseArgsParseArgs
             haddockProgramPaths :: HaddockFlags -> [(String, FilePath)]haddockProgramPaths (\v flags -> flags :: TestFlagsflags { haddockProgramPaths = v :: Flag [PathTemplate]v})
      (++) :: [a] -> [a] -> [a]++ programConfigurationOptions ::
  ProgramConfiguration
  -> ShowOrParseArgs
  -> (flags -> [(String, [String])])
  -> ([(String, [String])] -> flags -> flags)
  -> [OptionField flags]programConfigurationOptions progConf :: ProgramConfigurationprogConf ParseArgs :: ShowOrParseArgsParseArgs
             haddockProgramArgs :: HaddockFlags -> [(String, [String])]haddockProgramArgs  (\v flags -> flags :: TestFlagsflags { haddockProgramArgs = v :: Flag [PathTemplate]v})
    progConf = addKnownProgram :: Program -> ProgramDb -> ProgramDbaddKnownProgram haddockProgram :: ProgramhaddockProgram
             ($) :: (a -> b) -> a -> b$ addKnownProgram :: Program -> ProgramDb -> ProgramDbaddKnownProgram ghcProgram :: ProgramghcProgram
             ($) :: (a -> b) -> a -> b$ emptyProgramConfiguration :: ProgramConfigurationemptyProgramConfiguration

emptyHaddockFlags :: HaddockFlags
emptyHaddockFlags = mempty :: Monoid a => amempty

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid HaddockFlags where
  mempty = HaddockFlags {
    haddockProgramPaths = mempty :: Monoid a => amempty,
    haddockProgramArgs  = mempty :: Monoid a => amempty,
    haddockHoogle       = mempty :: Monoid a => amempty,
    haddockHtml         = mempty :: Monoid a => amempty,
    haddockAnnot        = mempty :: Monoid a => amempty,
    haddockHtmlLocation = mempty :: Monoid a => amempty,
    haddockExecutables  = mempty :: Monoid a => amempty,
    haddockInternal     = mempty :: Monoid a => amempty,
    haddockCss          = mempty :: Monoid a => amempty,
    haddockHscolour     = mempty :: Monoid a => amempty,
    haddockHscolourCss  = mempty :: Monoid a => amempty,
    haddockDistPref     = mempty :: Monoid a => amempty,
    haddockVerbosity    = mempty :: Monoid a => amempty
  }
  mappend a b = HaddockFlags {
    haddockProgramPaths = combine :: (GlobalFlags -> a) -> acombine haddockProgramPaths :: HaddockFlags -> [(String, FilePath)]haddockProgramPaths,
    haddockProgramArgs  = combine :: (GlobalFlags -> a) -> acombine haddockProgramArgs :: HaddockFlags -> [(String, [String])]haddockProgramArgs,
    haddockHoogle       = combine :: (GlobalFlags -> a) -> acombine haddockHoogle :: HaddockFlags -> Flag BoolhaddockHoogle,
    haddockHtml         = combine :: (GlobalFlags -> a) -> acombine haddockHtml :: HaddockFlags -> Flag BoolhaddockHtml, 
    haddockAnnot        = combine :: (GlobalFlags -> a) -> acombine haddockAnnot :: HaddockFlags -> Flag BoolhaddockAnnot,
    haddockHtmlLocation = combine :: (GlobalFlags -> a) -> acombine haddockHtmlLocation :: HaddockFlags -> Flag StringhaddockHtmlLocation,
    haddockExecutables  = combine :: (GlobalFlags -> a) -> acombine haddockExecutables :: HaddockFlags -> Flag BoolhaddockExecutables,
    haddockInternal     = combine :: (GlobalFlags -> a) -> acombine haddockInternal :: HaddockFlags -> Flag BoolhaddockInternal,
    haddockCss          = combine :: (GlobalFlags -> a) -> acombine haddockCss :: HaddockFlags -> Flag FilePathhaddockCss,
    haddockHscolour     = combine :: (GlobalFlags -> a) -> acombine haddockHscolour :: HaddockFlags -> Flag BoolhaddockHscolour,
    haddockHscolourCss  = combine :: (GlobalFlags -> a) -> acombine haddockHscolourCss :: HaddockFlags -> Flag FilePathhaddockHscolourCss,
    haddockDistPref     = combine :: (GlobalFlags -> a) -> acombine haddockDistPref :: HaddockFlags -> Flag FilePathhaddockDistPref,
    haddockVerbosity    = combine :: (GlobalFlags -> a) -> acombine haddockVerbosity :: HaddockFlags -> Flag VerbosityhaddockVerbosity
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

-- ------------------------------------------------------------
-- * Clean flags
-- ------------------------------------------------------------

data cleanVerbosity :: Flag VerbosityCleanFlags = CleanFlags {
    cleanSaveConf  :: Flag Bool,
    cleanDistPref  :: Flag FilePath,
    cleanVerbosity :: Flag Verbosity
  }
  deriving D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow

defaultCleanFlags :: CleanFlags
defaultCleanFlags  = CleanFlags {
    cleanSaveConf  = Flag :: a -> Flag aFlag False :: BoolFalse,
    cleanDistPref  = Flag :: a -> Flag aFlag defaultDistPref :: FilePathdefaultDistPref,
    cleanVerbosity = Flag :: a -> Flag aFlag normal :: Verbositynormal
  }

cleanCommand :: CommandUI CleanFlags
cleanCommand = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultCleanFlags :: CleanFlagsdefaultCleanFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "clean"
    shortDesc  = "Clean up after a build."
    longDesc   = Just :: a -> Maybe aJust (\_ -> "Removes .hi, .o, preprocessed sources, etc.\n")
    options showOrParseArgs =
      [optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity cleanVerbosity :: CleanFlags -> Flag VerbositycleanVerbosity (\v flags -> flags :: TestFlagsflags { cleanVerbosity = v :: Flag [PathTemplate]v })
      ,optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
         cleanDistPref :: CleanFlags -> Flag FilePathcleanDistPref (\d flags -> flags :: TestFlagsflags { cleanDistPref = d :: Flag FilePathd })
         showOrParseArgs :: ShowOrParseArgsshowOrParseArgs

      ,option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "s" ["save-configure"]
         "Do not remove the configuration file (dist/setup-config) during cleaning.  Saves need to reconfigure."
         cleanSaveConf :: CleanFlags -> Flag BoolcleanSaveConf (\v flags -> flags :: TestFlagsflags { cleanSaveConf = v :: Flag [PathTemplate]v })
         trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg
      ]

emptyCleanFlags :: CleanFlags
emptyCleanFlags = mempty :: Monoid a => amempty

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid CleanFlags where
  mempty = CleanFlags {
    cleanSaveConf  = mempty :: Monoid a => amempty,
    cleanDistPref  = mempty :: Monoid a => amempty,
    cleanVerbosity = mempty :: Monoid a => amempty
  }
  mappend a b = CleanFlags {
    cleanSaveConf  = combine :: (GlobalFlags -> a) -> acombine cleanSaveConf :: CleanFlags -> Flag BoolcleanSaveConf,
    cleanDistPref  = combine :: (GlobalFlags -> a) -> acombine cleanDistPref :: CleanFlags -> Flag FilePathcleanDistPref,
    cleanVerbosity = combine :: (GlobalFlags -> a) -> acombine cleanVerbosity :: CleanFlags -> Flag VerbositycleanVerbosity
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

-- ------------------------------------------------------------
-- * Build flags
-- ------------------------------------------------------------

data buildProgramPaths :: [(String, FilePath)]BuildFlags = BuildFlags {
    buildProgramPaths :: [(String, FilePath)],
    buildProgramArgs :: [(String, [String])],
    buildDistPref    :: Flag FilePath,
    buildVerbosity   :: Flag Verbosity
  }
  deriving D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow

{-# DEPRECATED buildVerbose "Use buildVerbosity instead" #-}
buildVerbose :: BuildFlags -> Verbosity
buildVerbose = fromFlagOrDefault :: a -> Flag a -> afromFlagOrDefault normal :: Verbositynormal (.) :: (b -> c) -> (a -> b) -> a -> c. buildVerbosity :: BuildFlags -> Flag VerbositybuildVerbosity

defaultBuildFlags :: BuildFlags
defaultBuildFlags  = BuildFlags {
    buildProgramPaths = mempty :: Monoid a => amempty,
    buildProgramArgs = [] :: [a][],
    buildDistPref    = Flag :: a -> Flag aFlag defaultDistPref :: FilePathdefaultDistPref,
    buildVerbosity   = Flag :: a -> Flag aFlag normal :: Verbositynormal
  }

buildCommand :: ProgramConfiguration -> CommandUI BuildFlags
buildCommand progConf = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultBuildFlags :: BuildFlagsdefaultBuildFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "build"
    shortDesc  = "Make this package ready for installation."
    longDesc   = Nothing :: Maybe aNothing
    options showOrParseArgs =
      optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity buildVerbosity :: BuildFlags -> Flag VerbositybuildVerbosity (\v flags -> flags :: TestFlagsflags { buildVerbosity = v :: Flag [PathTemplate]v })
      (:) :: a -> [a] -> [a]: optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
          buildDistPref :: BuildFlags -> Flag FilePathbuildDistPref (\d flags -> flags :: TestFlagsflags { buildDistPref = d :: Flag FilePathd })
          showOrParseArgs :: ShowOrParseArgsshowOrParseArgs

      (:) :: a -> [a] -> [a]: programConfigurationPaths ::
  ProgramConfiguration
  -> ShowOrParseArgs
  -> (flags -> [(String, FilePath)])
  -> ([(String, FilePath)] -> flags -> flags)
  -> [OptionField flags]programConfigurationPaths   progConf :: ProgramConfigurationprogConf showOrParseArgs :: ShowOrParseArgsshowOrParseArgs
          buildProgramPaths :: BuildFlags -> [(String, FilePath)]buildProgramPaths (\v flags -> flags :: TestFlagsflags { buildProgramPaths = v :: Flag [PathTemplate]v})

     (++) :: [a] -> [a] -> [a]++ programConfigurationOptions ::
  ProgramConfiguration
  -> ShowOrParseArgs
  -> (flags -> [(String, [String])])
  -> ([(String, [String])] -> flags -> flags)
  -> [OptionField flags]programConfigurationOptions progConf :: ProgramConfigurationprogConf showOrParseArgs :: ShowOrParseArgsshowOrParseArgs
          buildProgramArgs :: BuildFlags -> [(String, [String])]buildProgramArgs (\v flags -> flags :: TestFlagsflags { buildProgramArgs = v :: Flag [PathTemplate]v})

emptyBuildFlags :: BuildFlags
emptyBuildFlags = mempty :: Monoid a => amempty

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid BuildFlags where
  mempty = BuildFlags {
    buildProgramPaths = mempty :: Monoid a => amempty,
    buildProgramArgs = mempty :: Monoid a => amempty,
    buildVerbosity   = mempty :: Monoid a => amempty,
    buildDistPref    = mempty :: Monoid a => amempty
  }
  mappend a b = BuildFlags {
    buildProgramPaths = combine :: (GlobalFlags -> a) -> acombine buildProgramPaths :: BuildFlags -> [(String, FilePath)]buildProgramPaths,
    buildProgramArgs = combine :: (GlobalFlags -> a) -> acombine buildProgramArgs :: BuildFlags -> [(String, [String])]buildProgramArgs,
    buildVerbosity   = combine :: (GlobalFlags -> a) -> acombine buildVerbosity :: BuildFlags -> Flag VerbositybuildVerbosity,
    buildDistPref    = combine :: (GlobalFlags -> a) -> acombine buildDistPref :: BuildFlags -> Flag FilePathbuildDistPref
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

-- ------------------------------------------------------------
-- * Test flags
-- ------------------------------------------------------------

data TestShowDetails = Never | Failures | Always
    deriving (D:Eq :: (a -> a -> Bool) -> (a -> a -> Bool) -> T:Eq aEq, D:Ord ::
  Eq a =>
  (a -> a -> Ordering)
  -> (a -> a -> Bool)
  -> (a -> a -> Bool)
  -> (a -> a -> Bool)
  -> (a -> a -> Bool)
  -> (a -> a -> a)
  -> (a -> a -> a)
  -> T:Ord aOrd, D:Enum ::
  (a -> a)
  -> (a -> a)
  -> (Int -> a)
  -> (a -> Int)
  -> (a -> [a])
  -> (a -> a -> [a])
  -> (a -> a -> [a])
  -> (a -> a -> a -> [a])
  -> T:Enum aEnum, ($cminBound) :: Bounded a => Flag aBounded, D:Show ::
  (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> T:Show aShow)

knownTestShowDetails :: [TestShowDetails]
knownTestShowDetails = [minBound :: Bounded a => aminBound..maxBound :: Bounded a => amaxBound]

instance D:Text :: (a -> Doc) -> (forall r. ReadP r a) -> T:Text aText TestShowDetails where
    disp  = text :: String -> DocDisp.text (.) :: (b -> c) -> (a -> b) -> a -> c. lowercase :: String -> Stringlowercase (.) :: (b -> c) -> (a -> b) -> a -> c. show :: Show a => a -> Stringshow

    parse = maybe :: b -> (a -> b) -> Maybe a -> bmaybe pfail :: ReadP r aParse.pfail return :: Monad m => forall a. a -> m areturn (.) :: (b -> c) -> (a -> b) -> a -> c. classify :: String -> Maybe TestShowDetailsclassify (=<<) :: Monad m => (a -> m b) -> m a -> m b=<< ident :: ReadP r Stringident
      where
        ident        = munch1 :: (Char -> Bool) -> ReadP r StringParse.munch1 (\c -> isAlpha :: Char -> BoolisAlpha c :: ac (||) :: Bool -> Bool -> Bool|| c :: ac (==) :: Eq a => a -> a -> Bool== '_' (||) :: Bool -> Bool -> Bool|| c :: ac (==) :: Eq a => a -> a -> Bool== '-')
        classify str = lookup :: Eq a => a -> [(a, b)] -> Maybe blookup (lowercase :: String -> Stringlowercase str :: Stringstr) enumMap :: [(String, TestShowDetails)]enumMap
        enumMap     :: [(String, TestShowDetails)]
        enumMap      = [ (display :: Text a => a -> Stringdisplay x :: ax, x :: ax)
                       | x <- knownTestShowDetails :: [TestShowDetails]knownTestShowDetails ]

--TODO: do we need this instance?
instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid TestShowDetails where
    mempty = Never :: TestShowDetailsNever
    mappend a b = if a :: aa (<) :: Ord a => a -> a -> Bool< b :: ab then b :: ab else a :: aa

data testShowDetails :: Flag TestShowDetailsTestFlags = TestFlags {
    testDistPref  :: Flag FilePath,
    testVerbosity :: Flag Verbosity,
    testHumanLog :: Flag PathTemplate,
    testMachineLog :: Flag PathTemplate,
    testShowDetails :: Flag TestShowDetails,
    testKeepTix :: Flag Bool,
    --TODO: eliminate the test list and pass it directly as positional args to the testHook
    testList :: Flag [String],
    -- TODO: think about if/how options are passed to test exes
    testOptions :: Flag [PathTemplate]
  }

defaultTestFlags :: TestFlags
defaultTestFlags  = TestFlags {
    testDistPref  = Flag :: a -> Flag aFlag defaultDistPref :: FilePathdefaultDistPref,
    testVerbosity = Flag :: a -> Flag aFlag normal :: Verbositynormal,
    testHumanLog = toFlag :: a -> Flag atoFlag ($) :: (a -> b) -> a -> b$ toPathTemplate :: FilePath -> PathTemplatetoPathTemplate ($) :: (a -> b) -> a -> b$ "$pkgid-$test-suite.log",
    testMachineLog = toFlag :: a -> Flag atoFlag ($) :: (a -> b) -> a -> b$ toPathTemplate :: FilePath -> PathTemplatetoPathTemplate ($) :: (a -> b) -> a -> b$ "$pkgid.log",
    testShowDetails = toFlag :: a -> Flag atoFlag Failures :: TestShowDetailsFailures,
    testKeepTix = toFlag :: a -> Flag atoFlag False :: BoolFalse,
    testList = Flag :: a -> Flag aFlag [] :: [a][],
    testOptions = Flag :: a -> Flag aFlag [] :: [a][]
  }

testCommand :: CommandUI TestFlags
testCommand = makeCommand ::
  String
  -> String
  -> Maybe (String -> String)
  -> flags
  -> (ShowOrParseArgs -> [OptionField flags])
  -> CommandUI flagsmakeCommand name :: [Char]name shortDesc :: [Char]shortDesc longDesc :: Maybe alongDesc defaultTestFlags :: TestFlagsdefaultTestFlags options :: ShowOrParseArgs -> [OptionField TestFlags]options
  where
    name       = "test"
    shortDesc  = "Run the test suite, if any (configure with UserHooks)."
    longDesc   = Nothing :: Maybe aNothing
    options showOrParseArgs =
      [ optionVerbosity ::
  (flags -> Flag Verbosity)
  -> (Flag Verbosity -> flags -> flags)
  -> OptionField flagsoptionVerbosity testVerbosity :: TestFlags -> Flag VerbositytestVerbosity (\v flags -> flags :: TestFlagsflags { testVerbosity = v :: Flag [PathTemplate]v })
      , optionDistPref ::
  (flags -> Flag FilePath)
  -> (Flag FilePath -> flags -> flags)
  -> ShowOrParseArgs
  -> OptionField flagsoptionDistPref
            testDistPref :: TestFlags -> Flag FilePathtestDistPref (\d flags -> flags :: TestFlagsflags { testDistPref = d :: Flag FilePathd })
            showOrParseArgs :: ShowOrParseArgsshowOrParseArgs
      , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption [] :: [a][] ["log"]
            ("Log all test suite results to file (name template can use "
            (++) :: [a] -> [a] -> [a]++ "$pkgid, $compiler, $os, $arch, $test-suite, $result)")
            testHumanLog :: TestFlags -> Flag PathTemplatetestHumanLog (\v flags -> flags :: TestFlagsflags { testHumanLog = v :: Flag [PathTemplate]v })
            (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "TEMPLATE"
                (toFlag :: a -> Flag atoFlag (.) :: (b -> c) -> (a -> b) -> a -> c. toPathTemplate :: FilePath -> PathTemplatetoPathTemplate)
                (flagToList :: Flag a -> [a]flagToList (.) :: (b -> c) -> (a -> b) -> a -> c. fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap fromPathTemplate :: PathTemplate -> FilePathfromPathTemplate))
      , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption [] :: [a][] ["machine-log"]
            ("Produce a machine-readable log file (name template can use "
            (++) :: [a] -> [a] -> [a]++ "$pkgid, $compiler, $os, $arch, $result)")
            testMachineLog :: TestFlags -> Flag PathTemplatetestMachineLog (\v flags -> flags :: TestFlagsflags { testMachineLog = v :: Flag [PathTemplate]v })
            (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "TEMPLATE"
                (toFlag :: a -> Flag atoFlag (.) :: (b -> c) -> (a -> b) -> a -> c. toPathTemplate :: FilePath -> PathTemplatetoPathTemplate)
                (flagToList :: Flag a -> [a]flagToList (.) :: (b -> c) -> (a -> b) -> a -> c. fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap fromPathTemplate :: PathTemplate -> FilePathfromPathTemplate))
      , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption [] :: [a][] ["show-details"]
            ("'always': always show results of individual test cases. "
             (++) :: [a] -> [a] -> [a]++ "'never': never show results of individual test cases. "
             (++) :: [a] -> [a] -> [a]++ "'failures': show results of failing test cases.")
            testShowDetails :: TestFlags -> Flag TestShowDetailstestShowDetails (\v flags -> flags :: TestFlagsflags { testShowDetails = v :: Flag [PathTemplate]v })
            (reqArg ::
  Monoid b =>
  ArgPlaceHolder
  -> ReadE b
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg "FILTER"
                (readP_to_E :: (String -> ErrorMsg) -> ReadP a a -> ReadE areadP_to_E (\_ -> "--show-details flag expects one of "
                              (++) :: [a] -> [a] -> [a]++ intercalate :: [a] -> [[a]] -> [a]intercalate ", "
                                   (map :: (a -> b) -> [a] -> [b]map display :: Text a => a -> Stringdisplay knownTestShowDetails :: [TestShowDetails]knownTestShowDetails))
                            (fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap toFlag :: a -> Flag atoFlag parse :: Text a => forall r. ReadP r aparse))
                (flagToList :: Flag a -> [a]flagToList (.) :: (b -> c) -> (a -> b) -> a -> c. fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap display :: Text a => a -> Stringdisplay))
      , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption [] :: [a][] ["keep-tix-files"]
            "keep .tix files for HPC between test runs"
            testKeepTix :: TestFlags -> Flag BooltestKeepTix (\v flags -> flags :: TestFlagsflags { testKeepTix = v :: Flag [PathTemplate]v})
            trueArg ::
  SFlags
  -> LFlags
  -> Description
  -> (b -> Flag Bool)
  -> (Flag Bool -> b -> b)
  -> OptDescr btrueArg
      , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption [] :: [a][] ["test-options"]
            ("give extra options to test executables "
             (++) :: [a] -> [a] -> [a]++ "(name templates can use $pkgid, $compiler, "
             (++) :: [a] -> [a] -> [a]++ "$os, $arch, $test-suite)")
            testOptions :: TestFlags -> Flag [PathTemplate]testOptions (\v flags -> flags :: TestFlagsflags { testOptions = v :: Flag [PathTemplate]v })
            (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "TEMPLATES" (toFlag :: a -> Flag atoFlag (.) :: (b -> c) -> (a -> b) -> a -> c. map :: (a -> b) -> [a] -> [b]map toPathTemplate :: FilePath -> PathTemplatetoPathTemplate (.) :: (b -> c) -> (a -> b) -> a -> c. splitArgs :: String -> [String]splitArgs)
                (map :: (a -> b) -> [a] -> [b]map fromPathTemplate :: PathTemplate -> FilePathfromPathTemplate (.) :: (b -> c) -> (a -> b) -> a -> c. fromFlagOrDefault :: a -> Flag a -> afromFlagOrDefault [] :: [a][]))
      , option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption [] :: [a][] ["test-option"]
            ("give extra option to test executables "
             (++) :: [a] -> [a] -> [a]++ "(no need to quote options containing spaces, "
             (++) :: [a] -> [a] -> [a]++ "name template can use $pkgid, $compiler, "
             (++) :: [a] -> [a] -> [a]++ "$os, $arch, $test-suite)")
            testOptions :: TestFlags -> Flag [PathTemplate]testOptions (\v flags -> flags :: TestFlagsflags { testOptions = v :: Flag [PathTemplate]v })
            (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "TEMPLATE" (\x -> toFlag :: a -> Flag atoFlag [toPathTemplate :: FilePath -> PathTemplatetoPathTemplate x :: ax])
                (map :: (a -> b) -> [a] -> [b]map fromPathTemplate :: PathTemplate -> FilePathfromPathTemplate (.) :: (b -> c) -> (a -> b) -> a -> c. fromFlagOrDefault :: a -> Flag a -> afromFlagOrDefault [] :: [a][]))
      ]

emptyTestFlags :: TestFlags
emptyTestFlags  = mempty :: Monoid a => amempty

instance D:Monoid :: a -> (a -> a -> a) -> ([a] -> a) -> T:Monoid aMonoid TestFlags where
  mempty = TestFlags {
    testDistPref  = mempty :: Monoid a => amempty,
    testVerbosity = mempty :: Monoid a => amempty,
    testHumanLog = mempty :: Monoid a => amempty,
    testMachineLog = mempty :: Monoid a => amempty,
    testShowDetails = mempty :: Monoid a => amempty,
    testKeepTix = mempty :: Monoid a => amempty,
    testList = mempty :: Monoid a => amempty,
    testOptions = mempty :: Monoid a => amempty
  }
  mappend a b = TestFlags {
    testDistPref  = combine :: (GlobalFlags -> a) -> acombine testDistPref :: TestFlags -> Flag FilePathtestDistPref,
    testVerbosity = combine :: (GlobalFlags -> a) -> acombine testVerbosity :: TestFlags -> Flag VerbositytestVerbosity,
    testHumanLog = combine :: (GlobalFlags -> a) -> acombine testHumanLog :: TestFlags -> Flag PathTemplatetestHumanLog,
    testMachineLog = combine :: (GlobalFlags -> a) -> acombine testMachineLog :: TestFlags -> Flag PathTemplatetestMachineLog,
    testShowDetails = combine :: (GlobalFlags -> a) -> acombine testShowDetails :: TestFlags -> Flag TestShowDetailstestShowDetails,
    testKeepTix = combine :: (GlobalFlags -> a) -> acombine testKeepTix :: TestFlags -> Flag BooltestKeepTix,
    testList = combine :: (GlobalFlags -> a) -> acombine testList :: TestFlags -> Flag [String]testList,
    testOptions = combine :: (GlobalFlags -> a) -> acombine testOptions :: TestFlags -> Flag [PathTemplate]testOptions
  }
    where combine field = field :: GlobalFlags -> afield a :: aa mappend :: Monoid a => a -> a -> a`mappend` field :: GlobalFlags -> afield b :: ab

-- ------------------------------------------------------------
-- * Shared options utils
-- ------------------------------------------------------------

programFlagsDescription :: ProgramConfiguration -> String
programFlagsDescription progConf =
     "The flags --with-PROG and --PROG-option(s) can be used with"
  (++) :: [a] -> [a] -> [a]++ " the following programs:"
  (++) :: [a] -> [a] -> [a]++ (concatMap :: (a -> [b]) -> [a] -> [b]concatMap (\line -> "\n  " (++) :: [a] -> [a] -> [a]++ unwords :: [String] -> Stringunwords line :: [String]line) (.) :: (b -> c) -> (a -> b) -> a -> c. wrapLine :: Int -> [String] -> [[String]]wrapLine 77 (.) :: (b -> c) -> (a -> b) -> a -> c. sort :: Ord a => [a] -> [a]sort)
     [ programName :: Program -> StringprogramName prog :: Programprog | (prog, _) <- knownPrograms :: ProgramDb -> [(Program, Maybe ConfiguredProgram)]knownPrograms progConf :: ProgramConfigurationprogConf ]
  (++) :: [a] -> [a] -> [a]++ "\n"

programConfigurationPaths
  :: ProgramConfiguration
  -> ShowOrParseArgs
  -> (flags -> [(String, FilePath)])
  -> ([(String, FilePath)] -> (flags -> flags))
  -> [OptionField flags]
programConfigurationPaths progConf showOrParseArgs get set =
  case showOrParseArgs :: ShowOrParseArgsshowOrParseArgs of
    -- we don't want a verbose help text list so we just show a generic one:
    ShowArgs  -> [withProgramPath :: [Char] -> OptionField flagswithProgramPath "PROG"]
    ParseArgs -> map :: (a -> b) -> [a] -> [b]map (withProgramPath :: [Char] -> OptionField flagswithProgramPath (.) :: (b -> c) -> (a -> b) -> a -> c. programName :: Program -> StringprogramName (.) :: (b -> c) -> (a -> b) -> a -> c. fst :: (a, b) -> afst) (knownPrograms :: ProgramDb -> [(Program, Maybe ConfiguredProgram)]knownPrograms progConf :: ProgramConfigurationprogConf)
  where
    withProgramPath prog =
      option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" ["with-" (++) :: [a] -> [a] -> [a]++ prog :: Programprog]
        ("give the path to " (++) :: [a] -> [a] -> [a]++ prog :: Programprog)
        get :: b -> Flag PathTemplateget set :: Boolset
        (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "PATH" (\path -> [(prog :: Programprog, path :: FilePathpath)])
          (\progPaths -> [ path :: FilePathpath | (prog', path) <- progPaths :: [(String, FilePath)]progPaths, prog :: Programprog(==) :: Eq a => a -> a -> Bool==prog' :: Stringprog' ]))

programConfigurationOptions
  :: ProgramConfiguration
  -> ShowOrParseArgs
  -> (flags -> [(String, [String])])
  -> ([(String, [String])] -> (flags -> flags))
  -> [OptionField flags]
programConfigurationOptions progConf showOrParseArgs get set =
  case showOrParseArgs :: ShowOrParseArgsshowOrParseArgs of
    -- we don't want a verbose help text list so we just show a generic one:
    ShowArgs  -> [programOptions :: [Char] -> OptionField flagsprogramOptions  "PROG", programOption :: [Char] -> OptionField flagsprogramOption   "PROG"]
    ParseArgs -> map :: (a -> b) -> [a] -> [b]map (programOptions :: [Char] -> OptionField flagsprogramOptions (.) :: (b -> c) -> (a -> b) -> a -> c. programName :: Program -> StringprogramName (.) :: (b -> c) -> (a -> b) -> a -> c. fst :: (a, b) -> afst) (knownPrograms :: ProgramDb -> [(Program, Maybe ConfiguredProgram)]knownPrograms progConf :: ProgramConfigurationprogConf)
              (++) :: [a] -> [a] -> [a]++ map :: (a -> b) -> [a] -> [b]map (programOption :: [Char] -> OptionField flagsprogramOption  (.) :: (b -> c) -> (a -> b) -> a -> c. programName :: Program -> StringprogramName (.) :: (b -> c) -> (a -> b) -> a -> c. fst :: (a, b) -> afst) (knownPrograms :: ProgramDb -> [(Program, Maybe ConfiguredProgram)]knownPrograms progConf :: ProgramConfigurationprogConf)
  where
    programOptions prog =
      option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" [prog :: Programprog (++) :: [a] -> [a] -> [a]++ "-options"]
        ("give extra options to " (++) :: [a] -> [a] -> [a]++ prog :: Programprog)
        get :: b -> Flag PathTemplateget set :: Boolset
        (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "OPTS" (\args -> [(prog :: Programprog, splitArgs :: String -> [String]splitArgs args :: Stringargs)]) (const :: a -> b -> aconst [] :: [a][]))

    programOption prog =
      option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" [prog :: Programprog (++) :: [a] -> [a] -> [a]++ "-option"]
        ("give an extra option to " (++) :: [a] -> [a] -> [a]++ prog :: Programprog (++) :: [a] -> [a] -> [a]++
         " (no need to quote options containing spaces)")
        get :: b -> Flag PathTemplateget set :: Boolset
        (reqArg' ::
  Monoid b =>
  ArgPlaceHolder
  -> (String -> b)
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg' "OPT" (\arg -> [(prog :: Programprog, [arg :: Stringarg])])
           (\progArgs -> concat :: [[a]] -> [a]concat [ args :: Stringargs | (prog', args) <- progArgs :: [(String, [String])]progArgs, prog :: Programprog(==) :: Eq a => a -> a -> Bool==prog' :: Stringprog' ]))


-- ------------------------------------------------------------
-- * GetOpt Utils
-- ------------------------------------------------------------

boolOpt :: SFlags -> SFlags -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) a
boolOpt  = boolOpt ::
  (b -> Maybe Bool)
  -> (Bool -> b)
  -> SFlags
  -> SFlags
  -> MkOptDescr (a -> b) (b -> a -> a) aCommand.boolOpt  flagToMaybe :: Flag a -> Maybe aflagToMaybe Flag :: a -> Flag aFlag

boolOpt' :: OptFlags -> OptFlags -> MkOptDescr (a -> Flag Bool) (Flag Bool -> a -> a) a
boolOpt' = boolOpt' ::
  (b -> Maybe Bool)
  -> (Bool -> b)
  -> OptFlags
  -> OptFlags
  -> MkOptDescr (a -> b) (b -> a -> a) aCommand.boolOpt' flagToMaybe :: Flag a -> Maybe aflagToMaybe Flag :: a -> Flag aFlag

trueArg, falseArg :: SFlags -> LFlags -> Description -> (b -> Flag Bool) ->
                     (Flag Bool -> (b -> b)) -> OptDescr b
trueArg  = noArg ::
  (Eq b, Monoid b) => b -> MkOptDescr (a -> b) (b -> a -> a) anoArg (Flag :: a -> Flag aFlag True :: BoolTrue)
falseArg = noArg ::
  (Eq b, Monoid b) => b -> MkOptDescr (a -> b) (b -> a -> a) anoArg (Flag :: a -> Flag aFlag False :: BoolFalse)

reqArgFlag :: ArgPlaceHolder -> SFlags -> LFlags -> Description ->
              (b -> Flag String) -> (Flag String -> b -> b) -> OptDescr b
reqArgFlag ad = reqArg ::
  Monoid b =>
  ArgPlaceHolder
  -> ReadE b
  -> (b -> [String])
  -> MkOptDescr (a -> b) (b -> a -> a) areqArg ad :: ArgPlaceHolderad (succeedReadE :: (String -> a) -> ReadE asucceedReadE Flag :: a -> Flag aFlag) flagToList :: Flag a -> [a]flagToList

optionDistPref :: (flags -> Flag FilePath)
               -> (Flag FilePath -> flags -> flags)
               -> ShowOrParseArgs
               -> OptionField flags
optionDistPref get set = \showOrParseArgs ->
  option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "" (distPrefFlagName :: ShowOrParseArgs -> [[Char]]distPrefFlagName showOrParseArgs :: ShowOrParseArgsshowOrParseArgs)
    (   "The directory where Cabal puts generated build files "
     (++) :: [a] -> [a] -> [a]++ "(default " (++) :: [a] -> [a] -> [a]++ defaultDistPref :: FilePathdefaultDistPref (++) :: [a] -> [a] -> [a]++ ")")
    get :: b -> Flag PathTemplateget set :: Boolset
    (reqArgFlag ::
  ArgPlaceHolder
  -> SFlags
  -> LFlags
  -> Description
  -> (b -> Flag String)
  -> (Flag String -> b -> b)
  -> OptDescr breqArgFlag "DIR")
  where
    distPrefFlagName ShowArgs  = ["builddir"]
    distPrefFlagName ParseArgs = ["builddir", "distdir", "distpref"]

optionVerbosity :: (flags -> Flag Verbosity)
                -> (Flag Verbosity -> flags -> flags)
                -> OptionField flags
optionVerbosity get set =
  option ::
  SFlags
  -> LFlags
  -> Description
  -> get
  -> set
  -> MkOptDescr get set a
  -> OptionField aoption "v" ["verbose"]
    "Control verbosity (n is 0--3, default verbosity level is 1)"
    get :: b -> Flag PathTemplateget set :: Boolset
    (optArg ::
  Monoid b =>
  ArgPlaceHolder
  -> ReadE b
  -> b
  -> (b -> [Maybe String])
  -> MkOptDescr (a -> b) (b -> a -> a) aoptArg "n" (fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap Flag :: a -> Flag aFlag flagToVerbosity :: ReadE VerbosityflagToVerbosity)
                (Flag :: a -> Flag aFlag verbose :: Verbosityverbose) -- default Value if no n is given
                (fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap (Just :: a -> Maybe aJust (.) :: (b -> c) -> (a -> b) -> a -> c. showForCabal :: Verbosity -> StringshowForCabal) (.) :: (b -> c) -> (a -> b) -> a -> c. flagToList :: Flag a -> [a]flagToList))

-- ------------------------------------------------------------
-- * Other Utils
-- ------------------------------------------------------------

-- | Arguments to pass to a @configure@ script, e.g. generated by
-- @autoconf@.
configureArgs :: Bool -> ConfigFlags -> [String]
configureArgs bcHack flags
  = hc_flag :: [[Char]]hc_flag
 (++) :: [a] -> [a] -> [a]++ optFlag :: [Char] -> (ConfigFlags -> Flag [Char]) -> [[Char]]optFlag  "with-hc-pkg" configHcPkg :: ConfigFlags -> Flag FilePathconfigHcPkg
 (++) :: [a] -> [a] -> [a]++ optFlag' ::
  [Char]
  -> (InstallDirs (Flag PathTemplate) -> Flag PathTemplate)
  -> [[Char]]optFlag' "prefix"      prefix :: InstallDirs dir -> dirprefix
 (++) :: [a] -> [a] -> [a]++ optFlag' ::
  [Char]
  -> (InstallDirs (Flag PathTemplate) -> Flag PathTemplate)
  -> [[Char]]optFlag' "bindir"      bindir :: InstallDirs dir -> dirbindir
 (++) :: [a] -> [a] -> [a]++ optFlag' ::
  [Char]
  -> (InstallDirs (Flag PathTemplate) -> Flag PathTemplate)
  -> [[Char]]optFlag' "libdir"      libdir :: InstallDirs dir -> dirlibdir
 (++) :: [a] -> [a] -> [a]++ optFlag' ::
  [Char]
  -> (InstallDirs (Flag PathTemplate) -> Flag PathTemplate)
  -> [[Char]]optFlag' "libexecdir"  libexecdir :: InstallDirs dir -> dirlibexecdir
 (++) :: [a] -> [a] -> [a]++ optFlag' ::
  [Char]
  -> (InstallDirs (Flag PathTemplate) -> Flag PathTemplate)
  -> [[Char]]optFlag' "datadir"     datadir :: InstallDirs dir -> dirdatadir
 (++) :: [a] -> [a] -> [a]++ configConfigureArgs :: ConfigFlags -> [String]configConfigureArgs flags :: TestFlagsflags
  where
        hc_flag = case (configHcFlavor :: ConfigFlags -> Flag CompilerFlavorconfigHcFlavor flags :: TestFlagsflags, configHcPath :: ConfigFlags -> Flag FilePathconfigHcPath flags :: TestFlagsflags) of
                        (_, Flag hc_path) -> [hc_flag_name :: [Char]hc_flag_name (++) :: [a] -> [a] -> [a]++ hc_path :: FilePathhc_path]
                        (Flag hc, NoFlag) -> [hc_flag_name :: [Char]hc_flag_name (++) :: [a] -> [a] -> [a]++ display :: Text a => a -> Stringdisplay hc :: CompilerFlavorhc]
                        (NoFlag,NoFlag)   -> [] :: [a][]
        hc_flag_name
            --TODO kill off thic bc hack when defaultUserHooks is removed.
            | bcHack :: BoolbcHack    = "--with-hc="
            | otherwise :: Boolotherwise = "--with-compiler="
        optFlag name config_field = case config_field ::
  InstallDirs (Flag PathTemplate) -> Flag PathTemplateconfig_field flags :: TestFlagsflags of
                        Flag p -> ["--" (++) :: [a] -> [a] -> [a]++ name :: [Char]name (++) :: [a] -> [a] -> [a]++ "=" (++) :: [a] -> [a] -> [a]++ p :: FilePathp]
                        NoFlag -> [] :: [a][]
        optFlag' name config_field = optFlag :: [Char] -> (ConfigFlags -> Flag [Char]) -> [[Char]]optFlag name :: [Char]name (fmap :: Functor f => forall a b. (a -> b) -> f a -> f bfmap fromPathTemplate :: PathTemplate -> FilePathfromPathTemplate
                                                 (.) :: (b -> c) -> (a -> b) -> a -> c. config_field ::
  InstallDirs (Flag PathTemplate) -> Flag PathTemplateconfig_field
                                                 (.) :: (b -> c) -> (a -> b) -> a -> c. configInstallDirs :: ConfigFlags -> InstallDirs (Flag PathTemplate)configInstallDirs)

configureCCompiler :: Verbosity -> ProgramConfiguration -> IO (FilePath, [String])
configureCCompiler verbosity lbi = configureProg ::
  Verbosity
  -> ProgramConfiguration
  -> Program
  -> IO (FilePath, [String])configureProg verbosity :: Verbosityverbosity lbi :: ProgramConfigurationlbi gccProgram :: ProgramgccProgram

configureLinker :: Verbosity -> ProgramConfiguration -> IO (FilePath, [String])
configureLinker verbosity lbi = configureProg ::
  Verbosity
  -> ProgramConfiguration
  -> Program
  -> IO (FilePath, [String])configureProg verbosity :: Verbosityverbosity lbi :: ProgramConfigurationlbi ldProgram :: ProgramldProgram

configureProg :: Verbosity -> ProgramConfiguration -> Program -> IO (FilePath, [String])
configureProg verbosity programConfig prog = do
    (p, _) <- requireProgram ::
  Verbosity
  -> Program
  -> ProgramDb
  -> IO (ConfiguredProgram, ProgramDb)requireProgram verbosity :: Verbosityverbosity prog :: Programprog programConfig :: ProgramConfigurationprogramConfig
    let pInv = programInvocation ::
  ConfiguredProgram -> [String] -> ProgramInvocationprogramInvocation p :: FilePathp [] :: [a][]
    return :: Monad m => forall a. a -> m areturn (progInvokePath :: ProgramInvocation -> FilePathprogInvokePath pInv :: ProgramInvocationpInv, progInvokeArgs :: ProgramInvocation -> [String]progInvokeArgs pInv :: ProgramInvocationpInv)

-- | Helper function to split a string into a list of arguments.
-- It's supposed to handle quoted things sensibly, eg:
--
-- > splitArgs "--foo=\"C:\Program Files\Bar\" --baz"
-- >   = ["--foo=C:\Program Files\Bar", "--baz"]
--
splitArgs :: String -> [String]
splitArgs  = space :: String -> String -> [String]space [] :: [a][]
  where
    space :: String -> String -> [String]
    space w []      = word :: [a] -> [[a]] -> [[a]]word w :: Stringw [] :: [a][]
    space w ( c :s)
        | isSpace :: Char -> BoolisSpace c :: ac = word :: [a] -> [[a]] -> [[a]]word w :: Stringw (space :: String -> String -> [String]space [] :: [a][] s :: Strings)
    space w ('"':s) = string :: String -> String -> [String]string w :: Stringw s :: Strings
    space w s       = nonstring :: String -> String -> [String]nonstring w :: Stringw s :: Strings

    string :: String -> String -> [String]
    string w []      = word :: [a] -> [[a]] -> [[a]]word w :: Stringw [] :: [a][]
    string w ('"':s) = space :: String -> String -> [String]space w :: Stringw s :: Strings
    string w ( c :s) = string :: String -> String -> [String]string (c :: ac(:) :: a -> [a] -> [a]:w :: Stringw) s :: Strings

    nonstring :: String -> String -> [String]
    nonstring w  []      = word :: [a] -> [[a]] -> [[a]]word w :: Stringw [] :: [a][]
    nonstring w  ('"':s) = string :: String -> String -> [String]string w :: Stringw s :: Strings
    nonstring w  ( c :s) = space :: String -> String -> [String]space (c :: ac(:) :: a -> [a] -> [a]:w :: Stringw) s :: Strings

    word [] s = s :: Strings
    word w  s = reverse :: [a] -> [a]reverse w :: Stringw (:) :: a -> [a] -> [a]: s :: Strings

-- The test cases kinda have to be rewritten from the ground up... :/
--hunitTests :: [Test]
--hunitTests =
--    let m = [("ghc", GHC), ("nhc98", NHC), ("hugs", Hugs)]
--        (flags, commands', unkFlags, ers)
--               = getOpt Permute options ["configure", "foobar", "--prefix=/foo", "--ghc", "--nhc98", "--hugs", "--with-compiler=/comp", "--unknown1", "--unknown2", "--install-prefix=/foo", "--user", "--global"]
--       in  [TestLabel "very basic option parsing" $ TestList [
--                 "getOpt flags" ~: "failed" ~:
--                 [Prefix "/foo", GhcFlag, NhcFlag, HugsFlag,
--                  WithCompiler "/comp", InstPrefix "/foo", UserFlag, GlobalFlag]
--                 ~=? flags,
--                 "getOpt commands" ~: "failed" ~: ["configure", "foobar"] ~=? commands',
--                 "getOpt unknown opts" ~: "failed" ~:
--                      ["--unknown1", "--unknown2"] ~=? unkFlags,
--                 "getOpt errors" ~: "failed" ~: [] ~=? ers],
--
--               TestLabel "test location of various compilers" $ TestList
--               ["configure parsing for prefix and compiler flag" ~: "failed" ~:
--                    (Right (ConfigCmd (Just comp, Nothing, Just "/usr/local"), []))
--                   ~=? (parseArgs ["--prefix=/usr/local", "--"++name, "configure"])
--                   | (name, comp) <- m],
--
--               TestLabel "find the package tool" $ TestList
--               ["configure parsing for prefix comp flag, withcompiler" ~: "failed" ~:
--                    (Right (ConfigCmd (Just comp, Just "/foo/comp", Just "/usr/local"), []))
--                   ~=? (parseArgs ["--prefix=/usr/local", "--"++name,
--                                   "--with-compiler=/foo/comp", "configure"])
--                   | (name, comp) <- m],
--
--               TestLabel "simpler commands" $ TestList
--               [flag ~: "failed" ~: (Right (flagCmd, [])) ~=? (parseArgs [flag])
--                   | (flag, flagCmd) <- [("build", BuildCmd),
--                                         ("install", InstallCmd Nothing False),
--                                         ("sdist", SDistCmd),
--                                         ("register", RegisterCmd False)]
--                  ]
--               ]

{- Testing ideas:
   * IO to look for hugs and hugs-pkg (which hugs, etc)
   * quickCheck to test permutations of arguments
   * what other options can we over-ride with a command-line flag?
-}