summaryrefslogtreecommitdiffstats
path: root/pkg/commands
diff options
context:
space:
mode:
authorJesse Duffield <jessedduffield@gmail.com>2018-12-05 19:33:46 +1100
committerJesse Duffield <jessedduffield@gmail.com>2018-12-05 19:33:46 +1100
commitc0f9795910dd840fb83e6992f7f59c77ec4c13fc (patch)
tree05fe245b822008f458025a5dd75cae384bfda845 /pkg/commands
parent658e5a9faf8409c62f11f3ad6d636d0255e450f4 (diff)
staging lines and hunks
Diffstat (limited to 'pkg/commands')
-rw-r--r--pkg/commands/git.go21
-rw-r--r--pkg/commands/git_test.go79
-rw-r--r--pkg/commands/os.go26
-rw-r--r--pkg/commands/os_test.go32
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))
+ })
+ }
+}