{-# LANGUAGE LambdaCase #-} module Hpack.Options where import Imports import Data.Maybe import System.FilePath import System.Directory data ParseResult = Help | PrintVersion | PrintNumericVersion | Run ParseOptions | ParseError deriving (ParseResult -> ParseResult -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: ParseResult -> ParseResult -> Bool $c/= :: ParseResult -> ParseResult -> Bool == :: ParseResult -> ParseResult -> Bool $c== :: ParseResult -> ParseResult -> Bool Eq, Int -> ParseResult -> ShowS [ParseResult] -> ShowS ParseResult -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [ParseResult] -> ShowS $cshowList :: [ParseResult] -> ShowS show :: ParseResult -> String $cshow :: ParseResult -> String showsPrec :: Int -> ParseResult -> ShowS $cshowsPrec :: Int -> ParseResult -> ShowS Show) data Verbose = Verbose | NoVerbose deriving (Verbose -> Verbose -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Verbose -> Verbose -> Bool $c/= :: Verbose -> Verbose -> Bool == :: Verbose -> Verbose -> Bool $c== :: Verbose -> Verbose -> Bool Eq, Int -> Verbose -> ShowS [Verbose] -> ShowS Verbose -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Verbose] -> ShowS $cshowList :: [Verbose] -> ShowS show :: Verbose -> String $cshow :: Verbose -> String showsPrec :: Int -> Verbose -> ShowS $cshowsPrec :: Int -> Verbose -> ShowS Show) data Force = Force | NoForce deriving (Force -> Force -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: Force -> Force -> Bool $c/= :: Force -> Force -> Bool == :: Force -> Force -> Bool $c== :: Force -> Force -> Bool Eq, Int -> Force -> ShowS [Force] -> ShowS Force -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [Force] -> ShowS $cshowList :: [Force] -> ShowS show :: Force -> String $cshow :: Force -> String showsPrec :: Int -> Force -> ShowS $cshowsPrec :: Int -> Force -> ShowS Show) data OutputStrategy = CanonicalOutput | MinimizeDiffs deriving (OutputStrategy -> OutputStrategy -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: OutputStrategy -> OutputStrategy -> Bool $c/= :: OutputStrategy -> OutputStrategy -> Bool == :: OutputStrategy -> OutputStrategy -> Bool $c== :: OutputStrategy -> OutputStrategy -> Bool Eq, Int -> OutputStrategy -> ShowS [OutputStrategy] -> ShowS OutputStrategy -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [OutputStrategy] -> ShowS $cshowList :: [OutputStrategy] -> ShowS show :: OutputStrategy -> String $cshow :: OutputStrategy -> String showsPrec :: Int -> OutputStrategy -> ShowS $cshowsPrec :: Int -> OutputStrategy -> ShowS Show) data ParseOptions = ParseOptions { ParseOptions -> Verbose parseOptionsVerbose :: Verbose , ParseOptions -> Force parseOptionsForce :: Force , ParseOptions -> Maybe Bool parseOptionsHash :: Maybe Bool , ParseOptions -> Bool parseOptionsToStdout :: Bool , ParseOptions -> String parseOptionsTarget :: FilePath , ParseOptions -> OutputStrategy parseOptionsOutputStrategy :: OutputStrategy } deriving (ParseOptions -> ParseOptions -> Bool forall a. (a -> a -> Bool) -> (a -> a -> Bool) -> Eq a /= :: ParseOptions -> ParseOptions -> Bool $c/= :: ParseOptions -> ParseOptions -> Bool == :: ParseOptions -> ParseOptions -> Bool $c== :: ParseOptions -> ParseOptions -> Bool Eq, Int -> ParseOptions -> ShowS [ParseOptions] -> ShowS ParseOptions -> String forall a. (Int -> a -> ShowS) -> (a -> String) -> ([a] -> ShowS) -> Show a showList :: [ParseOptions] -> ShowS $cshowList :: [ParseOptions] -> ShowS show :: ParseOptions -> String $cshow :: ParseOptions -> String showsPrec :: Int -> ParseOptions -> ShowS $cshowsPrec :: Int -> ParseOptions -> ShowS Show) parseOptions :: FilePath -> [String] -> IO ParseResult parseOptions :: String -> [String] -> IO ParseResult parseOptions String defaultTarget = \ case [String "--version"] -> forall (m :: * -> *) a. Monad m => a -> m a return ParseResult PrintVersion [String "--numeric-version"] -> forall (m :: * -> *) a. Monad m => a -> m a return ParseResult PrintNumericVersion [String "--help"] -> forall (m :: * -> *) a. Monad m => a -> m a return ParseResult Help [String] args -> case Either ParseResult (Maybe String, Bool) targets of Right (Maybe String target, Bool toStdout) -> do String file <- String -> Maybe String -> IO String expandTarget String defaultTarget Maybe String target let options :: ParseOptions options | Bool toStdout = Verbose -> Force -> Maybe Bool -> Bool -> String -> OutputStrategy -> ParseOptions ParseOptions Verbose NoVerbose Force Force Maybe Bool hash Bool toStdout String file OutputStrategy outputStrategy | Bool otherwise = Verbose -> Force -> Maybe Bool -> Bool -> String -> OutputStrategy -> ParseOptions ParseOptions Verbose verbose Force force Maybe Bool hash Bool toStdout String file OutputStrategy outputStrategy forall (m :: * -> *) a. Monad m => a -> m a return (ParseOptions -> ParseResult Run ParseOptions options) Left ParseResult err -> forall (m :: * -> *) a. Monad m => a -> m a return ParseResult err where silentFlag :: String silentFlag = String "--silent" forceFlags :: [String] forceFlags = [String "--force", String "-f"] hashFlag :: String hashFlag = String "--hash" noHashFlag :: String noHashFlag = String "--no-hash" canonicalFlag :: String canonicalFlag = String "--canonical" flags :: [String] flags = String canonicalFlag forall a. a -> [a] -> [a] : String hashFlag forall a. a -> [a] -> [a] : String noHashFlag forall a. a -> [a] -> [a] : String silentFlag forall a. a -> [a] -> [a] : [String] forceFlags verbose :: Verbose verbose :: Verbose verbose = if String silentFlag forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool `elem` [String] args then Verbose NoVerbose else Verbose Verbose outputStrategy :: OutputStrategy outputStrategy :: OutputStrategy outputStrategy = if String canonicalFlag forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool `elem` [String] args then OutputStrategy CanonicalOutput else OutputStrategy MinimizeDiffs force :: Force force :: Force force = if forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Bool any (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool `elem` [String] args) [String] forceFlags then Force Force else Force NoForce hash :: Maybe Bool hash :: Maybe Bool hash = forall a. [a] -> Maybe a listToMaybe forall b c a. (b -> c) -> (a -> b) -> a -> c . forall a. [a] -> [a] reverse forall a b. (a -> b) -> a -> b $ forall a b. (a -> Maybe b) -> [a] -> [b] mapMaybe String -> Maybe Bool parse [String] args where parse :: String -> Maybe Bool parse :: String -> Maybe Bool parse String t = Bool True forall (f :: * -> *) a b. Functor f => a -> f b -> f a <$ forall (f :: * -> *). Alternative f => Bool -> f () guard (String t forall a. Eq a => a -> a -> Bool == String hashFlag) forall (f :: * -> *) a. Alternative f => f a -> f a -> f a <|> Bool False forall (f :: * -> *) a b. Functor f => a -> f b -> f a <$ forall (f :: * -> *). Alternative f => Bool -> f () guard (String t forall a. Eq a => a -> a -> Bool == String noHashFlag) ys :: [String] ys = forall a. (a -> Bool) -> [a] -> [a] filter (forall (t :: * -> *) a. (Foldable t, Eq a) => a -> t a -> Bool `notElem` [String] flags) [String] args targets :: Either ParseResult (Maybe FilePath, Bool) targets :: Either ParseResult (Maybe String, Bool) targets = case [String] ys of [String "-"] -> forall a b. b -> Either a b Right (forall a. Maybe a Nothing, Bool True) [String "-", String "-"] -> forall a b. a -> Either a b Left ParseResult ParseError [String path] -> forall a b. b -> Either a b Right (forall a. a -> Maybe a Just String path, Bool False) [String path, String "-"] -> forall a b. b -> Either a b Right (forall a. a -> Maybe a Just String path, Bool True) [] -> forall a b. b -> Either a b Right (forall a. Maybe a Nothing, Bool False) [String] _ -> forall a b. a -> Either a b Left ParseResult ParseError expandTarget :: FilePath -> Maybe FilePath -> IO FilePath expandTarget :: String -> Maybe String -> IO String expandTarget String defaultTarget = \ case Maybe String Nothing -> forall (m :: * -> *) a. Monad m => a -> m a return String defaultTarget Just String "" -> forall (m :: * -> *) a. Monad m => a -> m a return String defaultTarget Just String target -> do Bool isFile <- String -> IO Bool doesFileExist String target Bool isDirectory <- String -> IO Bool doesDirectoryExist String target forall (m :: * -> *) a. Monad m => a -> m a return forall a b. (a -> b) -> a -> b $ case ShowS takeFileName String target of String _ | Bool isFile -> String target String _ | Bool isDirectory -> String target String -> ShowS </> String defaultTarget String "" -> String target String -> ShowS </> String defaultTarget String _ -> String target