a haskell program for finding your new freebsd ports

the source code for this package is now hosted on github

newports.hs is a trivial haskell script that can be used to find what ports have been updated on your system in the last N days, which you would typically want to know after doing a daily cvsup. the instructions are easy - the script only takes one argument - a number signifying the age in days of ports you want displayed. if you wanted to use runhaskell utility, you could run it like:

runhaskell newports.hs 1

the code is under a bsd license.

here is a haskell HackageDB package for this script.

if you find bugs, errors, or want to suggest changes, let me know!

{-
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.
http://b7j0c.org/stuff/license.txt
-}
module Main (main) where
import qualified System.Directory as D
(getDirectoryContents,doesDirectoryExist,getModificationTime)
import qualified System.Time as T
(normalizeTimeDiff,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 (port,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
view raw findports.hs hosted with ❤ by GitHub

last update 2010-12-04