blob: 571012d0950186d464ec83a24f393e32ee5c4c75 (
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
|
-- |
-- Copyright : (c) 2015 Egor Tensin <Egor.Tensin@gmail.com>
-- License : MIT
-- Maintainer : Egor.Tensin@gmail.com
-- Stability : experimental
module Main (main) where
import Control.Monad (void, when)
import Control.Monad.Trans.Except (catchE, runExceptT, throwE)
import Data.List (union)
import System.IO.Error (ioError, isDoesNotExistError)
import Options.Applicative
import qualified Windows.Environment as Env
import Prompt
import PromptMessage
data Options = Options
{ optName :: Env.VarName
, optYes :: Bool
, optGlobal :: Bool
, optPaths :: [Env.VarValue]
} deriving (Eq, Show)
optionParser :: Parser Options
optionParser = Options
<$> optNameDesc
<*> optYesDesc
<*> optGlobalDesc
<*> optPathsDesc
where
optNameDesc = strOption
$ long "name" <> short 'n'
<> metavar "NAME" <> value "PATH"
<> help "Variable name ('PATH' by default)"
optYesDesc = switch
$ long "yes" <> short 'y'
<> help "Skip confirmation prompt"
optGlobalDesc = switch
$ long "global" <> short 'g'
<> help "Add for all users"
optPathsDesc = many $ argument str
$ metavar "PATH"
<> help "Directories to add"
main :: IO ()
main = execParser parser >>= addPath
where
parser = info (helper <*> optionParser) $
fullDesc <> progDesc "Add directories to your PATH"
addPath :: Options -> IO ()
addPath options = runExceptT doAddPath >>= either ioError return
where
varName = optName options
pathsToAdd = optPaths options
forAllUsers = optGlobal options
profile
| forAllUsers = Env.AllUsers
| otherwise = Env.CurrentUser
skipPrompt = optYes options
emptyIfMissing e
| isDoesNotExistError e = return ""
| otherwise = throwE e
doAddPath = do
oldValue <- Env.query profile varName `catchE` emptyIfMissing
let oldPaths = Env.pathSplit oldValue
let newPaths = oldPaths `union` pathsToAdd
when (length oldPaths /= length newPaths) $ do
let newValue = Env.pathJoin newPaths
let promptAnd = if skipPrompt
then withoutPrompt
else withPrompt $ oldNewMessage profile varName oldValue newValue
let engrave = Env.engrave profile varName newValue
void $ promptAnd engrave
|