{- this is a trivial script to tell us when a freebsd port has been updated within the last N days, where N is the argument provided to the script on the command line. this code is licensed under a "bsd" license, which is stated below Copyright (c) 2007, Brad Clawsie. All rights reserved. read more about this program at: -} module Main (main) where import qualified System.Directory as D (getDirectoryContents,doesDirectoryExist,getModificationTime) import qualified System.Time as T (diffClockTimes,getClockTime,tdSec,ClockTime(..)) import qualified System.Environment as S (getArgs) import qualified System.Exit as E (exitWith,ExitCode(..)) import qualified Control.Monad as M (liftM,mapM,filterM) import qualified Data.Char as C (isDigit) main :: IO () main = do args <- S.getArgs let useMsg = "use: newports [age-in-days]" :: String case (length args == 1) of False -> error useMsg True -> let rawArg = head args in case (all C.isDigit rawArg) of False -> error useMsg {- we will base our age comparisons on seconds, so we convert our arg to a day count as seconds -} True -> let age = 86400 * (read rawArg :: Int) in do now <- T.getClockTime let portsBase = "/usr/ports" :: FilePath dirs <- portsDirs portsBase allPorts <- M.mapM portsDirs dirs {- allPorts :: [[FilePath]] -} allPortDates <- M.liftM concat (M.mapM getModTimes allPorts) {- allPortDates:: [(FilePath,ClockTime)] where the ClockTime indicates the port mtime -} let newPorts = filter (isNewPort now age) allPortDates case (length newPorts) of 0 -> E.exitWith E.ExitSuccess _ -> do M.mapM putStrLn (map fst newPorts) E.exitWith E.ExitSuccess where isNewPort :: T.ClockTime -> Int -> (FilePath,T.ClockTime) -> Bool isNewPort now age (_,mtime) = let diff = T.tdSec(T.diffClockTimes now mtime) in diff <= age portsDirs :: FilePath -> IO [FilePath] portsDirs d = do rawDirs <- D.getDirectoryContents d l <- M.filterM (D.doesDirectoryExist) $ map ((d ++ "/") ++) $ filter (\x -> (head x) /= '.') rawDirs return l getModTimes :: [FilePath] -> IO [(FilePath,T.ClockTime)] getModTimes d = do t <- M.mapM D.getModificationTime d return $ zip d t