diff options
author | Jesse Duffield <jessedduffield@gmail.com> | 2018-12-05 19:33:46 +1100 |
---|---|---|
committer | Jesse Duffield <jessedduffield@gmail.com> | 2018-12-05 19:33:46 +1100 |
commit | c0f9795910dd840fb83e6992f7f59c77ec4c13fc (patch) | |
tree | 05fe245b822008f458025a5dd75cae384bfda845 /pkg/commands | |
parent | 658e5a9faf8409c62f11f3ad6d636d0255e450f4 (diff) |
staging lines and hunks
Diffstat (limited to 'pkg/commands')
-rw-r--r-- | pkg/commands/git.go | 21 | ||||
-rw-r--r-- | pkg/commands/git_test.go | 79 | ||||
-rw-r--r-- | pkg/commands/os.go | 26 | ||||
-rw-r--r-- | pkg/commands/os_test.go | 32 |
4 files changed, 140 insertions, 18 deletions
diff --git a/pkg/commands/git.go b/pkg/commands/git.go index 262a57c2f..1d8e5a10d 100644 --- a/pkg/commands/git.go +++ b/pkg/commands/git.go @@ -3,7 +3,6 @@ package commands import ( "errors" "fmt" - "io/ioutil" "os" "os/exec" "strings" @@ -486,7 +485,6 @@ func (c *GitCommand) getMergeBase() (string, error) { output, err := c.OSCommand.RunCommandWithOutput(fmt.Sprintf("git merge-base HEAD %s", baseBranch)) if err != nil { // swallowing error because it's not a big deal; probably because there are no commits yet - c.Log.Error(err) } return output, nil } @@ -595,24 +593,13 @@ func (c *GitCommand) Diff(file *File, plain bool) string { } func (c *GitCommand) ApplyPatch(patch string) (string, error) { - - content := []byte(patch) - tmpfile, err := ioutil.TempFile("", "patch") + filename, err := c.OSCommand.CreateTempFile("patch", patch) if err != nil { c.Log.Error(err) - return "", errors.New("Could not create patch file") // TODO: i18n - } - - defer os.Remove(tmpfile.Name()) // clean up - - if _, err := tmpfile.Write(content); err != nil { - c.Log.Error(err) - return "", err - } - if err := tmpfile.Close(); err != nil { - c.Log.Error(err) return "", err } - return c.OSCommand.RunCommandWithOutput(fmt.Sprintf("git apply --cached %s", tmpfile.Name())) + defer func() { _ = c.OSCommand.RemoveFile(filename) }() + + return c.OSCommand.RunCommandWithOutput(fmt.Sprintf("git apply --cached %s", filename)) } diff --git a/pkg/commands/git_test.go b/pkg/commands/git_test.go index 0e1390535..206696b22 100644 --- a/pkg/commands/git_test.go +++ b/pkg/commands/git_test.go @@ -1770,6 +1770,7 @@ func TestGitCommandDiff(t *testing.T) { testName string command func(string, ...string) *exec.Cmd file *File + plain bool } scenarios := []scenario{ @@ -1786,6 +1787,22 @@ func TestGitCommandDiff(t *testing.T) { HasStagedChanges: false, Tracked: true, }, + false, + }, + { + "Default case", + func(cmd string, args ...string) *exec.Cmd { + assert.EqualValues(t, "git", cmd) + assert.EqualValues(t, []string{"diff", "--", "test.txt"}, args) + + return exec.Command("echo") + }, + &File{ + Name: "test.txt", + HasStagedChanges: false, + Tracked: true, + }, + true, }, { "All changes staged", @@ -1801,6 +1818,7 @@ func TestGitCommandDiff(t *testing.T) { HasUnstagedChanges: false, Tracked: true, }, + false, }, { "File not tracked and file has no staged changes", @@ -1815,6 +1833,7 @@ func TestGitCommandDiff(t *testing.T) { HasStagedChanges: false, Tracked: false, }, + false, }, } @@ -1822,7 +1841,7 @@ func TestGitCommandDiff(t *testing.T) { t.Run(s.testName, func(t *testing.T) { gitCmd := newDummyGitCommand() gitCmd.OSCommand.command = s.command - gitCmd.Diff(s.file, false) + gitCmd.Diff(s.file, s.plain) }) } } @@ -1979,3 +1998,61 @@ func TestGitCommandCurrentBranchName(t *testing.T) { }) } } + +func TestGitCommandApplyPatch(t *testing.T) { + type scenario struct { + testName string + command func(string, ...string) *exec.Cmd + test func(string, error) + } + + scenarios := []scenario{ + { + "valid case", + func(cmd string, args ...string) *exec.Cmd { + assert.Equal(t, "git", cmd) + assert.EqualValues(t, []string{"apply", "--cached"}, args[0:2]) + filename := args[2] + content, err := ioutil.ReadFile(filename) + assert.NoError(t, err) + + assert.Equal(t, "test", string(content)) + + return exec.Command("echo", "done") + }, + func(output string, err error) { + assert.NoError(t, err) + assert.EqualValues(t, "done\n", output) + }, + }, + { + "command returns error", + func(cmd string, args ...string) *exec.Cmd { + assert.Equal(t, "git", cmd) + assert.EqualValues(t, []string{"apply", "--cached"}, args[0:2]) + filename := args[2] + // TODO: Ideally we want to mock out OSCommand here so that we're not + // double handling testing it's CreateTempFile functionality, + // but it is going to take a bit of work to make a proper mock for it + // so I'm leaving it for another PR + content, err := ioutil.ReadFile(filename) + assert.NoError(t, err) + + assert.Equal(t, "test", string(content)) + + return exec.Command("test") + }, + func(output string, err error) { + assert.Error(t, err) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + gitCmd := newDummyGitCommand() + gitCmd.OSCommand.command = s.command + s.test(gitCmd.ApplyPatch("test")) + }) + } +} diff --git a/pkg/commands/os.go b/pkg/commands/os.go index 8b4b7879e..6b28a69bb 100644 --- a/pkg/commands/os.go +++ b/pkg/commands/os.go @@ -2,6 +2,7 @@ package commands import ( "errors" + "io/ioutil" "os" "os/exec" "strings" @@ -176,3 +177,28 @@ func (c *OSCommand) AppendLineToFile(filename, line string) error { _, err = f.WriteString("\n" + line) return err } + +// CreateTempFile writes a string to a new temp file and returns the file's name +func (c *OSCommand) CreateTempFile(filename, content string) (string, error) { + tmpfile, err := ioutil.TempFile("", filename) + if err != nil { + c.Log.Error(err) + return "", err + } + + if _, err := tmpfile.Write([]byte(content)); err != nil { + c.Log.Error(err) + return "", err + } + if err := tmpfile.Close(); err != nil { + c.Log.Error(err) + return "", err + } + + return tmpfile.Name(), nil +} + +// RemoveFile removes a file at the specified path +func (c *OSCommand) RemoveFile(filename string) error { + return os.Remove(filename) +} diff --git a/pkg/commands/os_test.go b/pkg/commands/os_test.go index ebb855cbe..a08c4b57d 100644 --- a/pkg/commands/os_test.go +++ b/pkg/commands/os_test.go @@ -1,6 +1,7 @@ package commands import ( + "io/ioutil" "os" "os/exec" "testing" @@ -364,3 +365,34 @@ func TestOSCommandFileType(t *testing.T) { _ = os.RemoveAll(s.path) } } + +func TestOSCommandCreateTempFile(t *testing.T) { + type scenario struct { + testName string + filename string + content string + test func(string, error) + } + + scenarios := []scenario{ + { + "valid case", + "filename", + "content", + func(path string, err error) { + assert.NoError(t, err) + + content, err := ioutil.ReadFile(path) + assert.NoError(t, err) + + assert.Equal(t, "content", string(content)) + }, + }, + } + + for _, s := range scenarios { + t.Run(s.testName, func(t *testing.T) { + s.test(newDummyOSCommand().CreateTempFile(s.filename, s.content)) + }) + } +} |