mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-09 13:47:11 +02:00
Use an interface for tasks instead of a concrete struct
By using an interface for tasks we can use a fake implementation in tests with extra methods
This commit is contained in:
parent
8964cedf27
commit
6b9390409e
2
go.mod
2
go.mod
@ -18,7 +18,7 @@ require (
|
||||
github.com/integrii/flaggy v1.4.0
|
||||
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20230709105400-44d9f78b4b52
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20230710004407-9bbfd873713b
|
||||
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5
|
||||
github.com/jesseduffield/minimal/gitignore v0.3.3-0.20211018110810-9cde264e6b1e
|
||||
|
4
go.sum
4
go.sum
@ -72,8 +72,8 @@ github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68 h1:EQP2Tv8T
|
||||
github.com/jesseduffield/generics v0.0.0-20220320043834-727e535cbe68/go.mod h1:+LLj9/WUPAP8LqCchs7P+7X0R98HiFujVFANdNaxhGk=
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d h1:bO+OmbreIv91rCe8NmscRwhFSqkDJtzWCPV4Y+SQuXE=
|
||||
github.com/jesseduffield/go-git/v5 v5.1.2-0.20221018185014-fdd53fef665d/go.mod h1:nGNEErzf+NRznT+N2SWqmHnDnF9aLgANB1CUNEan09o=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20230709105400-44d9f78b4b52 h1:rrKgkOAVJD5rgC6aoX3zWTSiSiHkuQBA2JW/r+v1eKE=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20230709105400-44d9f78b4b52/go.mod h1:dJ/BEUt3OWtaRg/PmuJWendRqREhre9JQ1SLvqrVJ8s=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20230710004407-9bbfd873713b h1:8FmmdaYHes1m3oNyNdS+VIgkgkFpNZAWuwTnvp0tG14=
|
||||
github.com/jesseduffield/gocui v0.3.1-0.20230710004407-9bbfd873713b/go.mod h1:dJ/BEUt3OWtaRg/PmuJWendRqREhre9JQ1SLvqrVJ8s=
|
||||
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10 h1:jmpr7KpX2+2GRiE91zTgfq49QvgiqB0nbmlwZ8UnOx0=
|
||||
github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10/go.mod h1:aA97kHeNA+sj2Hbki0pvLslmE4CbDyhBeSSTUUnOuVo=
|
||||
github.com/jesseduffield/lazycore v0.0.0-20221012050358-03d2e40243c5 h1:CDuQmfOjAtb1Gms6a1p5L2P8RhbLUq5t8aL7PiQd2uY=
|
||||
|
@ -48,7 +48,7 @@ func (self *RemoteCommands) UpdateRemoteUrl(remoteName string, updatedUrl string
|
||||
return self.cmd.New(cmdArgs).Run()
|
||||
}
|
||||
|
||||
func (self *RemoteCommands) DeleteRemoteBranch(task *gocui.Task, remoteName string, branchName string) error {
|
||||
func (self *RemoteCommands) DeleteRemoteBranch(task gocui.Task, remoteName string, branchName string) error {
|
||||
cmdArgs := NewGitCmd("push").
|
||||
Arg(remoteName, "--delete", branchName).
|
||||
ToArgv()
|
||||
|
@ -24,7 +24,7 @@ type PushOpts struct {
|
||||
SetUpstream bool
|
||||
}
|
||||
|
||||
func (self *SyncCommands) PushCmdObj(task *gocui.Task, opts PushOpts) (oscommands.ICmdObj, error) {
|
||||
func (self *SyncCommands) PushCmdObj(task gocui.Task, opts PushOpts) (oscommands.ICmdObj, error) {
|
||||
if opts.UpstreamBranch != "" && opts.UpstreamRemote == "" {
|
||||
return nil, errors.New(self.Tr.MustSpecifyOriginError)
|
||||
}
|
||||
@ -40,7 +40,7 @@ func (self *SyncCommands) PushCmdObj(task *gocui.Task, opts PushOpts) (oscommand
|
||||
return cmdObj, nil
|
||||
}
|
||||
|
||||
func (self *SyncCommands) Push(task *gocui.Task, opts PushOpts) error {
|
||||
func (self *SyncCommands) Push(task gocui.Task, opts PushOpts) error {
|
||||
cmdObj, err := self.PushCmdObj(task, opts)
|
||||
if err != nil {
|
||||
return err
|
||||
@ -49,24 +49,33 @@ func (self *SyncCommands) Push(task *gocui.Task, opts PushOpts) error {
|
||||
return cmdObj.Run()
|
||||
}
|
||||
|
||||
func (self *SyncCommands) Fetch(task *gocui.Task) error {
|
||||
func (self *SyncCommands) FetchCmdObj(task gocui.Task) oscommands.ICmdObj {
|
||||
cmdArgs := NewGitCmd("fetch").
|
||||
ArgIf(self.UserConfig.Git.FetchAll, "--all").
|
||||
ToArgv()
|
||||
|
||||
cmdObj := self.cmd.New(cmdArgs)
|
||||
cmdObj.PromptOnCredentialRequest(task)
|
||||
return cmdObj.WithMutex(self.syncMutex).Run()
|
||||
return cmdObj
|
||||
}
|
||||
|
||||
func (self *SyncCommands) FetchBackground() error {
|
||||
func (self *SyncCommands) Fetch(task gocui.Task) error {
|
||||
return self.FetchCmdObj(task).Run()
|
||||
}
|
||||
|
||||
func (self *SyncCommands) FetchBackgroundCmdObj() oscommands.ICmdObj {
|
||||
cmdArgs := NewGitCmd("fetch").
|
||||
ArgIf(self.UserConfig.Git.FetchAll, "--all").
|
||||
ToArgv()
|
||||
|
||||
cmdObj := self.cmd.New(cmdArgs)
|
||||
cmdObj.DontLog().FailOnCredentialRequest()
|
||||
return cmdObj.WithMutex(self.syncMutex).Run()
|
||||
cmdObj.WithMutex(self.syncMutex)
|
||||
return cmdObj
|
||||
}
|
||||
|
||||
func (self *SyncCommands) FetchBackground() error {
|
||||
return self.FetchBackgroundCmdObj().Run()
|
||||
}
|
||||
|
||||
type PullOptions struct {
|
||||
@ -75,7 +84,7 @@ type PullOptions struct {
|
||||
FastForwardOnly bool
|
||||
}
|
||||
|
||||
func (self *SyncCommands) Pull(task *gocui.Task, opts PullOptions) error {
|
||||
func (self *SyncCommands) Pull(task gocui.Task, opts PullOptions) error {
|
||||
cmdArgs := NewGitCmd("pull").
|
||||
Arg("--no-edit").
|
||||
ArgIf(opts.FastForwardOnly, "--ff-only").
|
||||
@ -88,7 +97,7 @@ func (self *SyncCommands) Pull(task *gocui.Task, opts PullOptions) error {
|
||||
return self.cmd.New(cmdArgs).AddEnvVars("GIT_SEQUENCE_EDITOR=:").PromptOnCredentialRequest(task).WithMutex(self.syncMutex).Run()
|
||||
}
|
||||
|
||||
func (self *SyncCommands) FastForward(task *gocui.Task, branchName string, remoteName string, remoteBranchName string) error {
|
||||
func (self *SyncCommands) FastForward(task gocui.Task, branchName string, remoteName string, remoteBranchName string) error {
|
||||
cmdArgs := NewGitCmd("fetch").
|
||||
Arg(remoteName).
|
||||
Arg(remoteBranchName + ":" + branchName).
|
||||
@ -97,7 +106,7 @@ func (self *SyncCommands) FastForward(task *gocui.Task, branchName string, remot
|
||||
return self.cmd.New(cmdArgs).PromptOnCredentialRequest(task).WithMutex(self.syncMutex).Run()
|
||||
}
|
||||
|
||||
func (self *SyncCommands) FetchRemote(task *gocui.Task, remoteName string) error {
|
||||
func (self *SyncCommands) FetchRemote(task gocui.Task, remoteName string) error {
|
||||
cmdArgs := NewGitCmd("fetch").
|
||||
Arg(remoteName).
|
||||
ToArgv()
|
||||
|
@ -3,6 +3,7 @@ package git_commands
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/commands/oscommands"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
@ -88,7 +89,8 @@ func TestSyncPush(t *testing.T) {
|
||||
s := s
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
instance := buildSyncCommands(commonDeps{})
|
||||
s.test(instance.PushCmdObj(s.opts))
|
||||
task := gocui.NewFakeTask()
|
||||
s.test(instance.PushCmdObj(task, s.opts))
|
||||
})
|
||||
}
|
||||
}
|
||||
@ -96,7 +98,6 @@ func TestSyncPush(t *testing.T) {
|
||||
func TestSyncFetch(t *testing.T) {
|
||||
type scenario struct {
|
||||
testName string
|
||||
opts FetchOptions
|
||||
fetchAllConfig bool
|
||||
test func(oscommands.ICmdObj)
|
||||
}
|
||||
@ -104,7 +105,6 @@ func TestSyncFetch(t *testing.T) {
|
||||
scenarios := []scenario{
|
||||
{
|
||||
testName: "Fetch in foreground (all=false)",
|
||||
opts: FetchOptions{Background: false},
|
||||
fetchAllConfig: false,
|
||||
test: func(cmdObj oscommands.ICmdObj) {
|
||||
assert.True(t, cmdObj.ShouldLog())
|
||||
@ -114,7 +114,6 @@ func TestSyncFetch(t *testing.T) {
|
||||
},
|
||||
{
|
||||
testName: "Fetch in foreground (all=true)",
|
||||
opts: FetchOptions{Background: false},
|
||||
fetchAllConfig: true,
|
||||
test: func(cmdObj oscommands.ICmdObj) {
|
||||
assert.True(t, cmdObj.ShouldLog())
|
||||
@ -122,9 +121,29 @@ func TestSyncFetch(t *testing.T) {
|
||||
assert.Equal(t, cmdObj.Args(), []string{"git", "fetch", "--all"})
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
s := s
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
instance := buildSyncCommands(commonDeps{})
|
||||
instance.UserConfig.Git.FetchAll = s.fetchAllConfig
|
||||
task := gocui.NewFakeTask()
|
||||
s.test(instance.FetchCmdObj(task))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestSyncFetchBackground(t *testing.T) {
|
||||
type scenario struct {
|
||||
testName string
|
||||
fetchAllConfig bool
|
||||
test func(oscommands.ICmdObj)
|
||||
}
|
||||
|
||||
scenarios := []scenario{
|
||||
{
|
||||
testName: "Fetch in background (all=false)",
|
||||
opts: FetchOptions{Background: true},
|
||||
fetchAllConfig: false,
|
||||
test: func(cmdObj oscommands.ICmdObj) {
|
||||
assert.False(t, cmdObj.ShouldLog())
|
||||
@ -134,7 +153,6 @@ func TestSyncFetch(t *testing.T) {
|
||||
},
|
||||
{
|
||||
testName: "Fetch in background (all=true)",
|
||||
opts: FetchOptions{Background: true},
|
||||
fetchAllConfig: true,
|
||||
test: func(cmdObj oscommands.ICmdObj) {
|
||||
assert.False(t, cmdObj.ShouldLog())
|
||||
@ -149,7 +167,7 @@ func TestSyncFetch(t *testing.T) {
|
||||
t.Run(s.testName, func(t *testing.T) {
|
||||
instance := buildSyncCommands(commonDeps{})
|
||||
instance.UserConfig.Git.FetchAll = s.fetchAllConfig
|
||||
s.test(instance.FetchCmdObj(s.opts))
|
||||
s.test(instance.FetchBackgroundCmdObj())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ func (self *TagCommands) Delete(tagName string) error {
|
||||
return self.cmd.New(cmdArgs).Run()
|
||||
}
|
||||
|
||||
func (self *TagCommands) Push(task *gocui.Task, remoteName string, tagName string) error {
|
||||
func (self *TagCommands) Push(task gocui.Task, remoteName string, tagName string) error {
|
||||
cmdArgs := NewGitCmd("push").Arg(remoteName, "tag", tagName).
|
||||
ToArgv()
|
||||
|
||||
|
@ -57,14 +57,14 @@ type ICmdObj interface {
|
||||
// returns true if IgnoreEmptyError() was called
|
||||
ShouldIgnoreEmptyError() bool
|
||||
|
||||
PromptOnCredentialRequest(task *gocui.Task) ICmdObj
|
||||
PromptOnCredentialRequest(task gocui.Task) ICmdObj
|
||||
FailOnCredentialRequest() ICmdObj
|
||||
|
||||
WithMutex(mutex *deadlock.Mutex) ICmdObj
|
||||
Mutex() *deadlock.Mutex
|
||||
|
||||
GetCredentialStrategy() CredentialStrategy
|
||||
GetTask() *gocui.Task
|
||||
GetTask() gocui.Task
|
||||
}
|
||||
|
||||
type CmdObj struct {
|
||||
@ -87,7 +87,7 @@ type CmdObj struct {
|
||||
|
||||
// if set to true, it means we might be asked to enter a username/password by this command.
|
||||
credentialStrategy CredentialStrategy
|
||||
task *gocui.Task
|
||||
task gocui.Task
|
||||
|
||||
// can be set so that we don't run certain commands simultaneously
|
||||
mutex *deadlock.Mutex
|
||||
@ -195,7 +195,7 @@ func (self *CmdObj) RunAndProcessLines(onLine func(line string) (bool, error)) e
|
||||
return self.runner.RunAndProcessLines(self, onLine)
|
||||
}
|
||||
|
||||
func (self *CmdObj) PromptOnCredentialRequest(task *gocui.Task) ICmdObj {
|
||||
func (self *CmdObj) PromptOnCredentialRequest(task gocui.Task) ICmdObj {
|
||||
self.credentialStrategy = PROMPT
|
||||
self.task = task
|
||||
|
||||
@ -212,6 +212,6 @@ func (self *CmdObj) GetCredentialStrategy() CredentialStrategy {
|
||||
return self.credentialStrategy
|
||||
}
|
||||
|
||||
func (self *CmdObj) GetTask() *gocui.Task {
|
||||
func (self *CmdObj) GetTask() gocui.Task {
|
||||
return self.task
|
||||
}
|
||||
|
@ -318,7 +318,7 @@ func (self *cmdObjRunner) processOutput(
|
||||
reader io.Reader,
|
||||
writer io.Writer,
|
||||
promptUserForCredential func(CredentialType) <-chan string,
|
||||
task *gocui.Task,
|
||||
task gocui.Task,
|
||||
) {
|
||||
checkForCredentialRequest := self.getCheckForCredentialRequestFunc()
|
||||
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/jesseduffield/gocui"
|
||||
"github.com/jesseduffield/lazygit/pkg/utils"
|
||||
)
|
||||
|
||||
@ -111,7 +112,8 @@ func TestProcessOutput(t *testing.T) {
|
||||
reader := strings.NewReader(scenario.output)
|
||||
writer := &strings.Builder{}
|
||||
|
||||
runner.processOutput(reader, writer, toChanFn(scenario.promptUserForCredential))
|
||||
task := gocui.NewFakeTask()
|
||||
runner.processOutput(reader, writer, toChanFn(scenario.promptUserForCredential), task)
|
||||
|
||||
if writer.String() != scenario.expectedToWrite {
|
||||
t.Errorf("expected to write '%s' but got '%s'", scenario.expectedToWrite, writer.String())
|
||||
|
@ -86,7 +86,7 @@ func (self *BackgroundRoutineMgr) goEvery(interval time.Duration, stop chan stru
|
||||
if self.pauseBackgroundRefreshes {
|
||||
continue
|
||||
}
|
||||
self.gui.c.OnWorker(func(*gocui.Task) { _ = function() })
|
||||
self.gui.c.OnWorker(func(gocui.Task) { _ = function() })
|
||||
case <-stop:
|
||||
return
|
||||
}
|
||||
|
@ -364,7 +364,7 @@ func (self *BranchesController) fastForward(branch *models.Branch) error {
|
||||
},
|
||||
)
|
||||
|
||||
return self.c.WithLoaderPanel(message, func(task *gocui.Task) error {
|
||||
return self.c.WithLoaderPanel(message, func(task gocui.Task) error {
|
||||
if branch == self.c.Helpers().Refs.GetCheckedOutRef() {
|
||||
self.c.LogAction(action)
|
||||
|
||||
|
@ -177,7 +177,7 @@ func (self *CommitFilesController) discard(node *filetree.CommitFileNode) error
|
||||
Title: self.c.Tr.DiscardFileChangesTitle,
|
||||
Prompt: prompt,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.DiscardOldFileChange)
|
||||
if err := self.c.Git().Rebase.DiscardOldFileChanges(self.c.Model().Commits, self.c.Contexts().LocalCommits.GetSelectedLineIdx(), node.GetPath()); err != nil {
|
||||
if err := self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err); err != nil {
|
||||
@ -205,7 +205,7 @@ func (self *CommitFilesController) edit(node *filetree.CommitFileNode) error {
|
||||
|
||||
func (self *CommitFilesController) toggleForPatch(node *filetree.CommitFileNode) error {
|
||||
toggle := func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.UpdatingPatch, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.UpdatingPatch, func(gocui.Task) error {
|
||||
if !self.c.Git().Patch.PatchBuilder.Active() {
|
||||
if err := self.startPatchBuilder(); err != nil {
|
||||
return err
|
||||
|
@ -117,7 +117,7 @@ func (self *CustomPatchOptionsMenuAction) handleDeletePatchFromCommit() error {
|
||||
return err
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(gocui.Task) error {
|
||||
commitIndex := self.getPatchCommitIndex()
|
||||
self.c.LogAction(self.c.Tr.Actions.RemovePatchFromCommit)
|
||||
err := self.c.Git().Patch.DeletePatchesFromCommit(self.c.Model().Commits, commitIndex)
|
||||
@ -134,7 +134,7 @@ func (self *CustomPatchOptionsMenuAction) handleMovePatchToSelectedCommit() erro
|
||||
return err
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(gocui.Task) error {
|
||||
commitIndex := self.getPatchCommitIndex()
|
||||
self.c.LogAction(self.c.Tr.Actions.MovePatchToSelectedCommit)
|
||||
err := self.c.Git().Patch.MovePatchToSelectedCommit(self.c.Model().Commits, commitIndex, self.c.Contexts().LocalCommits.GetSelectedLineIdx())
|
||||
@ -152,7 +152,7 @@ func (self *CustomPatchOptionsMenuAction) handleMovePatchIntoWorkingTree() error
|
||||
}
|
||||
|
||||
pull := func(stash bool) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(gocui.Task) error {
|
||||
commitIndex := self.getPatchCommitIndex()
|
||||
self.c.LogAction(self.c.Tr.Actions.MovePatchIntoIndex)
|
||||
err := self.c.Git().Patch.MovePatchIntoIndex(self.c.Model().Commits, commitIndex, stash)
|
||||
@ -182,7 +182,7 @@ func (self *CustomPatchOptionsMenuAction) handlePullPatchIntoNewCommit() error {
|
||||
return err
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(gocui.Task) error {
|
||||
commitIndex := self.getPatchCommitIndex()
|
||||
self.c.LogAction(self.c.Tr.Actions.MovePatchIntoNewCommit)
|
||||
err := self.c.Git().Patch.PullPatchIntoNewCommit(self.c.Model().Commits, commitIndex)
|
||||
|
@ -800,7 +800,7 @@ func (self *FilesController) onClickSecondary(opts gocui.ViewMouseBindingOpts) e
|
||||
}
|
||||
|
||||
func (self *FilesController) fetch() error {
|
||||
return self.c.WithLoaderPanel(self.c.Tr.FetchWait, func(task *gocui.Task) error {
|
||||
return self.c.WithLoaderPanel(self.c.Tr.FetchWait, func(task gocui.Task) error {
|
||||
if err := self.fetchAux(task); err != nil {
|
||||
_ = self.c.Error(err)
|
||||
}
|
||||
@ -808,7 +808,7 @@ func (self *FilesController) fetch() error {
|
||||
})
|
||||
}
|
||||
|
||||
func (self *FilesController) fetchAux(task *gocui.Task) (err error) {
|
||||
func (self *FilesController) fetchAux(task gocui.Task) (err error) {
|
||||
self.c.LogAction("Fetch")
|
||||
err = self.c.Git().Sync.Fetch(task)
|
||||
|
||||
|
@ -146,7 +146,7 @@ func (self *FilesRemoveController) remove(node *filetree.FileNode) error {
|
||||
}
|
||||
|
||||
func (self *FilesRemoveController) ResetSubmodule(submodule *models.SubmoduleConfig) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.ResettingSubmoduleStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.ResettingSubmoduleStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.ResetSubmodule)
|
||||
|
||||
file := self.c.Helpers().WorkingTree.FileForSubmodule(submodule)
|
||||
|
@ -27,8 +27,8 @@ func (self *AppStatusHelper) Toast(message string) {
|
||||
}
|
||||
|
||||
// withWaitingStatus wraps a function and shows a waiting status while the function is still executing
|
||||
func (self *AppStatusHelper) WithWaitingStatus(message string, f func(*gocui.Task) error) {
|
||||
self.c.OnWorker(func(task *gocui.Task) {
|
||||
func (self *AppStatusHelper) WithWaitingStatus(message string, f func(gocui.Task) error) {
|
||||
self.c.OnWorker(func(task gocui.Task) {
|
||||
self.statusMgr().WithWaitingStatus(message, func() {
|
||||
self.renderAppStatus()
|
||||
|
||||
@ -50,7 +50,7 @@ func (self *AppStatusHelper) GetStatusString() string {
|
||||
}
|
||||
|
||||
func (self *AppStatusHelper) renderAppStatus() {
|
||||
self.c.OnWorker(func(_ *gocui.Task) {
|
||||
self.c.OnWorker(func(_ gocui.Task) {
|
||||
ticker := time.NewTicker(time.Millisecond * 50)
|
||||
defer ticker.Stop()
|
||||
for range ticker.C {
|
||||
|
@ -76,7 +76,7 @@ func (self *CherryPickHelper) Paste() error {
|
||||
Title: self.c.Tr.CherryPick,
|
||||
Prompt: self.c.Tr.SureCherryPick,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.CherryPickingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.CherryPickingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.CherryPick)
|
||||
err := self.c.Git().Rebase.CherryPickCommits(self.getData().CherryPickedCommits)
|
||||
return self.rebaseHelper.CheckMergeOrRebase(err)
|
||||
|
@ -42,7 +42,7 @@ func (self *GpgHelper) WithGpgHandling(cmdObj oscommands.ICmdObj, waitingStatus
|
||||
}
|
||||
|
||||
func (self *GpgHelper) runAndStream(cmdObj oscommands.ICmdObj, waitingStatus string, onSuccess func() error) error {
|
||||
return self.c.WithWaitingStatus(waitingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(waitingStatus, func(gocui.Task) error {
|
||||
if err := cmdObj.StreamOutput().Run(); err != nil {
|
||||
_ = self.c.Refresh(types.RefreshOptions{Mode: types.ASYNC})
|
||||
return self.c.Error(
|
||||
|
@ -87,7 +87,7 @@ func (self *RefreshHelper) Refresh(options types.RefreshOptions) error {
|
||||
|
||||
refresh := func(f func()) {
|
||||
if options.Mode == types.ASYNC {
|
||||
self.c.OnWorker(func(t *gocui.Task) {
|
||||
self.c.OnWorker(func(t gocui.Task) {
|
||||
f()
|
||||
})
|
||||
} else {
|
||||
@ -201,7 +201,7 @@ func getModeName(mode types.RefreshMode) string {
|
||||
func (self *RefreshHelper) refreshReflogCommitsConsideringStartup() {
|
||||
switch self.c.State().GetRepoState().GetStartupStage() {
|
||||
case types.INITIAL:
|
||||
self.c.OnWorker(func(_ *gocui.Task) {
|
||||
self.c.OnWorker(func(_ gocui.Task) {
|
||||
_ = self.refreshReflogCommits()
|
||||
self.refreshBranches()
|
||||
self.c.State().GetRepoState().SetStartupStage(types.COMPLETE)
|
||||
|
@ -51,7 +51,7 @@ func (self *RefsHelper) CheckoutRef(ref string, options types.CheckoutRefOptions
|
||||
self.c.Contexts().LocalCommits.SetLimitCommits(true)
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(waitingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(waitingStatus, func(gocui.Task) error {
|
||||
if err := self.c.Git().Branch.Checkout(ref, cmdOptions); err != nil {
|
||||
// note, this will only work for english-language git commands. If we force git to use english, and the error isn't this one, then the user will receive an english command they may not understand. I'm not sure what the best solution to this is. Running the command once in english and a second time in the native language is one option
|
||||
|
||||
|
@ -101,7 +101,7 @@ func (self *SuggestionsHelper) GetBranchNameSuggestionsFunc() func(string) []*ty
|
||||
// Notably, unlike other suggestion functions we're not showing all the options
|
||||
// if nothing has been typed because there'll be too much to display efficiently
|
||||
func (self *SuggestionsHelper) GetFilePathSuggestionsFunc() func(string) []*types.Suggestion {
|
||||
_ = self.c.WithWaitingStatus(self.c.Tr.LoadingFileSuggestions, func(*gocui.Task) error {
|
||||
_ = self.c.WithWaitingStatus(self.c.Tr.LoadingFileSuggestions, func(gocui.Task) error {
|
||||
trie := patricia.NewTrie()
|
||||
// load every non-gitignored file in the repo
|
||||
ignore, err := gitignore.FromGit()
|
||||
|
@ -38,7 +38,7 @@ func (self *UpdateHelper) CheckForUpdateInBackground() {
|
||||
}
|
||||
|
||||
func (self *UpdateHelper) CheckForUpdateInForeground() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.CheckingForUpdates, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.CheckingForUpdates, func(gocui.Task) error {
|
||||
self.updater.CheckForNewUpdate(func(newVersion string, err error) error {
|
||||
if err != nil {
|
||||
return self.c.Error(err)
|
||||
@ -54,7 +54,7 @@ func (self *UpdateHelper) CheckForUpdateInForeground() error {
|
||||
}
|
||||
|
||||
func (self *UpdateHelper) startUpdating(newVersion string) {
|
||||
_ = self.c.WithWaitingStatus(self.c.Tr.UpdateInProgressWaitingStatus, func(*gocui.Task) error {
|
||||
_ = self.c.WithWaitingStatus(self.c.Tr.UpdateInProgressWaitingStatus, func(gocui.Task) error {
|
||||
self.c.State().SetUpdating(true)
|
||||
err := self.updater.Update(newVersion)
|
||||
return self.onUpdateFinish(err)
|
||||
|
@ -218,7 +218,7 @@ func (self *LocalCommitsController) squashDown(commit *models.Commit) error {
|
||||
Title: self.c.Tr.Squash,
|
||||
Prompt: self.c.Tr.SureSquashThisCommit,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.SquashCommitDown)
|
||||
return self.interactiveRebase(todo.Squash)
|
||||
})
|
||||
@ -243,7 +243,7 @@ func (self *LocalCommitsController) fixup(commit *models.Commit) error {
|
||||
Title: self.c.Tr.Fixup,
|
||||
Prompt: self.c.Tr.SureFixupThisCommit,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.FixingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.FixingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.FixupCommit)
|
||||
return self.interactiveRebase(todo.Fixup)
|
||||
})
|
||||
@ -339,7 +339,7 @@ func (self *LocalCommitsController) drop(commit *models.Commit) error {
|
||||
Title: self.c.Tr.DeleteCommitTitle,
|
||||
Prompt: self.c.Tr.DeleteCommitPrompt,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.DeletingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.DeletingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.DropCommit)
|
||||
return self.interactiveRebase(todo.Drop)
|
||||
})
|
||||
@ -356,7 +356,7 @@ func (self *LocalCommitsController) edit(commit *models.Commit) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RebasingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.EditCommit)
|
||||
err := self.c.Git().Rebase.EditRebase(commit.Sha)
|
||||
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
|
||||
@ -461,7 +461,7 @@ func (self *LocalCommitsController) moveDown(commit *models.Commit) error {
|
||||
return self.c.ErrorMsg(self.c.Tr.AlreadyRebasing)
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(self.c.Tr.MovingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.MovingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.MoveCommitDown)
|
||||
err := self.c.Git().Rebase.MoveCommitDown(self.c.Model().Commits, index)
|
||||
if err == nil {
|
||||
@ -499,7 +499,7 @@ func (self *LocalCommitsController) moveUp(commit *models.Commit) error {
|
||||
return self.c.ErrorMsg(self.c.Tr.AlreadyRebasing)
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(self.c.Tr.MovingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.MovingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.MoveCommitUp)
|
||||
err := self.c.Git().Rebase.MoveCommitUp(self.c.Model().Commits, index)
|
||||
if err == nil {
|
||||
@ -525,7 +525,7 @@ func (self *LocalCommitsController) amendTo(commit *models.Commit) error {
|
||||
Title: self.c.Tr.AmendCommitTitle,
|
||||
Prompt: self.c.Tr.AmendCommitPrompt,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.AmendCommit)
|
||||
err := self.c.Git().Rebase.AmendTo(self.c.Model().Commits, self.context().GetView().SelectedLineIdx())
|
||||
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
|
||||
@ -559,7 +559,7 @@ func (self *LocalCommitsController) amendAttribute(commit *models.Commit) error
|
||||
}
|
||||
|
||||
func (self *LocalCommitsController) resetAuthor() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.ResetCommitAuthor)
|
||||
if err := self.c.Git().Rebase.ResetCommitAuthor(self.c.Model().Commits, self.context().GetSelectedLineIdx()); err != nil {
|
||||
return self.c.Error(err)
|
||||
@ -574,7 +574,7 @@ func (self *LocalCommitsController) setAuthor() error {
|
||||
Title: self.c.Tr.SetAuthorPromptTitle,
|
||||
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetAuthorsSuggestionsFunc(),
|
||||
HandleConfirm: func(value string) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.AmendingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.SetCommitAuthor)
|
||||
if err := self.c.Git().Rebase.SetCommitAuthor(self.c.Model().Commits, self.context().GetSelectedLineIdx(), value); err != nil {
|
||||
return self.c.Error(err)
|
||||
@ -672,7 +672,7 @@ func (self *LocalCommitsController) squashAllAboveFixupCommits(commit *models.Co
|
||||
Title: self.c.Tr.SquashAboveCommits,
|
||||
Prompt: prompt,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.SquashingStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.SquashAllAboveFixupCommits)
|
||||
err := self.c.Git().Rebase.SquashAllAboveFixupCommits(commit)
|
||||
return self.c.Helpers().MergeAndRebase.CheckMergeOrRebase(err)
|
||||
@ -724,7 +724,7 @@ func (self *LocalCommitsController) handleOpenLogMenu() error {
|
||||
self.context().SetLimitCommits(false)
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(self.c.Tr.LoadingCommits, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.LoadingCommits, func(gocui.Task) error {
|
||||
return self.c.Refresh(
|
||||
types.RefreshOptions{Mode: types.SYNC, Scope: []types.RefreshableView{types.COMMITS}},
|
||||
)
|
||||
@ -767,7 +767,7 @@ func (self *LocalCommitsController) handleOpenLogMenu() error {
|
||||
onPress := func(value string) func() error {
|
||||
return func() error {
|
||||
self.c.UserConfig.Git.Log.Order = value
|
||||
return self.c.WithWaitingStatus(self.c.Tr.LoadingCommits, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.LoadingCommits, func(gocui.Task) error {
|
||||
return self.c.Refresh(
|
||||
types.RefreshOptions{
|
||||
Mode: types.SYNC,
|
||||
@ -817,7 +817,7 @@ func (self *LocalCommitsController) GetOnFocus() func(types.OnFocusOpts) error {
|
||||
context := self.context()
|
||||
if context.GetSelectedLineIdx() > COMMIT_THRESHOLD && context.GetLimitCommits() {
|
||||
context.SetLimitCommits(false)
|
||||
self.c.OnWorker(func(_ *gocui.Task) {
|
||||
self.c.OnWorker(func(_ gocui.Task) {
|
||||
if err := self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.COMMITS}}); err != nil {
|
||||
_ = self.c.Error(err)
|
||||
}
|
||||
|
@ -118,7 +118,7 @@ func (self *RemoteBranchesController) delete(selectedBranch *models.RemoteBranch
|
||||
Title: self.c.Tr.DeleteRemoteBranch,
|
||||
Prompt: message,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.DeletingStatus, func(task *gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.DeletingStatus, func(task gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.DeleteRemoteBranch)
|
||||
err := self.c.Git().Remote.DeleteRemoteBranch(task, selectedBranch.RemoteName, selectedBranch.Name)
|
||||
if err != nil {
|
||||
|
@ -198,7 +198,7 @@ func (self *RemotesController) edit(remote *models.Remote) error {
|
||||
}
|
||||
|
||||
func (self *RemotesController) fetch(remote *models.Remote) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.FetchingRemoteStatus, func(task *gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.FetchingRemoteStatus, func(task gocui.Task) error {
|
||||
err := self.c.Git().Sync.FetchRemote(task, remote.Name)
|
||||
if err != nil {
|
||||
_ = self.c.Error(err)
|
||||
|
@ -60,7 +60,7 @@ func (self *SubCommitsController) GetOnFocus() func(types.OnFocusOpts) error {
|
||||
context := self.context()
|
||||
if context.GetSelectedLineIdx() > COMMIT_THRESHOLD && context.GetLimitCommits() {
|
||||
context.SetLimitCommits(false)
|
||||
self.c.OnWorker(func(_ *gocui.Task) {
|
||||
self.c.OnWorker(func(_ gocui.Task) {
|
||||
if err := self.c.Refresh(types.RefreshOptions{Scope: []types.RefreshableView{types.SUB_COMMITS}}); err != nil {
|
||||
_ = self.c.Error(err)
|
||||
}
|
||||
|
@ -131,7 +131,7 @@ func (self *SubmodulesController) add() error {
|
||||
Title: self.c.Tr.NewSubmodulePath,
|
||||
InitialContent: submoduleName,
|
||||
HandleConfirm: func(submodulePath string) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.AddingSubmoduleStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.AddingSubmoduleStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.AddSubmodule)
|
||||
err := self.c.Git().Submodule.Add(submoduleName, submodulePath, submoduleUrl)
|
||||
if err != nil {
|
||||
@ -153,7 +153,7 @@ func (self *SubmodulesController) editURL(submodule *models.SubmoduleConfig) err
|
||||
Title: fmt.Sprintf(self.c.Tr.UpdateSubmoduleUrl, submodule.Name),
|
||||
InitialContent: submodule.Url,
|
||||
HandleConfirm: func(newUrl string) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.UpdatingSubmoduleUrlStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.UpdatingSubmoduleUrlStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.UpdateSubmoduleUrl)
|
||||
err := self.c.Git().Submodule.UpdateUrl(submodule.Name, submodule.Path, newUrl)
|
||||
if err != nil {
|
||||
@ -167,7 +167,7 @@ func (self *SubmodulesController) editURL(submodule *models.SubmoduleConfig) err
|
||||
}
|
||||
|
||||
func (self *SubmodulesController) init(submodule *models.SubmoduleConfig) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.InitializingSubmoduleStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.InitializingSubmoduleStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.InitialiseSubmodule)
|
||||
err := self.c.Git().Submodule.Init(submodule.Path)
|
||||
if err != nil {
|
||||
@ -185,7 +185,7 @@ func (self *SubmodulesController) openBulkActionsMenu() error {
|
||||
{
|
||||
LabelColumns: []string{self.c.Tr.BulkInitSubmodules, style.FgGreen.Sprint(self.c.Git().Submodule.BulkInitCmdObj().ToString())},
|
||||
OnPress: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RunningCommand, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RunningCommand, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.BulkInitialiseSubmodules)
|
||||
err := self.c.Git().Submodule.BulkInitCmdObj().Run()
|
||||
if err != nil {
|
||||
@ -200,7 +200,7 @@ func (self *SubmodulesController) openBulkActionsMenu() error {
|
||||
{
|
||||
LabelColumns: []string{self.c.Tr.BulkUpdateSubmodules, style.FgYellow.Sprint(self.c.Git().Submodule.BulkUpdateCmdObj().ToString())},
|
||||
OnPress: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RunningCommand, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RunningCommand, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.BulkUpdateSubmodules)
|
||||
if err := self.c.Git().Submodule.BulkUpdateCmdObj().Run(); err != nil {
|
||||
return self.c.Error(err)
|
||||
@ -214,7 +214,7 @@ func (self *SubmodulesController) openBulkActionsMenu() error {
|
||||
{
|
||||
LabelColumns: []string{self.c.Tr.BulkDeinitSubmodules, style.FgRed.Sprint(self.c.Git().Submodule.BulkDeinitCmdObj().ToString())},
|
||||
OnPress: func() error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RunningCommand, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.RunningCommand, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.BulkDeinitialiseSubmodules)
|
||||
if err := self.c.Git().Submodule.BulkDeinitCmdObj().Run(); err != nil {
|
||||
return self.c.Error(err)
|
||||
@ -230,7 +230,7 @@ func (self *SubmodulesController) openBulkActionsMenu() error {
|
||||
}
|
||||
|
||||
func (self *SubmodulesController) update(submodule *models.SubmoduleConfig) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.UpdatingSubmoduleStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.UpdatingSubmoduleStatus, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.UpdateSubmodule)
|
||||
err := self.c.Git().Submodule.Update(submodule.Path)
|
||||
if err != nil {
|
||||
|
@ -139,12 +139,12 @@ type PullFilesOptions struct {
|
||||
}
|
||||
|
||||
func (self *SyncController) PullAux(opts PullFilesOptions) error {
|
||||
return self.c.WithLoaderPanel(self.c.Tr.PullWait, func(task *gocui.Task) error {
|
||||
return self.c.WithLoaderPanel(self.c.Tr.PullWait, func(task gocui.Task) error {
|
||||
return self.pullWithLock(task, opts)
|
||||
})
|
||||
}
|
||||
|
||||
func (self *SyncController) pullWithLock(task *gocui.Task, opts PullFilesOptions) error {
|
||||
func (self *SyncController) pullWithLock(task gocui.Task, opts PullFilesOptions) error {
|
||||
self.c.LogAction(opts.Action)
|
||||
|
||||
err := self.c.Git().Sync.Pull(
|
||||
@ -167,7 +167,7 @@ type pushOpts struct {
|
||||
}
|
||||
|
||||
func (self *SyncController) pushAux(opts pushOpts) error {
|
||||
return self.c.WithLoaderPanel(self.c.Tr.PushWait, func(task *gocui.Task) error {
|
||||
return self.c.WithLoaderPanel(self.c.Tr.PushWait, func(task gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.Push)
|
||||
err := self.c.Git().Sync.Push(
|
||||
task,
|
||||
|
@ -122,7 +122,7 @@ func (self *TagsController) push(tag *models.Tag) error {
|
||||
InitialContent: "origin",
|
||||
FindSuggestionsFunc: self.c.Helpers().Suggestions.GetRemoteSuggestionsFunc(),
|
||||
HandleConfirm: func(response string) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.PushingTagStatus, func(task *gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(self.c.Tr.PushingTagStatus, func(task gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.PushTag)
|
||||
err := self.c.Git().Tag.Push(task, response, tag.Name)
|
||||
if err != nil {
|
||||
|
@ -248,7 +248,7 @@ func (self *UndoController) hardResetWithAutoStash(commitSha string, options har
|
||||
Title: self.c.Tr.AutoStashTitle,
|
||||
Prompt: self.c.Tr.AutoStashPrompt,
|
||||
HandleConfirm: func() error {
|
||||
return self.c.WithWaitingStatus(options.WaitingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(options.WaitingStatus, func(gocui.Task) error {
|
||||
if err := self.c.Git().Stash.Save(self.c.Tr.StashPrefix + commitSha); err != nil {
|
||||
return self.c.Error(err)
|
||||
}
|
||||
@ -269,7 +269,7 @@ func (self *UndoController) hardResetWithAutoStash(commitSha string, options har
|
||||
})
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(options.WaitingStatus, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(options.WaitingStatus, func(gocui.Task) error {
|
||||
return reset()
|
||||
})
|
||||
}
|
||||
|
@ -472,10 +472,10 @@ func NewGui(
|
||||
func() error { return gui.State.ContextMgr.Pop() },
|
||||
func() types.Context { return gui.State.ContextMgr.Current() },
|
||||
gui.createMenu,
|
||||
func(message string, f func(*gocui.Task) error) { gui.helpers.AppStatus.WithWaitingStatus(message, f) },
|
||||
func(message string, f func(gocui.Task) error) { gui.helpers.AppStatus.WithWaitingStatus(message, f) },
|
||||
func(message string) { gui.helpers.AppStatus.Toast(message) },
|
||||
func() string { return gui.Views.Confirmation.TextArea.GetContent() },
|
||||
func(f func(*gocui.Task)) { gui.c.OnWorker(f) },
|
||||
func(f func(gocui.Task)) { gui.c.OnWorker(f) },
|
||||
)
|
||||
|
||||
guiCommon := &guiCommon{gui: gui, IPopupHandler: gui.PopupHandler}
|
||||
@ -780,19 +780,19 @@ func (gui *Gui) loadNewRepo() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (gui *Gui) showInitialPopups(tasks []func(chan struct{}) error) {
|
||||
gui.waitForIntro.Add(len(tasks))
|
||||
func (gui *Gui) showInitialPopups(popupTasks []func(chan struct{}) error) {
|
||||
gui.waitForIntro.Add(len(popupTasks))
|
||||
done := make(chan struct{})
|
||||
|
||||
gui.c.OnWorker(func(gocuiTask *gocui.Task) {
|
||||
for _, task := range tasks {
|
||||
if err := task(done); err != nil {
|
||||
gui.c.OnWorker(func(task gocui.Task) {
|
||||
for _, popupTask := range popupTasks {
|
||||
if err := popupTask(done); err != nil {
|
||||
_ = gui.c.Error(err)
|
||||
}
|
||||
|
||||
gocuiTask.Pause()
|
||||
task.Pause()
|
||||
<-done
|
||||
gocuiTask.Continue()
|
||||
task.Continue()
|
||||
gui.waitForIntro.Done()
|
||||
}
|
||||
})
|
||||
@ -833,7 +833,7 @@ func (gui *Gui) onUIThread(f func() error) {
|
||||
})
|
||||
}
|
||||
|
||||
func (gui *Gui) onWorker(f func(*gocui.Task)) {
|
||||
func (gui *Gui) onWorker(f func(gocui.Task)) {
|
||||
gui.g.OnWorker(f)
|
||||
}
|
||||
|
||||
|
@ -136,7 +136,7 @@ func (self *guiCommon) OnUIThread(f func() error) {
|
||||
self.gui.onUIThread(f)
|
||||
}
|
||||
|
||||
func (self *guiCommon) OnWorker(f func(*gocui.Task)) {
|
||||
func (self *guiCommon) OnWorker(f func(gocui.Task)) {
|
||||
self.gui.onWorker(f)
|
||||
}
|
||||
|
||||
|
@ -33,12 +33,12 @@ func (self *FakePopupHandler) Prompt(opts types.PromptOpts) error {
|
||||
return self.OnPrompt(opts)
|
||||
}
|
||||
|
||||
func (self *FakePopupHandler) WithLoaderPanel(message string, f func(*gocui.Task) error) error {
|
||||
return f(&gocui.Task{})
|
||||
func (self *FakePopupHandler) WithLoaderPanel(message string, f func(gocui.Task) error) error {
|
||||
return f(gocui.NewFakeTask())
|
||||
}
|
||||
|
||||
func (self *FakePopupHandler) WithWaitingStatus(message string, f func(*gocui.Task) error) error {
|
||||
return f(&gocui.Task{})
|
||||
func (self *FakePopupHandler) WithWaitingStatus(message string, f func(gocui.Task) error) error {
|
||||
return f(gocui.NewFakeTask())
|
||||
}
|
||||
|
||||
func (self *FakePopupHandler) Menu(opts types.CreateMenuOptions) error {
|
||||
|
@ -21,10 +21,10 @@ type PopupHandler struct {
|
||||
popContextFn func() error
|
||||
currentContextFn func() types.Context
|
||||
createMenuFn func(types.CreateMenuOptions) error
|
||||
withWaitingStatusFn func(message string, f func(*gocui.Task) error)
|
||||
withWaitingStatusFn func(message string, f func(gocui.Task) error)
|
||||
toastFn func(message string)
|
||||
getPromptInputFn func() string
|
||||
onWorker func(func(*gocui.Task))
|
||||
onWorker func(func(gocui.Task))
|
||||
}
|
||||
|
||||
var _ types.IPopupHandler = &PopupHandler{}
|
||||
@ -36,10 +36,10 @@ func NewPopupHandler(
|
||||
popContextFn func() error,
|
||||
currentContextFn func() types.Context,
|
||||
createMenuFn func(types.CreateMenuOptions) error,
|
||||
withWaitingStatusFn func(message string, f func(*gocui.Task) error),
|
||||
withWaitingStatusFn func(message string, f func(gocui.Task) error),
|
||||
toastFn func(message string),
|
||||
getPromptInputFn func() string,
|
||||
onWorker func(func(*gocui.Task)),
|
||||
onWorker func(func(gocui.Task)),
|
||||
) *PopupHandler {
|
||||
return &PopupHandler{
|
||||
Common: common,
|
||||
@ -64,7 +64,7 @@ func (self *PopupHandler) Toast(message string) {
|
||||
self.toastFn(message)
|
||||
}
|
||||
|
||||
func (self *PopupHandler) WithWaitingStatus(message string, f func(*gocui.Task) error) error {
|
||||
func (self *PopupHandler) WithWaitingStatus(message string, f func(gocui.Task) error) error {
|
||||
self.withWaitingStatusFn(message, f)
|
||||
return nil
|
||||
}
|
||||
@ -124,7 +124,7 @@ func (self *PopupHandler) Prompt(opts types.PromptOpts) error {
|
||||
})
|
||||
}
|
||||
|
||||
func (self *PopupHandler) WithLoaderPanel(message string, f func(*gocui.Task) error) error {
|
||||
func (self *PopupHandler) WithLoaderPanel(message string, f func(gocui.Task) error) error {
|
||||
index := 0
|
||||
self.Lock()
|
||||
self.index++
|
||||
@ -143,7 +143,7 @@ func (self *PopupHandler) WithLoaderPanel(message string, f func(*gocui.Task) er
|
||||
return nil
|
||||
}
|
||||
|
||||
self.onWorker(func(task *gocui.Task) {
|
||||
self.onWorker(func(task gocui.Task) {
|
||||
if err := f(task); err != nil {
|
||||
self.Log.Error(err)
|
||||
}
|
||||
|
@ -265,7 +265,7 @@ func (self *HandlerCreator) finalHandler(customCommand config.CustomCommand, ses
|
||||
loadingText = self.c.Tr.RunningCustomCommandStatus
|
||||
}
|
||||
|
||||
return self.c.WithWaitingStatus(loadingText, func(*gocui.Task) error {
|
||||
return self.c.WithWaitingStatus(loadingText, func(gocui.Task) error {
|
||||
self.c.LogAction(self.c.Tr.Actions.CustomCommand)
|
||||
|
||||
if customCommand.Stream {
|
||||
|
@ -130,7 +130,7 @@ func (gui *Gui) getManager(view *gocui.View) *tasks.ViewBufferManager {
|
||||
func() {
|
||||
_ = view.SetOrigin(0, 0)
|
||||
},
|
||||
func() *gocui.Task {
|
||||
func() gocui.Task {
|
||||
return gui.c.GocuiGui().NewTask()
|
||||
},
|
||||
)
|
||||
|
@ -79,7 +79,7 @@ type IGuiCommon interface {
|
||||
OnUIThread(f func() error)
|
||||
// Runs a function in a goroutine. Use this whenever you want to run a goroutine and keep track of the fact
|
||||
// that lazygit is still busy. See docs/dev/Busy.md
|
||||
OnWorker(f func(*gocui.Task))
|
||||
OnWorker(f func(gocui.Task))
|
||||
|
||||
// returns the gocui Gui struct. There is a good chance you don't actually want to use
|
||||
// this struct and instead want to use another method above
|
||||
@ -121,8 +121,8 @@ type IPopupHandler interface {
|
||||
Confirm(opts ConfirmOpts) error
|
||||
// Shows a popup prompting the user for input.
|
||||
Prompt(opts PromptOpts) error
|
||||
WithLoaderPanel(message string, f func(*gocui.Task) error) error
|
||||
WithWaitingStatus(message string, f func(*gocui.Task) error) error
|
||||
WithLoaderPanel(message string, f func(gocui.Task) error) error
|
||||
WithWaitingStatus(message string, f func(gocui.Task) error) error
|
||||
Menu(opts CreateMenuOptions) error
|
||||
Toast(message string)
|
||||
GetPromptInput() string
|
||||
|
@ -18,10 +18,10 @@ type AsyncHandler struct {
|
||||
lastId int
|
||||
mutex deadlock.Mutex
|
||||
onReject func()
|
||||
onWorker func(func(*gocui.Task))
|
||||
onWorker func(func(gocui.Task))
|
||||
}
|
||||
|
||||
func NewAsyncHandler(onWorker func(func(*gocui.Task))) *AsyncHandler {
|
||||
func NewAsyncHandler(onWorker func(func(gocui.Task))) *AsyncHandler {
|
||||
return &AsyncHandler{
|
||||
mutex: deadlock.Mutex{},
|
||||
onWorker: onWorker,
|
||||
@ -34,7 +34,7 @@ func (self *AsyncHandler) Do(f func() func()) {
|
||||
id := self.currentId
|
||||
self.mutex.Unlock()
|
||||
|
||||
self.onWorker(func(*gocui.Task) {
|
||||
self.onWorker(func(gocui.Task) {
|
||||
after := f()
|
||||
self.handle(after, id)
|
||||
})
|
||||
|
@ -13,8 +13,8 @@ func TestAsyncHandler(t *testing.T) {
|
||||
wg := sync.WaitGroup{}
|
||||
wg.Add(2)
|
||||
|
||||
onWorker := func(f func(*gocui.Task)) {
|
||||
go f(&gocui.Task{})
|
||||
onWorker := func(f func(gocui.Task)) {
|
||||
go f(gocui.NewFakeTask())
|
||||
}
|
||||
handler := NewAsyncHandler(onWorker)
|
||||
handler.onReject = func() {
|
||||
|
@ -50,7 +50,10 @@ type ViewBufferManager struct {
|
||||
onEndOfInput func()
|
||||
|
||||
// see docs/dev/Busy.md
|
||||
newTask func() *gocui.Task
|
||||
// A gocui task is not the same thing as the tasks defined in this file.
|
||||
// A gocui task simply represents the fact that lazygit is busy doing something,
|
||||
// whereas the tasks in this file are about rendering content to a view.
|
||||
newGocuiTask func() gocui.Task
|
||||
|
||||
// if the user flicks through a heap of items, with each one
|
||||
// spawning a process to render something to the main view,
|
||||
@ -80,7 +83,7 @@ func NewViewBufferManager(
|
||||
refreshView func(),
|
||||
onEndOfInput func(),
|
||||
onNewKey func(),
|
||||
newTask func() *gocui.Task,
|
||||
newGocuiTask func() gocui.Task,
|
||||
) *ViewBufferManager {
|
||||
return &ViewBufferManager{
|
||||
Log: log,
|
||||
@ -90,7 +93,7 @@ func NewViewBufferManager(
|
||||
onEndOfInput: onEndOfInput,
|
||||
readLines: make(chan LinesToRead, 1024),
|
||||
onNewKey: onNewKey,
|
||||
newTask: newTask,
|
||||
newGocuiTask: newGocuiTask,
|
||||
}
|
||||
}
|
||||
|
||||
@ -296,7 +299,7 @@ type TaskOpts struct {
|
||||
}
|
||||
|
||||
func (self *ViewBufferManager) NewTask(f func(TaskOpts) error, key string) error {
|
||||
task := self.newTask()
|
||||
task := self.newGocuiTask()
|
||||
|
||||
var completeTaskOnce sync.Once
|
||||
|
||||
|
@ -20,11 +20,6 @@ func getCounter() (func(), func() int) {
|
||||
return func() { counter++ }, func() int { return counter }
|
||||
}
|
||||
|
||||
func getIncDecCounter(initialValue int) (func(), func(), func() int) {
|
||||
counter := initialValue
|
||||
return func() { counter++ }, func() { counter-- }, func() int { return counter }
|
||||
}
|
||||
|
||||
func TestNewCmdTaskInstantStop(t *testing.T) {
|
||||
writer := bytes.NewBuffer(nil)
|
||||
beforeStart, getBeforeStartCallCount := getCounter()
|
||||
@ -32,8 +27,8 @@ func TestNewCmdTaskInstantStop(t *testing.T) {
|
||||
onEndOfInput, getOnEndOfInputCallCount := getCounter()
|
||||
onNewKey, getOnNewKeyCallCount := getCounter()
|
||||
onDone, getOnDoneCallCount := getCounter()
|
||||
task := &gocui.Task{}
|
||||
newTask := func() *gocui.Task {
|
||||
task := gocui.NewFakeTask()
|
||||
newTask := func() gocui.Task {
|
||||
return task
|
||||
}
|
||||
|
||||
@ -79,8 +74,8 @@ func TestNewCmdTaskInstantStop(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
if getBusyCount() != 0 {
|
||||
t.Errorf("expected busy count to be 0, got %d", getBusyCount())
|
||||
if task.Status() != gocui.TaskStatusDone {
|
||||
t.Errorf("expected task status to be 'done', got '%s'", task.FormatStatus())
|
||||
}
|
||||
|
||||
expectedContent := ""
|
||||
@ -97,7 +92,10 @@ func TestNewCmdTask(t *testing.T) {
|
||||
onEndOfInput, getOnEndOfInputCallCount := getCounter()
|
||||
onNewKey, getOnNewKeyCallCount := getCounter()
|
||||
onDone, getOnDoneCallCount := getCounter()
|
||||
incBusyCount, decBusyCount, getBusyCount := getIncDecCounter(1)
|
||||
task := gocui.NewFakeTask()
|
||||
newTask := func() gocui.Task {
|
||||
return task
|
||||
}
|
||||
|
||||
manager := NewViewBufferManager(
|
||||
utils.NewDummyLog(),
|
||||
@ -106,8 +104,7 @@ func TestNewCmdTask(t *testing.T) {
|
||||
refreshView,
|
||||
onEndOfInput,
|
||||
onNewKey,
|
||||
incBusyCount,
|
||||
decBusyCount,
|
||||
newTask,
|
||||
)
|
||||
|
||||
stop := make(chan struct{})
|
||||
@ -127,7 +124,7 @@ func TestNewCmdTask(t *testing.T) {
|
||||
close(stop)
|
||||
wg.Done()
|
||||
}()
|
||||
_ = fn(TaskOpts{Stop: stop, InitialContentLoaded: decBusyCount})
|
||||
_ = fn(TaskOpts{Stop: stop, InitialContentLoaded: func() { task.Done() }})
|
||||
|
||||
wg.Wait()
|
||||
|
||||
@ -148,8 +145,8 @@ func TestNewCmdTask(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
if getBusyCount() != 0 {
|
||||
t.Errorf("expected busy count to be 0, got %d", getBusyCount())
|
||||
if task.Status() != gocui.TaskStatusDone {
|
||||
t.Errorf("expected task status to be 'done', got '%s'", task.FormatStatus())
|
||||
}
|
||||
|
||||
expectedContent := "prefix\ntest\n"
|
||||
@ -230,7 +227,10 @@ func TestNewCmdTaskRefresh(t *testing.T) {
|
||||
lineCountsOnRefresh = append(lineCountsOnRefresh, strings.Count(writer.String(), "\n"))
|
||||
}
|
||||
|
||||
decBusyCount := func() {}
|
||||
task := gocui.NewFakeTask()
|
||||
newTask := func() gocui.Task {
|
||||
return task
|
||||
}
|
||||
|
||||
manager := NewViewBufferManager(
|
||||
utils.NewDummyLog(),
|
||||
@ -239,8 +239,7 @@ func TestNewCmdTaskRefresh(t *testing.T) {
|
||||
refreshView,
|
||||
func() {},
|
||||
func() {},
|
||||
func() {},
|
||||
decBusyCount,
|
||||
newTask,
|
||||
)
|
||||
|
||||
stop := make(chan struct{})
|
||||
@ -260,7 +259,7 @@ func TestNewCmdTaskRefresh(t *testing.T) {
|
||||
close(stop)
|
||||
wg.Done()
|
||||
}()
|
||||
_ = fn(TaskOpts{Stop: stop, InitialContentLoaded: decBusyCount})
|
||||
_ = fn(TaskOpts{Stop: stop, InitialContentLoaded: func() { task.Done() }})
|
||||
|
||||
wg.Wait()
|
||||
|
||||
|
93
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
93
vendor/github.com/jesseduffield/gocui/gui.go
generated
vendored
@ -177,87 +177,6 @@ type Gui struct {
|
||||
taskManager *TaskManager
|
||||
}
|
||||
|
||||
type TaskManager struct {
|
||||
// Tracks whether the program is busy (i.e. either something is happening on
|
||||
// the main goroutine or a worker goroutine). Used by integration tests
|
||||
// to wait until the program is idle before progressing.
|
||||
idleListeners []chan struct{}
|
||||
tasks map[int]*Task
|
||||
newTaskId int
|
||||
tasksMutex sync.Mutex
|
||||
}
|
||||
|
||||
func newTaskManager() *TaskManager {
|
||||
return &TaskManager{
|
||||
tasks: make(map[int]*Task),
|
||||
idleListeners: []chan struct{}{},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *TaskManager) NewTask() *Task {
|
||||
self.tasksMutex.Lock()
|
||||
defer self.tasksMutex.Unlock()
|
||||
|
||||
self.newTaskId++
|
||||
taskId := self.newTaskId
|
||||
|
||||
withMutex := func(f func()) {
|
||||
self.tasksMutex.Lock()
|
||||
defer self.tasksMutex.Unlock()
|
||||
|
||||
f()
|
||||
|
||||
// Check if all tasks are done
|
||||
for _, task := range self.tasks {
|
||||
if task.isBusy {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, all tasks are done, so
|
||||
// notify listeners that the program is idle
|
||||
for _, listener := range self.idleListeners {
|
||||
listener <- struct{}{}
|
||||
}
|
||||
}
|
||||
onDone := func() {
|
||||
withMutex(func() {
|
||||
delete(self.tasks, taskId)
|
||||
})
|
||||
}
|
||||
task := &Task{id: taskId, isBusy: true, onDone: onDone, withMutex: withMutex}
|
||||
self.tasks[taskId] = task
|
||||
|
||||
return task
|
||||
}
|
||||
|
||||
func (self *TaskManager) AddIdleListener(c chan struct{}) {
|
||||
self.idleListeners = append(self.idleListeners, c)
|
||||
}
|
||||
|
||||
type Task struct {
|
||||
id int
|
||||
isBusy bool
|
||||
onDone func()
|
||||
withMutex func(func())
|
||||
}
|
||||
|
||||
func (self *Task) Done() {
|
||||
self.onDone()
|
||||
}
|
||||
|
||||
func (self *Task) Pause() {
|
||||
self.withMutex(func() {
|
||||
self.isBusy = false
|
||||
})
|
||||
}
|
||||
|
||||
func (self *Task) Continue() {
|
||||
self.withMutex(func() {
|
||||
self.isBusy = true
|
||||
})
|
||||
}
|
||||
|
||||
// NewGui returns a new Gui object with a given output mode.
|
||||
func NewGui(mode OutputMode, supportOverlaps bool, playRecording bool, headless bool, runeReplacements map[rune]string) (*Gui, error) {
|
||||
g := &Gui{}
|
||||
@ -314,7 +233,7 @@ func NewGui(mode OutputMode, supportOverlaps bool, playRecording bool, headless
|
||||
return g, nil
|
||||
}
|
||||
|
||||
func (g *Gui) NewTask() *Task {
|
||||
func (g *Gui) NewTask() *TaskImpl {
|
||||
return g.taskManager.NewTask()
|
||||
}
|
||||
|
||||
@ -322,7 +241,7 @@ func (g *Gui) NewTask() *Task {
|
||||
// integration tests which can wait for the program to be idle before taking
|
||||
// the next step in the test.
|
||||
func (g *Gui) AddIdleListener(c chan struct{}) {
|
||||
g.taskManager.AddIdleListener(c)
|
||||
g.taskManager.addIdleListener(c)
|
||||
}
|
||||
|
||||
// Close finalizes the library. It should be called after a successful
|
||||
@ -689,7 +608,7 @@ func getKey(key interface{}) (Key, rune, error) {
|
||||
// userEvent represents an event triggered by the user.
|
||||
type userEvent struct {
|
||||
f func(*Gui) error
|
||||
task *Task
|
||||
task Task
|
||||
}
|
||||
|
||||
// Update executes the passed function. This method can be called safely from a
|
||||
@ -712,7 +631,7 @@ func (g *Gui) UpdateAsync(f func(*Gui) error) {
|
||||
g.updateAsyncAux(f, task)
|
||||
}
|
||||
|
||||
func (g *Gui) updateAsyncAux(f func(*Gui) error, task *Task) {
|
||||
func (g *Gui) updateAsyncAux(f func(*Gui) error, task Task) {
|
||||
g.userEvents <- userEvent{f: f, task: task}
|
||||
}
|
||||
|
||||
@ -722,7 +641,7 @@ func (g *Gui) updateAsyncAux(f func(*Gui) error, task *Task) {
|
||||
// consider itself 'busy` as it runs the code. Don't use for long-running
|
||||
// background goroutines where you wouldn't want lazygit to be considered busy
|
||||
// (i.e. when you wouldn't want a loader to be shown to the user)
|
||||
func (g *Gui) OnWorker(f func(*Task)) {
|
||||
func (g *Gui) OnWorker(f func(Task)) {
|
||||
task := g.NewTask()
|
||||
go func() {
|
||||
g.onWorkerAux(f, task)
|
||||
@ -730,7 +649,7 @@ func (g *Gui) OnWorker(f func(*Task)) {
|
||||
}()
|
||||
}
|
||||
|
||||
func (g *Gui) onWorkerAux(f func(*Task), task *Task) {
|
||||
func (g *Gui) onWorkerAux(f func(Task), task Task) {
|
||||
panicking := true
|
||||
defer func() {
|
||||
if panicking && Screen != nil {
|
||||
|
94
vendor/github.com/jesseduffield/gocui/task.go
generated
vendored
Normal file
94
vendor/github.com/jesseduffield/gocui/task.go
generated
vendored
Normal file
@ -0,0 +1,94 @@
|
||||
package gocui
|
||||
|
||||
// A task represents the fact that the program is busy doing something, which
|
||||
// is useful for integration tests which only want to proceed when the program
|
||||
// is idle.
|
||||
|
||||
type Task interface {
|
||||
Done()
|
||||
Pause()
|
||||
Continue()
|
||||
// not exporting because we don't need to
|
||||
isBusy() bool
|
||||
}
|
||||
|
||||
type TaskImpl struct {
|
||||
id int
|
||||
busy bool
|
||||
onDone func()
|
||||
withMutex func(func())
|
||||
}
|
||||
|
||||
func (self *TaskImpl) Done() {
|
||||
self.onDone()
|
||||
}
|
||||
|
||||
func (self *TaskImpl) Pause() {
|
||||
self.withMutex(func() {
|
||||
self.busy = false
|
||||
})
|
||||
}
|
||||
|
||||
func (self *TaskImpl) Continue() {
|
||||
self.withMutex(func() {
|
||||
self.busy = true
|
||||
})
|
||||
}
|
||||
|
||||
func (self *TaskImpl) isBusy() bool {
|
||||
return self.busy
|
||||
}
|
||||
|
||||
type TaskStatus int
|
||||
|
||||
const (
|
||||
TaskStatusBusy TaskStatus = iota
|
||||
TaskStatusPaused
|
||||
TaskStatusDone
|
||||
)
|
||||
|
||||
type FakeTask struct {
|
||||
status TaskStatus
|
||||
}
|
||||
|
||||
func NewFakeTask() *FakeTask {
|
||||
return &FakeTask{
|
||||
status: TaskStatusBusy,
|
||||
}
|
||||
}
|
||||
|
||||
func (self *FakeTask) Done() {
|
||||
self.status = TaskStatusDone
|
||||
}
|
||||
|
||||
func (self *FakeTask) Pause() {
|
||||
self.status = TaskStatusPaused
|
||||
}
|
||||
|
||||
func (self *FakeTask) Continue() {
|
||||
self.status = TaskStatusBusy
|
||||
}
|
||||
|
||||
func (self *FakeTask) isBusy() bool {
|
||||
return self.status == TaskStatusBusy
|
||||
}
|
||||
|
||||
func (self *FakeTask) Status() TaskStatus {
|
||||
return self.status
|
||||
}
|
||||
|
||||
func (self *FakeTask) FormatStatus() string {
|
||||
return formatTaskStatus(self.status)
|
||||
}
|
||||
|
||||
func formatTaskStatus(status TaskStatus) string {
|
||||
switch status {
|
||||
case TaskStatusBusy:
|
||||
return "busy"
|
||||
case TaskStatusPaused:
|
||||
return "paused"
|
||||
case TaskStatusDone:
|
||||
return "done"
|
||||
}
|
||||
return "unknown"
|
||||
}
|
67
vendor/github.com/jesseduffield/gocui/task_manager.go
generated
vendored
Normal file
67
vendor/github.com/jesseduffield/gocui/task_manager.go
generated
vendored
Normal file
@ -0,0 +1,67 @@
|
||||
package gocui
|
||||
|
||||
import "sync"
|
||||
|
||||
// Tracks whether the program is busy (i.e. either something is happening on
|
||||
// the main goroutine or a worker goroutine). Used by integration tests
|
||||
// to wait until the program is idle before progressing.
|
||||
type TaskManager struct {
|
||||
// each of these listeners will be notified when the program goes from busy to idle
|
||||
idleListeners []chan struct{}
|
||||
tasks map[int]Task
|
||||
// auto-incrementing id for new tasks
|
||||
nextId int
|
||||
|
||||
mutex sync.Mutex
|
||||
}
|
||||
|
||||
func newTaskManager() *TaskManager {
|
||||
return &TaskManager{
|
||||
tasks: make(map[int]Task),
|
||||
idleListeners: []chan struct{}{},
|
||||
}
|
||||
}
|
||||
|
||||
func (self *TaskManager) NewTask() *TaskImpl {
|
||||
self.mutex.Lock()
|
||||
defer self.mutex.Unlock()
|
||||
|
||||
self.nextId++
|
||||
taskId := self.nextId
|
||||
|
||||
onDone := func() { self.delete(taskId) }
|
||||
task := &TaskImpl{id: taskId, busy: true, onDone: onDone, withMutex: self.withMutex}
|
||||
self.tasks[taskId] = task
|
||||
|
||||
return task
|
||||
}
|
||||
|
||||
func (self *TaskManager) addIdleListener(c chan struct{}) {
|
||||
self.idleListeners = append(self.idleListeners, c)
|
||||
}
|
||||
|
||||
func (self *TaskManager) withMutex(f func()) {
|
||||
self.mutex.Lock()
|
||||
defer self.mutex.Unlock()
|
||||
|
||||
f()
|
||||
|
||||
// Check if all tasks are done
|
||||
for _, task := range self.tasks {
|
||||
if task.isBusy() {
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// If we get here, all tasks are done, so
|
||||
// notify listeners that the program is idle
|
||||
for _, listener := range self.idleListeners {
|
||||
listener <- struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
func (self *TaskManager) delete(taskId int) {
|
||||
self.withMutex(func() {
|
||||
delete(self.tasks, taskId)
|
||||
})
|
||||
}
|
2
vendor/modules.txt
vendored
2
vendor/modules.txt
vendored
@ -172,7 +172,7 @@ github.com/jesseduffield/go-git/v5/utils/merkletrie/filesystem
|
||||
github.com/jesseduffield/go-git/v5/utils/merkletrie/index
|
||||
github.com/jesseduffield/go-git/v5/utils/merkletrie/internal/frame
|
||||
github.com/jesseduffield/go-git/v5/utils/merkletrie/noder
|
||||
# github.com/jesseduffield/gocui v0.3.1-0.20230709105400-44d9f78b4b52
|
||||
# github.com/jesseduffield/gocui v0.3.1-0.20230710004407-9bbfd873713b
|
||||
## explicit; go 1.12
|
||||
github.com/jesseduffield/gocui
|
||||
# github.com/jesseduffield/kill v0.0.0-20220618033138-bfbe04675d10
|
||||
|
Loading…
x
Reference in New Issue
Block a user