blob: 6f2174bb2afbd751f523a3b9261421dc543e98f2 (
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
84
85
|
-- |
-- Copyright : (c) 2015 Egor Tensin <Egor.Tensin@gmail.com>
-- License : MIT
-- Maintainer : Egor.Tensin@gmail.com
-- Stability : experimental
-- Portability : Windows-only
module Main (main) where
import Control.Monad (void, when)
import Control.Monad.Trans.Except (catchE, runExceptT, throwE)
import Data.List ((\\))
import System.IO.Error (ioError, isDoesNotExistError)
import Options.Applicative
import qualified WindowsEnv
import Utils.Prompt
import Utils.PromptMessage
data Options = Options
{ optName :: WindowsEnv.VarName
, optYes :: Bool
, optGlobal :: Bool
, optPaths :: [WindowsEnv.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 "Remove for all users"
optPathsDesc = many $ argument str
$ metavar "PATH"
<> help "Directories to remove"
main :: IO ()
main = execParser parser >>= removePath
where
parser = info (helper <*> optionParser) $
fullDesc <> progDesc "Remove directories from your PATH"
removePath :: Options -> IO ()
removePath options = runExceptT doRemovePath >>= either ioError return
where
varName = optName options
pathsToRemove = optPaths options
forAllUsers = optGlobal options
skipPrompt = optYes options
emptyIfMissing e
| isDoesNotExistError e = return ""
| otherwise = throwE e
doRemovePath = do
removePathFrom WindowsEnv.CurrentUser
when forAllUsers $
removePathFrom WindowsEnv.AllUsers
removePathFrom profile = do
oldValue <- WindowsEnv.query profile varName `catchE` emptyIfMissing
let oldPaths = WindowsEnv.pathSplit oldValue
let newPaths = oldPaths \\ pathsToRemove
when (length oldPaths /= length newPaths) $ do
let newValue = WindowsEnv.pathJoin newPaths
let promptAnd = if skipPrompt
then withoutPrompt
else withPrompt $ oldNewMessage profile varName oldValue newValue
let engrave = WindowsEnv.engrave profile varName newValue
void $ promptAnd engrave
|