Skip to content

Instantly share code, notes, and snippets.

@bradclawsie
Created December 5, 2010 04:14
Show Gist options
  • Save bradclawsie/728778 to your computer and use it in GitHub Desktop.
Save bradclawsie/728778 to your computer and use it in GitHub Desktop.
find new bsd ports
{-
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
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment