    {-# LANGUAGE CPP #-}
    {-# LANGUAGE TemplateHaskell #-}

    -- | This module exports version information about the Futhark
    -- compiler.
    module Futhark.Version
      ( version,
        versionString,
      )
    where

    import Data.ByteString.Char8 qualified as BS
    import Data.FileEmbed
    import Data.Text qualified as T
    import Data.Version
    import Futhark.Util (showText, trim)
    import GitHash
    import Paths_futhark qualified

    {-# NOINLINE version #-}

    -- | The version of Futhark that we are using.  This is equivalent to
    -- the version defined in the .cabal file.
    version :: Version
    version :: Version
    version = Version
    Paths_futhark.version

    {-# NOINLINE versionString #-}

    -- | The version of Futhark that we are using, in human-readable form.
    versionString :: T.Text
    versionString :: Text
    versionString =
      String -> Text
    T.pack (Version -> String
    showVersion Version
    version)
        Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    unreleased
        Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ".\n"
        Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Either String GitInfo -> Text
    forall {a}. Either a GitInfo -> Text
    gitversion $$String
    String -> Either String GitInfo
    forall a b. a -> Either a b
    tGitInfoCwdTry
        Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ghcversion
      where
        unreleased :: Text
    unreleased =
          if [Int] -> Int
    forall a. HasCallStack => [a] -> a
    last (Version -> [Int]
    versionBranch Version
    version) Int -> Int -> Bool
    forall a. Eq a => a -> a -> Bool
    == Int
    0
            then Text
    " (prerelease - include info below when reporting bugs)"
            else Text
    forall a. Monoid a => a
    mempty
        gitversion :: Either a GitInfo -> Text
    gitversion (Left a
    _) =
          case Maybe String
    commitIdFromFile of
            Maybe String
    Nothing -> Text
    ""
            Just String
    commit -> Text
    "git: " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> String -> Text
    T.pack String
    commit Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "\n"
        gitversion (Right GitInfo
    gi) =
          [Text] -> Text
    forall a. Monoid a => [a] -> a
    mconcat
            [ Text
    "git: ",
              Text
    branch,
              String -> Text
    T.pack (Int -> String -> String
    forall a. Int -> [a] -> [a]
    take Int
    7 (String -> String) -> String -> String
    forall a b. (a -> b) -> a -> b
    $ GitInfo -> String
    giHash GitInfo
    gi),
              Text
    " (",
              String -> Text
    T.pack (GitInfo -> String
    giCommitDate GitInfo
    gi),
              Text
    ")",
              Text
    dirty,
              Text
    "\n"
            ]
          where
            branch :: Text
    branch
              | GitInfo -> String
    giBranch GitInfo
    gi String -> String -> Bool
    forall a. Eq a => a -> a -> Bool
    == String
    "master" = Text
    ""
              | Bool
    otherwise = String -> Text
    T.pack (GitInfo -> String
    giBranch GitInfo
    gi) Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    " @ "
            dirty :: Text
    dirty = if GitInfo -> Bool
    giDirty GitInfo
    gi then Text
    " [modified]" else Text
    ""

        ghcversion :: Text
    ghcversion = Text
    "Compiled with GHC " Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    showText Int
    a Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "." Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    showText Int
    b Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    "." Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Int -> Text
    forall a. Show a => a -> Text
    showText Int
    c Text -> Text -> Text
    forall a. Semigroup a => a -> a -> a
    <> Text
    ".\n"
          where
            a, b, c :: Int
            a :: Int
    a = __GLASGOW_HASKELL__ `div` 100
            b :: Int
    b = __GLASGOW_HASKELL__ `mod` 100
            c :: Int
    c = __GLASGOW_HASKELL_PATCHLEVEL1__

    commitIdFromFile :: Maybe String
    commitIdFromFile :: Maybe String
    commitIdFromFile = String -> String
    trim (String -> String)
    -> (ByteString -> String) -> ByteString -> String
    forall b c a. (b -> c) -> (a -> b) -> a -> c
    . ByteString -> String
    BS.unpack (ByteString -> String) -> Maybe ByteString -> Maybe String
    forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
    <$> $(embedFileIfExists "./commit-id")