Created

Embed URL

HTTPS clone URL

SSH clone URL

You can clone with HTTPS or SSH.

Download Gist

Example CABAL Setup.hs file for automatic package versioning via `git describe`

View Setup.hs
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81
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
Owner
hvr commented

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

Athas commented

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.