@@ -9,6 +9,7 @@ ghc-options: -Wall -Wno-type-defaults
99{-# LANGUAGE ImportQualifiedPost #-}
1010{-# LANGUAGE OverloadedStrings #-}
1111{-# LANGUAGE RecordWildCards #-}
12+ {-# LANGUAGE ViewPatterns #-}
1213
1314import Control.Exception
1415import Data.Binary
@@ -25,14 +26,33 @@ import Data.Vector qualified as V
2526import GitHub qualified as GH
2627import Options.Applicative
2728import System.IO
29+ import Prelude hiding (until )
2830
29- data Config
31+ data Config = Config {
32+ since :: UTCTime
33+ , until :: Maybe UTCTime
34+ , workMode :: WorkMode
35+ }
36+
37+ data WorkMode
3038 = Offline FilePath
3139 | Online (Maybe B. ByteString ) (Maybe FilePath )
3240
3341configParser :: Parser Config
3442configParser = do
3543 let
44+ parseStartTime =
45+ option auto $
46+ long " since"
47+ <> metavar " SINCE"
48+ <> help " The start date of the analysis (default: 2021-10-23)"
49+ <> value (read " 2021-10-23 00:00:00 UTC" )
50+ parseEndTime =
51+ optional $
52+ option auto $
53+ long " until"
54+ <> metavar " UNTIL"
55+ <> help " The end date of the analysis"
3656 parseUsername =
3757 optional $
3858 strOption $
@@ -51,7 +71,7 @@ configParser = do
5171 <> metavar " FILE"
5272 <> help " Work offline using previously saved cache"
5373
54- Offline <$> parseOffline <|> Online <$> parseUsername <*> parseCacheFile
74+ Config <$> parseStartTime <*> parseEndTime <*> ( Offline <$> parseOffline <|> Online <$> parseUsername <*> parseCacheFile)
5575
5676getPassword :: IO B. ByteString
5777getPassword = do
@@ -71,9 +91,9 @@ getBasicAuth username = do
7191 pure $ GH. BasicAuth username password
7292
7393getGithubIssues :: Config -> IO (V. Vector GH. Issue )
74- getGithubIssues (Offline cacheFile) =
94+ getGithubIssues (workMode -> ( Offline cacheFile) ) =
7595 decode <$> BL. readFile cacheFile
76- getGithubIssues (Online mUsername mCacheFile) = do
96+ getGithubIssues (workMode -> ( Online mUsername mCacheFile) ) = do
7797 let githubOrg = " haskell"
7898 githubRepo = " core-libraries-committee"
7999 am <- traverse getBasicAuth mUsername
@@ -126,6 +146,11 @@ isDeclined Issue {..} = "declined" `elem` issLabels
126146isMeta :: Issue -> Bool
127147isMeta Issue {.. } = " meta" `elem` issLabels
128148
149+ isWithinTimeFrame :: UTCTime -> UTCTime -> Issue -> Bool
150+ isWithinTimeFrame since to Issue {.. } =
151+ issCreatedAt >= since
152+ && issCreatedAt <= to
153+
129154isBase :: Int -> Issue -> Bool
130155isBase n Issue {.. } = (" base-4." <> T. pack (show n)) `elem` issLabels
131156
@@ -171,17 +196,19 @@ main = do
171196 (fullDesc <> header " Collect statistics for CLC proposals" )
172197 issues <- getGithubIssues cnf
173198
199+ let startTime = since cnf
200+ endTime <- maybe getCurrentTime pure (until cnf)
201+
174202 let proposals =
175- filter (not . isMeta) . map githubIssueToIssue $
176- filter (isNothing . GH. issuePullRequest) $
177- V. toList issues
203+ filter (isWithinTimeFrame startTime endTime) $
204+ filter (not . isMeta) . map githubIssueToIssue $
205+ filter (isNothing . GH. issuePullRequest) $
206+ V. toList issues
178207 approvedProposals = filter isApproved proposals
179208 declinedProposals = filter isDeclined proposals
180209
181210 putStrLn $ " Total number of CLC proposals: " ++ show (length proposals)
182- let startTime = read " 2021-10-23 00:00:00 UTC"
183- currTime <- getCurrentTime
184- putStrLn $ " Rate of proposals: " ++ show (round (fromIntegral (length proposals) * 86400 * 365.25 / 12 / realToFrac (diffUTCTime currTime startTime))) ++ " per month"
211+ putStrLn $ " Rate of proposals: " ++ show (round (fromIntegral (length proposals) * 86400 * 365.25 / 12 / realToFrac (diffUTCTime endTime startTime))) ++ " per month"
185212 putStrLn $ " Approved proposals: " ++ show (length approvedProposals)
186213 putStrLn $ " Declined proposals: " ++ show (length declinedProposals)
187214 putStrLn " "
@@ -217,7 +244,7 @@ main = do
217244
218245 let openProposals = filter (isNothing . issClosedAt) proposals
219246 putStrLn $ " Open proposals: " ++ show (length openProposals)
220- let openLifeTime = collectStat (Just . computeDaysSinceCreation currTime ) openProposals
247+ let openLifeTime = collectStat (Just . computeDaysSinceCreation endTime ) openProposals
221248 putStrLn $ " Median age for open proposals: " ++ show (statMed openLifeTime) ++ " days"
222249 putStrLn $ " Average age for open proposals: " ++ show (statAvg openLifeTime) ++ " days"
223250 putStrLn $ " Newest open proposal:\n\t " ++ show (round (statMinMetric openLifeTime)) ++ " days for " ++ show (issTitle (statMinIssue openLifeTime))
0 commit comments