module Unison.Codebase.Editor.HandleInput.DeleteBranch
( handleDeleteBranch,
handleDeleteBranch2,
doDeleteProjectBranch,
)
where
import Control.Lens
import Data.List qualified as List
import U.Codebase.Sqlite.DbId
import U.Codebase.Sqlite.Project (Project (..))
import U.Codebase.Sqlite.Project qualified as Sqlite
import U.Codebase.Sqlite.ProjectBranch (ProjectBranch (..))
import U.Codebase.Sqlite.ProjectBranch qualified as Sqlite
import U.Codebase.Sqlite.Queries qualified as Queries
import Unison.Cli.Monad (Cli)
import Unison.Cli.Monad qualified as Cli
import Unison.Cli.MonadUtils qualified as Cli
import Unison.Cli.ProjectUtils qualified as ProjectUtils
import Unison.Codebase qualified as Codebase
import Unison.Codebase.ProjectPath (ProjectPathG (..))
import Unison.Codebase.SqliteCodebase.Operations qualified as Ops
import Unison.Core.Project (ProjectBranchName (..), ProjectName (..))
import Unison.Prelude
import Unison.Project (ProjectAndBranch (..), defaultBranchName)
import Unison.Sqlite qualified as Sqlite
handleDeleteBranch :: ProjectAndBranch (Maybe ProjectName) ProjectBranchName -> Cli ()
handleDeleteBranch :: ProjectAndBranch (Maybe ProjectName) ProjectBranchName -> Cli ()
handleDeleteBranch ProjectAndBranch (Maybe ProjectName) ProjectBranchName
namesToDelete = do
current <- Cli ProjectPath
Cli.getCurrentProjectPath
toDelete <- ProjectUtils.resolveProjectBranchInProject current.project (namesToDelete & #branch %~ Just)
handleDeleteBranch2 toDelete
handleDeleteBranch2 :: ProjectAndBranch Project ProjectBranch -> Cli ()
handleDeleteBranch2 :: ProjectAndBranch Project ProjectBranch -> Cli ()
handleDeleteBranch2 ProjectAndBranch Project ProjectBranch
toDelete = do
current <- Cli ProjectPath
Cli.getCurrentProjectPath
when (toDelete.branch.branchId == current.branch.branchId) do
nextLocation <-
Cli.runTransaction do
maybeNextLocation <-
runMaybeT $
asum
[ parentBranch toDelete.branch.projectId toDelete.branch.parentBranchId,
findMainBranchInProjectExcept current.project.projectId toDelete.branch.branchId,
findAnyBranchInProjectExcept toDelete.branch.projectId toDelete.branch.branchId,
findAnyBranchInCodebaseExcept toDelete.branch.projectId toDelete.branch.branchId
]
case maybeNextLocation of
Just ProjectAndBranch ProjectId ProjectBranchId
nextLocation -> ProjectAndBranch ProjectId ProjectBranchId
-> Transaction (ProjectAndBranch ProjectId ProjectBranchId)
forall a. a -> Transaction a
forall (f :: * -> *) a. Applicative f => a -> f a
pure ProjectAndBranch ProjectId ProjectBranchId
nextLocation
Maybe (ProjectAndBranch ProjectId ProjectBranchId)
Nothing -> ProjectName
-> ProjectBranchName
-> Transaction (ProjectAndBranch ProjectId ProjectBranchId)
createNewBranchInProjectExcept ProjectAndBranch Project ProjectBranch
toDelete.project.name ProjectAndBranch Project ProjectBranch
toDelete.branch.name
Cli.switchProject nextLocation
doDeleteProjectBranch toDelete
where
parentBranch :: ProjectId -> Maybe ProjectBranchId -> MaybeT Sqlite.Transaction (ProjectAndBranch ProjectId ProjectBranchId)
parentBranch :: ProjectId
-> Maybe ProjectBranchId
-> MaybeT Transaction (ProjectAndBranch ProjectId ProjectBranchId)
parentBranch ProjectId
projectId Maybe ProjectBranchId
mayParentBranchId = do
parentBranchId <- Maybe ProjectBranchId -> MaybeT Transaction ProjectBranchId
forall (m :: * -> *) a. Applicative m => Maybe a -> MaybeT m a
hoistMaybe Maybe ProjectBranchId
mayParentBranchId
pure (ProjectAndBranch projectId parentBranchId)
findMainBranchInProjectExcept :: ProjectId -> ProjectBranchId -> MaybeT Sqlite.Transaction (ProjectAndBranch ProjectId ProjectBranchId)
findMainBranchInProjectExcept :: ProjectId
-> ProjectBranchId
-> MaybeT Transaction (ProjectAndBranch ProjectId ProjectBranchId)
findMainBranchInProjectExcept ProjectId
projectId ProjectBranchId
exceptBranchId = do
branch <- Transaction (Maybe ProjectBranch)
-> MaybeT Transaction ProjectBranch
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Transaction (Maybe ProjectBranch)
-> MaybeT Transaction ProjectBranch)
-> Transaction (Maybe ProjectBranch)
-> MaybeT Transaction ProjectBranch
forall a b. (a -> b) -> a -> b
$ ProjectId -> ProjectBranchName -> Transaction (Maybe ProjectBranch)
Queries.loadProjectBranchByName ProjectId
projectId ProjectBranchName
defaultBranchName
guard (branch.branchId /= exceptBranchId)
pure (ProjectAndBranch projectId branch.branchId)
findAnyBranchInProjectExcept :: ProjectId -> ProjectBranchId -> MaybeT Sqlite.Transaction (ProjectAndBranch ProjectId ProjectBranchId)
findAnyBranchInProjectExcept :: ProjectId
-> ProjectBranchId
-> MaybeT Transaction (ProjectAndBranch ProjectId ProjectBranchId)
findAnyBranchInProjectExcept ProjectId
projectId ProjectBranchId
exceptBranchId = do
(someBranchId, _) <- Transaction (Maybe (ProjectBranchId, ProjectBranchName))
-> MaybeT Transaction (ProjectBranchId, ProjectBranchName)
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Transaction (Maybe (ProjectBranchId, ProjectBranchName))
-> MaybeT Transaction (ProjectBranchId, ProjectBranchName))
-> (Transaction [(ProjectBranchId, ProjectBranchName)]
-> Transaction (Maybe (ProjectBranchId, ProjectBranchName)))
-> Transaction [(ProjectBranchId, ProjectBranchName)]
-> MaybeT Transaction (ProjectBranchId, ProjectBranchName)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(ProjectBranchId, ProjectBranchName)]
-> Maybe (ProjectBranchId, ProjectBranchName))
-> Transaction [(ProjectBranchId, ProjectBranchName)]
-> Transaction (Maybe (ProjectBranchId, ProjectBranchName))
forall a b. (a -> b) -> Transaction a -> Transaction b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ProjectBranchId, ProjectBranchName) -> Bool)
-> [(ProjectBranchId, ProjectBranchName)]
-> Maybe (ProjectBranchId, ProjectBranchName)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
List.find (\(ProjectBranchId
branchId, ProjectBranchName
_) -> ProjectBranchId
branchId ProjectBranchId -> ProjectBranchId -> Bool
forall a. Eq a => a -> a -> Bool
/= ProjectBranchId
exceptBranchId)) (Transaction [(ProjectBranchId, ProjectBranchName)]
-> MaybeT Transaction (ProjectBranchId, ProjectBranchName))
-> Transaction [(ProjectBranchId, ProjectBranchName)]
-> MaybeT Transaction (ProjectBranchId, ProjectBranchName)
forall a b. (a -> b) -> a -> b
$ ProjectId
-> Maybe Text -> Transaction [(ProjectBranchId, ProjectBranchName)]
Queries.loadAllProjectBranchesBeginningWith ProjectId
projectId Maybe Text
forall a. Maybe a
Nothing
pure (ProjectAndBranch projectId someBranchId)
findAnyBranchInCodebaseExcept :: ProjectId -> ProjectBranchId -> MaybeT Sqlite.Transaction (ProjectAndBranch ProjectId ProjectBranchId)
findAnyBranchInCodebaseExcept :: ProjectId
-> ProjectBranchId
-> MaybeT Transaction (ProjectAndBranch ProjectId ProjectBranchId)
findAnyBranchInCodebaseExcept ProjectId
exceptProjectId ProjectBranchId
exceptBranchId = do
(_, pbIds) <- Transaction
(Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId))
-> MaybeT
Transaction
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)
forall (m :: * -> *) a. m (Maybe a) -> MaybeT m a
MaybeT (Transaction
(Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId))
-> MaybeT
Transaction
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId))
-> (Transaction
[(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
-> Transaction
(Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)))
-> Transaction
[(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
-> MaybeT
Transaction
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)
forall b c a. (b -> c) -> (a -> b) -> a -> c
. ([(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
-> Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId))
-> Transaction
[(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
-> Transaction
(Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId))
forall a b. (a -> b) -> Transaction a -> Transaction b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap (((ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)
-> Bool)
-> [(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
-> Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)
forall (t :: * -> *) a. Foldable t => (a -> Bool) -> t a -> Maybe a
List.find (\(ProjectAndBranch ProjectName ProjectBranchName
_, ProjectAndBranch ProjectId ProjectBranchId
ids) -> ProjectAndBranch ProjectId ProjectBranchId
ids ProjectAndBranch ProjectId ProjectBranchId
-> ProjectAndBranch ProjectId ProjectBranchId -> Bool
forall a. Eq a => a -> a -> Bool
/= ProjectId
-> ProjectBranchId -> ProjectAndBranch ProjectId ProjectBranchId
forall a b. a -> b -> ProjectAndBranch a b
ProjectAndBranch ProjectId
exceptProjectId ProjectBranchId
exceptBranchId)) (Transaction
[(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
-> MaybeT
Transaction
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId))
-> Transaction
[(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
-> MaybeT
Transaction
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)
forall a b. (a -> b) -> a -> b
$ Transaction
[(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
Queries.loadAllProjectBranchNamePairs
pure pbIds
createNewBranchInProjectExcept :: ProjectName -> ProjectBranchName -> Sqlite.Transaction (ProjectAndBranch ProjectId ProjectBranchId)
createNewBranchInProjectExcept :: ProjectName
-> ProjectBranchName
-> Transaction (ProjectAndBranch ProjectId ProjectBranchId)
createNewBranchInProjectExcept ProjectName
projectName = \case
UnsafeProjectBranchName Text
"main" -> do
(_, emptyCausalHashId) <- Transaction (CausalHash, CausalHashId)
Codebase.emptyCausalHash
Ops.insertProjectAndBranch projectName (UnsafeProjectBranchName "main2") emptyCausalHashId
<&> \(Project
proj, ProjectBranchRow
branch) -> ProjectId
-> ProjectBranchId -> ProjectAndBranch ProjectId ProjectBranchId
forall a b. a -> b -> ProjectAndBranch a b
ProjectAndBranch Project
proj.projectId ProjectBranchRow
branch.branchId
ProjectBranchName
_ -> do
(_, emptyCausalHashId) <- Transaction (CausalHash, CausalHashId)
Codebase.emptyCausalHash
Ops.insertProjectAndBranch projectName (UnsafeProjectBranchName "main") emptyCausalHashId
<&> \(Project
proj, ProjectBranchRow
branch) -> ProjectId
-> ProjectBranchId -> ProjectAndBranch ProjectId ProjectBranchId
forall a b. a -> b -> ProjectAndBranch a b
ProjectAndBranch Project
proj.projectId ProjectBranchRow
branch.branchId
doDeleteProjectBranch :: (HasCallStack) => ProjectAndBranch Sqlite.Project Sqlite.ProjectBranch -> Cli ()
doDeleteProjectBranch :: HasCallStack => ProjectAndBranch Project ProjectBranch -> Cli ()
doDeleteProjectBranch ProjectAndBranch Project ProjectBranch
projectAndBranch = do
Transaction () -> Cli ()
forall a. Transaction a -> Cli a
Cli.runTransaction do
HasCallStack => ProjectId -> ProjectBranchId -> Transaction ()
ProjectId -> ProjectBranchId -> Transaction ()
Queries.deleteProjectBranch ProjectAndBranch Project ProjectBranch
projectAndBranch.project.projectId ProjectAndBranch Project ProjectBranch
projectAndBranch.branch.branchId