1 {-# LANGUAGE CPP #-}
    2 {-
    3 Version-related utilities. See the Makefile for details of our version
    4 numbering policy.
    5 -}
    6 
    7 module Hledger.Cli.Version (
    8                             version
    9                            ,progversionstr
   10                            ,binaryfilename
   11 )
   12 where
   13 import Data.List
   14 import System.Info (os, arch)
   15 import Text.Printf
   16 
   17 import Hledger.Utils
   18 
   19 
   20 -- version and PATCHLEVEL are set by the make process
   21 
   22 version :: String
   23 version       = "0.14.98"
   24 
   25 patchlevel :: String
   26 #ifdef PATCHLEVEL
   27 patchlevel = "." ++ show (PATCHLEVEL :: Int) -- must be numeric !
   28 #else
   29 patchlevel = ""
   30 #endif
   31 
   32 buildversion :: String
   33 buildversion  = version ++ patchlevel :: String
   34 
   35 -- | Given a program name, return a human-readable version string.  For
   36 -- development builds, at least non-cabal builds, the patch level (ie the
   37 -- number of patches applied since last release tag) will also be
   38 -- included.
   39 progversionstr :: String -> String
   40 progversionstr progname = progname ++ "-" ++ versionstr ++ configmsg
   41     where
   42       versionstr = prettify $ splitAtElement '.' buildversion
   43           where
   44             prettify (major:minor:bugfix:patches:[]) =
   45                 printf "%s.%s%s%s" major minor bugfix' patches'
   46                     where
   47                       bugfix'
   48                           | bugfix `elem` ["0"{-,"98","99"-}] = ""
   49                           | otherwise = '.' : bugfix
   50                       patches'
   51                           | patches/="0" = "+"++patches
   52                           | otherwise = ""
   53             prettify s = intercalate "." s
   54 
   55       configmsg | null buildflags = ""
   56                 | otherwise       = " with " ++ intercalate ", " buildflags
   57 
   58       buildflags = []
   59 
   60 -- | Given a program name, return a precise platform-specific executable
   61 -- name suitable for naming downloadable binaries.  Can raise an error if
   62 -- the version and patch level was not defined correctly at build time.
   63 binaryfilename :: String -> String
   64 binaryfilename progname = prettify $ splitAtElement '.' buildversion
   65                 where
   66                   prettify (major:minor:bugfix:patches:[]) =
   67                       printf "%s-%s.%s%s%s-%s-%s%s" progname major minor bugfix' patches' os' arch suffix
   68                           where
   69                             bugfix'
   70                                 | bugfix `elem` ["0"{-,"98","99"-}] = ""
   71                                 | otherwise = '.' : bugfix
   72                             patches'
   73                                 | patches/="0" = '+' : patches
   74                                 | otherwise = ""
   75                             (os',suffix)
   76                                 | os == "darwin"  = ("mac","")
   77                                 | os == "mingw32" = ("windows",".exe")
   78                                 | otherwise       = (os,"")
   79                   prettify (major:minor:bugfix:[]) = prettify [major,minor,bugfix,"0"]
   80                   prettify (major:minor:[])        = prettify [major,minor,"0","0"]
   81                   prettify (major:[])              = prettify [major,"0","0","0"]
   82                   prettify []                      = error' "VERSION is empty, please fix"
   83                   prettify _                       = error' "VERSION has too many components, please fix"