Skip to content

Instantly share code, notes, and snippets.

@tfausak
Last active June 23, 2017 17:32
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tfausak/f6ca02af0ed84a5eb4b926d68d6363ff to your computer and use it in GitHub Desktop.
Save tfausak/f6ca02af0ed84a5eb4b926d68d6363ff to your computer and use it in GitHub Desktop.
Counts revisions of packages on Hackage.
#!/usr/bin/env stack
-- stack --resolver lts-8.19 script --package Cabal --package Glob
-- This script counts the total number of versions and revisions on Hackage.
--
-- Usage:
-- 1. Download and unpack <https://hackage.haskell.org/01-index.tar.gz>.
-- 2. Run `./Main.hs 'path-to-unpacked-index/**/*.cabal'`.
--
-- Example output as of 23 July 2017:
-- Total number of package versions: 81000
-- Total number of package revisions: 12092
import qualified Data.Foldable as Foldable
import qualified Data.Maybe as Maybe
import qualified Distribution.PackageDescription as Cabal
import qualified Distribution.PackageDescription.Parse as Cabal
import qualified Distribution.Verbosity as Cabal
import qualified System.Environment as Environment
import qualified System.FilePath.Glob as Glob
import qualified Text.Read as Read
main :: IO ()
main = do
[pattern] <- Environment.getArgs
files <- Glob.glob pattern
(versions, revisions) <- Foldable.foldrM step (0, 0) files
putStrLn ("Total number of package versions: " ++ show versions)
putStrLn ("Total number of package revisions: " ++ show revisions)
step :: FilePath -> (Int, Int) -> IO (Int, Int)
step file (versions, revisions) = do
package <- Cabal.readPackageDescription Cabal.silent file
pure (succ versions, revisions + getRevision package)
getRevision :: Cabal.GenericPackageDescription -> Int
getRevision
= Maybe.fromMaybe 0
. Read.readMaybe
. Maybe.fromMaybe ""
. lookup "x-revision"
. Cabal.customFieldsPD
. Cabal.packageDescription
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment