aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/src/Environment.hs
blob: 0690278c0cc6370aadeaacd27196a922e4ddb31d (plain) (blame)
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
{-
 - Copyright 2015 Egor Tensin <Egor.Tensin@gmail.com>
 - This file is licensed under the terms of the MIT License.
 - See LICENSE.txt for details.
-}

module Environment ( saveToRegistry
                   , saveToRegistryWithPrompt
                   , queryFromRegistry
                   , wipeFromRegistry
                   , wipeFromRegistryWithPrompt
                   , getEnv
                   , splitPaths
                   , joinPaths
                   , RegistryBasedEnvironment(..) ) where

import Control.Monad ( liftM, when )
import Data.List ( intercalate )
import Data.List.Split ( splitOn )
import Data.Maybe ( fromMaybe )
import qualified System.Environment ( lookupEnv )
import System.IO.Error ( catchIOError, isDoesNotExistError )

import qualified Registry
import qualified Utils ( promptToContinue )

data RegistryBasedEnvironment = CurrentUserEnvironment
                              | AllUsersEnvironment
                              deriving (Eq, Show)

registrySubKeyPath :: RegistryBasedEnvironment -> String
registrySubKeyPath CurrentUserEnvironment = "Environment"
registrySubKeyPath AllUsersEnvironment = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment"

registryKey :: RegistryBasedEnvironment -> Registry.KeyHandle
registryKey CurrentUserEnvironment = Registry.hkcu
registryKey AllUsersEnvironment = Registry.hklm

registryKeyPath :: RegistryBasedEnvironment -> String
registryKeyPath CurrentUserEnvironment = "HKCU\\" ++ registrySubKeyPath CurrentUserEnvironment
registryKeyPath AllUsersEnvironment = "HKLM\\" ++ registrySubKeyPath AllUsersEnvironment

saveToRegistry :: RegistryBasedEnvironment -> String -> String -> IO ()
saveToRegistry env = Registry.setString (registryKey env) (registrySubKeyPath env)

saveToRegistryWithPrompt :: RegistryBasedEnvironment -> String -> String -> IO ()
saveToRegistryWithPrompt env name value = do
  putStrLn $ "Saving variable '" ++ name ++ "' to '" ++ registryKeyPath env ++ "'..."
  oldValue <- queryFromRegistry env name
  putStrLn $ "\tOld value: " ++ oldValue
  putStrLn $ "\tNew value: " ++ value
  agreed <- Utils.promptToContinue
  when agreed $ saveToRegistry env name value

queryFromRegistry :: RegistryBasedEnvironment -> String -> IO String
queryFromRegistry env name = catchIOError (Registry.getString (registryKey env) (registrySubKeyPath env) name) emptyIfDoesNotExist
  where
    emptyIfDoesNotExist :: IOError -> IO String
    emptyIfDoesNotExist e = if isDoesNotExistError e then return "" else ioError e

wipeFromRegistry :: RegistryBasedEnvironment -> String -> IO ()
wipeFromRegistry env name = catchIOError (Registry.delValue (registryKey env) (registrySubKeyPath env) name) ignoreIfDoesNotExist
  where
    ignoreIfDoesNotExist :: IOError -> IO ()
    ignoreIfDoesNotExist e = if isDoesNotExistError e then return () else ioError e

wipeFromRegistryWithPrompt :: RegistryBasedEnvironment -> String -> IO ()
wipeFromRegistryWithPrompt env name = do
  putStrLn $ "Deleting variable '" ++ name ++ "' from '" ++ registryKeyPath env ++ "'..."
  agreed <- Utils.promptToContinue
  when agreed $ wipeFromRegistry env name

getEnv :: String -> IO String
getEnv = liftM (fromMaybe "") . System.Environment.lookupEnv

pathSep :: String
pathSep = ";"

splitPaths :: String -> [String]
splitPaths = filter (not . null) . splitOn pathSep

joinPaths :: [String] -> String
joinPaths = intercalate pathSep . filter (not . null)