{-# LANGUAGE FlexibleInstances #-} {-# LANGUAGE LambdaCase #-} {-# LANGUAGE OverloadedStrings #-} module System.Handsy.Util where import Control.Applicative import Control.Concurrent import Control.Monad.IO.Class import Data.Bool import qualified Data.ByteString.Lazy.Char8 as C import Data.List.Split import Prelude hiding (appendFile, readFile, writeFile) import System.Handsy -- * Helpers for parsing return values of 'command' and 'shell' class IsReturnValue a where stdout :: a -> C.ByteString stderr :: a -> C.ByteString exitCode :: a -> ExitCode instance IsReturnValue (C.ByteString, C.ByteString) where stdout = fst stderr = snd exitCode = const ExitSuccess instance IsReturnValue (ExitCode, C.ByteString, C.ByteString) where stdout = \case (_, a, _) -> a stderr = \case (_, _, a) -> a exitCode = \case (a, _, _) -> a isSuccessful :: IsReturnValue a => a -> Bool isSuccessful = isExitSuccess . exitCode isExitSuccess :: ExitCode -> Bool isExitSuccess = \case ExitSuccess -> True ExitFailure _ -> False -- | Extract lines from a ByteString. Useful for parsing unix commands. strLines :: C.ByteString -> [String] strLines = lines . C.unpack -- * Frequently used functionality -- | Waits specified number of seconds sleep :: Int -> Handsy () sleep = liftIO . threadDelay . (* 1000000) -- | Creates a temporary file mkTemp :: String -> Handsy String mkTemp suffix = head . strLines . fst <$> command_ "mktemp" (bool ["--suffix=" ++ suffix] [] (null suffix)) def -- | Creates a temporary directory mkTempDir :: String -> Handsy String mkTempDir suffix = head . strLines . fst <$> command_ "mktemp" ("-d" : bool ["--suffix" ++ suffix] [] (null suffix)) def -- | Returns if the specified process is running. Uses `pidof` isRunning :: String -> Handsy Bool isRunning p = isSuccessful <$> command "pidof" ["-s", "-x", p] def data OS = NixOS | Debian | Ubuntu | RHEL | CentOS | Fedora | ArchLinux deriving (Show, Eq) {-| Guesses the os using `/etc/os-release`. This currently only supports Linux distributions abiding systemd standards. -} os :: Handsy (Maybe OS) os = parseOsRelease <$> readFile "/etc/os-release" >>= return . \case Just "ubuntu" -> Just Ubuntu Just "debian" -> Just Debian Just "nixos" -> Just NixOS Just "rhel" -> Just RHEL Just "centos" -> Just CentOS Just "fedora" -> Just Fedora Just "arch" -> Just ArchLinux _ -> Nothing where parseOsRelease = fmap (filter $ not . flip elem "'\"") -- Hack to unquote <$> lookup "ID" . map ((\(x:xs) -> (x, concat xs)) . splitOn "=") . strLines