-- for IdempotentIO
import Control.Monad (when)
-- for Link
import Control.Monad.Loops (andM)
import System.Posix.Files (fileExist, getSymbolicLinkStatus, isSymbolicLink, readSymbolicLink, createSymbolicLink)
import System.Directory (getHomeDirectory, getCurrentDirectory)
class IdempotentIO thing where
check :: thing -> IO Bool
set, ensure :: thing -> IO ()
ensure thing = do
isSet <- check thing
when (not isSet) $ set thing
data Link = Link
{ fromPath :: String
, toPath :: String
, qualifyPath :: String -> String
}
instance IdempotentIO Link where
check link = andM
[ fileExist $ qualified fromPath
, fmap isSymbolicLink . getSymbolicLinkStatus $ qualified fromPath
, fmap (== qualified toPath) . readSymbolicLink $ qualified fromPath
]
where qualified path = qualifyPath link $ path link
set link = createSymbolicLink (qualified toPath) (qualified fromPath)
where qualified path = qualifyPath link $ path link
main = ensure $ Link "foo" "bar" id