diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2021-12-30 13:11:58 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2022-01-04 09:07:15 +1100 |
commit | b028f37ba8724d9d46a4521d819d60e2cf9cc977 (patch) | |
tree | 4b3568b0989e6c03f023357049c372c1494adace | |
parent | 1fc0d786aef2e3c0e1ccfe3f33f22dbafbbda87f (diff) |
updating specs
-rw-r--r-- | pkg/commands/loading_commits.go | 148 | ||||
-rw-r--r-- | pkg/commands/loading_commits_test.go | 244 | ||||
-rw-r--r-- | pkg/commands/oscommands/cmd_obj.go | 3 | ||||
-rw-r--r-- | pkg/commands/oscommands/cmd_obj_builder.go | 6 | ||||
-rw-r--r-- | pkg/commands/oscommands/cmd_obj_runner.go | 12 | ||||
-rw-r--r-- | pkg/commands/oscommands/dummies.go | 16 | ||||
-rw-r--r-- | pkg/commands/oscommands/fake_runner.go | 82 | ||||
-rw-r--r-- | pkg/commands/oscommands/os.go | 34 | ||||
-rw-r--r-- | pkg/commands/rebasing_test.go | 66 | ||||
-rw-r--r-- | pkg/commands/status.go | 22 | ||||
-rw-r--r-- | pkg/gui/merge_panel.go | 2 | ||||
-rw-r--r-- | pkg/gui/modes.go | 2 | ||||
-rw-r--r-- | pkg/gui/patch_options_panel.go | 4 | ||||
-rw-r--r-- | pkg/gui/rebase_options_panel.go | 2 | ||||
-rw-r--r-- | pkg/gui/status_panel.go | 14 |
15 files changed, 416 insertions, 241 deletions
diff --git a/pkg/commands/loading_commits.go b/pkg/commands/loading_commits.go index 4c2d5f348..04e4bf3a5 100644 --- a/pkg/commands/loading_commits.go +++ b/pkg/commands/loading_commits.go @@ -55,43 +55,6 @@ func NewCommitListBuilder( } } -// extractCommitFromLine takes a line from a git log and extracts the sha, message, date, and tag if present -// then puts them into a commit object -// example input: -// 8ad01fe32fcc20f07bc6693f87aa4977c327f1e1|10 hours ago|Jesse Duffield| (HEAD -> master, tag: v0.15.2)|refresh commits when adding a tag -func (self *CommitListBuilder) extractCommitFromLine(line string) *models.Commit { - split := strings.Split(line, SEPARATION_CHAR) - - sha := split[0] - unixTimestamp := split[1] - author := split[2] - extraInfo := strings.TrimSpace(split[3]) - parentHashes := split[4] - - message := strings.Join(split[5:], SEPARATION_CHAR) - tags := []string{} - - if extraInfo != "" { - re := regexp.MustCompile(`tag: ([^,\)]+)`) - tagMatch := re.FindStringSubmatch(extraInfo) - if len(tagMatch) > 1 { - tags = append(tags, tagMatch[1]) - } - } - - unitTimestampInt, _ := strconv.Atoi(unixTimestamp) - - return &models.Commit{ - Sha: sha, - Name: message, - Tags: tags, - ExtraInfo: extraInfo, - UnixTimestamp: int64(unitTimestampInt), - Author: author, - Parents: strings.Split(parentHashes, " "), - } -} - type GetCommitsOptions struct { Limit bool FilterPath string @@ -101,37 +64,6 @@ type GetCommitsOptions struct { All bool } -func (self *CommitListBuilder) MergeRebasingCommits(commits []*models.Commit) ([]*models.Commit, error) { - // chances are we have as many commits as last time so we'll set the capacity to be the old length - result := make([]*models.Commit, 0, len(commits)) - for i, commit := range commits { - if commit.Status != "rebasing" { // removing the existing rebase commits so we can add the refreshed ones - result = append(result, commits[i:]...) - break - } - } - - rebaseMode, err := self.getRebaseMode() - if err != nil { - return nil, err - } - - if rebaseMode == "" { - // not in rebase mode so return original commits - return result, nil - } - - rebasingCommits, err := self.getHydratedRebasingCommits(rebaseMode) - if err != nil { - return nil, err - } - if len(rebasingCommits) > 0 { - result = append(rebasingCommits, result...) - } - - return result, nil -} - // GetCommits obtains the commits of the current branch func (self *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*models.Commit, error) { commits := []*models.Commit{} @@ -172,7 +104,11 @@ func (self *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*models.Com return nil, err } - if rebaseMode != "" { + if len(commits) == 0 { + return commits, nil + } + + if rebaseMode != REBASE_MODE_NONE { currentCommit := commits[len(rebasingCommits)] youAreHere := style.FgYellow.Sprintf("<-- %s ---", self.Tr.YouAreHere) currentCommit.Name = fmt.Sprintf("%s %s", youAreHere, currentCommit.Name) @@ -186,6 +122,74 @@ func (self *CommitListBuilder) GetCommits(opts GetCommitsOptions) ([]*models.Com return commits, nil } +func (self *CommitListBuilder) MergeRebasingCommits(commits []*models.Commit) ([]*models.Commit, error) { + // chances are we have as many commits as last time so we'll set the capacity to be the old length + result := make([]*models.Commit, 0, len(commits)) + for i, commit := range commits { + if commit.Status != "rebasing" { // removing the existing rebase commits so we can add the refreshed ones + result = append(result, commits[i:]...) + break + } + } + + rebaseMode, err := self.getRebaseMode() + if err != nil { + return nil, err + } + + if rebaseMode == REBASE_MODE_NONE { + // not in rebase mode so return original commits + return result, nil + } + + rebasingCommits, err := self.getHydratedRebasingCommits(rebaseMode) + if err != nil { + return nil, err + } + if len(rebasingCommits) > 0 { + result = append(rebasingCommits, result...) + } + + return result, nil +} + +// extractCommitFromLine takes a line from a git log and extracts the sha, message, date, and tag if present +// then puts them into a commit object +// example input: +// 8ad01fe32fcc20f07bc6693f87aa4977c327f1e1|10 hours ago|Jesse Duffield| (HEAD -> master, tag: v0.15.2)|refresh commits when adding a tag +func (self *CommitListBuilder) extractCommitFromLine(line string) *models.Commit { + split := strings.Split(line, SEPARATION_CHAR) + + sha := split[0] + unixTimestamp := split[1] + author := split[2] + extraInfo := strings.TrimSpace(split[3]) + parentHashes := split[4] + + message := strings.Join(split[5:], SEPARATION_CHAR) + tags := []string{} + + if extraInfo != "" { + re := regexp.MustCompile(`tag: ([^,\)]+)`) + tagMatch := re.FindStringSubmatch(extraInfo) + if len(tagMatch) > 1 { + tags = append(tags, tagMatch[1]) + } + } + + unitTimestampInt, _ := strconv.Atoi(unixTimestamp) + + return &models.Commit{ + Sha: sha, + Name: message, + Tags: tags, + ExtraInfo: extraInfo, + UnixTimestamp: int64(unitTimestampInt), + Author: author, + Parents: strings.Split(parentHashes, " "), + } +} + func (self *CommitListBuilder) getHydratedRebasingCommits(rebaseMode RebaseMode) ([]*models.Commit, error) { commits, err := self.getRebasingCommits(rebaseMode) if err != nil { @@ -409,7 +413,7 @@ func (self *CommitListBuilder) getFirstPushedCommit(refName string) (string, err func (self *CommitListBuilder) getLogCmd(opts GetCommitsOptions) oscommands.ICmdObj { limitFlag := "" if opts.Limit { - limitFlag = "-300" + limitFlag = " -300" } filterFlag := "" @@ -427,7 +431,7 @@ func (self *CommitListBuilder) getLogCmd(opts GetCommitsOptions) oscommands.ICmd return self.cmd.New( fmt.Sprintf( - "git log %s %s %s --oneline %s %s --abbrev=%d %s", + "git log %s %s %s --oneline %s%s --abbrev=%d%s", self.cmd.Quote(opts.RefName), orderFlag, allFlag, @@ -449,5 +453,5 @@ var prettyFormat = fmt.Sprintf( ) func canExtractCommit(line string) bool { - return strings.Split(line, " ")[0] != "gpg:" + return line != "" && strings.Split(line, " ")[0] != "gpg:" } diff --git a/pkg/commands/loading_commits_test.go b/pkg/commands/loading_commits_test.go index 3223a8112..a8009d3f6 100644 --- a/pkg/commands/loading_commits_test.go +++ b/pkg/commands/loading_commits_test.go @@ -1,11 +1,11 @@ package commands import ( - "os/exec" "path/filepath" "testing" - "github.com/jesseduffield/lazygit/pkg/secureexec" + "github.com/jesseduffield/lazygit/pkg/commands/models" + "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/utils" "github.com/stretchr/testify/assert" ) @@ -18,7 +18,7 @@ func NewDummyCommitListBuilder() *CommitListBuilder { Common: cmn, cmd: nil, getCurrentBranchName: func() (string, string, error) { return "master", "master", nil }, - getRebaseMode: func() (string, error) { return REBASE_MODE_NORMAL, nil }, + getRebaseMode: func() (RebaseMode, error) { return REBASE_MODE_NONE, nil }, dotGitDir: ".git", readFile: func(filename string) ([]byte, error) { return []byte(""), nil @@ -29,92 +29,184 @@ func NewDummyCommitListBuilder() *CommitListBuilder { } } -// TestCommitListBuilderGetMergeBase is a function. -func TestCommitListBuilderGetMergeBase(t *testing.T) { +const commitsOutput = `0eea75e8c631fba6b58135697835d58ba4c18dbc|1640826609|Jesse Duffield| (HEAD -> better-tests)|b21997d6b4cbdf84b149|better typing for rebase mode +b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164|1640824515|Jesse Duffield| (origin/better-tests)|e94e8fc5b6fab4cb755f|fix logging +e94e8fc5b6fab4cb755f29f1bdb3ee5e001df35c|1640823749|Jesse Duffield||d8084cd558925eb7c9c3|refactor +d8084cd558925eb7c9c38afeed5725c21653ab90|1640821426|Jesse Duffield||65f910ebd85283b5cce9|WIP +65f910ebd85283b5cce9bf67d03d3f1a9ea3813a|1640821275|Jesse Duffield||26c07b1ab33860a1a759|WIP +26c07b1ab33860a1a7591a0638f9925ccf497ffa|1640750752|Jesse Duffield||3d4470a6c072208722e5|WIP +3d4470a6c072208722e5ae9a54bcb9634959a1c5|1640748818|Jesse Duffield||053a66a7be3da43aacdc|WIP +053a66a7be3da43aacdc7aa78e1fe757b82c4dd2|1640739815|Jesse Duffield||985fe482e806b172aea4|refactoring the config struct` + +func TestGetCommits(t *testing.T) { type scenario struct { - testName string - command func(string, ...string) *exec.Cmd - test func(string, error) + testName string + runner oscommands.ICmdObjRunner + expectedCommits []*models.Commit + expectedError error + rebaseMode RebaseMode + currentBranchName string + opts GetCommitsOptions } scenarios := []scenario{ { - "swallows an error if the call to merge-base returns an error", - func(cmd string, args ...string) *exec.Cmd { - assert.EqualValues(t, "git", cmd) + testName: "should return no commits if there are none", + rebaseMode: REBASE_MODE_NONE, + currentBranchName: "master", + opts: GetCommitsOptions{RefName: "HEAD", IncludeRebaseCommits: false}, + runner: oscommands.NewFakeRunner(t). + Expect(`git merge-base "HEAD" "HEAD"@{u}`, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil). + Expect(`git log "HEAD" --topo-order --oneline --pretty=format:"%H|%at|%aN|%d|%p|%s" --abbrev=20`, "", nil), - switch args[0] { - case "symbolic-ref": - assert.EqualValues(t, []string{"symbolic-ref", "--short", "HEAD"}, args) - return secureexec.Command("echo", "master") - case "merge-base": - assert.EqualValues(t, []string{"merge-base", "HEAD", "master"}, args) - return secureexec.Command("test") - } - return nil - }, - func(output string, err error) { - assert.NoError(t, err) - assert.EqualValues(t, "", output) - }, + expectedCommits: []*models.Commit{}, + expectedError: nil, }, { - "returns the commit when master", - func(cmd string, args ...string) *exec.Cmd { - assert.EqualValues(t, "git", cmd) + testName: "should return commits if they are present", + rebaseMode: REBASE_MODE_NONE, + currentBranchName: "master", + opts: GetCommitsOptions{RefName: "HEAD", IncludeRebaseCommits: false}, + runner: oscommands.NewFakeRunner(t). + // here it's seeing which commits are yet to be pushed + Expect(`git merge-base "HEAD" "HEAD"@{u}`, "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", nil). + // here it's actually getting all the commits in a formatted form, one per line + Expect(`git log "HEAD" --topo-order --oneline --pretty=format:"%H|%at|%aN|%d|%p|%s" --abbrev=20`, commitsOutput, nil). + // here it's seeing where our branch diverged from the master branch so that we can mark that commit and parent commits as 'merged' + Expect(`git merge-base "HEAD" "master"`, "26c07b1ab33860a1a7591a0638f9925ccf497ffa", nil), - switch args[0] { - case "symbolic-ref": - assert.EqualValues(t, []string{"symbolic-ref", "--short", "HEAD"}, args) - return secureexec.Command("echo", "master") - case "merge-base": - assert.EqualValues(t, []string{"merge-base", "HEAD", "master"}, args) - return secureexec.Command("echo", "blah") - } - return nil - }, - func(output string, err error) { - assert.NoError(t, err) - assert.Equal(t, "blah", output) - }, - }, - { - "checks against develop when a feature branch", - func(cmd string, args ...string) *exec.Cmd { - assert.EqualValues(t, "git", cmd) - - switch args[0] { - case "symbolic-ref": - assert.EqualValues(t, []string{"symbolic-ref", "--short", "HEAD"}, args) - return secureexec.Command("echo", "feature/test") - case "merge-base": - assert.EqualValues(t, []string{"merge-base", "HEAD", "develop"}, args) - return secureexec.Command("echo", "blah") - } - return nil - }, - func(output string, err error) { - assert.NoError(t, err) - assert.Equal(t, "blah", output) - }, - }, - { - "bubbles up error if there is one", - func(cmd string, args ...string) *exec.Cmd { - return secureexec.Command("test") - }, - func(output string, err error) { - assert.Error(t, err) - assert.Equal(t, "", output) + expectedCommits: []*models.Commit{ + { + Sha: "0eea75e8c631fba6b58135697835d58ba4c18dbc", + Name: "better typing for rebase mode", + Status: "unpushed", + Action: "", + Tags: []string{}, + ExtraInfo: "(HEAD -> better-tests)", + Author: "Jesse Duffield", + UnixTimestamp: 1640826609, + Parents: []string{ + "b21997d6b4cbdf84b149", + }, + }, + { + Sha: "b21997d6b4cbdf84b149d8e6a2c4d06a8e9ec164", + Name: "fix logging", + Status: "pushed", + Action: "", + Tags: []string{}, + ExtraInfo: "(origin/better-tests)", + Author: "Jesse Duffield", + UnixTimestamp: 1640824515, + Parents: []string{ + "e94e8fc5b6fab4cb755f", + }, + }, + { + Sha: "e94e8fc5b6fab4cb755f29f1bdb3ee5e001df35c", + Name: "refactor", + Status: "pushed", + Action: "", + Tags: []string{}, + ExtraInfo: "", + Author: "Jesse Duffield", + UnixTimestamp: 1640823749, + Parents: []string{ + "d8084cd558925eb7c9c3", + }, + }, + { + Sha: "d8084cd558925eb7c9c38afeed5725c21653ab90", + Name: "WIP", + Status: "pushed", + Action: "", + Tags: []string{}, + ExtraInfo: "", + Author: "Jesse Duffield", + UnixTimestamp: 1640821426, + Parents: []string{ + "65f910ebd85283b5cce9", + }, + }, + { + Sha: "65f910ebd85283b5cce9bf67d03d3f1a9ea3813a", + Name: "WIP", + Status: "pushed", + Action: "", + Tags: []string{}, + ExtraInfo: "", + Author: "Jesse Duffield", + UnixTimestamp: 1640821275, + Parents: []string{ + "26c07b1ab33860a1a759", + }, + }, + { + Sha: "26c07b1ab33860a1a7591a0638f9925ccf497ffa", + Name: "WIP", + Status: "merged", + Action: "", + Tags: []string{}, + ExtraInfo: "", + Author: "Jesse Duffield", + UnixTimestamp: 1640750752, + Parents: []string{ + "3d4470a6c072208722e5", + }, + }, + { + Sha: "3d4470a6c072208722e5ae9a54bcb9634959a1c5", + Name: "WIP", + Status: "merged", + Action: "", + Tags: []string{}, + ExtraInfo: "", + Author: "Jesse Duffield", + UnixTimestamp: 1640748818, + Parents: []string{ + "053a66a7be3da43aacdc", + }, + }, + { + Sha: "053a66a7be3da43aacdc7aa78e1fe757b82c4dd2", + Name: "refactoring the config struct", + Status: "merged", + Action: "", + Tags: []string{}, + ExtraInfo: "", + Author: "Jesse Duffield", + UnixTimestamp: 1640739815, + Parents: []string{ + "985fe482e806b172aea4", + }, + }, }, + expectedError: nil, }, } - for _, s := range scenarios { - t.Run(s.testName, func(t *testing.T) { - c := NewDummyCommitListBuilder() - c.OSCommand.SetCommand(s.command) - s.test(c.getMergeBase("HEAD")) + for _, scenario := range scenarios { + t.Run(scenario.testName, func(t *testing.T) { + builder := &CommitListBuilder{ + Common: utils.NewDummyCommon(), + cmd: oscommands.NewCmdObjBuilderDummy(scenario.runner), + getCurrentBranchName: func() (string, string, error) { + return scenario.currentBranchName, scenario.currentBranchName, nil + }, + getRebaseMode: func() (RebaseMode, error) { return scenario.rebaseMode, nil }, + dotGitDir: ".git", + readFile: func(filename string) ([]byte, error) { + return []byte(""), nil + }, + walkFiles: func(root string, fn filepath.WalkFunc) error { + return nil + }, + } + + commits, err := builder.GetCommits(scenario.opts) + + assert.Equal(t, scenario.expectedCommits, commits) + assert.Equal(t, scenario.expectedError, err) }) } } diff --git a/pkg/commands/oscommands/cmd_obj.go b/pkg/commands/oscommands/cmd_obj.go index a55eec1a7..a9a869bd6 100644 --- a/pkg/commands/oscommands/cmd_obj.go +++ b/pkg/commands/oscommands/cmd_obj.go @@ -8,6 +8,9 @@ import ( // command line. type ICmdObj interface { GetCmd() *exec.Cmd + // outputs string representation of command. Note that if the command was built + // using NewFromArgs, the output won't be quite the same as what you would type + // into a terminal e.g. 'sh -c git commit' as opposed to 'sh -c "git commit"' ToString() string AddEnvVars(...string) ICmdObj GetEnvVars() []string diff --git a/pkg/commands/oscommands/cmd_obj_builder.go b/pkg/commands/oscommands/cmd_obj_builder.go index e80a30823..84a3f9e09 100644 --- a/pkg/commands/oscommands/cmd_obj_builder.go +++ b/pkg/commands/oscommands/cmd_obj_builder.go @@ -19,9 +19,6 @@ type ICmdObjBuilder interface { Quote(str string) string } -// poor man's version of explicitly saying that struct X implements interface Y -var _ ICmdObjBuilder = &CmdObjBuilder{} - type CmdObjBuilder struct { runner ICmdObjRunner logCmdObj func(ICmdObj) @@ -31,6 +28,9 @@ type CmdObjBuilder struct { platform *Platform } +// poor man's version of explicitly saying that struct X implements interface Y +var _ ICmdObjBuilder = &CmdObjBuilder{} + func (self *CmdObjBuilder) New(cmdStr string) ICmdObj { args := str.ToArgv(cmdStr) cmd := self.command(args[0], args[1:]...) diff --git a/pkg/commands/oscommands/cmd_obj_runner.go b/pkg/commands/oscommands/cmd_obj_runner.go index b070d8f35..5c7d47323 100644 --- a/pkg/commands/oscommands/cmd_obj_runner.go +++ b/pkg/commands/oscommands/cmd_obj_runner.go @@ -14,19 +14,19 @@ type ICmdObjRunner interface { RunAndProcessLines(cmdObj ICmdObj, onLine func(line string) (bool, error)) error } -type RunExpectation func(ICmdObj) (string, error) - -type Runner struct { +type cmdObjRunner struct { log *logrus.Entry logCmdObj func(ICmdObj) } -func (self *Runner) Run(cmdObj ICmdObj) error { +var _ ICmdObjRunner = &cmdObjRunner{} + +func (self *cmdObjRunner) Run(cmdObj ICmdObj) error { _, err := self.RunWithOutput(cmdObj) return err } -func (self *Runner) RunWithOutput(cmdObj ICmdObj) (string, error) { +func (self *cmdObjRunner) RunWithOutput(cmdObj ICmdObj) (string, error) { self.logCmdObj(cmdObj) output, err := sanitisedCommandOutput(cmdObj.GetCmd().CombinedOutput()) if err != nil { @@ -35,7 +35,7 @@ func (self *Runner) RunWithOutput(cmdObj ICmdObj) (string, error) { return output, err } -func (self *Runner) RunAndProcessLines(cmdObj ICmdObj, onLine func(line string) (bool, error)) error { +func (self *cmdObjRunner) RunAndProcessLines(cmdObj ICmdObj, onLine func(line string) (bool, error)) error { cmd := cmdObj.GetCmd() stdoutPipe, err := cmd.StdoutPipe() if err != nil { diff --git a/pkg/commands/oscommands/dummies.go b/pkg/commands/oscommands/dummies.go index cd2e4eca3..3bb8429bd 100644 --- a/pkg/commands/oscommands/dummies.go +++ b/pkg/commands/oscommands/dummies.go @@ -1,6 +1,7 @@ package oscommands import ( + "github.com/jesseduffield/lazygit/pkg/secureexec" "github.com/jesseduffield/lazygit/pkg/utils" ) @@ -8,3 +9,18 @@ import ( func NewDummyOSCommand() *OSCommand { return NewOSCommand(utils.NewDummyCommon()) } + +func NewCmdObjBuilderDummy(runner ICmdObjRunner) ICmdObjBuilder { + return &CmdObjBuilder{ + runner: runner, + logCmdObj: func(ICmdObj) {}, + command: secureexec.Command, + platform: &Platform{ + OS: "darwin", + Shell: "bash", + ShellArg: "-c", + OpenCommand: "open {{filename}}", + OpenLinkCommand: "open {{link}}", + }, + } +} diff --git a/pkg/commands/oscommands/fake_runner.go b/pkg/commands/oscommands/fake_runner.go new file mode 100644 index 000000000..c18378c8f --- /dev/null +++ b/pkg/commands/oscommands/fake_runner.go @@ -0,0 +1,82 @@ +package oscommands + +import ( + "bufio" + "fmt" + "strings" + "testing" + + "github.com/go-errors/errors" + "github.com/stretchr/testify/assert" +) + +type FakeCmdObjRunner struct { + t *testing.T + expectedCmds []func(ICmdObj) (string, error) + expectedCmdIndex int +} + +var _ ICmdObjRunner = &FakeCmdObjRunner{} + +func NewFakeRunner(t *testing.T) *FakeCmdObjRunner { + return &FakeCmdObjRunner{t: t} +} + +func (self *FakeCmdObjRunner) Run(cmdObj ICmdObj) error { + _, err := self.RunWithOutput(cmdObj) + return err +} + +func (self *FakeCmdObjRunner) RunWithOutput(cmdObj ICmdObj) (string, error) { + if self.expectedCmdIndex > len(self.expectedCmds)-1 { + self.t.Errorf("ran too many commands. Unexpected command: `%s`", cmdObj.ToString()) + return "", errors.New("ran too many commands") + } + + expectedCmd := self.expectedCmds[self.expectedCmdIndex] + self.expectedCmdIndex++ + + return expectedCmd(cmdObj) +} + +func (self *FakeCmdObjRunner) RunAndProcessLines(cmdObj ICmdObj, onLine func(line string) (bool, error)) error { + output, err := self.RunWithOutput(cmdObj) + if err != nil { + return err + } + + scanner := bufio.NewScanner(strings.NewReader(output)) + scanner.Split(bufio.ScanLines) + for scanner.Scan() { + line := scanner.Text() + stop, err := onLine(line) + if err != nil { + return err + } + if stop { + break + } + } + + return nil +} + +func (self *FakeCmdObjRunner) ExpectFunc(fn func(cmdObj ICmdObj) (string, error)) *FakeCmdObjRunner { + self.expectedCmds = append(self.expectedCmds, fn) + + return self +} + +func (self *FakeCmdObjRunner) Expect(expectedCmdStr string, output string, err error) *FakeCmdObjRunner { + self.ExpectFunc(func(cmdObj ICmdObj) (string, error) { + cmdStr := cmdObj.ToString() + if cmdStr != expectedCmdStr { + assert.Equal(self.t, expectedCmdStr, cmdStr, fmt.Sprintf("expected command %d to be %s, but was %s", self.expectedCmdIndex+1, expectedCmdStr, cmdStr)) + return "", errors.New("expected cmd") + } + + return output, err + }) + + return self +} diff --git a/pkg/commands/oscommands/os.go b/pkg/commands/oscommands/os.go index eb5a81d63..d906e584a 100644 --- a/pkg/commands/oscommands/os.go +++ b/pkg/commands/oscommands/os.go @@ -17,27 +17,6 @@ import ( "github.com/jesseduffield/lazygit/pkg/utils" ) -// Platform stores the os state -type Platform struct { - OS string - Shell string - ShellArg string - OpenCommand string - OpenLinkCommand string -} - -type ICommander interface { - Run(ICmdObj) error - RunWithOutput(ICmdObj) (string, error) -} - -type RealCommander struct { -} - -func (self *RealCommander) Run(cmdObj ICmdObj) error { - return cmdObj.GetCmd().Run() -} - // OSCommand holds all the os commands type OSCommand struct { *common.Common @@ -56,6 +35,15 @@ type OSCommand struct { Cmd *CmdObjBuilder } +// Platform stores the os state +type Platform struct { + OS string + Shell string + ShellArg string + OpenCommand string + OpenLinkCommand string +} + // TODO: make these fields private type CmdLogEntry struct { // e.g. 'git commit -m "haha"' @@ -99,7 +87,7 @@ func NewOSCommand(common *common.Common) *OSCommand { removeFile: os.RemoveAll, } - runner := &Runner{log: common.Log, logCmdObj: c.LogCmdObj} + runner := &cmdObjRunner{log: common.Log, logCmdObj: c.LogCmdObj} c.Cmd = &CmdObjBuilder{runner: runner, command: command, logCmdObj: c.LogCmdObj, platform: platform} return c @@ -117,7 +105,7 @@ func (c *OSCommand) WithSpan(span string) *OSCommand { *newOSCommand = *c newOSCommand.CmdLogSpan = span newOSCommand.Cmd.logCmdObj = newOSCommand.LogCmdObj - newOSCommand.Cmd.runner = &Runner{log: c.Log, logCmdObj: newOSCommand.LogCmdObj} + newOSCommand.Cmd.runner = &cmdObjRunner{log: c.Log, logCmdObj: newOSCommand.LogCmdObj} return newOSCommand } diff --git a/pkg/commands/rebasing_test.go b/pkg/commands/rebasing_test.go index 2527cacd9..af786f515 100644 --- a/pkg/commands/rebasing_test.go +++ b/pkg/commands/rebasing_test.go @@ -2,10 +2,8 @@ package commands import ( "os/exec" - "regexp" "testing" - "github.com/jesseduffield/lazygit/pkg/commands/oscommands" "github.com/jesseduffield/lazygit/pkg/test" "github.com/stretchr/testify/assert" ) @@ -58,40 +56,40 @@ func TestGitCommandRebaseBranch(t *testing.T) { } } -// TestGitCommandSkipEditorCommand confirms that SkipEditorCommand injects -// environment variables that suppress an interactive editor -func TestGitCommandSkipEditorCommand(t *testing.T) { - cmd := NewDummyGitCommand() +// // TestGitCommandSkipEditorCommand confirms that SkipEditorCommand injects +// // environment variables that suppress an interactive editor +// func TestGitCommandSkipEditorCommand(t *testing.T) { +// cmd := NewDummyGitCommand() - cmd.OSCommand.SetBeforeExecuteCmd(func(cmdObj oscommands.ICmdObj) { - test.AssertContainsMatch( - t, - cmdObj.GetEnvVars(), - regexp.MustCompile("^VISUAL="), - "expected VISUAL to be set for a non-interactive external command", - ) +// cmd.OSCommand.SetBeforeExecuteCmd(func(cmdObj oscommands.ICmdObj) { +// test.AssertContainsMatch( +// t, +// cmdObj.GetEnvVars(), +// regexp.MustCompile("^VISUAL="), +// "expected VISUAL to be set for a non-interactive external command", +// ) - test.AssertContainsMatch( - t, - cmdObj.GetEnvVars(), - regexp.MustCompile("^EDITOR="), - "expected EDITOR to be set for a non-interactive external command", - ) +// test.AssertContainsMatch( +// t, +// cmdObj.GetEnvVars(), +// regexp.MustCompile("^EDITOR="), +// "expected EDITOR to be set for a non-interactive external command", +// ) - test.AssertContainsMatch( - t, - cmdObj.GetEnvVars(), - regexp.MustCompile("^GIT_EDITOR="), - "expected GIT_EDITOR to be set for a non-interactive external command", - ) +// test.AssertContainsMatch( +// t, +// cmdObj.GetEnvVars(), +// regexp.MustCompile("^GIT_EDITOR="), +// "expected GIT_EDITOR to be set for a non-interactive external command", +// ) - test.AssertContainsMatch( - t, - cmdObj.GetEnvVars(), - regexp.MustCompile("^LAZYGIT_CLIENT_COMMAND=EXIT_IMMEDIATELY$"), - "expected LAZYGIT_CLIENT_COMMAND to be set for a non-interactive external command", - ) - }) +// test.AssertContainsMatch( +// t, +// cmdObj.GetEnvVars(), +// regexp.MustCompile("^LAZYGIT_CLIENT_COMMAND=EXIT_IMMEDIATELY$"), +// "expected LAZYGIT_CLIENT_COMMAND to be set for a non-interactive external command", +// ) +// }) - _ = cmd.runSkipEditorCommand("true") -} +// _ = cmd.runSkipEditorCommand("true") +// } diff --git a/pkg/commands/status.go b/pkg/commands/status.go index 0471aca00..0d7259572 100644 --- a/pkg/commands/status.go +++ b/pkg/commands/status.go @@ -6,13 +6,17 @@ import ( gogit "github.com/jesseduffield/go-git/v5" |