summaryrefslogtreecommitdiffstats
path: root/pkg
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2021-12-30 13:11:58 +1100
committerJesse Duffield <jessedduffield@gmail.com>2021-12-30 13:11:58 +1100
commitc24bb111411057ea90054630cdd29a545704240e (patch)
tree5542d0d4ec8e5f411af041d3229cfa42bfb3d0a3 /pkg
parent0eea75e8c631fba6b58135697835d58ba4c18dbc (diff)
updating specs
Diffstat (limited to 'pkg')
-rw-r--r--pkg/commands/loading_commits.go148
-rw-r--r--pkg/commands/loading_commits_test.go244
-rw-r--r--pkg/commands/oscommands/cmd_obj.go3
-rw-r--r--pkg/commands/oscommands/cmd_obj_builder.go6
-rw-r--r--pkg/commands/oscommands/cmd_obj_runner.go12
-rw-r--r--pkg/commands/oscommands/dummies.go16
-rw-r--r--pkg/commands/oscommands/fake_runner.go82
-rw-r--r--pkg/commands/oscommands/os.go34
-rw-r--r--pkg/commands/rebasing_test.go66
-rw-r--r--pkg/commands/status.go22
-rw-r--r--pkg/gui/merge_panel.go2
-rw-r--r--pkg/gui/modes.go2
-rw-r--r--pkg/gui/patch_options_panel.go4
-rw-r--r--pkg/gui/rebase_options_panel.go2
-rw-r--r--pkg/gui/status_panel.go14
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"
)
-type RebaseMode string
+type RebaseMode int
const (
- REBASE_MODE_NORMAL RebaseMode = "normal"
- REBASE_MODE_INTERACTIVE = "interactive"
- REBASE_MODE_REBASING = "rebasing"
- REBASE_MODE_MERGING = "merging"
+ // this means we're neither rebasing nor merging
+ REBASE_MODE_NONE RebaseMode = iota
+ // this means normal