{- | Module : $Header$ License : FreeBSD Maintainer : penzin.dev@gmail.com Stability : experimental Portability : non-portable (FreeBSD specific) Module to check existence and interact with various port and package tools -} module Config.FreeBSD.PortTools ( -- * Functions -- ** Check for Portmater isPortmasterPresent, -- ** Check for PkgTools (portupgrade and the like) isPkgToolsPresent, -- ** Check for PkgNG (newer package tool) isPkgNgPresent, -- ** Check for Pkg (older package tool) isPkgPresent, -- ** Upgrade a port using portmaster upgradeWithPortmaster, -- ** Upgrade a port using portupgrade upgradeWithPortupgrade, -- ** Upgrade a port using make command upgradeWithMake ) where import System.Process import System.Exit import System.Directory import Control.Exception {-| Run something and check if the exit code is "success" -} checkExitCode :: String -> [String] -> IO Bool checkExitCode nm args = readProcessWithExitCode nm args "" >>= \(status, _, _) -> return (status == ExitSuccess) {-| Run portmaster --help and check exit status -} checkPortmaster :: IO Bool checkPortmaster = checkExitCode "portmaster" ["--help"] {-| Run portupgrade --help and check exit status -} checkPortupgrade :: IO Bool checkPortupgrade = checkExitCode "portupgrade" ["--help"] {-| Run pkg help and check exit status -} checkPkg :: IO Bool checkPkg = checkExitCode "pkg" ["help"] {-| Run pkg_version -h (pre-NG package solution) and check exit status -} checkOldPkg :: IO Bool checkOldPkg = checkExitCode "pkg_version" ["-h"] {-| Return false for any exceptions -} handler :: SomeException -> IO Bool handler _ = return False {-| Check whether portmaster is installed by looking if we can run the command -} isPortmasterPresent :: IO Bool isPortmasterPresent = catch checkPortmaster handler {-| Check whether pkgtools is installed by looking if we can run portupgrade command -} isPkgToolsPresent :: IO Bool isPkgToolsPresent = catch checkPortupgrade handler {-| Check whether pkgNG is installed by looking if we can run pkg command -} isPkgNgPresent :: IO Bool isPkgNgPresent = catch checkPkg handler {-| Check for pre-NG package manager -} isPkgPresent :: IO Bool isPkgPresent = catch checkOldPkg handler {-| Upgrade a single port with portmaster -} upgradeWithPortmaster :: String -> IO () upgradeWithPortmaster name = callProcess "portmaster" [name] {-| Upgrade a single port with portupgrade -} upgradeWithPortupgrade :: String -> IO () upgradeWithPortupgrade name = callProcess "portupgrade" [name] {-| Upgrade a single port using Make -} upgradeWithMake :: String -> IO () upgradeWithMake name = readProcess "find" ["/usr/ports", name] "" -- cheat to locate the port directory >>= setCurrentDirectory >> callProcess "make" ["config-recursive"] >> callProcess "make" ["install", "clean"]