{-# LANGUAGE DeriveDataTypeable #-} module Distribution.Client.SavedFlags ( readCommandFlags, writeCommandFlags , readSavedArgs, writeSavedArgs ) where import Distribution.Simple.Command import Distribution.Simple.UserHooks ( Args ) import Distribution.Simple.Utils ( createDirectoryIfMissingVerbose, unintersperse ) import Distribution.Verbosity import Control.Exception ( Exception, throwIO ) import Control.Monad ( liftM ) import Data.List ( intercalate ) import Data.Maybe ( fromMaybe ) import Data.Typeable import System.Directory ( doesFileExist ) import System.FilePath ( takeDirectory ) writeSavedArgs :: Verbosity -> FilePath -> [String] -> IO () writeSavedArgs verbosity path args = do createDirectoryIfMissingVerbose (lessVerbose verbosity) True (takeDirectory path) writeFile path (intercalate "\0" args) -- | Write command-line flags to a file, separated by null characters. This -- format is also suitable for the @xargs -0@ command. Using the null -- character also avoids the problem of escaping newlines or spaces, -- because unlike other whitespace characters, the null character is -- not valid in command-line arguments. writeCommandFlags :: Verbosity -> FilePath -> CommandUI flags -> flags -> IO () writeCommandFlags verbosity path command flags = writeSavedArgs verbosity path (commandShowOptions command flags) readSavedArgs :: FilePath -> IO (Maybe [String]) readSavedArgs path = do exists <- doesFileExist path if exists then liftM (Just . unintersperse '\0') (readFile path) else return Nothing -- | Read command-line arguments, separated by null characters, from a file. -- Returns the default flags if the file does not exist. readCommandFlags :: FilePath -> CommandUI flags -> IO flags readCommandFlags path command = do savedArgs <- liftM (fromMaybe []) (readSavedArgs path) case (commandParseArgs command True savedArgs) of CommandHelp _ -> throwIO (SavedArgsErrorHelp savedArgs) CommandList _ -> throwIO (SavedArgsErrorList savedArgs) CommandErrors errs -> throwIO (SavedArgsErrorOther savedArgs errs) CommandReadyToGo (mkFlags, _) -> return (mkFlags (commandDefaultFlags command)) -- ----------------------------------------------------------------------------- -- * Exceptions -- ----------------------------------------------------------------------------- data SavedArgsError = SavedArgsErrorHelp Args | SavedArgsErrorList Args | SavedArgsErrorOther Args [String] deriving (Typeable) instance Show SavedArgsError where show (SavedArgsErrorHelp args) = "unexpected flag '--help', saved command line was:\n" ++ intercalate " " args show (SavedArgsErrorList args) = "unexpected flag '--list-options', saved command line was:\n" ++ intercalate " " args show (SavedArgsErrorOther args errs) = "saved command line was:\n" ++ intercalate " " args ++ "\n" ++ "encountered errors:\n" ++ intercalate "\n" errs instance Exception SavedArgsError