Skip to content

Embed URL

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Example CABAL Setup.hs file for automatic package versioning via `git describe`
import Control.Exception
import Control.Monad
import Data.Maybe
import Data.Version
import Distribution.PackageDescription (PackageDescription(..), HookedBuildInfo, GenericPackageDescription(..))
import Distribution.Package (PackageIdentifier(..))
import Distribution.Simple (defaultMainWithHooks, simpleUserHooks, UserHooks(..))
import Distribution.Simple.LocalBuildInfo (LocalBuildInfo(..))
import Distribution.Simple.Setup (BuildFlags(..), ConfigFlags(..))
import Distribution.Simple.Utils (die)
import System.Process (readProcess)
import Text.ParserCombinators.ReadP (readP_to_S)
main :: IO ()
main = defaultMainWithHooks simpleUserHooks
{ confHook = myConfHook
, buildHook = myBuildHook
}
-- configure hook
myConfHook :: (GenericPackageDescription, HookedBuildInfo)
-> ConfigFlags
-> IO LocalBuildInfo
myConfHook (gpdesc, hbinfo) cfg = do
gitVersion <- inferVersionFromGit
let GenericPackageDescription {
packageDescription = pdesc@PackageDescription {
package = pkgIden }} = gpdesc
let gpdesc' = gpdesc {
packageDescription = pdesc {
package = pkgIden { pkgVersion = gitVersion } } }
-- putStrLn $ showVersion gitVersion
confHook simpleUserHooks (gpdesc', hbinfo) cfg
-- build hook
myBuildHook :: PackageDescription
-> LocalBuildInfo
-> UserHooks
-> BuildFlags
-> IO ()
myBuildHook pdesc lbinfo uhooks bflags = do
gitVersion <- inferVersionFromGit
let lastVersion = pkgVersion $ package pdesc
when (gitVersion /= lastVersion) $
die("The version reported by git '" ++ showVersion gitVersion ++
"' has changed since last time this package was configured (version was '" ++
showVersion lastVersion ++ "' back then), please re-configure package")
buildHook simpleUserHooks pdesc lbinfo uhooks bflags
-- |Infer package version from Git tags. Uses `git describe` to infer 'Version'.
inferVersionFromGit :: IO Version
inferVersionFromGit = do
ver_line <- init `liftM` readProcess "git"
[ "describe"
, "--abbrev=5"
, "--tags"
, "--match=v[0-9].[0-9][0-9]"
, "--dirty"
, "--long"
] ""
-- ver_line <- return "v0.1-42-gf9f4eb3-dirty"
let versionStr = (head ver_line == 'v') `assert` replaceFirst '-' '.' (tail ver_line)
Just version = listToMaybe [ p | (p, "") <- readP_to_S parseVersion versionStr ]
return version
-- |Helper for replacing first occurence of character by another one.
replaceFirst :: Eq a => a -> a -> [a] -> [a]
replaceFirst _ _ [] = []
replaceFirst o r (x:xs) | o == x = r : xs
| otherwise = x : replaceFirst o r xs
@hvr
Owner

Alternative approach to the one described in http://www.hyperedsoftware.com/blog/entries/build-info-gen.html

@Athas

Note that this approach is no longer valid, as Cabal does not permit tags in package versions. A shame, because I feel this approach is cleaner than generating a new module, although I understand why the Cabal developers made the choice.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Something went wrong with that request. Please try again.