sprinkles-0.6.0.0: src/Data/EmbedVersion.hs
{-#LANGUAGE OverloadedStrings #-}
{-#LANGUAGE ScopedTypeVariables #-}
module Data.EmbedVersion
where
import Distribution.Version
import Distribution.Verbosity
import Distribution.Package
import Distribution.PackageDescription
import Distribution.PackageDescription.Parsec
import Language.Haskell.TH
import Language.Haskell.TH.Syntax
import Data.List (intercalate, isPrefixOf)
import System.Process
import System.Exit
import qualified Data.Text as Text
import Data.Text (Text)
import Data.Char (isSpace)
import Control.Exception
getPackageVersion :: FilePath -> IO Version
getPackageVersion cabalFileName = do
gpd <- readGenericPackageDescription silent cabalFileName
return . pkgVersion . package. packageDescription $ gpd
getPackageVersionStr :: FilePath -> IO String
getPackageVersionStr = fmap formatPackageVersion . getPackageVersion
runGit :: [String] -> IO String
runGit args = do
(exitCode, stdout, stderr) <- readProcessWithExitCode "git" args ""
case exitCode of
ExitSuccess -> return stdout
e -> fail $ "git:" ++ stderr
data GitVersion = GitTag String String
| GitCommit String
| Unversioned
getGitVersionStr :: IO GitVersion
getGitVersionStr = do
currentCommit <- runGit ["log", "-1", "--pretty=tformat:%H %d"]
let (commitHash, refInfo) = break isSpace currentCommit
let refStrs = map Text.strip
. Text.splitOn ","
. Text.dropAround (`elem` ("()" :: [Char]))
. Text.strip
. Text.pack
$ refInfo
return $ case filter ("tag: " `Text.isPrefixOf`) refStrs of
(tagRef:_) -> GitTag (Text.unpack $ Text.drop 5 tagRef) commitHash
[] -> GitCommit commitHash
haveGitModifications :: IO Bool
haveGitModifications = do
output <- runGit ["status", "--porcelain"]
let outLines = filter (not . null) . lines $ output
return . not . null $ outLines
formatPackageVersion :: Version -> String
formatPackageVersion =
intercalate "." . map show . versionNumbers
embedPackageVersionStr :: FilePath -> Q Exp
embedPackageVersionStr fp = do
gitVersion <- runIO $ getGitVersionStr `catch` \(err :: IOError) -> return Unversioned
cabalVersion <- runIO (getPackageVersionStr fp)
let version = case gitVersion of
GitCommit c -> cabalVersion ++ "+git-" ++ c
GitTag t c ->
if (cabalVersion ++ "-") `isPrefixOf` t || cabalVersion == t
then t
else cabalVersion ++ " (" ++ t ++ ")"
Unversioned -> cabalVersion
modificationsStr <- runIO $ do
modifications <- haveGitModifications `catch` \(err :: IOError) -> return False
if modifications
then return "+modifications"
else return ""
stringE $ version ++ modificationsStr