module Unison.Codebase.Editor.HandleInput.DeleteProject
( handleDeleteProject,
)
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.ProjectBranch (ProjectBranchRow (..))
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.Codebase qualified as Codebase
import Unison.Codebase.Editor.Output qualified as Output
import Unison.Codebase.ProjectPath (ProjectPathG (..))
import Unison.Codebase.SqliteCodebase.Operations qualified as Ops
import Unison.Core.Project (ProjectName (..))
import Unison.Prelude
import Unison.Project (ProjectAndBranch (..), defaultBranchName)
import Unison.Sqlite qualified as Sqlite
handleDeleteProject :: ProjectName -> Cli ()
handleDeleteProject :: ProjectName -> Cli ()
handleDeleteProject ProjectName
projectName = do
ProjectPath currentProject _ _ <- Cli (ProjectPathG Project ProjectBranch)
Cli.getCurrentProjectPath
projectToDelete <-
Cli.runTransactionWithRollback \forall void. Output -> Transaction void
rollback -> do
ProjectName -> Transaction (Maybe Project)
Queries.loadProjectByName ProjectName
projectName Transaction (Maybe Project)
-> (Transaction (Maybe Project) -> Transaction Project)
-> Transaction Project
forall a b. a -> (a -> b) -> b
& Transaction Project
-> Transaction (Maybe Project) -> Transaction Project
forall (m :: * -> *) a. Monad m => m a -> m (Maybe a) -> m a
onNothingM do
Output -> Transaction Project
forall void. Output -> Transaction void
rollback (ProjectName -> Output
Output.LocalProjectDoesntExist ProjectName
projectName)
when (projectToDelete.projectId == currentProject.projectId) do
nextLoc <- Cli.runTransaction $ findAnyBranchInCodebaseNotInProject (projectToDelete.projectId) `whenNothingM` createDummyProjectExcept projectToDelete.name
Cli.switchProject nextLoc
Cli.runTransaction do
Queries.deleteProject (projectToDelete ^. #projectId)
where
findAnyBranchInCodebaseNotInProject :: ProjectId -> Sqlite.Transaction (Maybe (ProjectAndBranch ProjectId ProjectBranchId))
findAnyBranchInCodebaseNotInProject :: ProjectId
-> Transaction (Maybe (ProjectAndBranch ProjectId ProjectBranchId))
findAnyBranchInCodebaseNotInProject ProjectId
exceptProjectId = do
Transaction
[(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
Queries.loadAllProjectBranchNamePairs
Transaction
[(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
-> ([(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)]
-> Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId))
-> Transaction
(Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> ((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
projId ProjectBranchId
_) -> ProjectId
projId ProjectId -> ProjectId -> Bool
forall a. Eq a => a -> a -> Bool
/= ProjectId
exceptProjectId)
Transaction
(Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId))
-> (Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)
-> Maybe (ProjectAndBranch ProjectId ProjectBranchId))
-> Transaction (Maybe (ProjectAndBranch ProjectId ProjectBranchId))
forall (f :: * -> *) a b. Functor f => f a -> (a -> b) -> f b
<&> ((ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)
-> ProjectAndBranch ProjectId ProjectBranchId)
-> Maybe
(ProjectAndBranch ProjectName ProjectBranchName,
ProjectAndBranch ProjectId ProjectBranchId)
-> Maybe (ProjectAndBranch ProjectId ProjectBranchId)
forall a b. (a -> b) -> Maybe a -> Maybe b
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
fmap \(ProjectAndBranch ProjectName ProjectBranchName
_, ProjectAndBranch ProjectId ProjectBranchId
pbIds) -> ProjectAndBranch ProjectId ProjectBranchId
pbIds
createDummyProjectExcept :: ProjectName -> Sqlite.Transaction (ProjectAndBranch ProjectId ProjectBranchId)
createDummyProjectExcept :: ProjectName
-> Transaction (ProjectAndBranch ProjectId ProjectBranchId)
createDummyProjectExcept (UnsafeProjectName Text
"scratch") = do
(_, emptyCausalHashId) <- Transaction (CausalHash, CausalHashId)
Codebase.emptyCausalHash
Ops.insertProjectAndBranch (UnsafeProjectName "scratch2") defaultBranchName 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
createDummyProjectExcept ProjectName
_ = do
(_, emptyCausalHashId) <- Transaction (CausalHash, CausalHashId)
Codebase.emptyCausalHash
Ops.insertProjectAndBranch (UnsafeProjectName "scratch") defaultBranchName 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