module State ( ImmediateCommand(..) , RunEnv(RunEnv) , State , initSt , opts , pid , StRun , srRmFilesToRm , srFreshTmpName , srRegisterFileForRm ) where ------------------------------------------------------------------------- -- Imports ------------------------------------------------------------------------- import Data.Lens.Common import Data.Lens.Template import Data.Lens.Strict import Data.Typeable -- import qualified Data.Set as Set import Control.Monad.State.Strict import qualified Control.Exception as CE import System.Posix.Types import System.FilePath import System.IO -- import System.IO.Temp import System.Directory import Opts ------------------------------------------------------------------------- -- Bits of info about runtime env ------------------------------------------------------------------------- data RunEnv = RunEnv { _tmpdir :: FilePath , _pid :: ProcessID , _argFile :: FilePath } deriving Typeable makeLens ''RunEnv ------------------------------------------------------------------------- -- State ------------------------------------------------------------------------- data St = St { _opts :: Opts , _runEnv :: RunEnv , _uniq :: Int , _filesToRm :: [FilePath] } deriving Typeable initSt :: Opts -> RunEnv -> St initSt o e = St o e 0 [] makeLens ''St ------------------------------------------------------------------------- -- St monad ------------------------------------------------------------------------- type StRun a = StateT St IO a -- | get a fresh uniq nr srFreshUniq :: StRun Int srFreshUniq = do i <- access uniq uniq += 1 return i -- | register file for removal srRegisterFileForRm :: FilePath -> StRun [FilePath] srRegisterFileForRm f = filesToRm %= ([f]++) -- | remove all files registered for removal srRmFilesToRm :: StRun () srRmFilesToRm = do files <- filesToRm %%= (\f -> (f,[])) liftIO $ forM_ files rm where rm f = CE.catch (removeFile f) (\(e :: CE.SomeException) -> hPutStrLn stderr (show f ++ ": " ++ show e)) -- | get a fresh tmp filename srFreshTmpName :: StRun FilePath srFreshTmpName = do i <- srFreshUniq e <- access runEnv let t = e ^. tmpdir takeBaseName (e ^. argFile) ++ "-" ++ show (e ^. pid) ++ "-" ++ show i srRegisterFileForRm t return t