-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathSetup.hs
120 lines (111 loc) · 5.19 KB
/
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
{-# LANGUAGE CPP #-}
import Data.Char (isDigit)
import Data.List (intercalate)
import Data.Monoid ((<>))
import Distribution.PackageDescription
import Distribution.Verbosity
import Distribution.Simple
import Distribution.Simple.Setup (BuildFlags(..), ReplFlags(..), TestFlags(..), fromFlag)
import Distribution.Simple.LocalBuildInfo
import Distribution.Simple.BuildPaths (autogenModulesDir)
import Distribution.Simple.Utils (createDirectoryIfMissingVerbose, rewriteFile, rawSystemStdout)
#ifndef MIN_VERSION_Cabal
#if __GLASGOW_HASKELL__ <= 710
-- GHC 7.10 and earlier do not support the MIN_VERSION_Cabal macro.
#define MIN_VERSION_Cabal(a,b,c) 0
#endif
#endif
#if !MIN_VERSION_Cabal(2,0,0)
import Data.Version (showVersion)
#endif
--
-- /===-_---~~~~~~~~~------____
-- |===-~___ _,-'
-- -==\\ `//~\\ ~~~~`---.___.-~~
-- ______-==| | | \\ _-~`
-- __--~~~ ,-/-==\\ | | `\ ,'
-- _-~ /' | \\ / / \ /
-- .' / | \\ /' / \ /'
-- / ____ / | \`\.__/-~~ ~ \ _ _/' / \/'
-- /-'~ ~~~~~---__ | ~-/~ ( ) /' _--~`
-- \_| / _) ; ), __--~~
-- '~~--_/ _-~/- / \ '-~ \
-- {\__--_/} / \\_>- )<__\ \
-- /' (_/ _-~ | |__>--<__| |
-- |0 0 _/) )-~ | |__>--<__| |
-- / /~ ,_/ / /__>---<__/ |
-- o o _// /-~_>---<__-~ /
-- (^(~ /~_>---<__- _-~
-- ,/| /__>--<__/ _-~
-- ,//('( |__>--<__| / .----_
-- ( ( ')) |__>--<__| | /' _---_~\
-- `-)) )) ( |__>--<__| | /' / ~\`\
-- ,/,'//( ( \__>--<__\ \ /' // ||
-- ,( ( ((, )) ~-__>--<_~-_ ~--____---~' _/'/ /'
-- `~/ )` ) ,/| ~-_~>--<_/-__ __-~ _/
-- ._-~//( )/ )) ` ~~-'_/_/ /~~~~~~~__--~
-- ;'( ')/ ,)( ~~~~~~~~~~
-- ' ') '( (/
-- ' ' `
--
-- NOTE This file differs from the standard Ambiata Setup.hs in that we use
-- NOTE 'autoconfUserHooks' below instead of 'simpleUserHooks'. Be sure to
-- NOTE take this in to account when upgrading.
--
main :: IO ()
main =
let hooks = autoconfUserHooks
in defaultMainWithHooks hooks {
preConf = \args flags -> do
createDirectoryIfMissingVerbose silent True "gen"
(preConf hooks) args flags
, sDistHook = \pd mlbi uh flags -> do
genBuildInfo silent pd
(sDistHook hooks) pd mlbi uh flags
, buildHook = \pd lbi uh flags -> do
genBuildInfo (fromFlag $ buildVerbosity flags) pd
(buildHook hooks) pd lbi uh flags
, replHook = \pd lbi uh flags args -> do
genBuildInfo (fromFlag $ replVerbosity flags) pd
(replHook hooks) pd lbi uh flags args
, testHook = \args pd lbi uh flags -> do
genBuildInfo (fromFlag $ testVerbosity flags) pd
(testHook hooks) args pd lbi uh flags
}
genBuildInfo :: Verbosity -> PackageDescription -> IO ()
genBuildInfo verbosity pkg = do
createDirectoryIfMissingVerbose verbosity True "gen"
let pname = unPackageName . pkgName . package $ pkg
version = pkgVersion . package $ pkg
name = "BuildInfo_" ++ (map (\c -> if c == '-' then '_' else c) pname)
targetHs = "gen/" ++ name ++ ".hs"
targetText = "gen/version.txt"
t <- timestamp verbosity
gv <- gitVersion verbosity
let v = showVersion version
let buildVersion = intercalate "-" [v, t, gv]
rewriteFile targetHs $ unlines [
"module " ++ name ++ " where"
, "import Prelude"
, "data RuntimeBuildInfo = RuntimeBuildInfo { buildVersion :: String, timestamp :: String, gitVersion :: String }"
, "buildInfo :: RuntimeBuildInfo"
, "buildInfo = RuntimeBuildInfo \"" ++ v ++ "\" \"" ++ t ++ "\" \"" ++ gv ++ "\""
, "buildInfoVersion :: String"
, "buildInfoVersion = \"" ++ buildVersion ++ "\""
]
rewriteFile targetText buildVersion
gitVersion :: Verbosity -> IO String
gitVersion verbosity = do
ver <- rawSystemStdout verbosity "git" ["log", "--pretty=format:%h", "-n", "1"]
notModified <- ((>) 1 . length) `fmap` rawSystemStdout verbosity "git" ["status", "--porcelain"]
return $ ver ++ if notModified then "" else "-M"
timestamp :: Verbosity -> IO String
timestamp verbosity =
rawSystemStdout verbosity "date" ["+%Y%m%d%H%M%S"] >>= \s ->
case splitAt 14 s of
(d, n : []) ->
if (length d == 14 && filter isDigit d == d)
then return d
else fail $ "date has failed to produce the correct format [" <> s <> "]."
_ ->
fail $ "date has failed to produce a date long enough [" <> s <> "]."