summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorAnthony HAMON <hamon.anth@gmail.com>2018-09-02 17:15:27 +0200
committerAnthony HAMON <hamon.anth@gmail.com>2018-09-04 06:21:58 +0200
commit43ad9a81c282022203e45ae3088b93763320bccc (patch)
treea4b478b0154216120c9410ed55819daf12989a9f /pkg
parent9f7775df263a83c5e0e845955a7abcd989f62d2a (diff)
merge setup in function that create a new git command
Diffstat (limited to 'pkg')
-rw-r--r--pkg/commands/git.go127
-rw-r--r--pkg/commands/git_test.go175
2 files changed, 210 insertions, 92 deletions
diff --git a/pkg/commands/git.go b/pkg/commands/git.go
index 48d51e900..6ba5f8a84 100644
--- a/pkg/commands/git.go
+++ b/pkg/commands/git.go
@@ -19,98 +19,95 @@ import (
// to check if we have a valid git repository and we get an error instead
var ErrGitRepositoryInvalid = fmt.Errorf("can't find a valid git repository in current directory")
-func openGitRepositoryAndWorktree() (*gogit.Repository, *gogit.Worktree, error) {
- r, err := gogit.PlainOpen(".")
-
- if err != nil {
- return nil, nil, err
- }
-
- w, err := r.Worktree()
-
- if err != nil {
- return nil, nil, err
- }
-
- return r, w, nil
-}
-
-// GitCommand is our main git interface
-type GitCommand struct {
- Log *logrus.Entry
- OSCommand *OSCommand
- Worktree *gogit.Worktree
- Repo *gogit.Repository
- Tr *i18n.Localizer
- openGitRepositoryAndWorktree func() (*gogit.Repository, *gogit.Worktree, error)
-}
-
-// NewGitCommand it runs git commands
-func NewGitCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Localizer) (*GitCommand, error) {
- gitCommand := &GitCommand{
- Log: log,
- OSCommand: osCommand,
- Tr: tr,
- openGitRepositoryAndWorktree: openGitRepositoryAndWorktree,
- }
- return gitCommand, nil
-}
-
-// SetupGit sets git repo up
-func (c *GitCommand) SetupGit() error {
- fs := []func() error{
- c.verifyInGitRepo,
- c.navigateToRepoRootDirectory,
- c.setupRepositoryAndWorktree,
- }
-
- for _, f := range fs {
- if err := f(); err != nil {
- return err
- }
- }
-
- return nil
-}
-
-func (c *GitCommand) verifyInGitRepo() error {
- if _, err := c.OSCommand.RunCommandWithOutput("git status"); err != nil {
+func verifyInGitRepo(runCmdWithOutput func(string) (string, error)) error {
+ if _, err := runCmdWithOutput("git status"); err != nil {
return ErrGitRepositoryInvalid
}
return nil
}
-func (c *GitCommand) navigateToRepoRootDirectory() error {
+func navigateToRepoRootDirectory(stat func(string) (os.FileInfo, error), chdir func(string) error) error {
for {
- f, err := os.Stat(".git")
+ f, err := stat(".git")
if err == nil && f.IsDir() {
return nil
}
- c.Log.Debug("going up a directory to find the root")
+ if !os.IsNotExist(err) {
+ return err
+ }
- if err = os.Chdir(".."); err != nil {
+ if err = chdir(".."); err != nil {
return err
}
}
}
-func (c *GitCommand) setupRepositoryAndWorktree() (err error) {
- c.Repo, c.Worktree, err = c.openGitRepositoryAndWorktree()
+func setupRepositoryAndWorktree(openGitRepository func(string) (*gogit.Repository, error), sLocalize func(string) string) (repository *gogit.Repository, worktree *gogit.Worktree, err error) {
+ repository, err = openGitRepository(".")
+
+ if err != nil {
+ if strings.Contains(err.Error(), `unquoted '\' must be followed by new line`) {
+ return nil, nil, errors.New(sLocalize("GitconfigParseErr"))
+ }
- if err == nil {
return
}
- if strings.Contains(err.Error(), `unquoted '\' must be followed by new line`) {
- return errors.New(c.Tr.SLocalize("GitconfigParseErr"))
+ worktree, err = repository.Worktree()
+
+ if err != nil {
+ return
}
return
}
+// GitCommand is our main git interface
+type GitCommand struct {
+ Log *logrus.Entry
+ OSCommand *OSCommand
+ Worktree *gogit.Worktree
+ Repo *gogit.Repository
+ Tr *i18n.Localizer
+}
+
+// NewGitCommand it runs git commands
+func NewGitCommand(log *logrus.Entry, osCommand *OSCommand, tr *i18n.Localizer) (*GitCommand, error) {
+ var worktree *gogit.Worktree
+ var repo *gogit.Repository
+
+ fs := []func() error{
+ func() error {
+ return verifyInGitRepo(osCommand.RunCommandWithOutput)
+ },
+ func() error {
+ return navigateToRepoRootDirectory(os.Stat, os.Chdir)
+ },
+ func() error {
+ var err error
+ repo, worktree, err = setupRepositoryAndWorktree(gogit.PlainOpen, tr.SLocalize)
+ return err
+ },
+ }
+
+ for _, f := range fs {
+ if err := f(); err != nil {
+ return nil, err
+ }
+ }
+
+ return &GitCommand{
+ Log: log,
+ OSCommand: osCommand,
+ Tr: tr,
+ Worktree: worktree,
+ Repo: repo,
+ }, nil
+}
+
// GetStashEntries stash entryies
func (c *GitCommand) GetStashEntries() []StashEntry {
rawString, _ := c.OSCommand.RunCommandWithOutput("git stash list --pretty='%gs'")
diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go
index 062e8ee3d..ebf4fd43d 100644
--- a/pkg/commands/git_test.go
+++ b/pkg/commands/git_test.go
@@ -3,8 +3,10 @@ package commands
import (
"fmt"
"io/ioutil"
+ "os"
"os/exec"
"testing"
+ "time"
"github.com/jesseduffield/lazygit/pkg/i18n"
"github.com/jesseduffield/lazygit/pkg/test"
@@ -13,6 +15,39 @@ import (
gogit "gopkg.in/src-d/go-git.v4"
)
+type fileInfoMock struct {
+ name string
+ size int64
+ fileMode os.FileMode
+ fileModTime time.Time
+ isDir bool
+ sys interface{}
+}
+
+func (f fileInfoMock) Name() string {
+ return f.name
+}
+
+func (f fileInfoMock) Size() int64 {
+ return f.size
+}
+
+func (f fileInfoMock) Mode() os.FileMode {
+ return f.fileMode
+}
+
+func (f fileInfoMock) ModTime() time.Time {
+ return f.fileModTime
+}
+
+func (f fileInfoMock) IsDir() bool {
+ return f.isDir
+}
+
+func (f fileInfoMock) Sys() interface{} {
+ return f.sys
+}
+
func newDummyLog() *logrus.Entry {
log := logrus.New()
log.Out = ioutil.Discard
@@ -27,69 +62,155 @@ func newDummyGitCommand() *GitCommand {
}
}
-func TestGitCommandSetupGit(t *testing.T) {
+func TestVerifyInGitRepo(t *testing.T) {
type scenario struct {
- command func(string, ...string) *exec.Cmd
- openGitRepositoryAndWorktree func() (*gogit.Repository, *gogit.Worktree, error)
- test func(error)
+ runCmdWithOutput func(string) (string, error)
+ test func(error)
}
scenarios := []scenario{
{
- func(string, ...string) *exec.Cmd {
- return exec.Command("exit", "1")
+ func(string) (string, error) {
+ return "", nil
},
- func() (*gogit.Repository, *gogit.Worktree, error) {
- return nil, nil, nil
+ func(err error) {
+ assert.NoError(t, err)
+ },
+ },
+ {
+ func(string) (string, error) {
+ return "", ErrGitRepositoryInvalid
},
func(err error) {
assert.Error(t, err)
assert.Equal(t, ErrGitRepositoryInvalid, err)
},
},
+ }
+
+ for _, s := range scenarios {
+ s.test(verifyInGitRepo(s.runCmdWithOutput))
+ }
+}
+
+func TestNavigateToRepoRootDirectory(t *testing.T) {
+ type scenario struct {
+ stat func(string) (os.FileInfo, error)
+ chdir func(string) error
+ test func(error)
+ }
+
+ scenarios := []scenario{
{
- func(string, ...string) *exec.Cmd {
- return exec.Command("echo")
+ func(string) (os.FileInfo, error) {
+ return fileInfoMock{isDir: true}, nil
+ },
+ func(string) error {
+ return nil
+ },
+ func(err error) {
+ assert.NoError(t, err)
},
- func() (*gogit.Repository, *gogit.Worktree, error) {
- return nil, nil, fmt.Errorf(`unquoted '\' must be followed by new line`)
+ },
+ {
+ func(string) (os.FileInfo, error) {
+ return nil, fmt.Errorf("An error occurred")
+ },
+ func(string) error {
+ return nil
},
func(err error) {
assert.Error(t, err)
- assert.Contains(t, err.Error(), "gitconfig")
+ assert.EqualError(t, err, "An error occurred")
},
},
{
- func(string, ...string) *exec.Cmd {
- return exec.Command("echo")
+ func(string) (os.FileInfo, error) {
+ return nil, os.ErrNotExist
},
- func() (*gogit.Repository, *gogit.Worktree, error) {
- return nil, nil, fmt.Errorf("Error from inside gogit")
+ func(string) error {
+ return fmt.Errorf("An error occurred")
},
func(err error) {
assert.Error(t, err)
- assert.EqualError(t, err, "Error from inside gogit")
+ assert.EqualError(t, err, "An error occurred")
},
},
{
- func(string, ...string) *exec.Cmd {
- return exec.Command("echo")
+ func(string) (os.FileInfo, error) {
+ return nil, os.ErrNotExist
},
- func() (*gogit.Repository, *gogit.Worktree, error) {
- return &gogit.Repository{}, &gogit.Worktree{}, nil
+ func(string) error {
+ return fmt.Errorf("An error occurred")
},
func(err error) {
- assert.NoError(t, err)
+ assert.Error(t, err)
+ assert.EqualError(t, err, "An error occurred")
},
},
}
for _, s := range scenarios {
- gitCmd := newDummyGitCommand()
- gitCmd.OSCommand.command = s.command
- gitCmd.openGitRepositoryAndWorktree = s.openGitRepositoryAndWorktree
+ s.test(navigateToRepoRootDirectory(s.stat, s.chdir))
+ }
+}
+
+func TestSetupRepositoryAndWorktree(t *testing.T) {
+ type scenario struct {
+ openGitRepository func(string) (*gogit.Repository, error)
+ sLocalize func(string) string
+ test func(*gogit.Repository, *gogit.Worktree, error)
+ }
+
+ scenarios := []scenario{
+ {
+ func(string) (*gogit.Repository, error) {
+ return nil, fmt.Errorf(`unquoted '\' must be followed by new line`)
+ },
+ func(string) string {
+ return "error translated"
+ },
+ func(r *gogit.Repository, w *gogit.Worktree, err error) {
+ assert.Error(t, err)
+ assert.EqualError(t, err, "error translated")
+ },
+ },
+ {
+ func(string) (*gogit.Repository, error) {
+ return nil, fmt.Errorf("Error from inside gogit")
+ },
+ func(string) string { return "" },
+ func(r *gogit.Repository, w *gogit.Worktree, err error) {
+ assert.Error(t, err)
+ assert.EqualError(t, err, "Error from inside gogit")
+ },
+ },
+ {
+ func(string) (*gogit.Repository, error) {
+ return &gogit.Repository{}, nil
+ },
+ func(string) string { return "" },
+ func(r *gogit.Repository, w *gogit.Worktree, err error) {
+ assert.Error(t, err)
+ assert.Equal(t, gogit.ErrIsBareRepository, err)
+ },
+ },
+ {
+ func(string) (*gogit.Repository, error) {
+ assert.NoError(t, os.RemoveAll("/tmp/lazygit-test"))
+ r, err := gogit.PlainInit("/tmp/lazygit-test", false)
+ assert.NoError(t, err)
+ return r, nil
+ },
+ func(string) string { return "" },
+ func(r *gogit.Repository, w *gogit.Worktree, err error) {
+ assert.NoError(t, err)
+ },
+ },
+ }
- s.test(gitCmd.SetupGit())
+ for _, s := range scenarios {
+ s.test(setupRepositoryAndWorktree(s.openGitRepository, s.sLocalize))
}
}