Inject cabal version or VCS version as a CPP macro

Hi, I'd like my program to print something like "this is $program 1.0.4 git 45fea6b" when invoked with --version, or at least just the 1.0.4 part. Can Cabal expose the version as a preprocessor macro by default, or do I have to use Build-Type: Custom and add a preprocessing step of my own? -- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/

For each package "myPackage" Cabal generates a module containing, among other things, the package's version as a Haskell value:
import Paths_myPackage ( version ) import Data.Version ( showVersion ) main = showVersion version
See also "Accessing data files from package code" in
http://www.haskell.org/cabal/users-guide/
I do not now how to expose information from the VCS.
2012/2/22 Eugene Kirpichov
Hi,
I'd like my program to print something like "this is $program 1.0.4 git 45fea6b" when invoked with --version, or at least just the 1.0.4 part.
Can Cabal expose the version as a preprocessor macro by default, or do I have to use Build-Type: Custom and add a preprocessing step of my own?

Thanks, this is exactly what I was looking for!
I might look some more into exposing VCS tags too, however.
On Wed, Feb 22, 2012 at 12:25 PM, Roel van Dijk
For each package "myPackage" Cabal generates a module containing, among other things, the package's version as a Haskell value:
import Paths_myPackage ( version ) import Data.Version ( showVersion ) main = showVersion version
See also "Accessing data files from package code" in http://www.haskell.org/cabal/users-guide/
I do not now how to expose information from the VCS.
2012/2/22 Eugene Kirpichov
: Hi,
I'd like my program to print something like "this is $program 1.0.4 git 45fea6b" when invoked with --version, or at least just the 1.0.4 part.
Can Cabal expose the version as a preprocessor macro by default, or do I have to use Build-Type: Custom and add a preprocessing step of my own?
-- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/

I have a project at work that embeds the Mercurial version in the
final executable. I use Template Haskell to call the hg executable and
parse its output. Here's the relevant code snippet:
putStrLn $ "Mercurial commit: " ++ $(do
let getChangeset s =
let (k, v') = break (== ':') s
v = dropWhile isSpace $ drop 1 v'
in if k == "changeset" then Just v else Nothing
res <- qRunIO $ readProcess "hg" ["heads"] ""
let cs = mapMaybe getChangeset $ lines res
lift $ case cs of
x:_ -> x
[] -> "unknown")
On Wed, Feb 22, 2012 at 10:37 AM, Eugene Kirpichov
Thanks, this is exactly what I was looking for!
I might look some more into exposing VCS tags too, however.
On Wed, Feb 22, 2012 at 12:25 PM, Roel van Dijk
wrote: For each package "myPackage" Cabal generates a module containing, among other things, the package's version as a Haskell value:
import Paths_myPackage ( version ) import Data.Version ( showVersion ) main = showVersion version
See also "Accessing data files from package code" in http://www.haskell.org/cabal/users-guide/
I do not now how to expose information from the VCS.
2012/2/22 Eugene Kirpichov
: Hi,
I'd like my program to print something like "this is $program 1.0.4 git 45fea6b" when invoked with --version, or at least just the 1.0.4 part.
Can Cabal expose the version as a preprocessor macro by default, or do I have to use Build-Type: Custom and add a preprocessing step of my own?
-- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe

Whoa, I didn't think about using Template Haskell here. Thanks.
Perhaps this should be abstracted into a library.
On Wed, Feb 22, 2012 at 12:40 PM, Michael Snoyman
I have a project at work that embeds the Mercurial version in the final executable. I use Template Haskell to call the hg executable and parse its output. Here's the relevant code snippet:
putStrLn $ "Mercurial commit: " ++ $(do let getChangeset s = let (k, v') = break (== ':') s v = dropWhile isSpace $ drop 1 v' in if k == "changeset" then Just v else Nothing res <- qRunIO $ readProcess "hg" ["heads"] "" let cs = mapMaybe getChangeset $ lines res lift $ case cs of x:_ -> x [] -> "unknown")
On Wed, Feb 22, 2012 at 10:37 AM, Eugene Kirpichov
wrote: Thanks, this is exactly what I was looking for!
I might look some more into exposing VCS tags too, however.
On Wed, Feb 22, 2012 at 12:25 PM, Roel van Dijk
wrote: For each package "myPackage" Cabal generates a module containing, among other things, the package's version as a Haskell value:
import Paths_myPackage ( version ) import Data.Version ( showVersion ) main = showVersion version
See also "Accessing data files from package code" in http://www.haskell.org/cabal/users-guide/
I do not now how to expose information from the VCS.
2012/2/22 Eugene Kirpichov
: Hi,
I'd like my program to print something like "this is $program 1.0.4
git
45fea6b" when invoked with --version, or at least just the 1.0.4 part.
Can Cabal expose the version as a preprocessor macro by default, or do I have to use Build-Type: Custom and add a preprocessing step of my own?
-- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/
_______________________________________________ Haskell-Cafe mailing list Haskell-Cafe@haskell.org http://www.haskell.org/mailman/listinfo/haskell-cafe
-- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/

Hi,
Eugene Kirpichov
I'd like my program to print something like "this is $program 1.0.4 git 45fea6b" when invoked with --version, or at least just the 1.0.4 part.
Here's some proof-of-concept code we use slightly modified in production here for over a year now successfully: https://gist.github.com/656738 The primary goal was to have a reliable version number (allowing to find the exact corresponding git-commit in the source-code repository), and to be able to detect when that version number is unreliable (there's nothing more annoying than wasting time debugging the wrong source-code...). The idea is to dynamically infer and overwrite cabal's version when building from the git repository, and have it accessible via the cabal's auto-generated "Paths_<pkg-name>" module Data.Version... ...and when creating a source-dist, via "runghc Setup.hs sdist" the current dynamic git-version string is embedded into the generated .tar.gz's .cabal file, so that the source-distribution is just a plain simple .cabal project (that could be uploaded to hackage) hth, hvr --

Hey,
I created a small package:
http://hackage.haskell.org/package/vcs-revision, repo
http://github.com/jkff/vcs-revision
It can be used like this:
{-# LANGUAGE TemplateHaskell #-}
import Distribution.VcsRevision.Git
import Language.Haskell.TH.Syntax
showMyGitVersion :: String
showMyGitVersion = $(do
v <- qRunIO getRevision
lift $ case v of
Nothing -> "<none>"
Just (hash,True) -> hash ++ " (with local modifications)"
Just (hash,False) -> hash)
On Wed, Feb 22, 2012 at 2:26 PM, Herbert Valerio Riedel
Hi,
Eugene Kirpichov
writes: I'd like my program to print something like "this is $program 1.0.4 git 45fea6b" when invoked with --version, or at least just the 1.0.4 part.
Here's some proof-of-concept code we use slightly modified in production here for over a year now successfully:
https://gist.github.com/656738
The primary goal was to have a reliable version number (allowing to find the exact corresponding git-commit in the source-code repository), and to be able to detect when that version number is unreliable (there's nothing more annoying than wasting time debugging the wrong source-code...).
The idea is to dynamically infer and overwrite cabal's version when building from the git repository, and have it accessible via the cabal's auto-generated "Paths_<pkg-name>" module Data.Version...
...and when creating a source-dist, via "runghc Setup.hs sdist" the current dynamic git-version string is embedded into the generated .tar.gz's .cabal file, so that the source-distribution is just a plain simple .cabal project (that could be uploaded to hackage)
hth, hvr --
-- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/

Eugene Kirpichov
It can be used like this:
{-# LANGUAGE TemplateHaskell #-} import Distribution.VcsRevision.Git import Language.Haskell.TH.Syntax
showMyGitVersion :: String showMyGitVersion = $(do v <- qRunIO getRevision lift $ case v of Nothing -> "<none>" Just (hash,True) -> hash ++ " (with local modifications)" Just (hash,False) -> hash)
Btw, I'm wondering (haven't tried myself), when using TH to generate the version string, does GHC's and/or cabal's dependency tracking a) reliably refresh the generated hash so that you can be sure it's the git-commit id compiled into the binary is reliable, and b) avoid re-generating the TH file and redundant recompilation if the git commit-id hasn't changed? hvr --

Eugene Kirpichov
writes: It can be used like this:
{-# LANGUAGE TemplateHaskell #-} import Distribution.VcsRevision.Git import Language.Haskell.TH.Syntax
showMyGitVersion :: String showMyGitVersion = $(do v <- qRunIO getRevision lift $ case v of Nothing -> "<none>" Just (hash,True) -> hash ++ " (with local modifications)" Just (hash,False) -> hash)
Btw, I'm wondering (haven't tried myself), when using TH to generate the version string, does GHC's and/or cabal's dependency tracking
a) reliably refresh the generated hash so that you can be sure it's the git-commit id compiled into the binary is reliable, and
b) avoid re-generating the TH file and redundant recompilation if the git commit-id hasn't changed?
Do you mean all this in the context where this resides in a library rather
On Wed, Feb 22, 2012 at 2:57 PM, Herbert Valerio Riedel
hvr --
-- Eugene Kirpichov Principal Engineer, Mirantis Inc. http://www.mirantis.com/ Editor, http://fprog.ru/
participants (4)
-
Eugene Kirpichov
-
Herbert Valerio Riedel
-
Michael Snoyman
-
Roel van Dijk