module Utils.ThankYouStars.Package ( getThisPackageName , allBuildDepends , readHackage , lookupRepo , readCabalFile , unPackageName ) where import Utils.ThankYouStars.GitHub import Data.List ( isInfixOf ) import Data.List.Split ( splitOneOf ) import qualified Data.Map as M import qualified Data.Set as S import Data.Maybe import Distribution.Hackage.DB ( Hackage, readHackage ) import Distribution.Package import Distribution.PackageDescription import Distribution.PackageDescription.Parse ( readPackageDescription ) import Distribution.Verbosity ( normal ) import System.Directory ( getCurrentDirectory ) import System.FilePath ( takeBaseName ) allBuildDepends :: GenericPackageDescription -> S.Set PackageName allBuildDepends desc = let ls = map (libBuildInfo . condTreeData) . maybeToList . condLibrary $ desc es = map (buildInfo . condTreeData . snd) . condExecutables $ desc ts = map (testBuildInfo . condTreeData . snd) . condTestSuites $ desc bs = map (benchmarkBuildInfo . condTreeData . snd) . condBenchmarks $ desc in S.fromList . concatMap depends $ ls ++ es ++ ts ++ bs depends :: BuildInfo -> [PackageName] depends = map toPackageName . targetBuildDepends getThisPackageName :: IO PackageName getThisPackageName = (PackageName . takeBaseName) <$> getCurrentDirectory readCabalFile :: FilePath -> IO GenericPackageDescription readCabalFile = readPackageDescription normal toPackageName :: Dependency -> PackageName toPackageName (Dependency name _) = name lookupRepo :: PackageName -> Hackage -> Maybe GitHubRepo lookupRepo pkg db = listToMaybe . catMaybes . map parseRepo $ repos where repos = fromMaybe [] $ toRepos <$> M.lookup (unPackageName pkg) db toRepos = sourceRepos . packageDescription . snd . M.findMax parseRepo :: SourceRepo -> Maybe GitHubRepo parseRepo src = case (repoType src, repoLocation src) of (Just Git, Just loc) -> parseLocation loc _ -> Nothing -- TODO: Too naive parsing parseLocation :: String -> Maybe GitHubRepo parseLocation loc | isGitHub && length ps > 5 = Just $ GitHubRepo { owner = ps !! 4, repo = ps !! 5 } | otherwise = Nothing where isGitHub = isInfixOf "github.com" loc ps = splitOneOf "/." loc