mirror of
https://github.com/jesseduffield/lazygit.git
synced 2025-02-07 13:42:01 +02:00
merge setup in function that create a new git command
This commit is contained in:
parent
9f7775df26
commit
43ad9a81c2
6
main.go
6
main.go
@ -49,11 +49,5 @@ func main() {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if err := app.GitCommand.SetupGit(); err != nil {
|
||||
app.Log.Error(err.Error())
|
||||
fmt.Println(err)
|
||||
os.Exit(1)
|
||||
}
|
||||
|
||||
app.Gui.RunWithSubprocesses()
|
||||
}
|
||||
|
@ -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'")
|
||||
|
@ -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() (*gogit.Repository, *gogit.Worktree, error) {
|
||||
return nil, nil, fmt.Errorf(`unquoted '\' must be followed by new line`)
|
||||
func(string) error {
|
||||
return nil
|
||||
},
|
||||
func(err error) {
|
||||
assert.Error(t, err)
|
||||
assert.Contains(t, err.Error(), "gitconfig")
|
||||
assert.NoError(t, err)
|
||||
},
|
||||
},
|
||||
{
|
||||
func(string, ...string) *exec.Cmd {
|
||||
return exec.Command("echo")
|
||||
func(string) (os.FileInfo, error) {
|
||||
return nil, fmt.Errorf("An error occurred")
|
||||
},
|
||||
func() (*gogit.Repository, *gogit.Worktree, error) {
|
||||
return nil, nil, fmt.Errorf("Error from inside gogit")
|
||||
func(string) error {
|
||||
return nil
|
||||
},
|
||||
func(err error) {
|
||||
assert.Error(t, err)
|
||||
assert.EqualError(t, err, "An error occurred")
|
||||
},
|
||||
},
|
||||
{
|
||||
func(string) (os.FileInfo, error) {
|
||||
return nil, os.ErrNotExist
|
||||
},
|
||||
func(string) error {
|
||||
return fmt.Errorf("An error occurred")
|
||||
},
|
||||
func(err error) {
|
||||
assert.Error(t, err)
|
||||
assert.EqualError(t, err, "An error occurred")
|
||||
},
|
||||
},
|
||||
{
|
||||
func(string) (os.FileInfo, error) {
|
||||
return nil, os.ErrNotExist
|
||||
},
|
||||
func(string) error {
|
||||
return fmt.Errorf("An error occurred")
|
||||
},
|
||||
func(err error) {
|
||||
assert.Error(t, err)
|
||||
assert.EqualError(t, err, "An error occurred")
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
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, ...string) *exec.Cmd {
|
||||
return exec.Command("echo")
|
||||
func(string) (*gogit.Repository, error) {
|
||||
return &gogit.Repository{}, nil
|
||||
},
|
||||
func() (*gogit.Repository, *gogit.Worktree, error) {
|
||||
return &gogit.Repository{}, &gogit.Worktree{}, 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(err error) {
|
||||
},
|
||||
{
|
||||
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)
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, s := range scenarios {
|
||||
gitCmd := newDummyGitCommand()
|
||||
gitCmd.OSCommand.command = s.command
|
||||
gitCmd.openGitRepositoryAndWorktree = s.openGitRepositoryAndWorktree
|
||||
|
||||
s.test(gitCmd.SetupGit())
|
||||
s.test(setupRepositoryAndWorktree(s.openGitRepository, s.sLocalize))
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user