{-# LANGUAGE DataKinds #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE TemplateHaskell #-}
module GHCup.Platform where
import GHCup.Errors
import GHCup.Types
import GHCup.Types.JSON ( )
import GHCup.Utils.File
import GHCup.Utils.Prelude
import GHCup.Utils.String.QQ
import Control.Applicative
import Control.Exception.Safe
import Control.Monad
import Control.Monad.Logger
import Control.Monad.Reader
import Data.ByteString ( ByteString )
import Data.Foldable
import Data.Maybe
import Data.String.Interpolate
import Data.Text ( Text )
import Data.Versions
import HPath
import HPath.IO
import Haskus.Utils.Variant.Excepts
import Prelude hiding ( abs
, readFile
, writeFile
)
import System.Info
import System.OsRelease
import Text.Regex.Posix
import qualified Data.Text as T
platformRequest :: (MonadLogger m, MonadCatch m, MonadIO m)
=> Excepts
'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
m
PlatformRequest
platformRequest :: Excepts
'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
m
PlatformRequest
platformRequest = do
(PlatformResult Platform
rp Maybe Versioning
rv) <- Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
-> Excepts
'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
m
PlatformResult
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
forall (m :: * -> *).
(MonadLogger m, MonadCatch m, MonadIO m) =>
Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
getPlatform
Architecture
ar <- Either NoCompatibleArch Architecture
-> Excepts
'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
m
Architecture
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
Either e a -> Excepts es m a
lE Either NoCompatibleArch Architecture
getArchitecture
PlatformRequest
-> Excepts
'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
m
PlatformRequest
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PlatformRequest
-> Excepts
'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
m
PlatformRequest)
-> PlatformRequest
-> Excepts
'[NoCompatiblePlatform, NoCompatibleArch, DistroNotFound]
m
PlatformRequest
forall a b. (a -> b) -> a -> b
$ Architecture -> Platform -> Maybe Versioning -> PlatformRequest
PlatformRequest Architecture
ar Platform
rp Maybe Versioning
rv
getArchitecture :: Either NoCompatibleArch Architecture
getArchitecture :: Either NoCompatibleArch Architecture
getArchitecture = case String
arch of
String
"x86_64" -> Architecture -> Either NoCompatibleArch Architecture
forall a b. b -> Either a b
Right Architecture
A_64
String
"i386" -> Architecture -> Either NoCompatibleArch Architecture
forall a b. b -> Either a b
Right Architecture
A_32
String
"powerpc" -> Architecture -> Either NoCompatibleArch Architecture
forall a b. b -> Either a b
Right Architecture
A_PowerPC
String
"powerpc64" -> Architecture -> Either NoCompatibleArch Architecture
forall a b. b -> Either a b
Right Architecture
A_PowerPC64
String
"powerpc64le" -> Architecture -> Either NoCompatibleArch Architecture
forall a b. b -> Either a b
Right Architecture
A_PowerPC64
String
"sparc" -> Architecture -> Either NoCompatibleArch Architecture
forall a b. b -> Either a b
Right Architecture
A_Sparc
String
"sparc64" -> Architecture -> Either NoCompatibleArch Architecture
forall a b. b -> Either a b
Right Architecture
A_Sparc64
String
"arm" -> Architecture -> Either NoCompatibleArch Architecture
forall a b. b -> Either a b
Right Architecture
A_ARM
String
"aarch64" -> Architecture -> Either NoCompatibleArch Architecture
forall a b. b -> Either a b
Right Architecture
A_ARM64
String
what -> NoCompatibleArch -> Either NoCompatibleArch Architecture
forall a b. a -> Either a b
Left (String -> NoCompatibleArch
NoCompatibleArch String
what)
getPlatform :: (MonadLogger m, MonadCatch m, MonadIO m)
=> Excepts
'[NoCompatiblePlatform, DistroNotFound]
m
PlatformResult
getPlatform :: Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
getPlatform = do
PlatformResult
pfr <- case String
os of
String
"linux" -> do
(LinuxDistro
distro, Maybe Versioning
ver) <- Excepts '[DistroNotFound] m (LinuxDistro, Maybe Versioning)
-> Excepts
'[NoCompatiblePlatform, DistroNotFound]
m
(LinuxDistro, Maybe Versioning)
forall (es' :: [*]) (es :: [*]) a (m :: * -> *).
(Monad m, VEitherLift es es') =>
Excepts es m a -> Excepts es' m a
liftE Excepts '[DistroNotFound] m (LinuxDistro, Maybe Versioning)
forall (m :: * -> *).
(MonadCatch m, MonadIO m) =>
Excepts '[DistroNotFound] m (LinuxDistro, Maybe Versioning)
getLinuxDistro
PlatformResult
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PlatformResult
-> Excepts
'[NoCompatiblePlatform, DistroNotFound] m PlatformResult)
-> PlatformResult
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
forall a b. (a -> b) -> a -> b
$ PlatformResult :: Platform -> Maybe Versioning -> PlatformResult
PlatformResult { _platform :: Platform
_platform = LinuxDistro -> Platform
Linux LinuxDistro
distro, _distroVersion :: Maybe Versioning
_distroVersion = Maybe Versioning
ver }
String
"darwin" -> do
Maybe Versioning
ver <-
(ParsingError -> Maybe Versioning)
-> (Versioning -> Maybe Versioning)
-> Either ParsingError Versioning
-> Maybe Versioning
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe Versioning -> ParsingError -> Maybe Versioning
forall a b. a -> b -> a
const Maybe Versioning
forall a. Maybe a
Nothing) Versioning -> Maybe Versioning
forall a. a -> Maybe a
Just
(Either ParsingError Versioning -> Maybe Versioning)
-> (ByteString -> Either ParsingError Versioning)
-> ByteString
-> Maybe Versioning
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either ParsingError Versioning
versioning
(Text -> Either ParsingError Versioning)
-> (ByteString -> Text)
-> ByteString
-> Either ParsingError Versioning
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Text
getMajorVersion
(Text -> Text) -> (ByteString -> Text) -> ByteString -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
decUTF8Safe
(ByteString -> Maybe Versioning)
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString
-> Excepts
'[NoCompatiblePlatform, DistroNotFound] m (Maybe Versioning)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString
getDarwinVersion
PlatformResult
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PlatformResult
-> Excepts
'[NoCompatiblePlatform, DistroNotFound] m PlatformResult)
-> PlatformResult
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
forall a b. (a -> b) -> a -> b
$ PlatformResult :: Platform -> Maybe Versioning -> PlatformResult
PlatformResult { _platform :: Platform
_platform = Platform
Darwin, _distroVersion :: Maybe Versioning
_distroVersion = Maybe Versioning
ver }
String
"freebsd" -> do
Maybe Versioning
ver <-
(ParsingError -> Maybe Versioning)
-> (Versioning -> Maybe Versioning)
-> Either ParsingError Versioning
-> Maybe Versioning
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe Versioning -> ParsingError -> Maybe Versioning
forall a b. a -> b -> a
const Maybe Versioning
forall a. Maybe a
Nothing) Versioning -> Maybe Versioning
forall a. a -> Maybe a
Just (Either ParsingError Versioning -> Maybe Versioning)
-> (ByteString -> Either ParsingError Versioning)
-> ByteString
-> Maybe Versioning
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either ParsingError Versioning
versioning (Text -> Either ParsingError Versioning)
-> (ByteString -> Text)
-> ByteString
-> Either ParsingError Versioning
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
decUTF8Safe
(ByteString -> Maybe Versioning)
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString
-> Excepts
'[NoCompatiblePlatform, DistroNotFound] m (Maybe Versioning)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString
getFreeBSDVersion
PlatformResult
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
forall (f :: * -> *) a. Applicative f => a -> f a
pure (PlatformResult
-> Excepts
'[NoCompatiblePlatform, DistroNotFound] m PlatformResult)
-> PlatformResult
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
forall a b. (a -> b) -> a -> b
$ PlatformResult :: Platform -> Maybe Versioning -> PlatformResult
PlatformResult { _platform :: Platform
_platform = Platform
FreeBSD, _distroVersion :: Maybe Versioning
_distroVersion = Maybe Versioning
ver }
String
what -> NoCompatiblePlatform
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
e -> Excepts es m a
throwE (NoCompatiblePlatform
-> Excepts
'[NoCompatiblePlatform, DistroNotFound] m PlatformResult)
-> NoCompatiblePlatform
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
forall a b. (a -> b) -> a -> b
$ String -> NoCompatiblePlatform
NoCompatiblePlatform String
what
m () -> Excepts '[NoCompatiblePlatform, DistroNotFound] m ()
forall (t :: (* -> *) -> * -> *) (m :: * -> *) a.
(MonadTrans t, Monad m) =>
m a -> t m a
lift (m () -> Excepts '[NoCompatiblePlatform, DistroNotFound] m ())
-> m () -> Excepts '[NoCompatiblePlatform, DistroNotFound] m ()
forall a b. (a -> b) -> a -> b
$ $(Int
String
LogLevel
String -> Text
String -> String -> String -> CharPos -> CharPos -> Loc
Text -> Text
Loc -> Text -> LogLevel -> Text -> m ()
(Text -> m ()) -> (Text -> Text) -> Text -> m ()
forall a. a -> a
forall b c a. (b -> c) -> (a -> b) -> a -> c
forall (m :: * -> *) msg.
(MonadLogger m, ToLogStr msg) =>
Loc -> Text -> LogLevel -> msg -> m ()
pack :: String -> Text
monadLoggerLog :: forall (m :: * -> *) msg.
(MonadLogger m, ToLogStr msg) =>
Loc -> Text -> LogLevel -> msg -> m ()
id :: forall a. a -> a
. :: forall b c a. (b -> c) -> (a -> b) -> a -> c
logDebug) [i|Identified Platform as: #{pfr}|]
PlatformResult
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m PlatformResult
forall (f :: * -> *) a. Applicative f => a -> f a
pure PlatformResult
pfr
where
getMajorVersion :: Text -> Text
getMajorVersion = Text -> [Text] -> Text
T.intercalate Text
"." ([Text] -> Text) -> (Text -> [Text]) -> Text -> Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Int -> [Text] -> [Text]
forall a. Int -> [a] -> [a]
take Int
2 ([Text] -> [Text]) -> (Text -> [Text]) -> Text -> [Text]
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Char -> Bool) -> Text -> [Text]
T.split (Char -> Char -> Bool
forall a. Eq a => a -> a -> Bool
== Char
'.')
getFreeBSDVersion :: Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString
getFreeBSDVersion =
IO ByteString
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString)
-> IO ByteString
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString
forall a b. (a -> b) -> a -> b
$ (CapturedProcess -> ByteString)
-> IO CapturedProcess -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CapturedProcess -> ByteString
_stdOut (IO CapturedProcess -> IO ByteString)
-> IO CapturedProcess -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Path Rel -> [ByteString] -> Maybe (Path Abs) -> IO CapturedProcess
forall b.
Path b -> [ByteString] -> Maybe (Path Abs) -> IO CapturedProcess
executeOut [rel|freebsd-version|] [] Maybe (Path Abs)
forall a. Maybe a
Nothing
getDarwinVersion :: Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString
getDarwinVersion = IO ByteString
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO ByteString
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString)
-> IO ByteString
-> Excepts '[NoCompatiblePlatform, DistroNotFound] m ByteString
forall a b. (a -> b) -> a -> b
$ (CapturedProcess -> ByteString)
-> IO CapturedProcess -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CapturedProcess -> ByteString
_stdOut (IO CapturedProcess -> IO ByteString)
-> IO CapturedProcess -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Path Rel -> [ByteString] -> Maybe (Path Abs) -> IO CapturedProcess
forall b.
Path b -> [ByteString] -> Maybe (Path Abs) -> IO CapturedProcess
executeOut [rel|sw_vers|]
[ByteString
"-productVersion"]
Maybe (Path Abs)
forall a. Maybe a
Nothing
getLinuxDistro :: (MonadCatch m, MonadIO m)
=> Excepts '[DistroNotFound] m (LinuxDistro, Maybe Versioning)
getLinuxDistro :: Excepts '[DistroNotFound] m (LinuxDistro, Maybe Versioning)
getLinuxDistro = do
(Text
name, Maybe Text
ver) <- (IOException -> Excepts '[DistroNotFound] m (Text, Maybe Text))
-> Excepts '[DistroNotFound] m (Text, Maybe Text)
-> Excepts '[DistroNotFound] m (Text, Maybe Text)
forall (m :: * -> *) a.
MonadCatch m =>
(IOException -> m a) -> m a -> m a
handleIO (\IOException
_ -> DistroNotFound -> Excepts '[DistroNotFound] m (Text, Maybe Text)
forall e (es :: [*]) a (m :: * -> *).
(Monad m, e :< es) =>
e -> Excepts es m a
throwE DistroNotFound
DistroNotFound) (Excepts '[DistroNotFound] m (Text, Maybe Text)
-> Excepts '[DistroNotFound] m (Text, Maybe Text))
-> Excepts '[DistroNotFound] m (Text, Maybe Text)
-> Excepts '[DistroNotFound] m (Text, Maybe Text)
forall a b. (a -> b) -> a -> b
$ IO (Text, Maybe Text)
-> Excepts '[DistroNotFound] m (Text, Maybe Text)
forall (m :: * -> *) a. MonadIO m => IO a -> m a
liftIO (IO (Text, Maybe Text)
-> Excepts '[DistroNotFound] m (Text, Maybe Text))
-> IO (Text, Maybe Text)
-> Excepts '[DistroNotFound] m (Text, Maybe Text)
forall a b. (a -> b) -> a -> b
$ [IO (Text, Maybe Text)] -> IO (Text, Maybe Text)
forall (t :: * -> *) (f :: * -> *) a.
(Foldable t, Alternative f) =>
t (f a) -> f a
asum
[ IO (Text, Maybe Text)
try_os_release
, IO (Text, Maybe Text)
try_lsb_release_cmd
, IO (Text, Maybe Text)
try_redhat_release
, IO (Text, Maybe Text)
try_debian_version
]
let parsedVer :: Maybe Versioning
parsedVer = Maybe Text
ver Maybe Text -> (Text -> Maybe Versioning) -> Maybe Versioning
forall (m :: * -> *) a b. Monad m => m a -> (a -> m b) -> m b
>>= (ParsingError -> Maybe Versioning)
-> (Versioning -> Maybe Versioning)
-> Either ParsingError Versioning
-> Maybe Versioning
forall a c b. (a -> c) -> (b -> c) -> Either a b -> c
either (Maybe Versioning -> ParsingError -> Maybe Versioning
forall a b. a -> b -> a
const Maybe Versioning
forall a. Maybe a
Nothing) Versioning -> Maybe Versioning
forall a. a -> Maybe a
Just (Either ParsingError Versioning -> Maybe Versioning)
-> (Text -> Either ParsingError Versioning)
-> Text
-> Maybe Versioning
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Text -> Either ParsingError Versioning
versioning
distro :: LinuxDistro
distro = if
| Text -> [String] -> Bool
forall (t :: * -> *). Foldable t => Text -> t String -> Bool
hasWord Text
name [String
"debian"] -> LinuxDistro
Debian
| Text -> [String] -> Bool
forall (t :: * -> *). Foldable t => Text -> t String -> Bool
hasWord Text
name [String
"ubuntu"] -> LinuxDistro
Ubuntu
| Text -> [String] -> Bool
forall (t :: * -> *). Foldable t => Text -> t String -> Bool
hasWord Text
name [String
"linuxmint", String
"Linux Mint"] -> LinuxDistro
Mint
| Text -> [String] -> Bool
forall (t :: * -> *). Foldable t => Text -> t String -> Bool
hasWord Text
name [String
"fedora"] -> LinuxDistro
Fedora
| Text -> [String] -> Bool
forall (t :: * -> *). Foldable t => Text -> t String -> Bool
hasWord Text
name [String
"centos"] -> LinuxDistro
CentOS
| Text -> [String] -> Bool
forall (t :: * -> *). Foldable t => Text -> t String -> Bool
hasWord Text
name [String
"Red Hat"] -> LinuxDistro
RedHat
| Text -> [String] -> Bool
forall (t :: * -> *). Foldable t => Text -> t String -> Bool
hasWord Text
name [String
"alpine"] -> LinuxDistro
Alpine
| Text -> [String] -> Bool
forall (t :: * -> *). Foldable t => Text -> t String -> Bool
hasWord Text
name [String
"exherbo"] -> LinuxDistro
Exherbo
| Text -> [String] -> Bool
forall (t :: * -> *). Foldable t => Text -> t String -> Bool
hasWord Text
name [String
"gentoo"] -> LinuxDistro
Gentoo
| Text -> [String] -> Bool
forall (t :: * -> *). Foldable t => Text -> t String -> Bool
hasWord Text
name [String
"amazonlinux", String
"Amazon Linux"] -> LinuxDistro
AmazonLinux
| Bool
otherwise -> LinuxDistro
UnknownLinux
(LinuxDistro, Maybe Versioning)
-> Excepts '[DistroNotFound] m (LinuxDistro, Maybe Versioning)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (LinuxDistro
distro, Maybe Versioning
parsedVer)
where
hasWord :: Text -> t String -> Bool
hasWord Text
t t String
matches = (String -> Bool -> Bool) -> Bool -> t String -> Bool
forall (t :: * -> *) a b.
Foldable t =>
(a -> b -> b) -> b -> t a -> b
foldr (\String
x Bool
y -> Regex -> String -> Bool
forall regex source target.
RegexContext regex source target =>
regex -> source -> target
match (String -> Regex
regex String
x) (Text -> String
T.unpack Text
t) Bool -> Bool -> Bool
|| Bool
y)
Bool
False
t String
matches
where
regex :: String -> Regex
regex String
x = CompOption -> ExecOption -> String -> Regex
forall regex compOpt execOpt source.
RegexMaker regex compOpt execOpt source =>
compOpt -> execOpt -> source -> regex
makeRegexOpts CompOption
compIgnoreCase ExecOption
execBlank ([s|\<|] String -> String -> String
forall a. [a] -> [a] -> [a]
++ String
x String -> String -> String
forall a. [a] -> [a] -> [a]
++ [s|\>|])
lsb_release_cmd :: Path Rel
lsb_release_cmd :: Path Rel
lsb_release_cmd = [rel|lsb-release|]
redhat_release :: Path Abs
redhat_release :: Path Abs
redhat_release = [abs|/etc/redhat-release|]
debian_version :: Path Abs
debian_version :: Path Abs
debian_version = [abs|/etc/debian_version|]
try_os_release :: IO (Text, Maybe Text)
try_os_release :: IO (Text, Maybe Text)
try_os_release = do
Just OsRelease{ name :: OsRelease -> String
name = String
name, version_id :: OsRelease -> Maybe String
version_id = Maybe String
version_id } <-
(OsReleaseResult -> OsRelease)
-> Maybe OsReleaseResult -> Maybe OsRelease
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap OsReleaseResult -> OsRelease
osRelease (Maybe OsReleaseResult -> Maybe OsRelease)
-> IO (Maybe OsReleaseResult) -> IO (Maybe OsRelease)
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> IO (Maybe OsReleaseResult)
parseOsRelease
(Text, Maybe Text) -> IO (Text, Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Text
T.pack String
name, (String -> Text) -> Maybe String -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Text
T.pack Maybe String
version_id)
try_lsb_release_cmd :: IO (Text, Maybe Text)
try_lsb_release_cmd :: IO (Text, Maybe Text)
try_lsb_release_cmd = do
(Just Path Abs
_) <- Path Rel -> IO (Maybe (Path Abs))
findExecutable Path Rel
lsb_release_cmd
ByteString
name <- (CapturedProcess -> ByteString)
-> IO CapturedProcess -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CapturedProcess -> ByteString
_stdOut (IO CapturedProcess -> IO ByteString)
-> IO CapturedProcess -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Path Rel -> [ByteString] -> Maybe (Path Abs) -> IO CapturedProcess
forall b.
Path b -> [ByteString] -> Maybe (Path Abs) -> IO CapturedProcess
executeOut Path Rel
lsb_release_cmd [ByteString
"-si"] Maybe (Path Abs)
forall a. Maybe a
Nothing
ByteString
ver <- (CapturedProcess -> ByteString)
-> IO CapturedProcess -> IO ByteString
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap CapturedProcess -> ByteString
_stdOut (IO CapturedProcess -> IO ByteString)
-> IO CapturedProcess -> IO ByteString
forall a b. (a -> b) -> a -> b
$ Path Rel -> [ByteString] -> Maybe (Path Abs) -> IO CapturedProcess
forall b.
Path b -> [ByteString] -> Maybe (Path Abs) -> IO CapturedProcess
executeOut Path Rel
lsb_release_cmd [ByteString
"-sr"] Maybe (Path Abs)
forall a. Maybe a
Nothing
(Text, Maybe Text) -> IO (Text, Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (ByteString -> Text
decUTF8Safe ByteString
name, Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text) -> Text -> Maybe Text
forall a b. (a -> b) -> a -> b
$ ByteString -> Text
decUTF8Safe ByteString
ver)
try_redhat_release :: IO (Text, Maybe Text)
try_redhat_release :: IO (Text, Maybe Text)
try_redhat_release = do
Text
t <- (ByteString -> Text) -> IO ByteString -> IO Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap ByteString -> Text
decUTF8Safe' (IO ByteString -> IO Text) -> IO ByteString -> IO Text
forall a b. (a -> b) -> a -> b
$ Path Abs -> IO ByteString
forall b. Path b -> IO ByteString
readFile Path Abs
redhat_release
let nameRegex :: String -> Regex
nameRegex String
n =
CompOption -> ExecOption -> ByteString -> Regex
forall regex compOpt execOpt source.
RegexMaker regex compOpt execOpt source =>
compOpt -> execOpt -> source -> regex
makeRegexOpts CompOption
compIgnoreCase
ExecOption
execBlank
([s|\<|] ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> String -> ByteString
forall a. IsString a => String -> a
fS String
n ByteString -> ByteString -> ByteString
forall a. Semigroup a => a -> a -> a
<> [s|\>|] :: ByteString) :: Regex
let verRegex :: Regex
verRegex =
CompOption -> ExecOption -> ByteString -> Regex
forall regex compOpt execOpt source.
RegexMaker regex compOpt execOpt source =>
compOpt -> execOpt -> source -> regex
makeRegexOpts CompOption
compIgnoreCase
ExecOption
execBlank
([s|\<([0-9])+(.([0-9])+)*\>|] :: ByteString) :: Regex
let nameRe :: String -> Maybe String
nameRe String
n =
String -> Maybe String
fromEmpty (String -> Maybe String)
-> (String -> String) -> String -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Regex -> String -> String
forall regex source target.
RegexContext regex source target =>
regex -> source -> target
match (String -> Regex
nameRegex String
n) (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
t :: Maybe String
verRe :: Maybe String
verRe = String -> Maybe String
fromEmpty (String -> Maybe String)
-> (String -> String) -> String -> Maybe String
forall b c a. (b -> c) -> (a -> b) -> a -> c
. Regex -> String -> String
forall regex source target.
RegexContext regex source target =>
regex -> source -> target
match Regex
verRegex (String -> Maybe String) -> String -> Maybe String
forall a b. (a -> b) -> a -> b
$ Text -> String
T.unpack Text
t :: Maybe String
(Just String
name) <- Maybe String -> IO (Maybe String)
forall (f :: * -> *) a. Applicative f => a -> f a
pure
(String -> Maybe String
nameRe String
"CentOS" Maybe String -> Maybe String -> Maybe String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> Maybe String
nameRe String
"Fedora" Maybe String -> Maybe String -> Maybe String
forall (f :: * -> *) a. Alternative f => f a -> f a -> f a
<|> String -> Maybe String
nameRe String
"Red Hat")
(Text, Maybe Text) -> IO (Text, Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Text
T.pack String
name, (String -> Text) -> Maybe String -> Maybe Text
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap String -> Text
T.pack Maybe String
verRe)
where
fromEmpty :: String -> Maybe String
fromEmpty :: String -> Maybe String
fromEmpty String
"" = Maybe String
forall a. Maybe a
Nothing
fromEmpty String
s' = String -> Maybe String
forall a. a -> Maybe a
Just String
s'
try_debian_version :: IO (Text, Maybe Text)
try_debian_version :: IO (Text, Maybe Text)
try_debian_version = do
ByteString
ver <- Path Abs -> IO ByteString
forall b. Path b -> IO ByteString
readFile Path Abs
debian_version
(Text, Maybe Text) -> IO (Text, Maybe Text)
forall (f :: * -> *) a. Applicative f => a -> f a
pure (String -> Text
T.pack String
"debian", Text -> Maybe Text
forall a. a -> Maybe a
Just (Text -> Maybe Text)
-> (ByteString -> Text) -> ByteString -> Maybe Text
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ByteString -> Text
decUTF8Safe' (ByteString -> Maybe Text) -> ByteString -> Maybe Text
forall a b. (a -> b) -> a -> b
$ ByteString
ver)