-
Notifications
You must be signed in to change notification settings - Fork 12
/
Copy pathInstaller.hs
128 lines (102 loc) · 5.06 KB
/
Installer.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
121
122
123
124
125
126
127
128
{-# LANGUAGE OverloadedStrings #-}
module Installer(installer) where
import Config
import Control.Monad
import Data.String
import Data.List.Extra
import Development.NSIS as NSIS
import Development.NSIS.Plugins.EnvVarUpdate
installer :: FilePath -> Arch -> (Program -> Version) -> String
installer projRoot arch version = nsis $ do
forM_ [minBound..maxBound] $ \prog ->
constantStr (upper $ show prog) (fromString $ version prog)
constantStr "ARCH" (fromString $ showArch arch)
constantStr "APPNAME" "MinGHC-$GHC-$ARCH"
name "$APPNAME"
outFile "minghc-$GHC-$ARCH.exe"
-- See: http://stackoverflow.com/questions/1831810/is-appdata-now-the-correct-place-to-install-user-specific-apps-which-modify-t/1845459#1845459
installDir "$LOCALAPPDATA/Programs/minghc-$GHC-$ARCH"
installIcon $ fromString projRoot & "/ico/minghc-install.ico"
uninstallIcon $ fromString projRoot & "/ico/minghc-uninstall.ico"
page Components
page Directory
page InstFiles
unpage Confirm
unpage InstFiles
-- Precedence: low to high
let pathAddRemove = ["$INSTDIR/bin"
,"$INSTDIR/ghc-$GHC/bin"
,"$INSTDIR/ghc-$GHC/mingw/bin"
,"$INSTDIR/git-$GIT/usr/bin"
,"$INSTDIR/git-$GIT/cmd"
]
let pathPreExisting = ["$APPDATA/cabal/bin"]
-- (potentially) preexisting paths should precede (i.e. have lower precedence than) new paths
let path = pathPreExisting ++ pathAddRemove
let uninstallRegKey = (HKEY_CURRENT_USER, "Software\\Microsoft\\Windows\\CurrentVersion\\Uninstall\\$APPNAME")
section "Install" [Required, Description "Install GHC, Cabal, and PortableGit"] $ do
setOutPath "$INSTDIR"
buildUninstaller uninstallRegKey
let rootArchives = map (\p -> dest (version p) arch p) [GHC, Git]
mapM_ (file [] . fromString) rootArchives
file [Recursive] "bin/7z.*"
file [Recursive] "bin/minghc-post-install.exe.7z"
file [Recursive] "bin/all-*"
--file [Recursive] $ fromString $ concat ["bin/", showArchAbbr arch, "-*"]
file [Recursive] $ fromString $ concat
[ "bin/stack-"
, version Stack
, "-"
, showArch arch
, ".zip"
]
execWait "\"$INSTDIR/bin/7z.exe\" x -y \"-o$INSTDIR/bin\" \"$INSTDIR/bin/minghc-post-install.exe.7z\""
NSIS.delete [] "$INSTDIR/bin/minghc-post-install.exe.7z"
let quote :: String -> String
quote x = concat ["\"", x, "\""]
execWait $ fromString $ unwords $ map quote
$ "$INSTDIR/bin/minghc-post-install.exe"
: rootArchives
NSIS.delete [] "$INSTDIR/bin/minghc-post-install.exe"
createDirectory "$INSTDIR/switch"
let switcherAliases = [fromString ("$INSTDIR/switch/minghc" ++ x ++ ".bat") | x <- switcherNameSuffixes]
forM_ switcherAliases $ flip writeFileLines $
["set PATH=" & x & ";%PATH%" | x <- path] ++
["ghc --version"]
section "Add programs to PATH" [Description "Put GHC, Cabal, and PortableGit on the %PATH%"] $ do
mapM_ (setEnvVarPrepend HKCU "PATH") path
section "Add switcher to PATH" [Description "Put minghc-$GHC.bat on the %PATH%, which puts the other programs on the %PATH%"] $ do
setEnvVarPrepend HKCU "PATH" "$INSTDIR/switch"
uninstall $ do
rmdir [Recursive] "$INSTDIR"
mapM_ (setEnvVarRemove HKCU "PATH") $ "$INSTDIR/switch" : pathAddRemove
uncurry deleteRegKey uninstallRegKey
where
switcherNameSuffixes
= "" -- no suffix
: map (concatMap ('-':))
[[showArchAbbr arch]
,[version GHC]
,[version GHC, showArchAbbr arch]
,[majorVersion (version GHC)]
,[majorVersion (version GHC), showArchAbbr arch]]
buildUninstaller uninstallRegKey = do
let uninstaller = "uninstall.exe"
writeUninstaller uninstaller
let setUninstallStr = uncurry writeRegStr uninstallRegKey
let setUninstallDWORD = uncurry writeRegDWORD uninstallRegKey
-- See possible settings here: http://nsis.sourceforge.net/Add_uninstall_information_to_Add/Remove_Programs
setUninstallStr "DisplayName" "$APPNAME"
setUninstallStr "UninstallString" ("$INSTDIR/" & uninstaller)
setUninstallStr "DisplayIcon" ("$INSTDIR/" & uninstaller)
setUninstallStr "InstallLocation" "$INSTDIR"
setUninstallStr "Readme" "https://github.com/fpco/minghc/blob/master/README.md"
setUninstallStr "DisplayVersion" (fromString $ version GHC)
setUninstallDWORD "NoModify" 1
setUninstallDWORD "NoRepair" 1
showArchAbbr :: Arch -> String
showArchAbbr Arch32 = "32"
showArchAbbr Arch64 = "64"
majorVersion :: Version -> Version
majorVersion ver = intercalate "." (take 2 parts)
where parts = wordsBy (== '.') ver