module Importify.Cabal.Module
( modulePaths
, splitOnExposedAndOther
) where
import Universum hiding (fromString)
import Data.List (partition)
import Distribution.ModuleName (ModuleName, fromString, toFilePath)
import qualified Distribution.ModuleName as Cabal
import Distribution.PackageDescription (BuildInfo (..), Library (..))
import qualified Language.Haskell.Exts as HSE
import Path (Abs, Dir, File, Path, Rel, parseRelDir,
parseRelFile, (</>))
import Path.IO (doesFileExist)
import Importify.Syntax (getModuleTitle)
splitOnExposedAndOther :: Library
-> [HSE.Module l]
-> ([HSE.Module l], [HSE.Module l])
splitOnExposedAndOther Library{..} =
partition ((`elem` exposedModules) . Cabal.fromString . getModuleTitle)
modulePaths :: Path Abs Dir
-> BuildInfo
-> Either [ModuleName] FilePath
-> IO [Path Abs File]
modulePaths packagePath BuildInfo{..} extra = do
let (cur, others) = partition (== ".") hsSourceDirs
case (cur, others) of
(_here, []) -> collectModulesHere
([] , paths) -> collectModulesThere paths
(_here, paths) -> liftA2 (++) collectModulesHere (collectModulesThere paths)
where
modulesToPaths :: [ModuleName] -> IO [Path Rel File]
modulesToPaths = mapM (parseRelFile . (++ ".hs") . toFilePath)
targetModulePaths :: IO [Path Rel File]
targetModulePaths = case extra of
Left modules -> modulesToPaths $ otherModules ++ modules
Right path -> liftA2 (:) (parseRelFile path) (modulesToPaths otherModules)
addDir :: Path Abs Dir -> [Path Rel File] -> [Path Abs File]
addDir dir = map (dir </>)
collectModulesHere :: IO [Path Abs File]
collectModulesHere = do
paths <- targetModulePaths
let packagePaths = addDir packagePath paths
keepExistingModules packagePaths
collectModulesThere :: [FilePath] -> IO [Path Abs File]
collectModulesThere dirs = do
dirPaths <- mapM parseRelDir dirs
modPaths <- targetModulePaths
concatForM dirPaths $ \dir ->
keepExistingModules $ addDir (packagePath </> dir) modPaths
keepExistingModules :: [Path Abs File] -> IO [Path Abs File]
keepExistingModules = filterM doesFileExist