diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2023-07-28 16:17:15 +1000 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2023-07-30 18:35:24 +1000 |
commit | de57cfd6ff17751f7243476441beab6486fb4381 (patch) | |
tree | 91f028b12eb403a2ae2e0e5c0460cdc548958a86 /pkg | |
parent | 2b24c15938c5ceb29a9b2d525aa1318b8bc8a87b (diff) |
Remove IO logic from presentation code for worktrees
We're doing all the IO in our workers loader method so that we don't need to do any
in our presentation code
Diffstat (limited to 'pkg')
-rw-r--r-- | pkg/commands/git_commands/file_loader.go | 2 | ||||
-rw-r--r-- | pkg/commands/git_commands/worktree.go | 33 | ||||
-rw-r--r-- | pkg/commands/git_commands/worktree_loader.go | 35 | ||||
-rw-r--r-- | pkg/commands/models/worktree.go | 12 | ||||
-rw-r--r-- | pkg/gui/context/worktrees_context.go | 2 | ||||
-rw-r--r-- | pkg/gui/controllers/branches_controller.go | 8 | ||||
-rw-r--r-- | pkg/gui/controllers/helpers/worktree_helper.go | 33 | ||||
-rw-r--r-- | pkg/gui/controllers/worktrees_controller.go | 6 | ||||
-rw-r--r-- | pkg/gui/presentation/worktrees.go | 12 |
9 files changed, 57 insertions, 86 deletions
diff --git a/pkg/commands/git_commands/file_loader.go b/pkg/commands/git_commands/file_loader.go index 685062a58..1585fced6 100644 --- a/pkg/commands/git_commands/file_loader.go +++ b/pkg/commands/git_commands/file_loader.go @@ -65,7 +65,7 @@ func (self *FileLoader) GetStatusFiles(opts GetStatusFileOptions) []*models.File files = append(files, file) } - // Go through the worktrees to see if any of these files are actually worktrees + // Go through the files to see if any of these files are actually worktrees // so that we can render them correctly worktreePaths := linkedWortkreePaths() for _, file := range files { diff --git a/pkg/commands/git_commands/worktree.go b/pkg/commands/git_commands/worktree.go index e35b3a715..1b57ab122 100644 --- a/pkg/commands/git_commands/worktree.go +++ b/pkg/commands/git_commands/worktree.go @@ -1,7 +1,6 @@ package git_commands import ( - "errors" "io/fs" "log" "os" @@ -59,36 +58,6 @@ func (self *WorktreeCommands) Detach(worktreePath string) error { return self.cmd.New(cmdArgs).Run() } -func (self *WorktreeCommands) IsCurrentWorktree(path string) bool { - return IsCurrentWorktree(path) -} - -func IsCurrentWorktree(path string) bool { - pwd, err := os.Getwd() - if err != nil { - return false - } - - return EqualPath(pwd, path) -} - -func (self *WorktreeCommands) IsWorktreePathMissing(path string) bool { - if _, err := os.Stat(path); err != nil { - if errors.Is(err, fs.ErrNotExist) { - return true - } - self.Log.Errorf("failed to check if worktree path `%s` exists\n%v", path, err) - return false - } - return false -} - -// checks if two paths are equal -// TODO: support relative paths -func EqualPath(a string, b string) bool { - return a == b -} - func WorktreeForBranch(branch *models.Branch, worktrees []*models.Worktree) (*models.Worktree, bool) { for _, worktree := range worktrees { if worktree.Branch == branch.Name { @@ -105,7 +74,7 @@ func CheckedOutByOtherWorktree(branch *models.Branch, worktrees []*models.Worktr return false } - return !IsCurrentWorktree(worktree.Path) + return !worktree.IsCurrent } // If in a non-bare repo, this returns the path of the main worktree diff --git a/pkg/commands/git_commands/worktree_loader.go b/pkg/commands/git_commands/worktree_loader.go index bbd8367f3..42f889156 100644 --- a/pkg/commands/git_commands/worktree_loader.go +++ b/pkg/commands/git_commands/worktree_loader.go @@ -1,10 +1,12 @@ package git_commands import ( + "io/fs" "os" "path/filepath" "strings" + "github.com/go-errors/errors" "github.com/jesseduffield/lazygit/pkg/commands/models" "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/common" @@ -30,6 +32,11 @@ func NewWorktreeLoader( func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) { currentRepoPath := GetCurrentRepoPath() + pwd, err := os.Getwd() + if err != nil { + return nil, err + } + cmdArgs := NewGitCmd("worktree").Arg("list", "--porcelain").ToArgv() worktreesOutput, err := self.cmd.New(cmdArgs).DontLog().RunWithOutput() if err != nil { @@ -54,6 +61,8 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) { if strings.HasPrefix(splitLine, "worktree ") { path := strings.SplitN(splitLine, " ", 2)[1] isMain := path == currentRepoPath + isCurrent := path == pwd + isPathMissing := self.pathExists(path) var gitDir string if isMain { @@ -67,9 +76,11 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) { } current = &models.Worktree{ - IsMain: path == currentRepoPath, - Path: path, - GitDir: gitDir, + IsMain: isMain, + IsCurrent: isCurrent, + IsPathMissing: isPathMissing, + Path: path, + GitDir: gitDir, } } else if strings.HasPrefix(splitLine, "branch ") { branch := strings.SplitN(splitLine, " ", 2)[1] @@ -85,14 +96,9 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) { worktree.NameField = names[index] } - pwd, err := os.Getwd() - if err != nil { - return nil, err - } - // move current worktree to the top for i, worktree := range worktrees { - if EqualPath(worktree.Path, pwd) { + if worktree.IsCurrent { worktrees = append(worktrees[:i], worktrees[i+1:]...) worktrees = append([]*models.Worktree{worktree}, worktrees...) break @@ -130,6 +136,17 @@ func (self *WorktreeLoader) GetWorktrees() ([]*models.Worktree, error) { return worktrees, nil } +func (self *WorktreeLoader) pathExists(path string) bool { + if _, err := os.Stat(path); err != nil { + if errors.Is(err, fs.ErrNotExist) { + return true + } + self.Log.Errorf("failed to check if worktree path `%s` exists\n%v", path, err) + return false + } + return false +} + func rebaseBranch(worktree *models.Worktree) (string, bool) { for _, dir := range []string{"rebase-merge", "rebase-apply"} { if bytesContent, err := os.ReadFile(filepath.Join(worktree.GitDir, dir, "head-name")); err == nil { diff --git a/pkg/commands/models/worktree.go b/pkg/commands/models/worktree.go index c14304233..662d137dc 100644 --- a/pkg/commands/models/worktree.go +++ b/pkg/commands/models/worktree.go @@ -4,8 +4,12 @@ package models type Worktree struct { // if false, this is a linked worktree IsMain bool + // if true, this is the worktree that is currently checked out + IsCurrent bool // path to the directory of the worktree i.e. the directory that contains all the user's files Path string + // if true, the path is not found + IsPathMissing bool // path of the git directory for this worktree. The equivalent of the .git directory // in the main worktree. For linked worktrees this would be <repo_path>/.git/worktrees/<name> GitDir string @@ -39,3 +43,11 @@ func (w *Worktree) Name() string { func (w *Worktree) Main() bool { return w.IsMain } + +func (w *Worktree) Current() bool { + return w.IsCurrent +} + +func (w *Worktree) PathMissing() bool { + return w.IsPathMissing +} diff --git a/pkg/gui/context/worktrees_context.go b/pkg/gui/context/worktrees_context.go index 17dd534a6..224a233e1 100644 --- a/pkg/gui/context/worktrees_context.go +++ b/pkg/gui/context/worktrees_context.go @@ -25,8 +25,6 @@ func NewWorktreesContext(c *ContextCommon) *WorktreesContext { return presentation.GetWorktreeDisplayStrings( c.Tr, viewModel.GetFilteredList(), - c.Git().Worktree.IsCurrentWorktree, - c.Git().Worktree.IsWorktreePathMissing, ) } diff --git a/pkg/gui/controllers/branches_controller.go b/pkg/gui/controllers/branches_controller.go index c5a5c1c78..b3c3fdcdc 100644 --- a/pkg/gui/controllers/branches_controller.go +++ b/pkg/gui/controllers/branches_controller.go @@ -203,7 +203,7 @@ func (self *BranchesController) press(selectedBranch *models.Branch) error { } worktreeForRef, ok := self.worktreeForBranch(selectedBranch) - if ok && !self.c.Git().Worktree.IsCurrentWorktree(worktreeForRef.Path) { + if ok && !worktreeForRef.Current() { return self.promptToCheckoutWorktree(worktreeForRef) } @@ -220,7 +220,7 @@ func (self *BranchesController) promptToCheckoutWorktree(worktree *models.Worktr Title: "Switch to worktree", Prompt: fmt.Sprintf("This branch is checked out by worktree %s. Do you want to switch to that worktree?", worktree.Name()), HandleConfirm: func() error { - return self.c.Helpers().Worktree.Switch(worktree.Path, context.LOCAL_BRANCHES_CONTEXT_KEY) + return self.c.Helpers().Worktree.Switch(worktree, context.LOCAL_BRANCHES_CONTEXT_KEY) }, }) } @@ -342,7 +342,7 @@ func (self *BranchesController) promptWorktreeBranchDelete(selectedBranch *model { Label: "Switch to worktree", OnPress: func() error { - return self.c.Helpers().Worktree.Switch(worktree.Path, context.LOCAL_BRANCHES_CONTEXT_KEY) + return self.c.Helpers().Worktree.Switch(worktree, context.LOCAL_BRANCHES_CONTEXT_KEY) }, }, { @@ -432,7 +432,7 @@ func (self *BranchesController) fastForward(branch *models.Branch) error { worktreeGitDir := "" // if it is the current worktree path, no need to specify the path - if !git_commands.IsCurrentWorktree(worktree.Path) { + if !worktree.Current() { worktreeGitDir = worktree.GitDir } diff --git a/pkg/gui/controllers/helpers/worktree_helper.go b/pkg/gui/controllers/helpers/worktree_helper.go index f122ac01e..0a0a505ac 100644 --- a/pkg/gui/controllers/helpers/worktree_helper.go +++ b/pkg/gui/controllers/helpers/worktree_helper.go @@ -1,9 +1,6 @@ package helpers import ( - "errors" - "io/fs" - "os" "strings" "github.com/jesseduffield/gocui" @@ -61,27 +58,6 @@ func (self *WorktreeHelper) GetLinkedWorktreeName() string { return currentWorktree.Name() } -func (self *WorktreeHelper) IsCurrentWorktree(w *models.Worktree) bool { - pwd, err := os.Getwd() - if err != nil { - self.c.Log.Errorf("failed to obtain current working directory: %v", err) - return false - } - - return pwd == w.Path -} - -func (self *WorktreeHelper) IsWorktreePathMissing(w *models.Worktree) bool { - if _, err := os.Stat(w.Path); err != nil { - if errors.Is(err, fs.ErrNotExist) { - return true - } - self.c.Log.Errorf("failed to check if worktree path `%s` exists: %v", w.Path, err) - return false - } - return false -} - func (self *WorktreeHelper) NewWorktree() error { branch := self.refsHelper.GetCheckedOutRef() currentBranchName := branch.RefName() @@ -132,7 +108,8 @@ func (self *WorktreeHelper) NewWorktreeCheckout(base string, canCheckoutBase boo if err := self.c.Git().Worktree.New(opts); err != nil { return err } - return self.Switch(opts.Path, contextKey) + + return self.reposHelper.DispatchSwitchTo(opts.Path, self.c.Tr.ErrWorktreeMovedOrRemoved, contextKey) }) } @@ -175,14 +152,14 @@ func (self *WorktreeHelper) NewWorktreeCheckout(base string, canCheckoutBase boo }) } -func (self *WorktreeHelper) Switch(path string, contextKey types.ContextKey) error { - if self.c.Git().Worktree.IsCurrentWorktree(path) { +func (self *WorktreeHelper) Switch(worktree *models.Worktree, contextKey types.ContextKey) error { + if worktree.Current() { return self.c.ErrorMsg(self.c.Tr.AlreadyInWorktree) } self.c.LogAction(self.c.Tr.SwitchToWorktree) - return self.reposHelper.DispatchSwitchTo(path, self.c.Tr.ErrWorktreeMovedOrRemoved, contextKey) + return self.reposHelper.DispatchSwitchTo(worktree.Path, self.c.Tr.ErrWorktreeMovedOrRemoved, contextKey) } func (self *WorktreeHelper) Remove(worktree *models.Worktree, force bool) error { diff --git a/pkg/gui/controllers/worktrees_controller.go b/pkg/gui/controllers/worktrees_controller.go index 6b403f0ee..78d53914d 100644 --- a/pkg/gui/controllers/worktrees_controller.go +++ b/pkg/gui/controllers/worktrees_controller.go @@ -72,7 +72,7 @@ func (self *WorktreesController) GetOnRenderToMain() func() error { } missing := "" - if self.c.Git().Worktree.IsWorktreePathMissing(worktree.Path) { + if worktree.PathMissing() { missing = style.FgRed.Sprintf(" %s", self.c.Tr.MissingWorktree) } @@ -105,7 +105,7 @@ func (self *WorktreesController) remove(worktree *models.Worktree) error { return self.c.ErrorMsg(self.c.Tr.CantDeleteMainWorktree) } - if self.c.Git().Worktree.IsCurrentWorktree(worktree.Path) { + if worktree.Current() { return self.c.ErrorMsg(self.c.Tr.CantDeleteCurrentWorktree) } @@ -117,7 +117,7 @@ func (self *WorktreesController) GetOnClick() func() error { } func (self *WorktreesController) enter(worktree *models.Worktree) error { - return self.c.Helpers().Worktree.Switch(worktree.Path, context.WORKTREES_CONTEXT_KEY) + return self.c.Helpers().Worktree.Switch(worktree, context.WORKTREES_CONTEXT_KEY) } func (self *WorktreesController) open(worktree *models.Worktree) error { diff --git a/pkg/gui/presentation/worktrees.go b/pkg/gui/presentation/worktrees.go index 6c8acf976..c16871c69 100644 --- a/pkg/gui/presentation/worktrees.go +++ b/pkg/gui/presentation/worktrees.go @@ -9,28 +9,26 @@ import ( "github.com/samber/lo" ) -func GetWorktreeDisplayStrings(tr *i18n.TranslationSet, worktrees []*models.Worktree, isCurrent func(string) bool, isMissing func(string) bool) [][]string { +func GetWorktreeDisplayStrings(tr *i18n.TranslationSet, worktrees []*models.Worktree) [][]string { return lo.Map(worktrees, func(worktree *models.Worktree, _ int) []string { return GetWorktreeDisplayString( tr, - isCurrent(worktree.Path), - isMissing(worktree.Path), worktree) }) } -func GetWorktreeDisplayString(tr *i18n.TranslationSet, isCurrent bool, isPathMissing bool, worktree *models.Worktree) []string { +func GetWorktreeDisplayString(tr *i18n.TranslationSet, worktree *models.Worktree) []string { textStyle := theme.DefaultTextColor current := "" currentColor := style.FgCyan - if isCurrent { + if worktree.Current() { current = " *" currentColor = style.FgGreen } icon := icons.IconForWorktree(false) - if isPathMissing { + if worktree.PathMissing() { textStyle = style.FgRed icon = icons.IconForWorktree(true) } @@ -45,7 +43,7 @@ func GetWorktreeDisplayString(tr *i18n.TranslationSet, isCurrent bool, isPathMis if worktree.Main() { name += " " + tr.MainWorktree } - if isPathMissing && !icons.IsIconEnabled() { + if worktree.PathMissing() && !icons.IsIconEnabled() { name += " " + tr.MissingWorktree } res = append(res, textStyle.Sprint(name)) |