Skip to content

Instantly share code, notes, and snippets.

@fujimura
Created May 28, 2014 09:00
Show Gist options
  • Save fujimura/3a61ddc3f9be57bde39e to your computer and use it in GitHub Desktop.
Save fujimura/3a61ddc3f9be57bde39e to your computer and use it in GitHub Desktop.
Code change frequency per file
-- How to run
-- $ git log --numstat --pretty="%0" |grep -v "%0" | runhaskell sum.hs
import Control.Applicative
import Data.Map (Map)
import qualified Data.Map as Map
import System.IO
import Text.Read
import Data.List
import Data.List.Split
type FileName = String
type NumStat = (Int, Int)
type Change = (FileName, NumStat)
type Result = Map FileName NumStat
parseLine :: String -> Maybe (FileName, NumStat)
parseLine = go . splitOn "\t"
where go (added:deleted:filename:_) =
case (readIntMaybe added, readIntMaybe deleted) of
(Just a, Just d) -> Just (filename, (a, d))
_ -> Nothing
go _ = Nothing
readIntMaybe x = readMaybe x :: Maybe Int
walk :: [Change] -> IO [Change]
walk changes = do
eof <- isEOF
if eof then return changes
else parseLine <$> getLine >>= walk . maybe changes (: changes)
sumChanges :: [Change] -> Result
sumChanges = foldl incrementChange Map.empty
incrementChange :: Result -> Change -> Result
incrementChange result (fileName,numStat@(a,d)) =
case Map.lookup fileName result of
Just (a',d') -> Map.insert fileName (a+a', d+d') result
Nothing -> Map.insert fileName numStat result
render :: Change -> IO ()
render (fileName,(added,deleted)) =
putStrLn $ fileName ++ "," ++ show added ++ "," ++ show deleted
main :: IO ()
main = do
changes <- walk []
mapM_ render $ ignoreJustAdded . sortResult . Map.toList $ sumChanges changes
where
sortResult :: [Change] -> [Change]
sortResult = let f (_,(xa,xd)) (_,(ya,yd)) = (ya+yd) `compare` (xa+xd) in sortBy f
ignoreJustAdded :: [Change] -> [Change]
ignoreJustAdded [] = []
ignoreJustAdded (x@(_,(a,d)):xs)
| a == d = ignoreJustAdded xs
| d == 0 = ignoreJustAdded xs
| otherwise = x:ignoreJustAdded xs
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment