+ let indexFile = appDir </> "00-index.tar.gz"
+
+ putStrLn "Downloading the Hackage index..."
+ cwd <- pwd
+ cd appDir
+ runIO ("wget", ["-N", indexURL])
+ cd cwd
+ putStrLn "Done."
+
+ indexBin <- fmap GZip.decompress $ Lazy.readFile indexFile
+ let runQuery q = queryIndex q indexBin
+
+ makefiles <- namesMatching (pkgsrcPath </> "*" </> "*" </> "Makefile")
+ scanPkgs runQuery makefiles
+
+scanPkgs :: (Query -> [PackageDescription]) -> [FilePath] -> IO ()
+scanPkgs runQuery = mapM_ scanPkg
+ where
+ scanPkg :: FilePath -> IO ()
+ scanPkg makPath
+ = do mak <- readFile makPath
+ case grep "mk/haskell.mk" (lines mak) of
+ [] -> return ()
+ _ -> checkPkg mak
+
+ checkPkg :: String -> IO ()
+ checkPkg mak
+ = case grep "DISTNAME=" (lines mak) of
+ [l] -> let line = (trd ' ' . trd '\t') l
+ distname = cut 1 '=' line
+ name = extractPkgName distname
+ ver = extractPkgVersion distname
+ pkgId = PackageIdentifier name ver
+ query = Id ((`isNewerThan` pkgId) . package)
+ in
+ case runQuery query of
+ [] -> putStrLn (distname ++ ": is the LATEST")
+ xs -> let sorted = sortBy cmpVers xs
+ latest = last sorted
+ lVer = (pkgVersion . package) latest
+ in
+ putStrLn (distname ++ ": has a newer version " ++ showVersion lVer)
+ _ -> return ()
+
+ isNewerThan :: PackageIdentifier -> PackageIdentifier -> Bool
+ isNewerThan a b
+ = pkgName a == pkgName b &&
+ pkgVersion a > pkgVersion b
+
+ cmpVers :: PackageDescription -> PackageDescription -> Ordering
+ cmpVers a b = (pkgVersion . package) a `compare` (pkgVersion . package) b
+
+extractPkgName :: String -> PackageName
+extractPkgName = PackageName . head . split "-"
+
+extractPkgVersion :: String -> Version
+extractPkgVersion = take' . readP_to_S parseVersion . last . split "-"
+ where
+ take' ((v, ""):_ ) = v
+ take' (_ :xs) = take' xs
+ take' [] = error "Unparsable version"