You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

96 lines
2.7 KiB

import System.Environment
import System.Directory
import System.IO
import System.Exit (exitSuccess,exitFailure)
import Data.List
type EnvKey = String
type EnvValue = String
data EnvFile =
End
| Entry EnvKey EnvValue EnvFile
deriving (Show,Eq,Read)
main = do
args <- getArgs
cliRun args
cliRun :: [String] -> IO ()
cliRun ("get":args) = cliGet args
cliRun ("set":args) = cliSet args
cliRun ("unset":args) = cliUnset args
cliRun ("list":_) = cliList
cliRun _ = cliFail "USAGE: fenv <get|set|unset> [...args]"
cliGet :: [String] -> IO ()
cliGet (name:_) = do
env <- getEnvFile
case (getEntry env name) of
(Just value) -> putStrLn value
Nothing -> cliFail "ERROR: No value defined"
cliGet _ = cliFail "USAGE: fenv get <name>"
cliUnset :: [String] -> IO ()
cliUnset (name:_) = do
env <- getEnvFile
let env' = (removeEntry env name) in
replaceEnvFile env'
cliUnset _ = cliFail "USAGE: fenv unset <name>"
cliSet :: [String] -> IO ()
cliSet (name:value:_) = do
env <- getEnvFile
let env' = (setEntry env name value) in
replaceEnvFile env'
cliSet _ = cliFail "USAGE: fenv set <name> <value>"
cliList :: IO ()
cliList = do
env <- getEnvFile
printLevel env
where
printLevel (Entry key value rest) = putStrLn (key ++ ": " ++ value) >>= (printLevel rest)
printLevel End = return ()
cliFail :: String -> IO ()
cliFail message = putStrLn message >>= return exitFailure
setEntry :: EnvFile -> EnvKey -> EnvValue -> EnvFile
setEntry env key value = let env'=(removeEntry env key) in
(Entry key value env')
removeEntry :: EnvFile -> EnvKey -> EnvFile
removeEntry End _ = End
removeEntry (Entry entryKey entryValue rest) key = if entryKey==key
then rest
else (Entry entryKey entryValue (removeEntry rest key))
getEntry :: EnvFile -> EnvKey -> Maybe EnvValue
getEntry End _ = Nothing
getEntry (Entry entryKey entryValue rest) key = if entryKey==key
then return entryValue
else (getEntry rest key)
replaceEnvFile :: EnvFile -> IO ()
replaceEnvFile env = do
path <- getEnvFilePath
(tempName, tempHandle) <- openTempFile "/tmp" ".fenv"
hPutStr tempHandle (show env)
hClose tempHandle
removeFile path
renameFile tempName path
getEnvFile :: IO EnvFile
getEnvFile = do
path <- getEnvFilePath
contents <- readFile path
if contents == "" then return End
else return $ read contents
getEnvFilePath :: IO FilePath
getEnvFilePath = do
home <- getHomeDirectory
return (home ++ "/.fenv")