module Extensions.Package
(
getPackageExtentions
, getPackageExtentionsBySources
, getModuleAndCabalExtentions
, getModuleExtentions
, getModuleAndCabalExtentionsBySource
, getModuleExtentionsBySource
) where
import Control.Exception (catch)
import Data.ByteString (ByteString)
import Data.Functor ((<&>))
import Data.Map.Merge.Strict (mapMissing, merge, zipWithMatched)
import Data.Map.Strict (Map)
import Extensions.Cabal (parseCabalFileExtensions)
import Extensions.Module (parseFile, parseSourceWithPath)
import Extensions.Types (CabalAndModuleExtensions (..), CabalException, ExtensionsError (..),
ExtensionsResult, ModuleParseError, ParsedExtensions (..),
mergeAnyExtensions)
import qualified Data.Map.Strict as Map
getPackageExtentions
:: FilePath
-> IO (Map FilePath ExtensionsResult)
getPackageExtentions :: FilePath -> IO (Map FilePath ExtensionsResult)
getPackageExtentions cabalFile :: FilePath
cabalFile = do
Map FilePath ParsedExtensions
cabalMap <- FilePath -> IO (Map FilePath ParsedExtensions)
parseCabalFileExtensions FilePath
cabalFile
(FilePath -> ParsedExtensions -> IO ExtensionsResult)
-> Map FilePath ParsedExtensions
-> IO (Map FilePath ExtensionsResult)
forall (t :: * -> *) k a b.
Applicative t =>
(k -> a -> t b) -> Map k a -> t (Map k b)
Map.traverseWithKey FilePath -> ParsedExtensions -> IO ExtensionsResult
perModuleParseMerge Map FilePath ParsedExtensions
cabalMap
where
perModuleParseMerge :: FilePath -> ParsedExtensions -> IO ExtensionsResult
perModuleParseMerge :: FilePath -> ParsedExtensions -> IO ExtensionsResult
perModuleParseMerge path :: FilePath
path cabalExts :: ParsedExtensions
cabalExts = do
Either ModuleParseError ParsedExtensions
moduleRes <- FilePath -> IO (Either ModuleParseError ParsedExtensions)
parseFile FilePath
path
ExtensionsResult -> IO ExtensionsResult
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExtensionsResult -> IO ExtensionsResult)
-> ExtensionsResult -> IO ExtensionsResult
forall a b. (a -> b) -> a -> b
$ ParsedExtensions
-> FilePath
-> Either ModuleParseError ParsedExtensions
-> ExtensionsResult
mergeCabalAndModule ParsedExtensions
cabalExts FilePath
path Either ModuleParseError ParsedExtensions
moduleRes
getPackageExtentionsBySources
:: FilePath
-> Map FilePath ByteString
-> IO (Map FilePath ExtensionsResult)
getPackageExtentionsBySources :: FilePath
-> Map FilePath ByteString -> IO (Map FilePath ExtensionsResult)
getPackageExtentionsBySources cabalFile :: FilePath
cabalFile sourcesMap :: Map FilePath ByteString
sourcesMap =
FilePath
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
parseCabalHandleException FilePath
cabalFile IO (Either ExtensionsError (Map FilePath ParsedExtensions))
-> (Either ExtensionsError (Map FilePath ParsedExtensions)
-> Map FilePath ExtensionsResult)
-> IO (Map FilePath ExtensionsResult)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
Left err :: ExtensionsError
err -> ExtensionsError -> ExtensionsResult
forall a b. a -> Either a b
Left ExtensionsError
err ExtensionsResult
-> Map FilePath ByteString -> Map FilePath ExtensionsResult
forall (f :: * -> *) a b. Functor f => a -> f b -> f a
<$ Map FilePath ByteString
sourcesMap
Right cabalMap :: Map FilePath ParsedExtensions
cabalMap -> SimpleWhenMissing FilePath ParsedExtensions ExtensionsResult
-> SimpleWhenMissing FilePath ByteString ExtensionsResult
-> SimpleWhenMatched
FilePath ParsedExtensions ByteString ExtensionsResult
-> Map FilePath ParsedExtensions
-> Map FilePath ByteString
-> Map FilePath ExtensionsResult
forall k a c b.
Ord k =>
SimpleWhenMissing k a c
-> SimpleWhenMissing k b c
-> SimpleWhenMatched k a b c
-> Map k a
-> Map k b
-> Map k c
merge
((FilePath -> ParsedExtensions -> ExtensionsResult)
-> SimpleWhenMissing FilePath ParsedExtensions ExtensionsResult
forall (f :: * -> *) k x y.
Applicative f =>
(k -> x -> y) -> WhenMissing f k x y
mapMissing FilePath -> ParsedExtensions -> ExtensionsResult
cabalNotSource)
((FilePath -> ByteString -> ExtensionsResult)
-> SimpleWhenMissing FilePath ByteString ExtensionsResult
forall (f :: * -> *) k x y.
Applicative f =>
(k -> x -> y) -> WhenMissing f k x y
mapMissing FilePath -> ByteString -> ExtensionsResult
sourceNotCabal)
((FilePath -> ParsedExtensions -> ByteString -> ExtensionsResult)
-> SimpleWhenMatched
FilePath ParsedExtensions ByteString ExtensionsResult
forall (f :: * -> *) k x y z.
Applicative f =>
(k -> x -> y -> z) -> WhenMatched f k x y z
zipWithMatched FilePath -> ParsedExtensions -> ByteString -> ExtensionsResult
cabalAndSource)
Map FilePath ParsedExtensions
cabalMap
Map FilePath ByteString
sourcesMap
where
cabalNotSource :: FilePath -> ParsedExtensions -> ExtensionsResult
cabalNotSource :: FilePath -> ParsedExtensions -> ExtensionsResult
cabalNotSource path :: FilePath
path _cabalExts :: ParsedExtensions
_cabalExts = ExtensionsError -> ExtensionsResult
forall a b. a -> Either a b
Left (ExtensionsError -> ExtensionsResult)
-> ExtensionsError -> ExtensionsResult
forall a b. (a -> b) -> a -> b
$ FilePath -> ExtensionsError
SourceNotFound FilePath
path
sourceNotCabal :: FilePath -> ByteString -> ExtensionsResult
sourceNotCabal :: FilePath -> ByteString -> ExtensionsResult
sourceNotCabal path :: FilePath
path _source :: ByteString
_source = ExtensionsError -> ExtensionsResult
forall a b. a -> Either a b
Left (ExtensionsError -> ExtensionsResult)
-> ExtensionsError -> ExtensionsResult
forall a b. (a -> b) -> a -> b
$ FilePath -> ExtensionsError
NotCabalModule FilePath
path
cabalAndSource
:: FilePath
-> ParsedExtensions
-> ByteString
-> ExtensionsResult
cabalAndSource :: FilePath -> ParsedExtensions -> ByteString -> ExtensionsResult
cabalAndSource path :: FilePath
path cabalExts :: ParsedExtensions
cabalExts source :: ByteString
source =
ParsedExtensions
-> FilePath
-> Either ModuleParseError ParsedExtensions
-> ExtensionsResult
mergeCabalAndModule ParsedExtensions
cabalExts FilePath
path (Either ModuleParseError ParsedExtensions -> ExtensionsResult)
-> Either ModuleParseError ParsedExtensions -> ExtensionsResult
forall a b. (a -> b) -> a -> b
$ FilePath -> ByteString -> Either ModuleParseError ParsedExtensions
parseSourceWithPath FilePath
path ByteString
source
getModuleAndCabalExtentions
:: FilePath
-> FilePath
-> IO (Either ExtensionsError CabalAndModuleExtensions)
getModuleAndCabalExtentions :: FilePath
-> FilePath -> IO (Either ExtensionsError CabalAndModuleExtensions)
getModuleAndCabalExtentions cabalFile :: FilePath
cabalFile path :: FilePath
path =
FilePath
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
parseCabalHandleException FilePath
cabalFile IO (Either ExtensionsError (Map FilePath ParsedExtensions))
-> (Either ExtensionsError (Map FilePath ParsedExtensions)
-> IO (Either ExtensionsError CabalAndModuleExtensions))
-> IO (Either ExtensionsError CabalAndModuleExtensions)
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left err :: ExtensionsError
err -> Either ExtensionsError CabalAndModuleExtensions
-> IO (Either ExtensionsError CabalAndModuleExtensions)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ExtensionsError CabalAndModuleExtensions
-> IO (Either ExtensionsError CabalAndModuleExtensions))
-> Either ExtensionsError CabalAndModuleExtensions
-> IO (Either ExtensionsError CabalAndModuleExtensions)
forall a b. (a -> b) -> a -> b
$ ExtensionsError -> Either ExtensionsError CabalAndModuleExtensions
forall a b. a -> Either a b
Left ExtensionsError
err
Right cabalMap :: Map FilePath ParsedExtensions
cabalMap -> case FilePath -> Map FilePath ParsedExtensions -> Maybe ParsedExtensions
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup FilePath
path Map FilePath ParsedExtensions
cabalMap of
Nothing -> Either ExtensionsError CabalAndModuleExtensions
-> IO (Either ExtensionsError CabalAndModuleExtensions)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ExtensionsError CabalAndModuleExtensions
-> IO (Either ExtensionsError CabalAndModuleExtensions))
-> Either ExtensionsError CabalAndModuleExtensions
-> IO (Either ExtensionsError CabalAndModuleExtensions)
forall a b. (a -> b) -> a -> b
$ ExtensionsError -> Either ExtensionsError CabalAndModuleExtensions
forall a b. a -> Either a b
Left (ExtensionsError
-> Either ExtensionsError CabalAndModuleExtensions)
-> ExtensionsError
-> Either ExtensionsError CabalAndModuleExtensions
forall a b. (a -> b) -> a -> b
$ FilePath -> ExtensionsError
NotCabalModule FilePath
path
Just cabalExts :: ParsedExtensions
cabalExts -> FilePath
-> ParsedExtensions
-> Either ModuleParseError ParsedExtensions
-> Either ExtensionsError CabalAndModuleExtensions
getCabalAndModuleExts FilePath
path ParsedExtensions
cabalExts (Either ModuleParseError ParsedExtensions
-> Either ExtensionsError CabalAndModuleExtensions)
-> IO (Either ModuleParseError ParsedExtensions)
-> IO (Either ExtensionsError CabalAndModuleExtensions)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO (Either ModuleParseError ParsedExtensions)
parseFile FilePath
path
getModuleExtentions
:: FilePath
-> FilePath
-> IO ExtensionsResult
getModuleExtentions :: FilePath -> FilePath -> IO ExtensionsResult
getModuleExtentions cabalFile :: FilePath
cabalFile path :: FilePath
path =
FilePath
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
parseCabalHandleException FilePath
cabalFile IO (Either ExtensionsError (Map FilePath ParsedExtensions))
-> (Either ExtensionsError (Map FilePath ParsedExtensions)
-> IO ExtensionsResult)
-> IO ExtensionsResult
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= \case
Left err :: ExtensionsError
err -> ExtensionsResult -> IO ExtensionsResult
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExtensionsResult -> IO ExtensionsResult)
-> ExtensionsResult -> IO ExtensionsResult
forall a b. (a -> b) -> a -> b
$ ExtensionsError -> ExtensionsResult
forall a b. a -> Either a b
Left ExtensionsError
err
Right cabalMap :: Map FilePath ParsedExtensions
cabalMap -> case FilePath -> Map FilePath ParsedExtensions -> Maybe ParsedExtensions
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup FilePath
path Map FilePath ParsedExtensions
cabalMap of
Nothing -> ExtensionsResult -> IO ExtensionsResult
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExtensionsResult -> IO ExtensionsResult)
-> ExtensionsResult -> IO ExtensionsResult
forall a b. (a -> b) -> a -> b
$ ExtensionsError -> ExtensionsResult
forall a b. a -> Either a b
Left (ExtensionsError -> ExtensionsResult)
-> ExtensionsError -> ExtensionsResult
forall a b. (a -> b) -> a -> b
$ FilePath -> ExtensionsError
NotCabalModule FilePath
path
Just cabalExts :: ParsedExtensions
cabalExts -> do
Either ModuleParseError ParsedExtensions
moduleRes <- FilePath -> IO (Either ModuleParseError ParsedExtensions)
parseFile FilePath
path
ExtensionsResult -> IO ExtensionsResult
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ExtensionsResult -> IO ExtensionsResult)
-> ExtensionsResult -> IO ExtensionsResult
forall a b. (a -> b) -> a -> b
$ ParsedExtensions
-> FilePath
-> Either ModuleParseError ParsedExtensions
-> ExtensionsResult
mergeCabalAndModule ParsedExtensions
cabalExts FilePath
path Either ModuleParseError ParsedExtensions
moduleRes
getModuleAndCabalExtentionsBySource
:: FilePath
-> FilePath
-> ByteString
-> IO (Either ExtensionsError CabalAndModuleExtensions)
getModuleAndCabalExtentionsBySource :: FilePath
-> FilePath
-> ByteString
-> IO (Either ExtensionsError CabalAndModuleExtensions)
getModuleAndCabalExtentionsBySource cabalFile :: FilePath
cabalFile path :: FilePath
path source :: ByteString
source =
FilePath
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
parseCabalHandleException FilePath
cabalFile IO (Either ExtensionsError (Map FilePath ParsedExtensions))
-> (Either ExtensionsError (Map FilePath ParsedExtensions)
-> Either ExtensionsError CabalAndModuleExtensions)
-> IO (Either ExtensionsError CabalAndModuleExtensions)
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
Left cabalError :: ExtensionsError
cabalError -> ExtensionsError -> Either ExtensionsError CabalAndModuleExtensions
forall a b. a -> Either a b
Left ExtensionsError
cabalError
Right cabalMap :: Map FilePath ParsedExtensions
cabalMap -> case FilePath -> Map FilePath ParsedExtensions -> Maybe ParsedExtensions
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup FilePath
path Map FilePath ParsedExtensions
cabalMap of
Nothing -> ExtensionsError -> Either ExtensionsError CabalAndModuleExtensions
forall a b. a -> Either a b
Left (ExtensionsError
-> Either ExtensionsError CabalAndModuleExtensions)
-> ExtensionsError
-> Either ExtensionsError CabalAndModuleExtensions
forall a b. (a -> b) -> a -> b
$ FilePath -> ExtensionsError
NotCabalModule FilePath
path
Just cabalExts :: ParsedExtensions
cabalExts -> FilePath
-> ParsedExtensions
-> Either ModuleParseError ParsedExtensions
-> Either ExtensionsError CabalAndModuleExtensions
getCabalAndModuleExts FilePath
path ParsedExtensions
cabalExts
(FilePath -> ByteString -> Either ModuleParseError ParsedExtensions
parseSourceWithPath FilePath
path ByteString
source)
getModuleExtentionsBySource
:: FilePath
-> FilePath
-> ByteString
-> IO ExtensionsResult
getModuleExtentionsBySource :: FilePath -> FilePath -> ByteString -> IO ExtensionsResult
getModuleExtentionsBySource cabalFile :: FilePath
cabalFile path :: FilePath
path source :: ByteString
source =
FilePath
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
parseCabalHandleException FilePath
cabalFile IO (Either ExtensionsError (Map FilePath ParsedExtensions))
-> (Either ExtensionsError (Map FilePath ParsedExtensions)
-> ExtensionsResult)
-> IO ExtensionsResult
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> \case
Left cabalError :: ExtensionsError
cabalError -> ExtensionsError -> ExtensionsResult
forall a b. a -> Either a b
Left ExtensionsError
cabalError
Right cabalMap :: Map FilePath ParsedExtensions
cabalMap -> case FilePath -> Map FilePath ParsedExtensions -> Maybe ParsedExtensions
forall k a. Ord k => k -> Map k a -> Maybe a
Map.lookup FilePath
path Map FilePath ParsedExtensions
cabalMap of
Nothing -> ExtensionsError -> ExtensionsResult
forall a b. a -> Either a b
Left (ExtensionsError -> ExtensionsResult)
-> ExtensionsError -> ExtensionsResult
forall a b. (a -> b) -> a -> b
$ FilePath -> ExtensionsError
NotCabalModule FilePath
path
Just cabalExts :: ParsedExtensions
cabalExts -> ParsedExtensions
-> FilePath
-> Either ModuleParseError ParsedExtensions
-> ExtensionsResult
mergeCabalAndModule ParsedExtensions
cabalExts FilePath
path
(FilePath -> ByteString -> Either ModuleParseError ParsedExtensions
parseSourceWithPath FilePath
path ByteString
source)
mergeCabalAndModule
:: ParsedExtensions
-> FilePath
-> Either ModuleParseError ParsedExtensions
-> ExtensionsResult
mergeCabalAndModule :: ParsedExtensions
-> FilePath
-> Either ModuleParseError ParsedExtensions
-> ExtensionsResult
mergeCabalAndModule cabalExts :: ParsedExtensions
cabalExts path :: FilePath
path moduleRes :: Either ModuleParseError ParsedExtensions
moduleRes = case Either ModuleParseError ParsedExtensions
moduleRes of
Right moduleExts :: ParsedExtensions
moduleExts -> ParsedExtensions -> ParsedExtensions -> ExtensionsResult
mergeAnyExtensions ParsedExtensions
cabalExts ParsedExtensions
moduleExts
Left parseErr :: ModuleParseError
parseErr -> ExtensionsError -> ExtensionsResult
forall a b. a -> Either a b
Left (ExtensionsError -> ExtensionsResult)
-> ExtensionsError -> ExtensionsResult
forall a b. (a -> b) -> a -> b
$ FilePath -> ModuleParseError -> ExtensionsError
ModuleParseError FilePath
path ModuleParseError
parseErr
parseCabalHandleException
:: FilePath
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
parseCabalHandleException :: FilePath
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
parseCabalHandleException cabalFile :: FilePath
cabalFile = (Map FilePath ParsedExtensions
-> Either ExtensionsError (Map FilePath ParsedExtensions)
forall a b. b -> Either a b
Right (Map FilePath ParsedExtensions
-> Either ExtensionsError (Map FilePath ParsedExtensions))
-> IO (Map FilePath ParsedExtensions)
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> FilePath -> IO (Map FilePath ParsedExtensions)
parseCabalFileExtensions FilePath
cabalFile)
IO (Either ExtensionsError (Map FilePath ParsedExtensions))
-> (CabalException
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions)))
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
forall e a. Exception e => IO a -> (e -> IO a) -> IO a
`catch` CabalException
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
handleCabalException
handleCabalException
:: CabalException
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
handleCabalException :: CabalException
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
handleCabalException = Either ExtensionsError (Map FilePath ParsedExtensions)
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
forall (f :: * -> *) a. Applicative f => a -> f a
pure (Either ExtensionsError (Map FilePath ParsedExtensions)
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions)))
-> (CabalException
-> Either ExtensionsError (Map FilePath ParsedExtensions))
-> CabalException
-> IO (Either ExtensionsError (Map FilePath ParsedExtensions))
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ExtensionsError
-> Either ExtensionsError (Map FilePath ParsedExtensions)
forall a b. a -> Either a b
Left (ExtensionsError
-> Either ExtensionsError (Map FilePath ParsedExtensions))
-> (CabalException -> ExtensionsError)
-> CabalException
-> Either ExtensionsError (Map FilePath ParsedExtensions)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. CabalException -> ExtensionsError
CabalError
getCabalAndModuleExts
:: FilePath
-> ParsedExtensions
-> Either ModuleParseError ParsedExtensions
-> Either ExtensionsError CabalAndModuleExtensions
getCabalAndModuleExts :: FilePath
-> ParsedExtensions
-> Either ModuleParseError ParsedExtensions
-> Either ExtensionsError CabalAndModuleExtensions
getCabalAndModuleExts path :: FilePath
path cabalExts :: ParsedExtensions
cabalExts moduleRes :: Either ModuleParseError ParsedExtensions
moduleRes = case Either ModuleParseError ParsedExtensions
moduleRes of
Left err :: ModuleParseError
err -> ExtensionsError -> Either ExtensionsError CabalAndModuleExtensions
forall a b. a -> Either a b
Left (ExtensionsError
-> Either ExtensionsError CabalAndModuleExtensions)
-> ExtensionsError
-> Either ExtensionsError CabalAndModuleExtensions
forall a b. (a -> b) -> a -> b
$ FilePath -> ModuleParseError -> ExtensionsError
ModuleParseError FilePath
path ModuleParseError
err
Right moduleExts :: ParsedExtensions
moduleExts -> CabalAndModuleExtensions
-> Either ExtensionsError CabalAndModuleExtensions
forall a b. b -> Either a b
Right (CabalAndModuleExtensions
-> Either ExtensionsError CabalAndModuleExtensions)
-> CabalAndModuleExtensions
-> Either ExtensionsError CabalAndModuleExtensions
forall a b. (a -> b) -> a -> b
$ $WCabalAndModuleExtensions :: ParsedExtensions -> ParsedExtensions -> CabalAndModuleExtensions
CabalAndModuleExtensions
{ cabalExtensions :: ParsedExtensions
cabalExtensions = ParsedExtensions
cabalExts
, moduleExtensions :: ParsedExtensions
moduleExtensions = ParsedExtensions
moduleExts
}