module Require where import qualified Data.Text as Text import Options.Generic import Relude import System.Directory import qualified Require.Error as Error import qualified Require.File as File import Require.Transform import Require.Types data CommandArguments = CommandArguments Text Text Text deriving ((forall x. CommandArguments -> Rep CommandArguments x) -> (forall x. Rep CommandArguments x -> CommandArguments) -> Generic CommandArguments forall x. Rep CommandArguments x -> CommandArguments forall x. CommandArguments -> Rep CommandArguments x forall a. (forall x. a -> Rep a x) -> (forall x. Rep a x -> a) -> Generic a $cto :: forall x. Rep CommandArguments x -> CommandArguments $cfrom :: forall x. CommandArguments -> Rep CommandArguments x Generic) instance ParseRecord CommandArguments findRequires :: IO (Maybe File.Name) findRequires :: IO (Maybe Name) findRequires = do FilePath currentDir <- IO FilePath getCurrentDirectory [FilePath] files <- FilePath -> IO [FilePath] getDirectoryContents FilePath currentDir let textFiles :: [Text] textFiles = (FilePath -> Text) -> [FilePath] -> [Text] forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b fmap FilePath -> Text forall a. ToText a => a -> Text toText [FilePath] files Maybe Name -> IO (Maybe Name) forall (m :: * -> *) a. Monad m => a -> m a return (Maybe Name -> IO (Maybe Name)) -> Maybe Name -> IO (Maybe Name) forall a b. (a -> b) -> a -> b $ Text -> Name File.Name (Text -> Name) -> (NonEmpty Text -> Text) -> NonEmpty Text -> Name forall b c a. (b -> c) -> (a -> b) -> a -> c . NonEmpty Text -> Text forall (f :: * -> *) a. IsNonEmpty f a a "head" => f a -> a head (NonEmpty Text -> Name) -> Maybe (NonEmpty Text) -> Maybe Name forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b <$> [Text] -> Maybe (NonEmpty Text) forall a. [a] -> Maybe (NonEmpty a) nonEmpty ((Text -> Bool) -> [Text] -> [Text] forall a. (a -> Bool) -> [a] -> [a] filter (Text -> Text -> Bool Text.isSuffixOf Text "Requires") [Text] textFiles) requireMain :: IO () requireMain :: IO () requireMain = do CommandArguments Text inputFile Text _ Text outputFile <- Text -> IO CommandArguments forall (io :: * -> *) a. (MonadIO io, ParseRecord a) => Text -> io a getRecord Text "Require Haskell preprocessor" :: IO CommandArguments Maybe Name requiresFile <- IO (Maybe Name) findRequires AutorequireMode Name -> Name -> Name -> IO () run (Maybe Name -> AutorequireMode Name forall a. Maybe a -> AutorequireMode a AutorequireOnDirective Maybe Name requiresFile) (Text -> Name File.Name Text inputFile) (Text -> Name File.Name Text outputFile) autorequireMain :: IO () autorequireMain :: IO () autorequireMain = do CommandArguments Text inputFile Text _ Text outputFile <- Text -> IO CommandArguments forall (io :: * -> *) a. (MonadIO io, ParseRecord a) => Text -> io a getRecord Text "Require Haskell preprocessor" :: IO CommandArguments Maybe Name requiresFile <- IO (Maybe Name) findRequires case Maybe Name requiresFile of Maybe Name Nothing -> Name -> Error -> IO () forall a. Name -> Error -> IO a Error.die (Text -> Name File.Name Text inputFile) Error Error.MissingRequiresFile Just Name fn -> AutorequireMode Name -> Name -> Name -> IO () run (Name -> AutorequireMode Name forall a. a -> AutorequireMode a AutorequireEnabled Name fn) (Text -> Name File.Name Text inputFile) (Text -> Name File.Name Text outputFile) run :: AutorequireMode File.Name -> File.Name -> File.Name -> IO () run :: AutorequireMode Name -> Name -> Name -> IO () run AutorequireMode Name autoMode Name inputFile Name outputFile = do Input input <- Name -> IO Input File.read Name inputFile AutorequireMode Input autoInput <- (Name -> IO Input) -> AutorequireMode Name -> IO (AutorequireMode Input) forall (t :: * -> *) (f :: * -> *) a b. (Traversable t, Applicative f) => (a -> f b) -> t a -> f (t b) traverse Name -> IO Input File.read AutorequireMode Name autoMode case AutorequireMode Input -> Input -> Either Error [Text] transform AutorequireMode Input autoInput Input input of Left Error err -> Name -> Error -> IO () forall a. Name -> Error -> IO a Error.die Name inputFile Error err Right [Text] ls -> Name -> [Text] -> IO () File.writeLines Name outputFile [Text] ls