module Mit.State ( MitState (..), emptyMitState, deleteMitState, readMitState, writeMitState, ) where import Data.Text qualified as Text import Data.Text.Encoding.Base64 qualified as Text import Data.Text.IO qualified as Text import Mit.Env (Env (..)) import Mit.Git import Mit.Monad import Mit.Prelude import Mit.Undo import System.Directory (removeFile) data MitState a = MitState { head :: a, merging :: Maybe Text, undos :: [Undo] } deriving stock (Eq, Show) emptyMitState :: MitState () emptyMitState = MitState {head = (), merging = Nothing, undos = []} deleteMitState :: Text -> Mit Env x () deleteMitState branch64 = do mitfile <- getMitfile branch64 io (removeFile mitfile `catch` \(_ :: IOException) -> pure ()) parseMitState :: Text -> Maybe (MitState Text) parseMitState contents = do [headLine, mergingLine, undosLine] <- Just (Text.lines contents) ["head", head] <- Just (Text.words headLine) merging <- case Text.words mergingLine of ["merging"] -> Just Nothing ["merging", branch] -> Just (Just branch) _ -> Nothing undos <- Text.stripPrefix "undos " undosLine >>= parseUndos pure MitState {head, merging, undos} readMitState :: Text -> Mit Env x (MitState ()) readMitState branch = label \return -> do head <- gitMaybeHead >>= \case Nothing -> return emptyMitState Just head -> pure head mitfile <- getMitfile branch64 contents <- io (try (Text.readFile mitfile)) >>= \case Left (_ :: IOException) -> return emptyMitState Right contents -> pure contents let maybeState = do state <- parseMitState contents guard (head == state.head) pure state state <- case maybeState of Nothing -> do deleteMitState branch64 return emptyMitState Just state -> pure state pure (state {head = ()} :: MitState ()) where branch64 = Text.encodeBase64 branch writeMitState :: Text -> MitState () -> Mit Env x () writeMitState branch state = do head <- gitHead let contents :: Text contents = Text.unlines [ "head " <> head, "merging " <> fromMaybe Text.empty state.merging, "undos " <> showUndos state.undos ] mitfile <- getMitfile (Text.encodeBase64 branch) io (Text.writeFile mitfile contents `catch` \(_ :: IOException) -> pure ()) getMitfile :: Text -> Mit Env x FilePath getMitfile branch64 = do env <- getEnv pure (Text.unpack (env.gitdir <> "/.mit-" <> branch64))