module Unison.Codebase.Editor.HandleInput.ProjectSwitch
( projectSwitch,
)
where
import Data.These (These (..))
import U.Codebase.Sqlite.Project (Project (..))
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.Editor.Output qualified as Output
import Unison.Prelude
import Unison.Project (ProjectAndBranch (..), ProjectAndBranchNames (..), ProjectBranchName, ProjectName, defaultBranchName)
projectSwitch :: ProjectAndBranchNames -> Cli ()
projectSwitch :: ProjectAndBranchNames -> Cli ()
projectSwitch ProjectAndBranchNames
projectNames = do
case ProjectAndBranchNames
projectNames of
ProjectAndBranchNames'Ambiguous ProjectName
projectName ProjectBranchName
branchName -> do
ProjectAndBranch currentProject _currentBranch <- Cli (ProjectAndBranch Project ProjectBranch)
Cli.getCurrentProjectAndBranch
(projectExists, branchExists) <-
Cli.runTransaction do
(,)
<$> Queries.projectExistsByName projectName
<*> Queries.projectBranchExistsByName currentProject.projectId branchName
case (projectExists, branchExists) of
(Bool
False, Bool
False) -> Output -> Cli ()
Cli.respond (ProjectName -> ProjectBranchName -> Output
Output.LocalProjectNorProjectBranchExist ProjectName
projectName ProjectBranchName
branchName)
(Bool
False, Bool
True) -> These ProjectName ProjectBranchName -> Cli ()
switchToProjectAndBranchByTheseNames (ProjectName
-> ProjectBranchName -> These ProjectName ProjectBranchName
forall a b. a -> b -> These a b
These Project
currentProject.name ProjectBranchName
branchName)
(Bool
True, Bool
False) -> These ProjectName ProjectBranchName -> Cli ()
switchToProjectAndBranchByTheseNames (ProjectName -> These ProjectName ProjectBranchName
forall a b. a -> These a b
This ProjectName
projectName)
(Bool
True, Bool
True) ->
NumberedOutput -> Cli ()
Cli.respondNumbered (NumberedOutput -> Cli ()) -> NumberedOutput -> Cli ()
forall a b. (a -> b) -> a -> b
$
ProjectName
-> ProjectAndBranch ProjectName ProjectBranchName -> NumberedOutput
Output.AmbiguousSwitch
ProjectName
projectName
(ProjectName
-> ProjectBranchName
-> ProjectAndBranch ProjectName ProjectBranchName
forall a b. a -> b -> ProjectAndBranch a b
ProjectAndBranch Project
currentProject.name ProjectBranchName
branchName)
ProjectAndBranchNames'Unambiguous These ProjectName ProjectBranchName
projectAndBranchNames0 ->
These ProjectName ProjectBranchName -> Cli ()
switchToProjectAndBranchByTheseNames These ProjectName ProjectBranchName
projectAndBranchNames0
switchToProjectAndBranchByTheseNames :: These ProjectName ProjectBranchName -> Cli ()
switchToProjectAndBranchByTheseNames :: These ProjectName ProjectBranchName -> Cli ()
switchToProjectAndBranchByTheseNames These ProjectName ProjectBranchName
projectAndBranchNames0 = do
branch <- case These ProjectName ProjectBranchName
projectAndBranchNames0 of
This ProjectName
projectName ->
((forall void. Output -> Transaction void)
-> Transaction ProjectBranch)
-> Cli ProjectBranch
forall a.
((forall void. Output -> Transaction void) -> Transaction a)
-> Cli a
Cli.runTransactionWithRollback \forall void. Output -> Transaction void
rollback -> do
project <-
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)
Queries.loadMostRecentBranch (project ^. #projectId) >>= \case
Maybe ProjectBranchId
Nothing -> do
let branchName :: ProjectBranchName
branchName = ProjectBranchName
defaultBranchName
branch <-
ProjectId -> ProjectBranchName -> Transaction (Maybe ProjectBranch)
Queries.loadProjectBranchByName Project
project.projectId ProjectBranchName
branchName Transaction (Maybe ProjectBranch)
-> (Transaction (Maybe ProjectBranch) -> Transaction ProjectBranch)
-> Transaction ProjectBranch
forall a b. a -> (a -> b) -> b
& Transaction ProjectBranch
-> Transaction (Maybe ProjectBranch) -> Transaction ProjectBranch
forall (m :: * -> *) a. Monad m => m a -> m (Maybe a) -> m a
onNothingM do
Output -> Transaction ProjectBranch
forall void. Output -> Transaction void
rollback (ProjectAndBranch ProjectName ProjectBranchName -> Output
Output.LocalProjectBranchDoesntExist (ProjectName
-> ProjectBranchName
-> ProjectAndBranch ProjectName ProjectBranchName
forall a b. a -> b -> ProjectAndBranch a b
ProjectAndBranch ProjectName
projectName ProjectBranchName
branchName))
pure branch
Just ProjectBranchId
branchId -> ProjectId -> ProjectBranchId -> Transaction ProjectBranch
Queries.expectProjectBranch Project
project.projectId ProjectBranchId
branchId
These ProjectName ProjectBranchName
_ -> do
projectAndBranchNames@(ProjectAndBranch projectName branchName) <- These ProjectName ProjectBranchName
-> Cli (ProjectAndBranch ProjectName ProjectBranchName)
ProjectUtils.hydrateNames These ProjectName ProjectBranchName
projectAndBranchNames0
Cli.runTransactionWithRollback \forall void. Output -> Transaction void
rollback -> do
branch <-
ProjectName
-> ProjectBranchName -> Transaction (Maybe ProjectBranch)
Queries.loadProjectBranchByNames ProjectName
projectName ProjectBranchName
branchName Transaction (Maybe ProjectBranch)
-> (Transaction (Maybe ProjectBranch) -> Transaction ProjectBranch)
-> Transaction ProjectBranch
forall a b. a -> (a -> b) -> b
& Transaction ProjectBranch
-> Transaction (Maybe ProjectBranch) -> Transaction ProjectBranch
forall (m :: * -> *) a. Monad m => m a -> m (Maybe a) -> m a
onNothingM do
Output -> Transaction ProjectBranch
forall void. Output -> Transaction void
rollback (ProjectAndBranch ProjectName ProjectBranchName -> Output
Output.LocalProjectBranchDoesntExist ProjectAndBranch ProjectName ProjectBranchName
projectAndBranchNames)
pure branch
Cli.switchProject (ProjectAndBranch (branch ^. #projectId) (branch ^. #branchId))