From f5f056d79087f4ee3038643d02a82c1ad574553f Mon Sep 17 00:00:00 2001 From: Egor Tensin Date: Sun, 11 Jun 2017 03:05:02 +0300 Subject: refactoring The fact whether the registry value was a regular or an expandable string is now propagated up to the `Environment` module (and even further to the apps). This was done to get rid of these weird `setString*` functions (and the like). I don't feel like I've came up with the right abstractions yet though, so there's more work on this to come. --- app/AddPath.hs | 39 ++++++++++++++++++++++++--------------- app/ListPaths.hs | 4 ++-- app/RemovePath.hs | 16 +++++++++++----- app/SetEnv.hs | 4 ++-- app/Utils/PromptMessage.hs | 4 ++-- 5 files changed, 41 insertions(+), 26 deletions(-) (limited to 'app') diff --git a/app/AddPath.hs b/app/AddPath.hs index fc8d5de..1993b4a 100644 --- a/app/AddPath.hs +++ b/app/AddPath.hs @@ -20,11 +20,11 @@ import Utils.Prompt import Utils.PromptMessage data Options = Options - { optName :: WindowsEnv.VarName + { optName :: WindowsEnv.VarName , optYes :: Bool , optGlobal :: Bool , optPrepend :: Bool - , optPaths :: [WindowsEnv.VarValue] + , optPaths :: [String] } deriving (Eq, Show) optionParser :: Parser Options @@ -62,7 +62,7 @@ addPath :: Options -> IO () addPath options = runExceptT doAddPath >>= either ioError return where varName = optName options - pathsToAdd = optPaths options + pathsToAdd = nub $ optPaths options forAllUsers = optGlobal options profile @@ -72,22 +72,31 @@ addPath options = runExceptT doAddPath >>= either ioError return skipPrompt = optYes options prepend = optPrepend options - append xs ys - | prepend = ys ++ xs - | otherwise = xs ++ ys + mergePaths old new + | prepend = new ++ old + | otherwise = old ++ new emptyIfMissing e - | isDoesNotExistError e = return "" + | isDoesNotExistError e = defaultValue | otherwise = throwE e + defaultValue = do + expandedPaths <- mapM WindowsEnv.expand pathsToAdd + if pathsToAdd == expandedPaths + then return $ WindowsEnv.VarValue False "" + else return $ WindowsEnv.VarValue True "" + doAddPath = do oldValue <- WindowsEnv.query profile varName `catchE` emptyIfMissing - let oldPaths = WindowsEnv.pathSplit oldValue - let newPaths = (nub pathsToAdd) \\ oldPaths + let oldPaths = WindowsEnv.pathSplit $ show oldValue + let newPaths = pathsToAdd \\ oldPaths unless (null newPaths) $ do - let newValue = WindowsEnv.pathJoin $ append oldPaths newPaths - let promptAnd = if skipPrompt - then withoutPrompt - else withPrompt $ oldNewMessage profile varName oldValue newValue - let engrave = WindowsEnv.engrave profile varName newValue - void $ promptAnd engrave + let newValue = WindowsEnv.VarValue (WindowsEnv.varValueExpandable oldValue) $ WindowsEnv.pathJoin (mergePaths oldPaths newPaths) + promptAndEngrave oldValue newValue + + promptAndEngrave oldValue newValue = do + let promptAnd = if skipPrompt + then withoutPrompt + else withPrompt $ oldNewMessage profile varName (show oldValue) (show newValue) + let engrave = WindowsEnv.engrave profile varName newValue + void $ promptAnd engrave diff --git a/app/ListPaths.hs b/app/ListPaths.hs index 4193ad6..8a31cb8 100644 --- a/app/ListPaths.hs +++ b/app/ListPaths.hs @@ -22,7 +22,7 @@ import qualified WindowsEnv data WhichPaths = All | ExistingOnly | MissingOnly deriving (Eq, Show) -shouldListPath :: WhichPaths -> WindowsEnv.VarValue -> IO Bool +shouldListPath :: WhichPaths -> String -> IO Bool shouldListPath All = return . const True shouldListPath ExistingOnly = doesDirectoryExist shouldListPath MissingOnly = fmap not . doesDirectoryExist @@ -72,7 +72,7 @@ listPaths options = runExceptT doListPaths >>= either ioError return query = queryFrom $ optSource options queryFrom Environment = lift $ fromMaybe "" <$> lookupEnv varName - queryFrom (Registry profile) = WindowsEnv.query profile varName + queryFrom (Registry profile) = show <$> WindowsEnv.query profile varName filterPaths = filterM (shouldListPath whichPaths . WindowsEnv.pathExpanded) diff --git a/app/RemovePath.hs b/app/RemovePath.hs index bc2a076..2d0d47c 100644 --- a/app/RemovePath.hs +++ b/app/RemovePath.hs @@ -22,7 +22,7 @@ data Options = Options { optName :: WindowsEnv.VarName , optYes :: Bool , optGlobal :: Bool - , optPaths :: [WindowsEnv.VarValue] + , optPaths :: [String] } deriving (Eq, Show) optionParser :: Parser Options @@ -63,9 +63,15 @@ removePath options = runExceptT doRemovePath >>= either ioError return skipPrompt = optYes options emptyIfMissing e - | isDoesNotExistError e = return "" + | isDoesNotExistError e = defaultValue | otherwise = throwE e + defaultValue = do + expandedPaths <- mapM WindowsEnv.expand pathsToRemove + if pathsToRemove == expandedPaths + then return $ WindowsEnv.VarValue False "" + else return $ WindowsEnv.VarValue True "" + doRemovePath = do removePathFrom WindowsEnv.CurrentUser when forAllUsers $ @@ -73,12 +79,12 @@ removePath options = runExceptT doRemovePath >>= either ioError return removePathFrom profile = do oldValue <- WindowsEnv.query profile varName `catchE` emptyIfMissing - let oldPaths = WindowsEnv.pathSplit oldValue + let oldPaths = WindowsEnv.pathSplit $ show oldValue let newPaths = filter (flip notElem pathsToRemove) oldPaths when (length oldPaths /= length newPaths) $ do - let newValue = WindowsEnv.pathJoin newPaths + let newValue = WindowsEnv.VarValue (WindowsEnv.varValueExpandable oldValue) (WindowsEnv.pathJoin newPaths) let promptAnd = if skipPrompt then withoutPrompt - else withPrompt $ oldNewMessage profile varName oldValue newValue + else withPrompt $ oldNewMessage profile varName (show oldValue) (show newValue) let engrave = WindowsEnv.engrave profile varName newValue void $ promptAnd engrave diff --git a/app/SetEnv.hs b/app/SetEnv.hs index 5948d3e..bb058d8 100644 --- a/app/SetEnv.hs +++ b/app/SetEnv.hs @@ -22,7 +22,7 @@ data Options = Options { optYes :: Bool , optGlobal :: Bool , optName :: WindowsEnv.VarName - , optValue :: WindowsEnv.VarValue + , optValue :: String } deriving (Eq, Show) optionParser :: Parser Options @@ -67,6 +67,6 @@ setEnv options = runExceptT doSetEnv >>= either ioError return | skipPrompt = withoutPrompt | otherwise = withPrompt $ newMessage profile varName varValue - engrave = WindowsEnv.engraveForce profile varName varValue + engrave = WindowsEnv.engrave profile varName $ WindowsEnv.VarValue False varValue doSetEnv = void $ promptAnd engrave diff --git a/app/Utils/PromptMessage.hs b/app/Utils/PromptMessage.hs index 37fc1e6..9afffb1 100644 --- a/app/Utils/PromptMessage.hs +++ b/app/Utils/PromptMessage.hs @@ -15,7 +15,7 @@ import Text.Printf (printf) import qualified WindowsEnv -oldNewMessage :: WindowsEnv.Profile -> WindowsEnv.VarName -> WindowsEnv.VarValue -> WindowsEnv.VarValue -> String +oldNewMessage :: WindowsEnv.Profile -> WindowsEnv.VarName -> String -> String -> String oldNewMessage profile name oldValue newValue = descrMsg ++ oldValueMsg ++ newValueMsg where @@ -24,7 +24,7 @@ oldNewMessage profile name oldValue newValue = oldValueMsg = printf "\tOld value: %s\n" oldValue newValueMsg = printf "\tNew value: %s\n" newValue -newMessage :: WindowsEnv.Profile -> WindowsEnv.VarName -> WindowsEnv.VarValue -> String +newMessage :: WindowsEnv.Profile -> WindowsEnv.VarName -> String -> String newMessage profile name newValue = descrMsg ++ newValueMsg where -- cgit v1.2.3