Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import Distribution.Package
- import Distribution.PackageDescription
- import Distribution.PackageDescription.Parse
- import Distribution.Verbosity
- import Distribution.Version
- import System.Environment
- import qualified Codec.Archive.Tar as Tar
- import qualified Data.ByteString.Lazy as L
- import qualified Data.Map as Map
- import qualified Data.Text.Lazy as T
- import qualified Data.Text.Lazy.Encoding as T
- import qualified Data.Text.Encoding.Error as T
- import Data.List (foldl', group, sort, isInfixOf)
- import Control.Applicative
- import Data.List.Split (splitOn)
- import Distribution.Text
- import Data.Maybe (mapMaybe)
- import Data.Char (toLower)
- loadNewest :: FilePath -> IO Newest
- loadNewest db = foldl' addPackage Map.empty
- . entriesToList . Tar.read <$> L.readFile db
- main :: IO ()
- main = do
- [cabal, db, needle] <- getArgs
- desc <- readPackageDescription normal cabal
- newest <- loadNewest db
- print $ checkDeps newest desc
- mapM_ (print . checkDeps newest) $ findMyPackages needle newest
- findMyPackages :: String -> Newest -> [GenericPackageDescription]
- findMyPackages needle =
- mapMaybe go . Map.elems
- where
- needle' = map toLower needle
- go (_, Just desc) =
- let d = packageDescription desc
- a = author d
- m = maintainer d
- haystack = map toLower $ a ++ m
- in if needle' `isInfixOf` haystack
- then Just desc
- else Nothing
- go _ = Nothing
- data CheckDeps = AllNewest
- | WontAccept [(String, String)]
- deriving Show
- checkDeps :: Newest -> GenericPackageDescription -> (PackageName, CheckDeps)
- checkDeps newest desc =
- case mapMaybe (notNewest newest) $ getDeps desc of
- [] -> (name, AllNewest)
- x -> (name, WontAccept $ map head $ group $ sort x)
- where
- PackageIdentifier name _ = package $ packageDescription desc
- notNewest :: Newest -> Dependency -> Maybe (String, String)
- notNewest newest (Dependency (PackageName s) range) =
- case Map.lookup s newest of
- Nothing -> Just (s, " no version found")
- Just (version, _) ->
- if withinRange version range
- then Nothing
- else Just (s, display version)
- entriesToList :: Tar.Entries -> [Tar.Entry]
- entriesToList Tar.Done = []
- entriesToList (Tar.Fail s) = error s
- entriesToList (Tar.Next e es) = e : entriesToList es
- type Newest = Map.Map String (Version, Maybe GenericPackageDescription)
- addPackage :: Newest -> Tar.Entry -> Newest
- addPackage m entry =
- case splitOn "/" $ Tar.entryPath entry of
- [".", package', versionS, _] ->
- case simpleParse versionS of
- Just version ->
- case Map.lookup package' m of
- Nothing -> go package' version
- Just (oldv, _) ->
- if version > oldv
- then go package' version
- else m
- Nothing -> m
- _ -> m
- where
- go package' version =
- case Tar.entryContent entry of
- Tar.NormalFile bs _ ->
- let p =
- case parsePackageDescription $ T.unpack
- $ T.decodeUtf8With T.lenientDecode bs of
- ParseOk _ x -> Just x
- _ -> Nothing
- in Map.insert package' (version, p) m
- _ -> m
- getDeps :: GenericPackageDescription -> [Dependency]
- getDeps x = concat
- $ maybe id ((:) . condTreeConstraints) (condLibrary x)
- $ map (condTreeConstraints . snd) (condExecutables x)
Add Comment
Please, Sign In to add comment